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 ...@@ -1006,8 +1006,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
return preambleStream.str(); return preambleStream.str();
} }
std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Context *context,
const gl::ContextState &data, gl::PrimitiveType primitiveType,
const gl::ProgramState &programData, const gl::ProgramState &programData,
const bool useViewScale, const bool useViewScale,
const bool hasANGLEMultiviewEnabled, const bool hasANGLEMultiviewEnabled,
...@@ -1114,10 +1114,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT ...@@ -1114,10 +1114,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT
"};\n" "};\n"
"\n" "\n"
"static float minPointSize = " "static float minPointSize = "
<< static_cast<int>(data.getCaps().minAliasedPointSize) << static_cast<int>(context->getCaps().minAliasedPointSize)
<< ".0f;\n" << ".0f;\n"
"static float maxPointSize = " "static float maxPointSize = "
<< static_cast<int>(data.getCaps().maxAliasedPointSize) << ".0f;\n" << static_cast<int>(context->getCaps().maxAliasedPointSize) << ".0f;\n"
<< "\n"; << "\n";
} }
......
...@@ -135,8 +135,8 @@ class DynamicHLSL : angle::NonCopyable ...@@ -135,8 +135,8 @@ class DynamicHLSL : angle::NonCopyable
const bool hasANGLEMultiviewEnabled, const bool hasANGLEMultiviewEnabled,
const bool selectViewInVS) const; const bool selectViewInVS) const;
std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, std::string generateGeometryShaderHLSL(const gl::Context *context,
const gl::ContextState &data, gl::PrimitiveType primitiveType,
const gl::ProgramState &programData, const gl::ProgramState &programData,
const bool useViewScale, const bool useViewScale,
const bool hasANGLEMultiviewEnabled, const bool hasANGLEMultiviewEnabled,
......
...@@ -1272,7 +1272,7 @@ gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3 ...@@ -1272,7 +1272,7 @@ gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3
return gl::NoError(); return gl::NoError();
} }
gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextState &data, gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Context *context,
GLenum drawMode, GLenum drawMode,
ShaderExecutableD3D **outExecutable, ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog) gl::InfoLog *infoLog)
...@@ -1300,7 +1300,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta ...@@ -1300,7 +1300,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta
} }
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL( std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
geometryShaderType, data, mState, mRenderer->presentPathFastEnabled(), context, geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(), mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble); usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
...@@ -1404,8 +1404,8 @@ void ProgramD3D::updateCachedOutputLayoutFromShader() ...@@ -1404,8 +1404,8 @@ void ProgramD3D::updateCachedOutputLayoutFromShader()
class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask
{ {
public: public:
GetGeometryExecutableTask(ProgramD3D *program, const gl::ContextState &contextState) GetGeometryExecutableTask(ProgramD3D *program, const gl::Context *context)
: GetExecutableTask(program), mContextState(contextState) : GetExecutableTask(program), mContext(context)
{ {
} }
...@@ -1415,15 +1415,15 @@ class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTa ...@@ -1415,15 +1415,15 @@ class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTa
// D3D11. // D3D11.
if (mProgram->usesGeometryShader(GL_POINTS)) if (mProgram->usesGeometryShader(GL_POINTS))
{ {
ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(mContextState, GL_POINTS, ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(mContext, GL_POINTS, &mResult,
&mResult, &mInfoLog)); &mInfoLog));
} }
return gl::NoError(); return gl::NoError();
} }
private: private:
const gl::ContextState &mContextState; const gl::Context *mContext;
}; };
gl::Error ProgramD3D::getComputeExecutable(ShaderExecutableD3D **outExecutable) gl::Error ProgramD3D::getComputeExecutable(ShaderExecutableD3D **outExecutable)
...@@ -1446,7 +1446,7 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context, ...@@ -1446,7 +1446,7 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context,
GetVertexExecutableTask vertexTask(this, context); GetVertexExecutableTask vertexTask(this, context);
GetPixelExecutableTask pixelTask(this); GetPixelExecutableTask pixelTask(this);
GetGeometryExecutableTask geometryTask(this, context->getContextState()); GetGeometryExecutableTask geometryTask(this, context);
std::array<WaitableEvent, 3> waitEvents = {{workerPool->postWorkerTask(&vertexTask), std::array<WaitableEvent, 3> waitEvents = {{workerPool->postWorkerTask(&vertexTask),
workerPool->postWorkerTask(&pixelTask), workerPool->postWorkerTask(&pixelTask),
......
...@@ -184,7 +184,7 @@ class ProgramD3D : public ProgramImpl ...@@ -184,7 +184,7 @@ class ProgramD3D : public ProgramImpl
gl::Error getVertexExecutableForCachedInputLayout(ShaderExecutableD3D **outExectuable, gl::Error getVertexExecutableForCachedInputLayout(ShaderExecutableD3D **outExectuable,
gl::InfoLog *infoLog); gl::InfoLog *infoLog);
gl::Error getGeometryExecutableForPrimitiveType(const gl::ContextState &data, gl::Error getGeometryExecutableForPrimitiveType(const gl::Context *context,
GLenum drawMode, GLenum drawMode,
ShaderExecutableD3D **outExecutable, ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog); gl::InfoLog *infoLog);
......
...@@ -59,18 +59,16 @@ void RendererD3D::cleanup() ...@@ -59,18 +59,16 @@ void RendererD3D::cleanup()
mIncompleteTextures.clear(); 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) 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, // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
// which affects varying interpolation. Since the value of gl_PointSize is // which affects varying interpolation. Since the value of gl_PointSize is
// undefined when not written, just skip drawing to avoid unexpected results. // 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. // Notify developers of risking undefined behavior.
WARN() << "Point rendering without writing to gl_PointSize."; WARN() << "Point rendering without writing to gl_PointSize.";
...@@ -79,8 +77,8 @@ bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode) ...@@ -79,8 +77,8 @@ bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode)
} }
else if (gl::IsTriangleMode(drawMode)) else if (gl::IsTriangleMode(drawMode))
{ {
if (state.getRasterizerState().cullFace && if (glState.getRasterizerState().cullFace &&
state.getRasterizerState().cullMode == GL_FRONT_AND_BACK) glState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
{ {
return true; return true;
} }
...@@ -89,23 +87,6 @@ bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode) ...@@ -89,23 +87,6 @@ bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode)
return false; 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, size_t RendererD3D::getBoundFramebufferTextures(const gl::ContextState &data,
FramebufferTextureArray *outTextureArray) FramebufferTextureArray *outTextureArray)
{ {
......
...@@ -331,8 +331,7 @@ class RendererD3D : public BufferFactoryD3D ...@@ -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. // 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); bool skipDraw(const gl::State &glState, GLenum drawMode);
gl::Error markTransformFeedbackUsage(const gl::ContextState &data);
egl::Display *mDisplay; egl::Display *mDisplay;
......
...@@ -153,6 +153,9 @@ gl::Error Context11::finish() ...@@ -153,6 +153,9 @@ gl::Error Context11::finish()
gl::Error Context11::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count) 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); return mRenderer->genericDrawArrays(context, mode, first, count, 0);
} }
...@@ -162,6 +165,9 @@ gl::Error Context11::drawArraysInstanced(const gl::Context *context, ...@@ -162,6 +165,9 @@ gl::Error Context11::drawArraysInstanced(const gl::Context *context,
GLsizei count, GLsizei count,
GLsizei instanceCount) 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); return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount);
} }
...@@ -171,6 +177,9 @@ gl::Error Context11::drawElements(const gl::Context *context, ...@@ -171,6 +177,9 @@ gl::Error Context11::drawElements(const gl::Context *context,
GLenum type, GLenum type,
const void *indices) 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); return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
} }
...@@ -181,6 +190,9 @@ gl::Error Context11::drawElementsInstanced(const gl::Context *context, ...@@ -181,6 +190,9 @@ gl::Error Context11::drawElementsInstanced(const gl::Context *context,
const void *indices, const void *indices,
GLsizei instances) 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); return mRenderer->genericDrawElements(context, mode, count, type, indices, instances);
} }
...@@ -192,6 +204,9 @@ gl::Error Context11::drawRangeElements(const gl::Context *context, ...@@ -192,6 +204,9 @@ gl::Error Context11::drawRangeElements(const gl::Context *context,
GLenum type, GLenum type,
const void *indices) 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); return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
} }
...@@ -199,6 +214,9 @@ gl::Error Context11::drawArraysIndirect(const gl::Context *context, ...@@ -199,6 +214,9 @@ gl::Error Context11::drawArraysIndirect(const gl::Context *context,
GLenum mode, GLenum mode,
const void *indirect) 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); return mRenderer->genericDrawIndirect(context, mode, GL_NONE, indirect);
} }
...@@ -207,6 +225,9 @@ gl::Error Context11::drawElementsIndirect(const gl::Context *context, ...@@ -207,6 +225,9 @@ gl::Error Context11::drawElementsIndirect(const gl::Context *context,
GLenum type, GLenum type,
const void *indirect) 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); return mRenderer->genericDrawIndirect(context, mode, type, indirect);
} }
...@@ -335,8 +356,8 @@ gl::Error Context11::triggerDrawCallProgramRecompilation(const gl::Context *cont ...@@ -335,8 +356,8 @@ gl::Error Context11::triggerDrawCallProgramRecompilation(const gl::Context *cont
if (recompileGS) if (recompileGS)
{ {
ShaderExecutableD3D *geometryExe = nullptr; ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType( ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe,
context->getContextState(), drawMode, &geometryExe, infoLog)); infoLog));
if (!programD3D->hasGeometryExecutableForPrimitiveType(drawMode)) if (!programD3D->hasGeometryExecutableForPrimitiveType(drawMode))
{ {
return gl::InternalError() << "Error compiling dynamic geometry executable."; return gl::InternalError() << "Error compiling dynamic geometry executable.";
......
...@@ -147,7 +147,6 @@ class Renderer11 : public RendererD3D ...@@ -147,7 +147,6 @@ class Renderer11 : public RendererD3D
const egl::AttributeMap &attribs) const override; const egl::AttributeMap &attribs) const override;
bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize); bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
gl::Error applyTransformFeedbackBuffers(const gl::ContextState &data);
// lost device // lost device
bool testDeviceLost() override; bool testDeviceLost() override;
...@@ -485,13 +484,13 @@ class Renderer11 : public RendererD3D ...@@ -485,13 +484,13 @@ class Renderer11 : public RendererD3D
angle::WorkaroundsD3D generateWorkarounds() const override; angle::WorkaroundsD3D generateWorkarounds() const override;
gl::Error drawLineLoop(const gl::ContextState &data, gl::Error drawLineLoop(const gl::State &glState,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const void *indices, const void *indices,
int baseVertex, int baseVertex,
int instances); int instances);
gl::Error drawTriangleFan(const gl::ContextState &data, gl::Error drawTriangleFan(const gl::State &glState,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
const void *indices, const void *indices,
...@@ -525,6 +524,8 @@ class Renderer11 : public RendererD3D ...@@ -525,6 +524,8 @@ class Renderer11 : public RendererD3D
d3d11::ANGLED3D11DeviceType getDeviceType() const; d3d11::ANGLED3D11DeviceType getDeviceType() const;
gl::Error markTransformFeedbackUsage(const gl::State &glState);
HMODULE mD3d11Module; HMODULE mD3d11Module;
HMODULE mDxgiModule; HMODULE mDxgiModule;
HMODULE mDCompModule; HMODULE mDCompModule;
...@@ -540,9 +541,6 @@ class Renderer11 : public RendererD3D ...@@ -540,9 +541,6 @@ class Renderer11 : public RendererD3D
StateManager11 mStateManager; StateManager11 mStateManager;
// Currently applied transform feedback buffers
uintptr_t mAppliedTFObject;
StreamingIndexBufferInterface *mLineLoopIB; StreamingIndexBufferInterface *mLineLoopIB;
StreamingIndexBufferInterface *mTriangleFanIB; StreamingIndexBufferInterface *mTriangleFanIB;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
namespace rx namespace rx
...@@ -541,7 +542,8 @@ StateManager11::StateManager11(Renderer11 *renderer) ...@@ -541,7 +542,8 @@ StateManager11::StateManager11(Renderer11 *renderer)
mAppliedIBChanged(false), mAppliedIBChanged(false),
mVertexDataManager(renderer), mVertexDataManager(renderer),
mIndexDataManager(renderer, RENDERER_D3D11), mIndexDataManager(renderer, RENDERER_D3D11),
mIsMultiviewEnabled(false) mIsMultiviewEnabled(false),
mEmptySerial(mRenderer->generateSerial())
{ {
mCurBlendState.blend = false; mCurBlendState.blend = false;
mCurBlendState.sourceBlendRGB = GL_ONE; mCurBlendState.sourceBlendRGB = GL_ONE;
...@@ -1343,6 +1345,8 @@ void StateManager11::invalidateEverything(const gl::Context *context) ...@@ -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 // As long as all calls to *SSetConstantBuffes go through the StateManager11, it should not be
// necessary to invalidate constant buffer state. // necessary to invalidate constant buffer state.
mAppliedTFSerial = Serial();
} }
void StateManager11::invalidateVertexBuffer() void StateManager11::invalidateVertexBuffer()
...@@ -1899,6 +1903,8 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod ...@@ -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. // Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
ASSERT(mInternalDirtyBits.none()); ASSERT(mInternalDirtyBits.none());
...@@ -2253,8 +2259,8 @@ gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMod ...@@ -2253,8 +2259,8 @@ gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMod
ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr)); ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr));
ShaderExecutableD3D *geometryExe = nullptr; ShaderExecutableD3D *geometryExe = nullptr;
ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context->getContextState(), ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe,
drawMode, &geometryExe, nullptr)); nullptr));
const d3d11::VertexShader *vertexShader = const d3d11::VertexShader *vertexShader =
(vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : nullptr); (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : nullptr);
...@@ -2371,13 +2377,13 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context, ...@@ -2371,13 +2377,13 @@ gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
gl::Error StateManager11::applyIndexBuffer(const gl::ContextState &data, gl::Error StateManager11::applyIndexBuffer(const gl::Context *context,
const void *indices, const void *indices,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
TranslatedIndexData *indexInfo) TranslatedIndexData *indexInfo)
{ {
const auto &glState = data.getState(); const auto &glState = context->getGLState();
gl::VertexArray *vao = glState.getVertexArray(); gl::VertexArray *vao = glState.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
ANGLE_TRY(mIndexDataManager.prepareIndexData(type, count, elementArrayBuffer, indices, ANGLE_TRY(mIndexDataManager.prepareIndexData(type, count, elementArrayBuffer, indices,
...@@ -2792,4 +2798,40 @@ gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, Program ...@@ -2792,4 +2798,40 @@ gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, Program
return gl::NoError(); 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 } // namespace rx
...@@ -225,7 +225,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -225,7 +225,7 @@ class StateManager11 final : angle::NonCopyable
GLsizei instances, GLsizei instances,
TranslatedIndexData *indexInfo); TranslatedIndexData *indexInfo);
gl::Error applyIndexBuffer(const gl::ContextState &data, gl::Error applyIndexBuffer(const gl::Context *context,
const void *indices, const void *indices,
GLsizei count, GLsizei count,
GLenum type, GLenum type,
...@@ -301,6 +301,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -301,6 +301,7 @@ class StateManager11 final : angle::NonCopyable
gl::Error applyUniforms(ProgramD3D *programD3D); gl::Error applyUniforms(ProgramD3D *programD3D);
gl::Error syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D); gl::Error syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D);
gl::Error syncTransformFeedbackBuffers(const gl::Context *context);
enum DirtyBitType enum DirtyBitType
{ {
...@@ -481,6 +482,11 @@ class StateManager11 final : angle::NonCopyable ...@@ -481,6 +482,11 @@ class StateManager11 final : angle::NonCopyable
FragmentConstantBufferArray<ResourceSerial> mCurrentConstantBufferPS; FragmentConstantBufferArray<ResourceSerial> mCurrentConstantBufferPS;
FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset; FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset;
FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize; FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize;
// Currently applied transform feedback buffers
Serial mAppliedTFSerial;
Serial mEmptySerial;
}; };
} // namespace rx } // namespace rx
......
...@@ -21,7 +21,8 @@ TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state ...@@ -21,7 +21,8 @@ TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state
mRenderer(renderer), mRenderer(renderer),
mIsDirty(true), mIsDirty(true),
mBuffers(state.getIndexedBuffers().size(), nullptr), 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 ...@@ -113,4 +114,10 @@ const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const
{ {
return mBufferOffsets; return mBufferOffsets;
} }
Serial TransformFeedback11::getSerial() const
{
return mSerial;
}
} // namespace rx } // namespace rx
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
#include "common/platform.h" #include "common/platform.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/TransformFeedbackImpl.h" #include "libANGLE/renderer/TransformFeedbackImpl.h"
#include "libANGLE/renderer/renderer_utils.h"
namespace rx namespace rx
{ {
...@@ -43,12 +44,16 @@ class TransformFeedback11 : public TransformFeedbackImpl ...@@ -43,12 +44,16 @@ class TransformFeedback11 : public TransformFeedbackImpl
gl::ErrorOrResult<const std::vector<ID3D11Buffer *> *> getSOBuffers(); gl::ErrorOrResult<const std::vector<ID3D11Buffer *> *> getSOBuffers();
const std::vector<UINT> &getSOBufferOffsets() const; const std::vector<UINT> &getSOBufferOffsets() const;
Serial getSerial() const;
private: private:
Renderer11 *mRenderer; Renderer11 *mRenderer;
bool mIsDirty; bool mIsDirty;
std::vector<ID3D11Buffer *> mBuffers; std::vector<ID3D11Buffer *> mBuffers;
std::vector<UINT> mBufferOffsets; std::vector<UINT> mBufferOffsets;
Serial mSerial;
}; };
} // namespace rx } // namespace rx
......
...@@ -1360,12 +1360,6 @@ gl::Error Renderer9::applyIndexBuffer(const gl::ContextState &data, ...@@ -1360,12 +1360,6 @@ gl::Error Renderer9::applyIndexBuffer(const gl::ContextState &data,
return gl::NoError(); 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, gl::Error Renderer9::drawArraysImpl(const gl::ContextState &data,
GLenum mode, GLenum mode,
GLint startVertex, GLint startVertex,
...@@ -3140,19 +3134,10 @@ gl::Error Renderer9::genericDrawElements(const gl::Context *context, ...@@ -3140,19 +3134,10 @@ gl::Error Renderer9::genericDrawElements(const gl::Context *context,
} }
ANGLE_TRY(updateState(context, mode)); 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(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode)); ANGLE_TRY(applyShaders(context, mode));
if (!skipDraw(data, mode)) if (!skipDraw(data.getState(), mode))
{ {
ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances)); ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances));
} }
...@@ -3180,19 +3165,13 @@ gl::Error Renderer9::genericDrawArrays(const gl::Context *context, ...@@ -3180,19 +3165,13 @@ gl::Error Renderer9::genericDrawArrays(const gl::Context *context,
} }
ANGLE_TRY(updateState(context, mode)); ANGLE_TRY(updateState(context, mode));
ANGLE_TRY(applyTransformFeedbackBuffers(data.getState()));
ANGLE_TRY(applyVertexBuffer(data.getState(), mode, first, count, instances, nullptr)); ANGLE_TRY(applyVertexBuffer(data.getState(), mode, first, count, instances, nullptr));
ANGLE_TRY(applyTextures(context)); ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode)); ANGLE_TRY(applyShaders(context, mode));
if (!skipDraw(data, mode)) if (!skipDraw(data.getState(), mode))
{ {
ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances)); ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances));
if (data.getState().isTransformFeedbackActiveUnpaused())
{
ANGLE_TRY(markTransformFeedbackUsage(data));
}
} }
return gl::NoError(); return gl::NoError();
......
...@@ -158,8 +158,6 @@ class Renderer9 : public RendererD3D ...@@ -158,8 +158,6 @@ class Renderer9 : public RendererD3D
GLenum type, GLenum type,
TranslatedIndexData *indexInfo); TranslatedIndexData *indexInfo);
gl::Error applyTransformFeedbackBuffers(const gl::State &state);
gl::Error clear(const gl::Context *context, gl::Error clear(const gl::Context *context,
const ClearParameters &clearParams, const ClearParameters &clearParams,
const gl::FramebufferAttachment *colorBuffer, 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