Commit e403eef9 by Jamie Madill Committed by Commit Bot

D3D11: Add primitive type dirty bits.

Bug: angleproject:1155 Bug: angleproject:2389 Change-Id: If410bc9e2ea97385def5d6a8a95d6bf6ea4c6a28 Reviewed-on: https://chromium-review.googlesource.com/948797 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 3988f34e
...@@ -407,12 +407,6 @@ void PopulateFormatDeviceCaps(ID3D11Device *device, ...@@ -407,12 +407,6 @@ void PopulateFormatDeviceCaps(ID3D11Device *device,
} }
} }
bool CullsEverything(const gl::State &glState)
{
return (glState.getRasterizerState().cullFace &&
glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
}
} // anonymous namespace } // anonymous namespace
Renderer11DeviceCaps::Renderer11DeviceCaps() = default; Renderer11DeviceCaps::Renderer11DeviceCaps() = default;
...@@ -1404,85 +1398,14 @@ void *Renderer11::getD3DDevice() ...@@ -1404,85 +1398,14 @@ void *Renderer11::getD3DDevice()
return reinterpret_cast<void *>(mDevice); return reinterpret_cast<void *>(mDevice);
} }
bool Renderer11::applyPrimitiveType(const gl::State &glState, GLenum mode, GLsizei count)
{
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
GLsizei minCount = 0;
switch (mode)
{
case GL_POINTS:
{
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 && !glState.isTransformFeedbackActiveUnpaused())
{
// Notify developers of risking undefined behavior.
WARN() << "Point rendering without writing to gl_PointSize.";
return false;
}
// If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
// must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
if (usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation)
{
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
else
{
primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
}
minCount = 1;
break;
}
case GL_LINES:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
minCount = 2;
break;
case GL_LINE_LOOP:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
minCount = 2;
break;
case GL_LINE_STRIP:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
minCount = 2;
break;
case GL_TRIANGLES:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
minCount = CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
break;
case GL_TRIANGLE_STRIP:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
minCount = CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
break;
// emulate fans via rewriting index buffer
case GL_TRIANGLE_FAN:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
minCount = CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
break;
default:
UNREACHABLE();
return false;
}
mStateManager.setPrimitiveTopology(primitiveTopology);
return count >= minCount;
}
gl::Error Renderer11::drawArrays(const gl::Context *context, const gl::DrawCallParams &params) gl::Error Renderer11::drawArrays(const gl::Context *context, const gl::DrawCallParams &params)
{ {
const auto &glState = context->getGLState(); if (params.vertexCount() < mStateManager.getCurrentMinimumDrawCount())
if (!applyPrimitiveType(glState, params.mode(), params.vertexCount()))
{ {
return gl::NoError(); return gl::NoError();
} }
const auto &glState = context->getGLState();
if (glState.isTransformFeedbackActiveUnpaused()) if (glState.isTransformFeedbackActiveUnpaused())
{ {
ANGLE_TRY(markTransformFeedbackUsage(context)); ANGLE_TRY(markTransformFeedbackUsage(context));
...@@ -1602,15 +1525,14 @@ gl::Error Renderer11::drawArrays(const gl::Context *context, const gl::DrawCallP ...@@ -1602,15 +1525,14 @@ gl::Error Renderer11::drawArrays(const gl::Context *context, const gl::DrawCallP
gl::Error Renderer11::drawElements(const gl::Context *context, const gl::DrawCallParams &params) gl::Error Renderer11::drawElements(const gl::Context *context, const gl::DrawCallParams &params)
{ {
const auto &glState = context->getGLState(); if (params.indexCount() < mStateManager.getCurrentMinimumDrawCount())
if (!applyPrimitiveType(glState, params.mode(), params.indexCount()))
{ {
return gl::NoError(); return gl::NoError();
} }
// Transform feedback is not allowed for DrawElements, this error should have been caught at the // Transform feedback is not allowed for DrawElements, this error should have been caught at the
// API validation layer. // API validation layer.
const auto &glState = context->getGLState();
ASSERT(!glState.isTransformFeedbackActiveUnpaused()); ASSERT(!glState.isTransformFeedbackActiveUnpaused());
bool usePrimitiveRestartWorkaround = bool usePrimitiveRestartWorkaround =
...@@ -1693,14 +1615,14 @@ gl::Error Renderer11::drawElements(const gl::Context *context, const gl::DrawCal ...@@ -1693,14 +1615,14 @@ gl::Error Renderer11::drawElements(const gl::Context *context, const gl::DrawCal
gl::Error Renderer11::drawArraysIndirect(const gl::Context *context, gl::Error Renderer11::drawArraysIndirect(const gl::Context *context,
const gl::DrawCallParams &params) const gl::DrawCallParams &params)
{ {
const auto &glState = context->getGLState(); if (std::numeric_limits<GLsizei>::max() == mStateManager.getCurrentMinimumDrawCount())
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
if (!applyPrimitiveType(glState, params.mode(), std::numeric_limits<int>::max() - 1))
{ {
return gl::NoError(); return gl::NoError();
} }
const gl::State &glState = context->getGLState();
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
ANGLE_TRY(mStateManager.applyVertexBuffer(context, params)); ANGLE_TRY(mStateManager.applyVertexBuffer(context, params));
gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
...@@ -1718,14 +1640,14 @@ gl::Error Renderer11::drawArraysIndirect(const gl::Context *context, ...@@ -1718,14 +1640,14 @@ gl::Error Renderer11::drawArraysIndirect(const gl::Context *context,
gl::Error Renderer11::drawElementsIndirect(const gl::Context *context, gl::Error Renderer11::drawElementsIndirect(const gl::Context *context,
const gl::DrawCallParams &params) const gl::DrawCallParams &params)
{ {
const auto &glState = context->getGLState(); if (std::numeric_limits<GLsizei>::max() == mStateManager.getCurrentMinimumDrawCount())
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
if (!applyPrimitiveType(glState, params.mode(), std::numeric_limits<int>::max() - 1))
{ {
return gl::NoError(); return gl::NoError();
} }
const gl::State &glState = context->getGLState();
ASSERT(!glState.isTransformFeedbackActiveUnpaused());
gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
ASSERT(drawIndirectBuffer); ASSERT(drawIndirectBuffer);
Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer); Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
......
...@@ -148,8 +148,6 @@ class Renderer11 : public RendererD3D ...@@ -148,8 +148,6 @@ class Renderer11 : public RendererD3D
HANDLE shareHandle, HANDLE shareHandle,
const egl::AttributeMap &attribs) const override; const egl::AttributeMap &attribs) const override;
bool applyPrimitiveType(const gl::State &glState, GLenum mode, GLsizei count);
// lost device // lost device
bool testDeviceLost() override; bool testDeviceLost() override;
bool testDeviceResettable() override; bool testDeviceResettable() override;
......
...@@ -185,6 +185,12 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation) ...@@ -185,6 +185,12 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
{ {
return usesPointSpriteEmulation ? 1 : 0; return usesPointSpriteEmulation ? 1 : 0;
} }
bool CullsEverything(const gl::State &glState)
{
return (glState.getRasterizerState().cullFace &&
glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
}
} // anonymous namespace } // anonymous namespace
// StateManager11::ViewCache Implementation. // StateManager11::ViewCache Implementation.
...@@ -585,6 +591,8 @@ StateManager11::StateManager11(Renderer11 *renderer) ...@@ -585,6 +591,8 @@ StateManager11::StateManager11(Renderer11 *renderer)
mVertexAttribsNeedTranslation(false), mVertexAttribsNeedTranslation(false),
mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0), mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED), mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
mLastAppliedDrawMode(GL_INVALID_INDEX),
mCurrentMinimumDrawCount(0),
mDirtySwizzles(false), mDirtySwizzles(false),
mAppliedIB(nullptr), mAppliedIB(nullptr),
mAppliedIBFormat(DXGI_FORMAT_UNKNOWN), mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
...@@ -923,18 +931,21 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -923,18 +931,21 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
{ {
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
} }
break; break;
case gl::State::DIRTY_BIT_CULL_FACE: case gl::State::DIRTY_BIT_CULL_FACE:
if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
{ {
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
} }
break; break;
case gl::State::DIRTY_BIT_FRONT_FACE: case gl::State::DIRTY_BIT_FRONT_FACE:
if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
{ {
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
} }
break; break;
case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
...@@ -1020,7 +1031,8 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -1020,7 +1031,8 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
break; break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
{ {
mInternalDirtyBits.set(DIRTY_BIT_SHADERS); mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
invalidateShaders();
invalidateVertexBuffer(); invalidateVertexBuffer();
invalidateRenderTarget(); invalidateRenderTarget();
invalidateTexturesAndSamplers(); invalidateTexturesAndSamplers();
...@@ -1205,11 +1217,12 @@ gl::Error StateManager11::syncDepthStencilState(const gl::State &glState) ...@@ -1205,11 +1217,12 @@ gl::Error StateManager11::syncDepthStencilState(const gl::State &glState)
return gl::NoError(); return gl::NoError();
} }
gl::Error StateManager11::syncRasterizerState(const gl::Context *context, bool pointDrawMode) gl::Error StateManager11::syncRasterizerState(const gl::Context *context,
const gl::DrawCallParams &drawCallParams)
{ {
// TODO: Remove pointDrawMode and multiSample from gl::RasterizerState. // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
gl::RasterizerState rasterState = context->getGLState().getRasterizerState(); gl::RasterizerState rasterState = context->getGLState().getRasterizerState();
rasterState.pointDrawMode = pointDrawMode; rasterState.pointDrawMode = (drawCallParams.mode() == GL_POINTS);
rasterState.multiSample = mCurRasterState.multiSample; rasterState.multiSample = mCurRasterState.multiSample;
ID3D11RasterizerState *dxRasterState = nullptr; ID3D11RasterizerState *dxRasterState = nullptr;
...@@ -2011,15 +2024,6 @@ gl::Error StateManager11::updateState(const gl::Context *context, ...@@ -2011,15 +2024,6 @@ gl::Error StateManager11::updateState(const gl::Context *context,
Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer); Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
ANGLE_TRY(framebuffer11->markAttachmentsDirty(context)); ANGLE_TRY(framebuffer11->markAttachmentsDirty(context));
bool pointDrawMode = (drawCallParams.mode() == GL_POINTS);
if (pointDrawMode != mCurRasterState.pointDrawMode)
{
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
// Changing from points to not points (or vice-versa) affects the geometry shader.
invalidateShaders();
}
// TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask
// state changes. // state changes.
RenderTarget11 *firstRT = framebuffer11->getFirstRenderTarget(); RenderTarget11 *firstRT = framebuffer11->getFirstRenderTarget();
...@@ -2038,6 +2042,21 @@ gl::Error StateManager11::updateState(const gl::Context *context, ...@@ -2038,6 +2042,21 @@ gl::Error StateManager11::updateState(const gl::Context *context,
mInternalDirtyBits.set(DIRTY_BIT_SHADERS); mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
} }
if (mLastAppliedDrawMode != drawCallParams.mode())
{
mLastAppliedDrawMode = drawCallParams.mode();
mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
bool pointDrawMode = (drawCallParams.mode() == GL_POINTS);
if (pointDrawMode != mCurRasterState.pointDrawMode)
{
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
// Changing from points to not points (or vice-versa) affects the geometry shader.
invalidateShaders();
}
}
auto dirtyBitsCopy = mInternalDirtyBits; auto dirtyBitsCopy = mInternalDirtyBits;
mInternalDirtyBits.reset(); mInternalDirtyBits.reset();
...@@ -2055,7 +2074,7 @@ gl::Error StateManager11::updateState(const gl::Context *context, ...@@ -2055,7 +2074,7 @@ gl::Error StateManager11::updateState(const gl::Context *context,
syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
break; break;
case DIRTY_BIT_RASTERIZER_STATE: case DIRTY_BIT_RASTERIZER_STATE:
ANGLE_TRY(syncRasterizerState(context, pointDrawMode)); ANGLE_TRY(syncRasterizerState(context, drawCallParams));
break; break;
case DIRTY_BIT_BLEND_STATE: case DIRTY_BIT_BLEND_STATE:
ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(), ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(),
...@@ -2087,6 +2106,9 @@ gl::Error StateManager11::updateState(const gl::Context *context, ...@@ -2087,6 +2106,9 @@ gl::Error StateManager11::updateState(const gl::Context *context,
case DIRTY_BIT_TRANSFORM_FEEDBACK: case DIRTY_BIT_TRANSFORM_FEEDBACK:
ANGLE_TRY(syncTransformFeedbackBuffers(context)); ANGLE_TRY(syncTransformFeedbackBuffers(context));
break; break;
case DIRTY_BIT_PRIMITIVE_TOPOLOGY:
syncPrimitiveTopology(glState, programD3D, drawCallParams.mode());
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -2121,10 +2143,23 @@ void StateManager11::setShaderResource(gl::ShaderType shaderType, ...@@ -2121,10 +2143,23 @@ void StateManager11::setShaderResource(gl::ShaderType shaderType,
void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology) void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
{ {
if (setPrimitiveTopologyInternal(primitiveTopology))
{
mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
}
}
bool StateManager11::setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
{
if (primitiveTopology != mCurrentPrimitiveTopology) if (primitiveTopology != mCurrentPrimitiveTopology)
{ {
mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology); mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology);
mCurrentPrimitiveTopology = primitiveTopology; mCurrentPrimitiveTopology = primitiveTopology;
return true;
}
else
{
return false;
} }
} }
...@@ -3435,4 +3470,76 @@ void StateManager11::OnConstantBufferDirtyReceiver::reset() ...@@ -3435,4 +3470,76 @@ void StateManager11::OnConstantBufferDirtyReceiver::reset()
} }
} }
void StateManager11::syncPrimitiveTopology(const gl::State &glState,
ProgramD3D *programD3D,
GLenum currentDrawMode)
{
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
switch (currentDrawMode)
{
case GL_POINTS:
{
bool usesPointSize = programD3D->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 && !glState.isTransformFeedbackActiveUnpaused())
{
// Notify developers of risking undefined behavior.
WARN() << "Point rendering without writing to gl_PointSize.";
mCurrentMinimumDrawCount = std::numeric_limits<GLsizei>::max();
return;
}
// If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
// must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
if (usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation)
{
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
else
{
primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
}
mCurrentMinimumDrawCount = 1;
break;
}
case GL_LINES:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
mCurrentMinimumDrawCount = 2;
break;
case GL_LINE_LOOP:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
mCurrentMinimumDrawCount = 2;
break;
case GL_LINE_STRIP:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
mCurrentMinimumDrawCount = 2;
break;
case GL_TRIANGLES:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
mCurrentMinimumDrawCount =
CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
break;
case GL_TRIANGLE_STRIP:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
mCurrentMinimumDrawCount =
CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
break;
// emulate fans via rewriting index buffer
case GL_TRIANGLE_FAN:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
mCurrentMinimumDrawCount =
CullsEverything(glState) ? std::numeric_limits<GLsizei>::max() : 3;
break;
default:
UNREACHABLE();
break;
}
setPrimitiveTopologyInternal(primitiveTopology);
}
} // namespace rx } // namespace rx
...@@ -251,6 +251,8 @@ class StateManager11 final : angle::NonCopyable ...@@ -251,6 +251,8 @@ class StateManager11 final : angle::NonCopyable
// Only used in testing. // Only used in testing.
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
GLsizei getCurrentMinimumDrawCount() const { return mCurrentMinimumDrawCount; }
private: private:
template <typename SRVType> template <typename SRVType>
void setShaderResourceInternal(gl::ShaderType shaderType, void setShaderResourceInternal(gl::ShaderType shaderType,
...@@ -276,7 +278,8 @@ class StateManager11 final : angle::NonCopyable ...@@ -276,7 +278,8 @@ class StateManager11 final : angle::NonCopyable
gl::Error syncDepthStencilState(const gl::State &glState); gl::Error syncDepthStencilState(const gl::State &glState);
gl::Error syncRasterizerState(const gl::Context *context, bool pointDrawMode); gl::Error syncRasterizerState(const gl::Context *context,
const gl::DrawCallParams &drawCallParams);
void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled); void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled);
...@@ -344,6 +347,10 @@ class StateManager11 final : angle::NonCopyable ...@@ -344,6 +347,10 @@ class StateManager11 final : angle::NonCopyable
UINT stride, UINT stride,
UINT offset); UINT offset);
void applyVertexBufferChanges(); void applyVertexBufferChanges();
bool setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
void syncPrimitiveTopology(const gl::State &glState,
ProgramD3D *programD3D,
GLenum currentDrawMode);
enum DirtyBitType enum DirtyBitType
{ {
...@@ -360,6 +367,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -360,6 +367,7 @@ class StateManager11 final : angle::NonCopyable
DIRTY_BIT_SHADERS, DIRTY_BIT_SHADERS,
DIRTY_BIT_CURRENT_VALUE_ATTRIBS, DIRTY_BIT_CURRENT_VALUE_ATTRIBS,
DIRTY_BIT_TRANSFORM_FEEDBACK, DIRTY_BIT_TRANSFORM_FEEDBACK,
DIRTY_BIT_PRIMITIVE_TOPOLOGY,
DIRTY_BIT_INVALID, DIRTY_BIT_INVALID,
DIRTY_BIT_MAX = DIRTY_BIT_INVALID, DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
}; };
...@@ -479,6 +487,8 @@ class StateManager11 final : angle::NonCopyable ...@@ -479,6 +487,8 @@ class StateManager11 final : angle::NonCopyable
// Currently applied primitive topology // Currently applied primitive topology
D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
GLenum mLastAppliedDrawMode;
GLsizei mCurrentMinimumDrawCount;
// Currently applied shaders // Currently applied shaders
ResourceSerial mAppliedVertexShader; ResourceSerial mAppliedVertexShader;
......
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