Commit 0550d038 by Geoff Lang

Implement GL_RASTERIZER_DISCARD.

BUG=angle:498 Change-Id: Ib60c39e206003ae67c93769e35f7f9ef790ce9f4 Reviewed-on: https://chromium-review.googlesource.com/184396Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 2e5c6042
...@@ -59,6 +59,7 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere ...@@ -59,6 +59,7 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
mState.depthClearValue = 1.0f; mState.depthClearValue = 1.0f;
mState.stencilClearValue = 0; mState.stencilClearValue = 0;
mState.rasterizer.rasterizerDiscard = false;
mState.rasterizer.cullFace = false; mState.rasterizer.cullFace = false;
mState.rasterizer.cullMode = GL_BACK; mState.rasterizer.cullMode = GL_BACK;
mState.rasterizer.frontFace = GL_CCW; mState.rasterizer.frontFace = GL_CCW;
...@@ -405,6 +406,44 @@ bool Context::isContextLost() ...@@ -405,6 +406,44 @@ bool Context::isContextLost()
return mContextLost; return mContextLost;
} }
void Context::setCap(GLenum cap, bool enabled)
{
switch (cap)
{
case GL_CULL_FACE: setCullFace(enabled); break;
case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
case GL_SCISSOR_TEST: setScissorTest(enabled); break;
case GL_STENCIL_TEST: setStencilTest(enabled); break;
case GL_DEPTH_TEST: setDepthTest(enabled); break;
case GL_BLEND: setBlend(enabled); break;
case GL_DITHER: setDither(enabled); break;
case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
default: UNREACHABLE();
}
}
bool Context::getCap(GLenum cap)
{
switch (cap)
{
case GL_CULL_FACE: return isCullFaceEnabled();
case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
case GL_SCISSOR_TEST: return isScissorTestEnabled();
case GL_STENCIL_TEST: return isStencilTestEnabled();
case GL_DEPTH_TEST: return isDepthTestEnabled();
case GL_BLEND: return isBlendEnabled();
case GL_DITHER: return isDitherEnabled();
case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
default: UNREACHABLE(); return false;
}
}
void Context::setClearColor(float red, float green, float blue, float alpha) void Context::setClearColor(float red, float green, float blue, float alpha)
{ {
mState.colorClearValue.red = red; mState.colorClearValue.red = red;
...@@ -423,6 +462,16 @@ void Context::setClearStencil(int stencil) ...@@ -423,6 +462,16 @@ void Context::setClearStencil(int stencil)
mState.stencilClearValue = stencil; mState.stencilClearValue = stencil;
} }
void Context::setRasterizerDiscard(bool enabled)
{
mState.rasterizer.rasterizerDiscard = enabled;
}
bool Context::isRasterizerDiscardEnabled() const
{
return mState.rasterizer.rasterizerDiscard;
}
void Context::setCullFace(bool enabled) void Context::setCullFace(bool enabled)
{ {
mState.rasterizer.cullFace = enabled; mState.rasterizer.cullFace = enabled;
...@@ -2400,10 +2449,10 @@ void Context::applyState(GLenum drawMode) ...@@ -2400,10 +2449,10 @@ void Context::applyState(GLenum drawMode)
} }
// Applies the shaders and shader constants to the Direct3D 9 device // Applies the shaders and shader constants to the Direct3D 9 device
void Context::applyShaders(ProgramBinary *programBinary) void Context::applyShaders(ProgramBinary *programBinary, bool rasterizerDiscard)
{ {
mRenderer->applyShaders(programBinary); mRenderer->applyShaders(programBinary, rasterizerDiscard);
programBinary->applyUniforms(); programBinary->applyUniforms();
} }
...@@ -2550,6 +2599,11 @@ bool Context::applyUniformBuffers() ...@@ -2550,6 +2599,11 @@ bool Context::applyUniformBuffers()
void Context::clear(GLbitfield mask) void Context::clear(GLbitfield mask)
{ {
if (isRasterizerDiscardEnabled())
{
return;
}
ClearParameters clearParams = { 0 }; ClearParameters clearParams = { 0 };
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{ {
...@@ -2618,8 +2672,12 @@ void Context::clear(GLbitfield mask) ...@@ -2618,8 +2672,12 @@ void Context::clear(GLbitfield mask)
void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
{ {
// glClearBufferfv can be called to clear the color buffer or depth buffer if (isRasterizerDiscardEnabled())
{
return;
}
// glClearBufferfv can be called to clear the color buffer or depth buffer
ClearParameters clearParams = { 0 }; ClearParameters clearParams = { 0 };
if (buffer == GL_COLOR) if (buffer == GL_COLOR)
...@@ -2673,8 +2731,12 @@ void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) ...@@ -2673,8 +2731,12 @@ void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values) void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
{ {
// glClearBufferuv can only be called to clear a color buffer if (isRasterizerDiscardEnabled())
{
return;
}
// glClearBufferuv can only be called to clear a color buffer
ClearParameters clearParams = { 0 }; ClearParameters clearParams = { 0 };
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{ {
...@@ -2704,8 +2766,12 @@ void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int * ...@@ -2704,8 +2766,12 @@ void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *
void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
{ {
// glClearBufferfv can be called to clear the color buffer or stencil buffer if (isRasterizerDiscardEnabled())
{
return;
}
// glClearBufferfv can be called to clear the color buffer or stencil buffer
ClearParameters clearParams = { 0 }; ClearParameters clearParams = { 0 };
if (buffer == GL_COLOR) if (buffer == GL_COLOR)
...@@ -2760,8 +2826,12 @@ void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) ...@@ -2760,8 +2826,12 @@ void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil) void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
{ {
// glClearBufferfi can only be called to clear a depth stencil buffer if (isRasterizerDiscardEnabled())
{
return;
}
// glClearBufferfi can only be called to clear a depth stencil buffer
ClearParameters clearParams = { 0 }; ClearParameters clearParams = { 0 };
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{ {
...@@ -2851,7 +2921,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan ...@@ -2851,7 +2921,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
return gl::error(err); return gl::error(err);
} }
applyShaders(programBinary); applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
applyTextures(programBinary); applyTextures(programBinary);
if (!applyUniformBuffers()) if (!applyUniformBuffers())
...@@ -2914,7 +2984,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid ...@@ -2914,7 +2984,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
return gl::error(err); return gl::error(err);
} }
applyShaders(programBinary); applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
applyTextures(programBinary); applyTextures(programBinary);
if (!applyUniformBuffers()) if (!applyUniformBuffers())
......
...@@ -146,12 +146,18 @@ class Context ...@@ -146,12 +146,18 @@ class Context
bool isContextLost(); bool isContextLost();
// State manipulation // State manipulation
void setCap(GLenum cap, bool enabled);
bool getCap(GLenum cap);
void setClearColor(float red, float green, float blue, float alpha); void setClearColor(float red, float green, float blue, float alpha);
void setClearDepth(float depth); void setClearDepth(float depth);
void setClearStencil(int stencil); void setClearStencil(int stencil);
void setRasterizerDiscard(bool enabled);
bool isRasterizerDiscardEnabled() const;
void setCullFace(bool enabled); void setCullFace(bool enabled);
bool isCullFaceEnabled() const; bool isCullFaceEnabled() const;
...@@ -453,7 +459,7 @@ class Context ...@@ -453,7 +459,7 @@ class Context
bool applyRenderTarget(GLenum drawMode, bool ignoreViewport); bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode); void applyState(GLenum drawMode);
void applyShaders(ProgramBinary *programBinary); void applyShaders(ProgramBinary *programBinary, bool rasterizerDiscard);
void applyTextures(ProgramBinary *programBinary); void applyTextures(ProgramBinary *programBinary);
void applyTextures(ProgramBinary *programBinary, SamplerType type); void applyTextures(ProgramBinary *programBinary, SamplerType type);
bool applyUniformBuffers(); bool applyUniformBuffers();
......
...@@ -100,6 +100,8 @@ struct RasterizerState ...@@ -100,6 +100,8 @@ struct RasterizerState
bool pointDrawMode; bool pointDrawMode;
bool multiSample; bool multiSample;
bool rasterizerDiscard;
}; };
struct BlendState struct BlendState
......
...@@ -1632,30 +1632,12 @@ void __stdcall glDisable(GLenum cap) ...@@ -1632,30 +1632,12 @@ void __stdcall glDisable(GLenum cap)
if (context) if (context)
{ {
switch (cap) if (!ValidCap(context, cap))
{ {
case GL_CULL_FACE: context->setCullFace(false); break;
case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
case GL_SCISSOR_TEST: context->setScissorTest(false); break;
case GL_STENCIL_TEST: context->setStencilTest(false); break;
case GL_DEPTH_TEST: context->setDepthTest(false); break;
case GL_BLEND: context->setBlend(false); break;
case GL_DITHER: context->setDither(false); break;
case GL_PRIMITIVE_RESTART_FIXED_INDEX:
case GL_RASTERIZER_DISCARD:
if (context->getClientVersion() < 3)
{
return gl::error(GL_INVALID_ENUM);
}
UNIMPLEMENTED();
break;
default:
return gl::error(GL_INVALID_ENUM); return gl::error(GL_INVALID_ENUM);
} }
context->setCap(cap, false);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -1832,20 +1814,12 @@ void __stdcall glEnable(GLenum cap) ...@@ -1832,20 +1814,12 @@ void __stdcall glEnable(GLenum cap)
if (context) if (context)
{ {
switch (cap) if (!ValidCap(context, cap))
{ {
case GL_CULL_FACE: context->setCullFace(true); break;
case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
case GL_SCISSOR_TEST: context->setScissorTest(true); break;
case GL_STENCIL_TEST: context->setStencilTest(true); break;
case GL_DEPTH_TEST: context->setDepthTest(true); break;
case GL_BLEND: context->setBlend(true); break;
case GL_DITHER: context->setDither(true); break;
default:
return gl::error(GL_INVALID_ENUM); return gl::error(GL_INVALID_ENUM);
} }
context->setCap(cap, true);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -4105,20 +4079,12 @@ GLboolean __stdcall glIsEnabled(GLenum cap) ...@@ -4105,20 +4079,12 @@ GLboolean __stdcall glIsEnabled(GLenum cap)
if (context) if (context)
{ {
switch (cap) if (!ValidCap(context, cap))
{ {
case GL_CULL_FACE: return context->isCullFaceEnabled();
case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
case GL_STENCIL_TEST: return context->isStencilTestEnabled();
case GL_DEPTH_TEST: return context->isDepthTestEnabled();
case GL_BLEND: return context->isBlendEnabled();
case GL_DITHER: return context->isDitherEnabled();
default:
return gl::error(GL_INVALID_ENUM, false); return gl::error(GL_INVALID_ENUM, false);
} }
return context->getCap(cap);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
...@@ -136,7 +136,7 @@ class Renderer ...@@ -136,7 +136,7 @@ class Renderer
bool ignoreViewport) = 0; bool ignoreViewport) = 0;
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
virtual void applyShaders(gl::ProgramBinary *programBinary) = 0; virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard) = 0;
virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0; virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
......
...@@ -1403,7 +1403,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic ...@@ -1403,7 +1403,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
} }
} }
void Renderer11::applyShaders(gl::ProgramBinary *programBinary) void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
{ {
ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
...@@ -1419,6 +1419,12 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary) ...@@ -1419,6 +1419,12 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
geometryShader = NULL; geometryShader = NULL;
} }
// Skip pixel shader if we're doing rasterizer discard.
if (rasterizerDiscard)
{
pixelShader = NULL;
}
bool dirtyUniforms = false; bool dirtyUniforms = false;
if (vertexShader != mAppliedVertexShader) if (vertexShader != mAppliedVertexShader)
......
...@@ -75,7 +75,7 @@ class Renderer11 : public Renderer ...@@ -75,7 +75,7 @@ class Renderer11 : public Renderer
virtual bool applyPrimitiveType(GLenum mode, GLsizei count); virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary); virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard);
virtual void applyUniforms(const gl::ProgramBinary &programBinary); virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances); GLint first, GLsizei count, GLsizei instances);
......
...@@ -1722,8 +1722,10 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi ...@@ -1722,8 +1722,10 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi
} }
} }
void Renderer9::applyShaders(gl::ProgramBinary *programBinary) void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
{ {
ASSERT(!rasterizerDiscard);
ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
......
...@@ -86,7 +86,7 @@ class Renderer9 : public Renderer ...@@ -86,7 +86,7 @@ class Renderer9 : public Renderer
bool ignoreViewport); bool ignoreViewport);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary); virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard);
virtual void applyUniforms(const gl::ProgramBinary &programBinary); virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
......
...@@ -21,6 +21,28 @@ ...@@ -21,6 +21,28 @@
namespace gl namespace gl
{ {
bool ValidCap(const Context *context, GLenum cap)
{
switch (cap)
{
case GL_CULL_FACE:
case GL_POLYGON_OFFSET_FILL:
case GL_SAMPLE_ALPHA_TO_COVERAGE:
case GL_SAMPLE_COVERAGE:
case GL_SCISSOR_TEST:
case GL_STENCIL_TEST:
case GL_DEPTH_TEST:
case GL_BLEND:
case GL_DITHER:
return true;
case GL_PRIMITIVE_RESTART_FIXED_INDEX:
case GL_RASTERIZER_DISCARD:
return (context->getClientVersion() >= 3);
default:
return false;
}
}
bool ValidTextureTarget(const Context *context, GLenum target) bool ValidTextureTarget(const Context *context, GLenum target)
{ {
switch (target) switch (target)
......
...@@ -14,6 +14,7 @@ namespace gl ...@@ -14,6 +14,7 @@ namespace gl
class Context; class Context;
bool ValidCap(const Context *context, GLenum cap);
bool ValidTextureTarget(const Context *context, GLenum target); bool ValidTextureTarget(const Context *context, GLenum target);
bool ValidFramebufferTarget(GLenum target); bool ValidFramebufferTarget(GLenum target);
bool ValidMipLevel(const Context *context, GLenum target, GLint level); bool ValidMipLevel(const Context *context, GLenum target, GLint level);
......
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