Commit 4c19a8a8 by Jamie Madill Committed by Commit Bot

D3D11: Update cached dynamically recompiled programs.

This change makes it so that when we need to recompile a program on a draw call, we also update the cache. It also streamlines the internal queries of the dynamic vertex and fragment shaders such that we only update the input and output signatures a single time per draw. This should also facilitate dirty bit implementations for the D3D11 back- end. BUG=angleproject:2116 Change-Id: Iccb0501b700bc894f40a8c68d7f297ff0c8f46bd Reviewed-on: https://chromium-review.googlesource.com/531798Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent b6664925
...@@ -1837,14 +1837,14 @@ void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params) ...@@ -1837,14 +1837,14 @@ void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
void Context::drawArrays(GLenum mode, GLint first, GLsizei count) void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count)); ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback()); MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
} }
void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY( ANGLE_CONTEXT_TRY(
mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount)); mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback()); MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
...@@ -1852,7 +1852,7 @@ void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz ...@@ -1852,7 +1852,7 @@ void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices)); ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
} }
...@@ -1862,7 +1862,7 @@ void Context::drawElementsInstanced(GLenum mode, ...@@ -1862,7 +1862,7 @@ void Context::drawElementsInstanced(GLenum mode,
const void *indices, const void *indices,
GLsizei instances) GLsizei instances)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY( ANGLE_CONTEXT_TRY(
mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances)); mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
} }
...@@ -1874,20 +1874,20 @@ void Context::drawRangeElements(GLenum mode, ...@@ -1874,20 +1874,20 @@ void Context::drawRangeElements(GLenum mode,
GLenum type, GLenum type,
const void *indices) const void *indices)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY( ANGLE_CONTEXT_TRY(
mImplementation->drawRangeElements(this, mode, start, end, count, type, indices)); mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
} }
void Context::drawArraysIndirect(GLenum mode, const void *indirect) void Context::drawArraysIndirect(GLenum mode, const void *indirect)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect)); ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
} }
void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect) void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
{ {
ANGLE_CONTEXT_TRY(prepareForDraw()); ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect)); ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
} }
...@@ -2170,7 +2170,7 @@ GLint Context::getProgramResourceLocation(GLuint program, ...@@ -2170,7 +2170,7 @@ GLint Context::getProgramResourceLocation(GLuint program,
return QueryProgramResourceLocation(programObject, programInterface, name); return QueryProgramResourceLocation(programObject, programInterface, name);
} }
void Context::handleError(const Error &error) Error Context::handleError(const Error &error)
{ {
if (error.isError()) if (error.isError())
{ {
...@@ -2188,6 +2188,8 @@ void Context::handleError(const Error &error) ...@@ -2188,6 +2188,8 @@ void Context::handleError(const Error &error)
GL_DEBUG_SEVERITY_HIGH, error.getMessage()); GL_DEBUG_SEVERITY_HIGH, error.getMessage());
} }
} }
return error;
} }
// Get one of the recorded errors and clear its flag, if any. // Get one of the recorded errors and clear its flag, if any.
...@@ -2820,10 +2822,18 @@ void Context::initWorkarounds() ...@@ -2820,10 +2822,18 @@ void Context::initWorkarounds()
mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
} }
Error Context::prepareForDraw() Error Context::prepareForDraw(GLenum drawMode)
{ {
syncRendererState(); syncRendererState();
return NoError();
InfoLog infoLog;
Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
mMemoryProgramCache, drawMode);
if (err.isError())
{
WARN() << "Dynamic recompilation error log: " << infoLog.str();
}
return err;
} }
void Context::syncRendererState() void Context::syncRendererState()
......
...@@ -779,7 +779,8 @@ class Context final : public ValidationContext ...@@ -779,7 +779,8 @@ class Context final : public ValidationContext
void *binary); void *binary);
void programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); void programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
void handleError(const Error &error) override; // Returns the error.
Error handleError(const Error &error) override;
GLenum getError(); GLenum getError();
void markContextLost(); void markContextLost();
...@@ -832,7 +833,7 @@ class Context final : public ValidationContext ...@@ -832,7 +833,7 @@ class Context final : public ValidationContext
egl::Surface *getCurrentReadSurface() const { return mCurrentSurface; } egl::Surface *getCurrentReadSurface() const { return mCurrentSurface; }
private: private:
Error prepareForDraw(); Error prepareForDraw(GLenum drawMode);
void syncRendererState(); void syncRendererState();
void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask); void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
void syncStateForReadPixels(); void syncStateForReadPixels();
......
...@@ -100,7 +100,7 @@ class ValidationContext : angle::NonCopyable ...@@ -100,7 +100,7 @@ class ValidationContext : angle::NonCopyable
bool skipValidation); bool skipValidation);
virtual ~ValidationContext() {} virtual ~ValidationContext() {}
virtual void handleError(const Error &error) = 0; virtual Error handleError(const Error &error) = 0;
const ContextState &getContextState() const { return mState; } const ContextState &getContextState() const { return mState; }
GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); } GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
......
...@@ -585,6 +585,13 @@ void MemoryProgramCache::putProgram(const ProgramHash &programHash, ...@@ -585,6 +585,13 @@ void MemoryProgramCache::putProgram(const ProgramHash &programHash,
put(programHash, std::move(binaryProgram)); put(programHash, std::move(binaryProgram));
} }
void MemoryProgramCache::updateProgram(const Context *context, const Program *program)
{
gl::ProgramHash programHash;
ComputeHash(context, program, &programHash);
putProgram(programHash, context, program);
}
void MemoryProgramCache::putBinary(const ProgramHash &programHash, void MemoryProgramCache::putBinary(const ProgramHash &programHash,
const uint8_t *binary, const uint8_t *binary,
size_t length) size_t length)
......
...@@ -82,6 +82,9 @@ class MemoryProgramCache final : angle::NonCopyable ...@@ -82,6 +82,9 @@ class MemoryProgramCache final : angle::NonCopyable
// Helper method that serializes a program. // Helper method that serializes a program.
void putProgram(const ProgramHash &programHash, const Context *context, const Program *program); void putProgram(const ProgramHash &programHash, const Context *context, const Program *program);
// Same as putProgram but computes the hash.
void updateProgram(const Context *context, const Program *program);
// Store a binary directly. // Store a binary directly.
void putBinary(const ProgramHash &programHash, const uint8_t *binary, size_t length); void putBinary(const ProgramHash &programHash, const uint8_t *binary, size_t length);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
namespace gl namespace gl
{ {
class MemoryProgramCache;
class Path; class Path;
struct Workarounds; struct Workarounds;
} }
...@@ -155,6 +156,18 @@ class ContextImpl : public GLImplFactory ...@@ -155,6 +156,18 @@ class ContextImpl : public GLImplFactory
GLuint numGroupsY, GLuint numGroupsY,
GLuint numGroupsZ) = 0; GLuint numGroupsZ) = 0;
// This does not correspond to a GL API, but matches a common GL driver behaviour where
// draw call states can trigger dynamic shader recompilation. We pass the Program cache
// handle as a mutable pointer to this Impl method to both trigger dynamic recompilations
// and to allow the back-end to store the refreshed shaders in the cache.
virtual gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context,
gl::InfoLog *infoLog,
gl::MemoryProgramCache *memoryCache,
GLenum drawMode)
{
return gl::NoError();
}
const gl::ContextState &getContextState() { return mState; } const gl::ContextState &getContextState() { return mState; }
int getClientMajorVersion() const { return mState.getClientMajorVersion(); } int getClientMajorVersion() const { return mState.getClientMajorVersion(); }
int getClientMinorVersion() const { return mState.getClientMinorVersion(); } int getClientMinorVersion() const { return mState.getClientMinorVersion(); }
......
...@@ -165,19 +165,14 @@ class ProgramD3D : public ProgramImpl ...@@ -165,19 +165,14 @@ class ProgramD3D : public ProgramImpl
void setBinaryRetrievableHint(bool retrievable) override; void setBinaryRetrievableHint(bool retrievable) override;
void setSeparable(bool separable) override; void setSeparable(bool separable) override;
gl::Error getPixelExecutableForFramebuffer(const gl::Context *context, gl::Error getVertexExecutableForCachedInputLayout(ShaderExecutableD3D **outExectuable,
const gl::Framebuffer *fbo,
ShaderExecutableD3D **outExectuable);
gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout,
ShaderExecutableD3D **outExectuable,
gl::InfoLog *infoLog);
gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout,
ShaderExecutableD3D **outExectuable,
gl::InfoLog *infoLog); gl::InfoLog *infoLog);
gl::Error getGeometryExecutableForPrimitiveType(const gl::ContextState &data, gl::Error getGeometryExecutableForPrimitiveType(const gl::ContextState &data,
GLenum drawMode, GLenum drawMode,
ShaderExecutableD3D **outExecutable, ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog); gl::InfoLog *infoLog);
gl::Error getPixelExecutableForCachedOutputLayout(ShaderExecutableD3D **outExectuable,
gl::InfoLog *infoLog);
gl::Error getComputeExecutable(ShaderExecutableD3D **outExecutable); gl::Error getComputeExecutable(ShaderExecutableD3D **outExecutable);
gl::LinkResult link(const gl::Context *context, gl::LinkResult link(const gl::Context *context,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
...@@ -261,10 +256,15 @@ class ProgramD3D : public ProgramImpl ...@@ -261,10 +256,15 @@ class ProgramD3D : public ProgramImpl
} }
void updateCachedInputLayout(Serial associatedSerial, const gl::State &state); void updateCachedInputLayout(Serial associatedSerial, const gl::State &state);
const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; } void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer);
bool isSamplerMappingDirty() { return mDirtySamplerMapping; } bool isSamplerMappingDirty() { return mDirtySamplerMapping; }
// Checks if we need to recompile certain shaders.
bool hasVertexExecutableForCachedInputLayout();
bool hasGeometryExecutableForPrimitiveType(GLenum drawMode);
bool hasPixelExecutableForCachedOutputLayout();
private: private:
// These forward-declared tasks are used for multi-thread shader compiles. // These forward-declared tasks are used for multi-thread shader compiles.
class GetExecutableTask; class GetExecutableTask;
...@@ -381,6 +381,9 @@ class ProgramD3D : public ProgramImpl ...@@ -381,6 +381,9 @@ class ProgramD3D : public ProgramImpl
void initUniformBlockInfo(const gl::Context *context, gl::Shader *shader); void initUniformBlockInfo(const gl::Context *context, gl::Shader *shader);
size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock); size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock);
void updateCachedInputLayoutFromShader(const gl::Context *context);
void updateCachedOutputLayoutFromShader();
RendererD3D *mRenderer; RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL; DynamicHLSL *mDynamicHLSL;
...@@ -417,8 +420,8 @@ class ProgramD3D : public ProgramImpl ...@@ -417,8 +420,8 @@ class ProgramD3D : public ProgramImpl
GLuint mUsedComputeSamplerRange; GLuint mUsedComputeSamplerRange;
bool mDirtySamplerMapping; bool mDirtySamplerMapping;
// Cache for getPixelExecutableForFramebuffer // Cache for pixel shader output layout to save reallocations.
std::vector<GLenum> mPixelShaderOutputFormatCache; std::vector<GLenum> mPixelShaderOutputLayoutCache;
AttribIndexArray mAttribLocationToD3DSemantic; AttribIndexArray mAttribLocationToD3DSemantic;
...@@ -441,6 +444,6 @@ class ProgramD3D : public ProgramImpl ...@@ -441,6 +444,6 @@ class ProgramD3D : public ProgramImpl
Serial mCurrentVertexArrayStateSerial; Serial mCurrentVertexArrayStateSerial;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ #endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "libANGLE/renderer/d3d/d3d11/Context11.h" #include "libANGLE/renderer/d3d/d3d11/Context11.h"
#include "common/string_utils.h" #include "common/string_utils.h"
#include "libANGLE/Context.h"
#include "libANGLE/MemoryProgramCache.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h" #include "libANGLE/renderer/d3d/CompilerD3D.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/ProgramD3D.h"
#include "libANGLE/renderer/d3d/RenderbufferD3D.h" #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
...@@ -294,4 +296,58 @@ gl::Error Context11::dispatchCompute(const gl::Context *context, ...@@ -294,4 +296,58 @@ gl::Error Context11::dispatchCompute(const gl::Context *context,
return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ); return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
} }
gl::Error Context11::triggerDrawCallProgramRecompilation(const gl::Context *context,
gl::InfoLog *infoLog,
gl::MemoryProgramCache *memoryCache,
GLenum drawMode)
{
const auto &glState = context->getGLState();
const auto *va11 = GetImplAs<VertexArray11>(glState.getVertexArray());
const auto *drawFBO = glState.getDrawFramebuffer();
gl::Program *program = glState.getProgram();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState);
programD3D->updateCachedOutputLayout(context, drawFBO);
bool recompileVS = !programD3D->hasVertexExecutableForCachedInputLayout();
bool recompileGS = !programD3D->hasGeometryExecutableForPrimitiveType(drawMode);
bool recompilePS = !programD3D->hasPixelExecutableForCachedOutputLayout();
if (!recompileVS && !recompileGS && !recompilePS)
{
return gl::NoError();
}
// Load the compiler if necessary and recompile the programs.
ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized());
if (recompileVS)
{
ShaderExecutableD3D *vertexExe = nullptr;
ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, infoLog));
}
if (recompileGS)
{
ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(
context->getContextState(), drawMode, &geometryExe, infoLog));
}
if (recompilePS)
{
ShaderExecutableD3D *pixelExe = nullptr;
ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, infoLog));
}
// Refresh the program cache entry.
if (memoryCache)
{
memoryCache->updateProgram(context, program);
}
return gl::NoError();
}
} // namespace rx } // namespace rx
...@@ -135,6 +135,11 @@ class Context11 : public ContextImpl ...@@ -135,6 +135,11 @@ class Context11 : public ContextImpl
GLuint numGroupsY, GLuint numGroupsY,
GLuint numGroupsZ) override; GLuint numGroupsZ) override;
gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context,
gl::InfoLog *infoLog,
gl::MemoryProgramCache *memoryCache,
GLenum drawMode) override;
private: private:
Renderer11 *mRenderer; Renderer11 *mRenderer;
}; };
......
...@@ -35,19 +35,6 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation) ...@@ -35,19 +35,6 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
return usesPointSpriteEmulation ? 1 : 0; return usesPointSpriteEmulation ? 1 : 0;
} }
gl::InputLayout GetInputLayout(const std::vector<const TranslatedAttribute *> &translatedAttributes)
{
gl::InputLayout inputLayout(translatedAttributes.size(), gl::VERTEX_FORMAT_INVALID);
for (size_t attributeIndex = 0; attributeIndex < translatedAttributes.size(); ++attributeIndex)
{
const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex];
inputLayout[attributeIndex] = gl::GetVertexFormatType(
*translatedAttribute->attribute, translatedAttribute->currentValueType);
}
return inputLayout;
}
GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, size_t index) GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, size_t index)
{ {
// Count matrices differently // Count matrices differently
...@@ -547,10 +534,8 @@ gl::Error InputLayoutCache::createInputLayout(Renderer11 *renderer, ...@@ -547,10 +534,8 @@ gl::Error InputLayoutCache::createInputLayout(Renderer11 *renderer,
inputElementCount++; inputElementCount++;
} }
const gl::InputLayout &shaderInputLayout = GetInputLayout(mCurrentAttributes);
ShaderExecutableD3D *shader = nullptr; ShaderExecutableD3D *shader = nullptr;
ANGLE_TRY(programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr)); ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&shader, nullptr));
ShaderExecutableD3D *shader11 = GetAs<ShaderExecutable11>(shader); ShaderExecutableD3D *shader11 = GetAs<ShaderExecutable11>(shader);
......
...@@ -1709,8 +1709,7 @@ gl::Error Renderer11::drawArraysImpl(const gl::Context *context, ...@@ -1709,8 +1709,7 @@ gl::Error Renderer11::drawArraysImpl(const gl::Context *context,
} }
rx::ShaderExecutableD3D *pixelExe = nullptr; rx::ShaderExecutableD3D *pixelExe = nullptr;
ANGLE_TRY(programD3D->getPixelExecutableForFramebuffer( ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
context, glState.getDrawFramebuffer(), &pixelExe));
// Skip the draw call if rasterizer discard is enabled (or no fragment shader). // Skip the draw call if rasterizer discard is enabled (or no fragment shader).
if (!pixelExe || glState.getRasterizerState().rasterizerDiscard) if (!pixelExe || glState.getRasterizerState().rasterizerDiscard)
......
...@@ -1737,23 +1737,22 @@ gl::Error StateManager11::setTexture(const gl::Context *context, ...@@ -1737,23 +1737,22 @@ gl::Error StateManager11::setTexture(const gl::Context *context,
gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMode) gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMode)
{ {
// This method is called single-threaded.
ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized());
const auto &glState = context->getGLState(); const auto &glState = context->getGLState();
const auto *va11 = GetImplAs<VertexArray11>(glState.getVertexArray()); const auto *va11 = GetImplAs<VertexArray11>(glState.getVertexArray());
auto *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState); programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState);
const auto &inputLayout = programD3D->getCachedInputLayout(); // Binaries must be compiled before the sync.
ASSERT(programD3D->hasVertexExecutableForCachedInputLayout());
ASSERT(programD3D->hasGeometryExecutableForPrimitiveType(drawMode));
ASSERT(programD3D->hasPixelExecutableForCachedOutputLayout());
ShaderExecutableD3D *vertexExe = nullptr; ShaderExecutableD3D *vertexExe = nullptr;
ANGLE_TRY(programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr)); ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, nullptr));
const gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
ShaderExecutableD3D *pixelExe = nullptr; ShaderExecutableD3D *pixelExe = nullptr;
ANGLE_TRY(programD3D->getPixelExecutableForFramebuffer(context, drawFramebuffer, &pixelExe)); ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
ShaderExecutableD3D *geometryExe = nullptr; ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context->getContextState(), ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context->getContextState(),
......
...@@ -1796,14 +1796,14 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode) ...@@ -1796,14 +1796,14 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode)
VertexArray9 *vao = GetImplAs<VertexArray9>(state.getVertexArray()); VertexArray9 *vao = GetImplAs<VertexArray9>(state.getVertexArray());
programD3D->updateCachedInputLayout(vao->getCurrentStateSerial(), state); programD3D->updateCachedInputLayout(vao->getCurrentStateSerial(), state);
const auto &inputLayout = programD3D->getCachedInputLayout();
ShaderExecutableD3D *vertexExe = nullptr; ShaderExecutableD3D *vertexExe = nullptr;
ANGLE_TRY(programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr)); ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, nullptr));
const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer(); const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer();
programD3D->updateCachedOutputLayout(context, drawFramebuffer);
ShaderExecutableD3D *pixelExe = nullptr; ShaderExecutableD3D *pixelExe = nullptr;
ANGLE_TRY(programD3D->getPixelExecutableForFramebuffer(context, drawFramebuffer, &pixelExe)); ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
IDirect3DVertexShader9 *vertexShader = IDirect3DVertexShader9 *vertexShader =
(vertexExe ? GetAs<ShaderExecutable9>(vertexExe)->getVertexShader() : nullptr); (vertexExe ? GetAs<ShaderExecutable9>(vertexExe)->getVertexShader() : nullptr);
......
...@@ -52,7 +52,7 @@ class MockValidationContext : public ValidationContext ...@@ -52,7 +52,7 @@ class MockValidationContext : public ValidationContext
{ {
} }
MOCK_METHOD1(handleError, void(const Error &)); MOCK_METHOD1(handleError, Error(const Error &));
}; };
// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value // Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment