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
mState.depthClearValue = 1.0f;
mState.stencilClearValue = 0;
mState.rasterizer.rasterizerDiscard = false;
mState.rasterizer.cullFace = false;
mState.rasterizer.cullMode = GL_BACK;
mState.rasterizer.frontFace = GL_CCW;
......@@ -405,6 +406,44 @@ bool Context::isContextLost()
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)
{
mState.colorClearValue.red = red;
......@@ -423,6 +462,16 @@ void Context::setClearStencil(int 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)
{
mState.rasterizer.cullFace = enabled;
......@@ -2400,10 +2449,10 @@ void Context::applyState(GLenum drawMode)
}
// 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();
}
......@@ -2550,6 +2599,11 @@ bool Context::applyUniformBuffers()
void Context::clear(GLbitfield mask)
{
if (isRasterizerDiscardEnabled())
{
return;
}
ClearParameters clearParams = { 0 };
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
......@@ -2618,8 +2672,12 @@ void Context::clear(GLbitfield mask)
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 };
if (buffer == GL_COLOR)
......@@ -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)
{
// 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 };
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
......@@ -2704,8 +2766,12 @@ void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *
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 };
if (buffer == GL_COLOR)
......@@ -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)
{
// 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 };
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
return gl::error(err);
}
applyShaders(programBinary);
applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
applyTextures(programBinary);
if (!applyUniformBuffers())
......@@ -2914,7 +2984,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
return gl::error(err);
}
applyShaders(programBinary);
applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
applyTextures(programBinary);
if (!applyUniformBuffers())
......
......@@ -146,12 +146,18 @@ class Context
bool isContextLost();
// State manipulation
void setCap(GLenum cap, bool enabled);
bool getCap(GLenum cap);
void setClearColor(float red, float green, float blue, float alpha);
void setClearDepth(float depth);
void setClearStencil(int stencil);
void setRasterizerDiscard(bool enabled);
bool isRasterizerDiscardEnabled() const;
void setCullFace(bool enabled);
bool isCullFaceEnabled() const;
......@@ -453,7 +459,7 @@ class Context
bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode);
void applyShaders(ProgramBinary *programBinary);
void applyShaders(ProgramBinary *programBinary, bool rasterizerDiscard);
void applyTextures(ProgramBinary *programBinary);
void applyTextures(ProgramBinary *programBinary, SamplerType type);
bool applyUniformBuffers();
......
......@@ -100,6 +100,8 @@ struct RasterizerState
bool pointDrawMode;
bool multiSample;
bool rasterizerDiscard;
};
struct BlendState
......
......@@ -1632,30 +1632,12 @@ void __stdcall glDisable(GLenum cap)
if (context)
{
switch (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:
if (!ValidCap(context, cap))
{
return gl::error(GL_INVALID_ENUM);
}
context->setCap(cap, false);
}
}
catch(std::bad_alloc&)
......@@ -1832,20 +1814,12 @@ void __stdcall glEnable(GLenum cap)
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);
}
context->setCap(cap, true);
}
}
catch(std::bad_alloc&)
......@@ -4105,20 +4079,12 @@ GLboolean __stdcall glIsEnabled(GLenum cap)
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 context->getCap(cap);
}
}
catch(std::bad_alloc&)
......
......@@ -136,7 +136,7 @@ class Renderer
bool ignoreViewport) = 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 bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
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
}
}
void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard)
{
ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
......@@ -1419,6 +1419,12 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
geometryShader = NULL;
}
// Skip pixel shader if we're doing rasterizer discard.
if (rasterizerDiscard)
{
pixelShader = NULL;
}
bool dirtyUniforms = false;
if (vertexShader != mAppliedVertexShader)
......
......@@ -75,7 +75,7 @@ class Renderer11 : public Renderer
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
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 GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
......
......@@ -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 *pixelExe = programBinary->getPixelExecutable();
......
......@@ -86,7 +86,7 @@ class Renderer9 : public Renderer
bool ignoreViewport);
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 bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
......
......@@ -21,6 +21,28 @@
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)
{
switch (target)
......
......@@ -14,6 +14,7 @@ namespace gl
class Context;
bool ValidCap(const Context *context, GLenum cap);
bool ValidTextureTarget(const Context *context, GLenum target);
bool ValidFramebufferTarget(GLenum target);
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