diff options
Diffstat (limited to 'mesalib/src/mesa/drivers/common/meta.c')
-rw-r--r-- | mesalib/src/mesa/drivers/common/meta.c | 81 |
1 files changed, 76 insertions, 5 deletions
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index c92bf29c3..a3964798b 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -40,6 +40,7 @@ #include "main/bufferobj.h" #include "main/buffers.h" #include "main/colortab.h" +#include "main/condrender.h" #include "main/depth.h" #include "main/enable.h" #include "main/fbobject.h" @@ -92,6 +93,9 @@ #define META_TEXTURE 0x1000 #define META_VERTEX 0x2000 #define META_VIEWPORT 0x4000 +#define META_CLAMP_FRAGMENT_COLOR 0x8000 +#define META_CLAMP_VERTEX_COLOR 0x10000 +#define META_CONDITIONAL_RENDER 0x20000 /*@}*/ @@ -180,6 +184,16 @@ struct save_state GLint ViewportX, ViewportY, ViewportW, ViewportH; GLclampd DepthNear, DepthFar; + /** META_CLAMP_FRAGMENT_COLOR */ + GLenum ClampFragmentColor; + + /** META_CLAMP_VERTEX_COLOR */ + GLenum ClampVertexColor; + + /** META_CONDITIONAL_RENDER */ + struct gl_query_object *CondRenderQuery; + GLenum CondRenderMode; + /** Miscellaneous (always disabled) */ GLboolean Lighting; }; @@ -569,6 +583,34 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) _mesa_DepthRange(0.0, 1.0); } + if (state & META_CLAMP_FRAGMENT_COLOR) { + save->ClampFragmentColor = ctx->Color.ClampFragmentColor; + + /* Generally in here we want to do clamping according to whether + * it's for the pixel path (ClampFragmentColor is GL_TRUE), + * regardless of the internal implementation of the metaops. + */ + if (ctx->Color.ClampFragmentColor != GL_TRUE) + _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); + } + + if (state & META_CLAMP_VERTEX_COLOR) { + save->ClampVertexColor = ctx->Light.ClampVertexColor; + + /* Generally in here we never want vertex color clamping -- + * result clamping is only dependent on fragment clamping. + */ + _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE); + } + + if (state & META_CONDITIONAL_RENDER) { + save->CondRenderQuery = ctx->Query.CondRenderQuery; + save->CondRenderMode = ctx->Query.CondRenderMode; + + if (ctx->Query.CondRenderQuery) + _mesa_EndConditionalRender(); + } + /* misc */ { save->Lighting = ctx->Light.Enabled; @@ -833,6 +875,20 @@ _mesa_meta_end(struct gl_context *ctx) _mesa_DepthRange(save->DepthNear, save->DepthFar); } + if (state & META_CLAMP_FRAGMENT_COLOR) { + _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor); + } + + if (state & META_CLAMP_VERTEX_COLOR) { + _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor); + } + + if (state & META_CONDITIONAL_RENDER) { + if (save->CondRenderQuery) + _mesa_BeginConditionalRender(save->CondRenderQuery->Id, + save->CondRenderMode); + } + /* misc */ if (save->Lighting) { _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); @@ -1406,7 +1462,10 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) }; struct vertex verts[4]; /* save all state but scissor, pixel pack/unpack */ - GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE; + GLbitfield metaSave = (META_ALL - + META_SCISSOR - + META_PIXEL_STORE - + META_CONDITIONAL_RENDER); const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; if (buffers & BUFFER_BITS_COLOR) { @@ -1441,6 +1500,9 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) /* GL_COLOR_BUFFER_BIT */ if (buffers & BUFFER_BITS_COLOR) { /* leave colormask, glDrawBuffer state as-is */ + + /* Clears never have the color clamped. */ + _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); } else { ASSERT(metaSave & META_COLOR_MASK); @@ -1494,10 +1556,10 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) /* vertex colors */ for (i = 0; i < 4; i++) { - verts[i].r = ctx->Color.ClearColor[0]; - verts[i].g = ctx->Color.ClearColor[1]; - verts[i].b = ctx->Color.ClearColor[2]; - verts[i].a = ctx->Color.ClearColor[3]; + verts[i].r = ctx->Color.ClearColorUnclamped[0]; + verts[i].g = ctx->Color.ClearColorUnclamped[1]; + verts[i].b = ctx->Color.ClearColorUnclamped[2]; + verts[i].a = ctx->Color.ClearColorUnclamped[3]; } /* upload new vertex data */ @@ -1803,6 +1865,14 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, texIntFormat = format; else texIntFormat = GL_RGBA; + + /* If we're not supposed to clamp the resulting color, then just + * promote our texture to fully float. We could do better by + * just going for the matching set of channels, in floating + * point. + */ + if (ctx->Color.ClampFragmentColor != GL_TRUE) + texIntFormat = GL_RGBA32F; } else if (_mesa_is_stencil_format(format)) { if (ctx->Extensions.ARB_fragment_program && @@ -1861,6 +1931,7 @@ _mesa_meta_DrawPixels(struct gl_context *ctx, META_TRANSFORM | META_VERTEX | META_VIEWPORT | + META_CLAMP_FRAGMENT_COLOR | metaExtraSave)); newTex = alloc_texture(tex, width, height, texIntFormat); |