Commit c9fed8dd by Jamie Madill Committed by Commit Bot

D3D11: Move TF state management to StateManager11.

This also changes the dirty TF object to use a Serial, which is more secure for very edge-care reallocation issues. It also moves the StateManager11::updateState call to be the very first thing that happens in a draw call. This prepares the back-end for making the state sync actually happen in Context11::syncState, instead of inside the draw call. Also moves a bit more TF management code out of RendererD3D and Renderer9. BUG=angleproject:2052 Change-Id: I93d033a07be2049023111975a31637c53893e8c8 Reviewed-on: https://chromium-review.googlesource.com/659229Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent cd8e9729
......@@ -1006,8 +1006,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
return preambleStream.str();
}
std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveType,
const gl::ContextState &data,
std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Context *context,
gl::PrimitiveType primitiveType,
const gl::ProgramState &programData,
const bool useViewScale,
const bool hasANGLEMultiviewEnabled,
......@@ -1114,10 +1114,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
"};\n"
"\n"
"static float minPointSize = "
<< static_cast<int>(data.getCaps().minAliasedPointSize)
<< static_cast<int>(context->getCaps().minAliasedPointSize)
<< ".0f;\n"
"static float maxPointSize = "
<< static_cast<int>(data.getCaps().maxAliasedPointSize) << ".0f;\n"
<< static_cast<int>(context->getCaps().maxAliasedPointSize) << ".0f;\n"
<< "\n";
}
......
......@@ -135,8 +135,8 @@ class DynamicHLSL : angle::NonCopyable
const bool hasANGLEMultiviewEnabled,
const bool selectViewInVS) const;
std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType,
const gl::ContextState &data,
std::string generateGeometryShaderHLSL(const gl::Context *context,
gl::PrimitiveType primitiveType,
const gl::ProgramState &programData,
const bool useViewScale,
const bool hasANGLEMultiviewEnabled,
......
......@@ -1272,7 +1272,7 @@ gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3
return gl::NoError();
}
gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextState &data,
gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Context *context,
GLenum drawMode,
ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog)
......@@ -1300,7 +1300,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta
}
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
geometryShaderType, data, mState, mRenderer->presentPathFastEnabled(),
context, geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
......@@ -1404,8 +1404,8 @@ void ProgramD3D::updateCachedOutputLayoutFromShader()
class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask
{
public:
GetGeometryExecutableTask(ProgramD3D *program, const gl::ContextState &contextState)
: GetExecutableTask(program), mContextState(contextState)
GetGeometryExecutableTask(ProgramD3D *program, const gl::Context *context)
: GetExecutableTask(program), mContext(context)
{
}
......@@ -1415,15 +1415,15 @@ class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTa
// D3D11.
if (mProgram->usesGeometryShader(GL_POINTS))
{
ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(mContextState, GL_POINTS,
&mResult, &mInfoLog));
ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(mContext, GL_POINTS, &mResult,
&mInfoLog));
}
return gl::NoError();
}
private:
const gl::ContextState &mContextState;
const gl::Context *mContext;
};
gl::Error ProgramD3D::getComputeExecutable(ShaderExecutableD3D **outExecutable)
......@@ -1446,7 +1446,7 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context,
GetVertexExecutableTask vertexTask(this, context);
GetPixelExecutableTask pixelTask(this);
GetGeometryExecutableTask geometryTask(this, context->getContextState());
GetGeometryExecutableTask geometryTask(this, context);
std::array<WaitableEvent, 3> waitEvents = {{workerPool->postWorkerTask(&vertexTask),
workerPool->postWorkerTask(&pixelTask),
......
......@@ -184,7 +184,7 @@ class ProgramD3D : public ProgramImpl
gl::Error getVertexExecutableForCachedInputLayout(ShaderExecutableD3D **outExectuable,
gl::InfoLog *infoLog);
gl::Error getGeometryExecutableForPrimitiveType(const gl::ContextState &data,
gl::Error getGeometryExecutableForPrimitiveType(const gl::Context *context,
GLenum drawMode,
ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog);
......
......@@ -59,18 +59,16 @@ void RendererD3D::cleanup()
mIncompleteTextures.clear();
}
bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode)
bool RendererD3D::skipDraw(const gl::State &glState, GLenum drawMode)
{
const gl::State &state = data.getState();
if (drawMode == GL_POINTS)
{
bool usesPointSize = GetImplAs<ProgramD3D>(state.getProgram())->usesPointSize();
bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize();
// ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
// which affects varying interpolation. Since the value of gl_PointSize is
// undefined when not written, just skip drawing to avoid unexpected results.
if (!usesPointSize && !state.isTransformFeedbackActiveUnpaused())
if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
{
// Notify developers of risking undefined behavior.
WARN() << "Point rendering without writing to gl_PointSize.";
......@@ -79,8 +77,8 @@ bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode)
}
else if (gl::IsTriangleMode(drawMode))
{
if (state.getRasterizerState().cullFace &&
state.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
if (glState.getRasterizerState().cullFace &&
glState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
{
return true;
}
......@@ -89,23 +87,6 @@ bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode)
return false;
}
gl::Error RendererD3D::markTransformFeedbackUsage(const gl::ContextState &data)
{
const gl::TransformFeedback *transformFeedback = data.getState().getCurrentTransformFeedback();
for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
{
const gl::OffsetBindingPointer<gl::Buffer> &binding =
transformFeedback->getIndexedBuffer(i);
if (binding.get() != nullptr)
{
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get());
ANGLE_TRY(bufferD3D->markTransformFeedbackUsage());
}
}
return gl::NoError();
}
size_t RendererD3D::getBoundFramebufferTextures(const gl::ContextState &data,
FramebufferTextureArray *outTextureArray)
{
......
......@@ -331,8 +331,7 @@ class RendererD3D : public BufferFactoryD3D
// dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
bool skipDraw(const gl::ContextState &data, GLenum drawMode);
gl::Error markTransformFeedbackUsage(const gl::ContextState &data);
bool skipDraw(const gl::State &glState, GLenum drawMode);
egl::Display *mDisplay;
......
......@@ -153,6 +153,9 @@ gl::Error Context11::finish()
gl::Error Context11::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawArrays(context, mode, first, count, 0);
}
......@@ -162,6 +165,9 @@ gl::Error Context11::drawArraysInstanced(const gl::Context *context,
GLsizei count,
GLsizei instanceCount)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount);
}
......@@ -171,6 +177,9 @@ gl::Error Context11::drawElements(const gl::Context *context,
GLenum type,
const void *indices)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
}
......@@ -181,6 +190,9 @@ gl::Error Context11::drawElementsInstanced(const gl::Context *context,
const void *indices,
GLsizei instances)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawElements(context, mode, count, type, indices, instances);
}
......@@ -192,6 +204,9 @@ gl::Error Context11::drawRangeElements(const gl::Context *context,
GLenum type,
const void *indices)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
}
......@@ -199,6 +214,9 @@ gl::Error Context11::drawArraysIndirect(const gl::Context *context,
GLenum mode,
const void *indirect)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawIndirect(context, mode, GL_NONE, indirect);
}
......@@ -207,6 +225,9 @@ gl::Error Context11::drawElementsIndirect(const gl::Context *context,
GLenum type,
const void *indirect)
{
// TODO(jmadill): Update state in syncState before the draw call.
ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode));
return mRenderer->genericDrawIndirect(context, mode, type, indirect);
}
......@@ -335,8 +356,8 @@ gl::Error Context11::triggerDrawCallProgramRecompilation(const gl::Context *cont
if (recompileGS)
{
ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(
context->getContextState(), drawMode, &geometryExe, infoLog));
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe,
infoLog));
if (!programD3D->hasGeometryExecutableForPrimitiveType(drawMode))
{
return gl::InternalError() << "Error compiling dynamic geometry executable.";
......
......@@ -469,8 +469,6 @@ Renderer11::Renderer11(egl::Display *display)
mDxgiAdapter = nullptr;
mDxgiFactory = nullptr;
mAppliedTFObject = angle::DirtyPointer;
ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription));
if (mDisplay->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE)
......@@ -1455,50 +1453,13 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSi
return count >= minCount;
}
gl::Error Renderer11::applyTransformFeedbackBuffers(const gl::ContextState &data)
{
const auto &state = data.getState();
// If transform feedback is not active, unbind all buffers
if (!state.isTransformFeedbackActiveUnpaused())
{
if (mAppliedTFObject != 0)
{
mDeviceContext->SOSetTargets(0, nullptr, nullptr);
mAppliedTFObject = 0;
}
return gl::NoError();
}
gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback();
TransformFeedback11 *transformFeedback11 = GetImplAs<TransformFeedback11>(transformFeedback);
uintptr_t transformFeedbackId = reinterpret_cast<uintptr_t>(transformFeedback11);
if (mAppliedTFObject == transformFeedbackId && !transformFeedback11->isDirty())
{
return gl::NoError();
}
const std::vector<ID3D11Buffer *> *soBuffers = nullptr;
ANGLE_TRY_RESULT(transformFeedback11->getSOBuffers(), soBuffers);
const std::vector<UINT> &soOffsets = transformFeedback11->getSOBufferOffsets();
mDeviceContext->SOSetTargets(transformFeedback11->getNumSOBuffers(), soBuffers->data(),
soOffsets.data());
mAppliedTFObject = transformFeedbackId;
transformFeedback11->onApply();
return gl::NoError();
}
gl::Error Renderer11::drawArraysImpl(const gl::Context *context,
GLenum mode,
GLint startVertex,
GLsizei count,
GLsizei instances)
{
const auto &data = context->getContextState();
const auto &glState = data.getState();
const auto &glState = context->getGLState();
gl::Program *program = glState.getProgram();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances);
......@@ -1533,8 +1494,8 @@ gl::Error Renderer11::drawArraysImpl(const gl::Context *context,
// Retrieve the geometry shader.
rx::ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(
programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe, nullptr));
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, mode, &geometryExe,
nullptr));
mStateManager.setGeometryShader(
&GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader());
......@@ -1552,12 +1513,12 @@ gl::Error Renderer11::drawArraysImpl(const gl::Context *context,
if (mode == GL_LINE_LOOP)
{
return drawLineLoop(data, count, GL_NONE, nullptr, 0, adjustedInstanceCount);
return drawLineLoop(glState, count, GL_NONE, nullptr, 0, adjustedInstanceCount);
}
if (mode == GL_TRIANGLE_FAN)
{
return drawTriangleFan(data, count, GL_NONE, nullptr, 0, adjustedInstanceCount);
return drawTriangleFan(glState, count, GL_NONE, nullptr, 0, adjustedInstanceCount);
}
bool useInstancedPointSpriteEmulation =
......@@ -1611,14 +1572,14 @@ gl::Error Renderer11::drawElementsImpl(const gl::Context *context,
const void *indices,
GLsizei instances)
{
const auto &data = context->getContextState();
const auto &glState = context->getGLState();
TranslatedIndexData indexInfo;
const gl::Program *program = data.getState().getProgram();
const gl::Program *program = glState.getProgram();
GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances);
if (!DrawCallNeedsTranslation(context, mode, type))
{
ANGLE_TRY(mStateManager.applyIndexBuffer(data, nullptr, 0, type, &indexInfo));
ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, &indexInfo));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo));
const gl::Type &typeInfo = gl::GetTypeInfo(type);
unsigned int startIndexLocation =
......@@ -1639,7 +1600,7 @@ gl::Error Renderer11::drawElementsImpl(const gl::Context *context,
context->getParams<gl::HasIndexRange>().getIndexRange().value();
indexInfo.indexRange = indexRange;
ANGLE_TRY(mStateManager.applyIndexBuffer(data, indices, count, type, &indexInfo));
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo));
size_t vertexCount = indexInfo.indexRange.vertexCount();
ANGLE_TRY(mStateManager.applyVertexBuffer(
context, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
......@@ -1650,15 +1611,15 @@ gl::Error Renderer11::drawElementsImpl(const gl::Context *context,
if (mode == GL_LINE_LOOP)
{
return drawLineLoop(data, count, type, indices, baseVertex, adjustedInstanceCount);
return drawLineLoop(glState, count, type, indices, baseVertex, adjustedInstanceCount);
}
if (mode == GL_TRIANGLE_FAN)
{
return drawTriangleFan(data, count, type, indices, baseVertex, adjustedInstanceCount);
return drawTriangleFan(glState, count, type, indices, baseVertex, adjustedInstanceCount);
}
const ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.getState().getProgram());
const ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
if (mode != GL_POINTS || !programD3D->usesInstancedPointSpriteEmulation())
{
......@@ -1712,13 +1673,12 @@ gl::Error Renderer11::drawArraysIndirectImpl(const gl::Context *context,
GLenum mode,
const void *indirect)
{
const auto &contextState = context->getContextState();
if (skipDraw(contextState, mode))
const auto &glState = context->getGLState();
if (skipDraw(glState, mode))
{
return gl::NoError();
}
const auto &glState = context->getGLState();
gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
ASSERT(drawIndirectBuffer);
Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
......@@ -1746,11 +1706,11 @@ gl::Error Renderer11::drawArraysIndirectImpl(const gl::Context *context,
if (mode == GL_LINE_LOOP)
{
return drawLineLoop(contextState, count, GL_NONE, nullptr, 0, instances);
return drawLineLoop(glState, count, GL_NONE, nullptr, 0, instances);
}
if (mode == GL_TRIANGLE_FAN)
{
return drawTriangleFan(contextState, count, GL_NONE, nullptr, 0, instances);
return drawTriangleFan(glState, count, GL_NONE, nullptr, 0, instances);
}
mDeviceContext->DrawInstanced(count, instances, 0, 0);
......@@ -1762,13 +1722,12 @@ gl::Error Renderer11::drawElementsIndirectImpl(const gl::Context *context,
GLenum type,
const void *indirect)
{
const auto &contextState = context->getContextState();
if (skipDraw(contextState, mode))
const auto &glState = context->getGLState();
if (skipDraw(glState, mode))
{
return gl::NoError();
}
const auto &glState = context->getGLState();
gl::Buffer *drawIndirectBuffer = glState.getDrawIndirectBuffer();
ASSERT(drawIndirectBuffer);
Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
......@@ -1777,7 +1736,7 @@ gl::Error Renderer11::drawElementsIndirectImpl(const gl::Context *context,
TranslatedIndexData indexInfo;
if (!DrawCallNeedsTranslation(context, mode, type))
{
ANGLE_TRY(mStateManager.applyIndexBuffer(contextState, nullptr, 0, type, &indexInfo));
ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, &indexInfo));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, 0, 0, 0, &indexInfo));
ID3D11Buffer *buffer = nullptr;
ANGLE_TRY_RESULT(storage->getBuffer(BUFFER_USAGE_INDIRECT), buffer);
......@@ -1806,7 +1765,7 @@ gl::Error Renderer11::drawElementsIndirectImpl(const gl::Context *context,
glState.isPrimitiveRestartEnabled(), &indexRange));
indexInfo.indexRange = indexRange;
ANGLE_TRY(mStateManager.applyIndexBuffer(contextState, indices, count, type, &indexInfo));
ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, &indexInfo));
size_t vertexCount = indexRange.vertexCount();
ANGLE_TRY(mStateManager.applyVertexBuffer(
context, mode, static_cast<GLsizei>(indexRange.start) + baseVertex,
......@@ -1815,26 +1774,25 @@ gl::Error Renderer11::drawElementsIndirectImpl(const gl::Context *context,
int baseVertexLocation = -static_cast<int>(indexRange.start);
if (mode == GL_LINE_LOOP)
{
return drawLineLoop(contextState, count, type, indices, baseVertexLocation, instances);
return drawLineLoop(glState, count, type, indices, baseVertexLocation, instances);
}
if (mode == GL_TRIANGLE_FAN)
{
return drawTriangleFan(contextState, count, type, indices, baseVertexLocation, instances);
return drawTriangleFan(glState, count, type, indices, baseVertexLocation, instances);
}
mDeviceContext->DrawIndexedInstanced(count, instances, 0, baseVertexLocation, 0);
return gl::NoError();
}
gl::Error Renderer11::drawLineLoop(const gl::ContextState &data,
gl::Error Renderer11::drawLineLoop(const gl::State &glState,
GLsizei count,
GLenum type,
const void *indexPointer,
int baseVertex,
int instances)
{
const auto &glState = data.getState();
gl::VertexArray *vao = glState.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
......@@ -1911,14 +1869,14 @@ gl::Error Renderer11::drawLineLoop(const gl::ContextState &data,
return gl::NoError();
}
gl::Error Renderer11::drawTriangleFan(const gl::ContextState &data,
gl::Error Renderer11::drawTriangleFan(const gl::State &glState,
GLsizei count,
GLenum type,
const void *indices,
int baseVertex,
int instances)
{
gl::VertexArray *vao = data.getState().getVertexArray();
gl::VertexArray *vao = glState.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
const void *indexPointer = indices;
......@@ -1958,7 +1916,7 @@ gl::Error Renderer11::drawTriangleFan(const gl::ContextState &data,
"too many indices required.";
}
GetTriFanIndices(indexPointer, type, count, data.getState().isPrimitiveRestartEnabled(),
GetTriFanIndices(indexPointer, type, count, glState.isPrimitiveRestartEnabled(),
&mScratchIndexDataBuffer);
const unsigned int spaceNeeded =
......@@ -1998,8 +1956,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context)
TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
mStateManager.invalidateEverything(context);
mAppliedTFObject = angle::DirtyPointer;
}
void Renderer11::releaseDeviceResources()
......@@ -3806,8 +3762,7 @@ gl::Error Renderer11::genericDrawElements(const gl::Context *context,
const void *indices,
GLsizei instances)
{
const auto &data = context->getContextState();
const auto &glState = data.getState();
const auto &glState = context->getGLState();
gl::Program *program = glState.getProgram();
ASSERT(program != nullptr);
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
......@@ -3818,14 +3773,11 @@ gl::Error Renderer11::genericDrawElements(const gl::Context *context,
return gl::NoError();
}
ANGLE_TRY(mStateManager.updateState(context, mode));
applyTransformFeedbackBuffers(data);
// Transform feedback is not allowed for DrawElements, this error should have been caught at the
// API validation layer.
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
if (!skipDraw(data, mode))
if (!skipDraw(glState, mode))
{
ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances));
}
......@@ -3839,29 +3791,25 @@ gl::Error Renderer11::genericDrawArrays(const gl::Context *context,
GLsizei count,
GLsizei instances)
{
const auto &data = context->getContextState();
const auto &glState = data.getState();
const auto &glState = context->getGLState();
gl::Program *program = glState.getProgram();
ASSERT(program != nullptr);
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
bool usesPointSize = programD3D->usesPointSize();
if (!applyPrimitiveType(mode, count, usesPointSize))
if (!applyPrimitiveType(mode, count, programD3D->usesPointSize()))
{
return gl::NoError();
}
ANGLE_TRY(mStateManager.updateState(context, mode));
ANGLE_TRY(applyTransformFeedbackBuffers(data));
ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, first, count, instances, nullptr));
if (!skipDraw(data, mode))
if (!skipDraw(glState, mode))
{
ANGLE_TRY(drawArraysImpl(context, mode, first, count, instances));
if (glState.isTransformFeedbackActiveUnpaused())
{
ANGLE_TRY(markTransformFeedbackUsage(data));
ANGLE_TRY(markTransformFeedbackUsage(glState));
}
}
......@@ -3873,17 +3821,13 @@ gl::Error Renderer11::genericDrawIndirect(const gl::Context *context,
GLenum type,
const void *indirect)
{
const auto &contextState = context->getContextState();
const auto &glState = context->getGLState();
const auto &glState = context->getGLState();
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
gl::Program *program = glState.getProgram();
ASSERT(program != nullptr);
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
bool usesPointSize = programD3D->usesPointSize();
applyPrimitiveType(mode, 0, usesPointSize);
ANGLE_TRY(mStateManager.updateState(context, mode));
ANGLE_TRY(applyTransformFeedbackBuffers(contextState));
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
applyPrimitiveType(mode, 0, programD3D->usesPointSize());
if (type == GL_NONE)
{
......@@ -4066,4 +4010,21 @@ bool Renderer11::canSelectViewInVertexShader() const
getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader;
}
gl::Error Renderer11::markTransformFeedbackUsage(const gl::State &glState)
{
const gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
{
const gl::OffsetBindingPointer<gl::Buffer> &binding =
transformFeedback->getIndexedBuffer(i);
if (binding.get() != nullptr)
{
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get());
ANGLE_TRY(bufferD3D->markTransformFeedbackUsage());
}
}
return gl::NoError();
}
} // namespace rx
......@@ -147,7 +147,6 @@ class Renderer11 : public RendererD3D
const egl::AttributeMap &attribs) const override;
bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
gl::Error applyTransformFeedbackBuffers(const gl::ContextState &data);
// lost device
bool testDeviceLost() override;
......@@ -485,13 +484,13 @@ class Renderer11 : public RendererD3D
angle::WorkaroundsD3D generateWorkarounds() const override;
gl::Error drawLineLoop(const gl::ContextState &data,
gl::Error drawLineLoop(const gl::State &glState,
GLsizei count,
GLenum type,
const void *indices,
int baseVertex,
int instances);
gl::Error drawTriangleFan(const gl::ContextState &data,
gl::Error drawTriangleFan(const gl::State &glState,
GLsizei count,
GLenum type,
const void *indices,
......@@ -525,6 +524,8 @@ class Renderer11 : public RendererD3D
d3d11::ANGLED3D11DeviceType getDeviceType() const;
gl::Error markTransformFeedbackUsage(const gl::State &glState);
HMODULE mD3d11Module;
HMODULE mDxgiModule;
HMODULE mDCompModule;
......@@ -540,9 +541,6 @@ class Renderer11 : public RendererD3D
StateManager11 mStateManager;
// Currently applied transform feedback buffers
uintptr_t mAppliedTFObject;
StreamingIndexBufferInterface *mLineLoopIB;
StreamingIndexBufferInterface *mTriangleFanIB;
......
......@@ -21,6 +21,7 @@
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
namespace rx
......@@ -541,7 +542,8 @@ StateManager11::StateManager11(Renderer11 *renderer)
mAppliedIBChanged(false),
mVertexDataManager(renderer),
mIndexDataManager(renderer, RENDERER_D3D11),
mIsMultiviewEnabled(false)
mIsMultiviewEnabled(false),
mEmptySerial(mRenderer->generateSerial())
{
mCurBlendState.blend = false;
mCurBlendState.sourceBlendRGB = GL_ONE;
......@@ -1343,6 +1345,8 @@ void StateManager11::invalidateEverything(const gl::Context *context)
// As long as all calls to *SSetConstantBuffes go through the StateManager11, it should not be
// necessary to invalidate constant buffer state.
mAppliedTFSerial = Serial();
}
void StateManager11::invalidateVertexBuffer()
......@@ -1899,6 +1903,8 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
}
}
ANGLE_TRY(syncTransformFeedbackBuffers(context));
// Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
ASSERT(mInternalDirtyBits.none());
......@@ -2253,8 +2259,8 @@ gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMod
ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context->getContextState(),
drawMode, &geometryExe, nullptr));
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe,
nullptr));
const d3d11::VertexShader *vertexShader =
(vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : nullptr);
......@@ -2371,13 +2377,13 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
return gl::NoError();
}
gl::Error StateManager11::applyIndexBuffer(const gl::ContextState &data,
gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
const void *indices,
GLsizei count,
GLenum type,
TranslatedIndexData *indexInfo)
{
const auto &glState = data.getState();
const auto &glState = context->getGLState();
gl::VertexArray *vao = glState.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
ANGLE_TRY(mIndexDataManager.prepareIndexData(type, count, elementArrayBuffer, indices,
......@@ -2792,4 +2798,40 @@ gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, Program
return gl::NoError();
}
gl::Error StateManager11::syncTransformFeedbackBuffers(const gl::Context *context)
{
const auto &glState = context->getGLState();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
// If transform feedback is not active, unbind all buffers
if (!glState.isTransformFeedbackActiveUnpaused())
{
if (mAppliedTFSerial != mEmptySerial)
{
deviceContext->SOSetTargets(0, nullptr, nullptr);
mAppliedTFSerial = mEmptySerial;
}
return gl::NoError();
}
gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
TransformFeedback11 *tf11 = GetImplAs<TransformFeedback11>(transformFeedback);
if (mAppliedTFSerial == tf11->getSerial() && !tf11->isDirty())
{
return gl::NoError();
}
const std::vector<ID3D11Buffer *> *soBuffers = nullptr;
ANGLE_TRY_RESULT(tf11->getSOBuffers(), soBuffers);
const std::vector<UINT> &soOffsets = tf11->getSOBufferOffsets();
deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data());
mAppliedTFSerial = tf11->getSerial();
tf11->onApply();
return gl::NoError();
}
} // namespace rx
......@@ -225,7 +225,7 @@ class StateManager11 final : angle::NonCopyable
GLsizei instances,
TranslatedIndexData *indexInfo);
gl::Error applyIndexBuffer(const gl::ContextState &data,
gl::Error applyIndexBuffer(const gl::Context *context,
const void *indices,
GLsizei count,
GLenum type,
......@@ -301,6 +301,7 @@ class StateManager11 final : angle::NonCopyable
gl::Error applyUniforms(ProgramD3D *programD3D);
gl::Error syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D);
gl::Error syncTransformFeedbackBuffers(const gl::Context *context);
enum DirtyBitType
{
......@@ -481,6 +482,11 @@ class StateManager11 final : angle::NonCopyable
FragmentConstantBufferArray<ResourceSerial> mCurrentConstantBufferPS;
FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset;
FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize;
// Currently applied transform feedback buffers
Serial mAppliedTFSerial;
Serial mEmptySerial;
};
} // namespace rx
......
......@@ -21,7 +21,8 @@ TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state
mRenderer(renderer),
mIsDirty(true),
mBuffers(state.getIndexedBuffers().size(), nullptr),
mBufferOffsets(state.getIndexedBuffers().size(), 0)
mBufferOffsets(state.getIndexedBuffers().size(), 0),
mSerial(mRenderer->generateSerial())
{
}
......@@ -113,4 +114,10 @@ const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const
{
return mBufferOffsets;
}
Serial TransformFeedback11::getSerial() const
{
return mSerial;
}
} // namespace rx
......@@ -11,9 +11,10 @@
#include "common/platform.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/Error.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/TransformFeedbackImpl.h"
#include "libANGLE/renderer/renderer_utils.h"
namespace rx
{
......@@ -43,12 +44,16 @@ class TransformFeedback11 : public TransformFeedbackImpl
gl::ErrorOrResult<const std::vector<ID3D11Buffer *> *> getSOBuffers();
const std::vector<UINT> &getSOBufferOffsets() const;
Serial getSerial() const;
private:
Renderer11 *mRenderer;
bool mIsDirty;
std::vector<ID3D11Buffer *> mBuffers;
std::vector<UINT> mBufferOffsets;
Serial mSerial;
};
} // namespace rx
......
......@@ -1360,12 +1360,6 @@ gl::Error Renderer9::applyIndexBuffer(const gl::ContextState &data,
return gl::NoError();
}
gl::Error Renderer9::applyTransformFeedbackBuffers(const gl::State &state)
{
ASSERT(!state.isTransformFeedbackActiveUnpaused());
return gl::NoError();
}
gl::Error Renderer9::drawArraysImpl(const gl::ContextState &data,
GLenum mode,
GLint startVertex,
......@@ -3140,19 +3134,10 @@ gl::Error Renderer9::genericDrawElements(const gl::Context *context,
}
ANGLE_TRY(updateState(context, mode));
applyTransformFeedbackBuffers(data.getState());
// Transform feedback is not allowed for DrawElements, this error should have been caught at the
// API validation
// layer.
ASSERT(!data.getState().isTransformFeedbackActiveUnpaused());
ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode));
if (!skipDraw(data, mode))
if (!skipDraw(data.getState(), mode))
{
ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances));
}
......@@ -3180,19 +3165,13 @@ gl::Error Renderer9::genericDrawArrays(const gl::Context *context,
}
ANGLE_TRY(updateState(context, mode));
ANGLE_TRY(applyTransformFeedbackBuffers(data.getState()));
ANGLE_TRY(applyVertexBuffer(data.getState(), mode, first, count, instances, nullptr));
ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode));
if (!skipDraw(data, mode))
if (!skipDraw(data.getState(), mode))
{
ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances));
if (data.getState().isTransformFeedbackActiveUnpaused())
{
ANGLE_TRY(markTransformFeedbackUsage(data));
}
}
return gl::NoError();
......
......@@ -158,8 +158,6 @@ class Renderer9 : public RendererD3D
GLenum type,
TranslatedIndexData *indexInfo);
gl::Error applyTransformFeedbackBuffers(const gl::State &state);
gl::Error clear(const gl::Context *context,
const ClearParameters &clearParams,
const gl::FramebufferAttachment *colorBuffer,
......
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