[Mesa-dev] [PATCH 1/6] mesa: implement clamping controls (ARB_color_buffer_float)
Marek Olšák
maraeo at gmail.com
Sun Mar 20 18:12:30 PDT 2011
Squashed commit of the following:
Author: Marek Olšák <maraeo at gmail.com>
mesa: fix getteximage so that it doesn't clamp values
mesa: update the compute_version function
mesa: add display list support for ARB_color_buffer_float
mesa: fix glGet query with GL_ALPHA_TEST_REF and ARB_color_buffer_float
commit b2f6ddf907935b2594d2831ddab38cf57a1729ce
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Tue Aug 31 16:50:57 2010 +0200
mesa: document known possible deviations from ARB_color_buffer_float
commit 5458935be800c1b19d1c9d1569dc4fa30a97e8b8
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Tue Aug 24 21:54:56 2010 +0200
mesa: expose GL_ARB_color_buffer_float
commit aef5c3c6be6edd076e955e37c80905bc447f8a82
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Thu Aug 26 18:12:34 2010 +0200
mesa, mesa/st: handle read color clamping properly
(I'll squash the st/mesa part to a separate commit. -Marek)
We set IMAGE_CLAMP_BIT in the caller based on _ClampReadColor, where
the operation mandates it.
TODO: did I get the set of operations mandating it right?
commit 3a9cb5e59b676b6148c50907ce6eef5441677e36
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Thu Aug 26 18:09:41 2010 +0200
mesa: respect color clamping in texenv programs (v2)
Changes in v2:
- Fix attributes other than vertex color sometimes getting clamped
commit de26f9e47e886e176aab6e5a2c3d4481efb64362
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Thu Aug 26 18:05:53 2010 +0200
mesa: restore color clamps on glPopAttrib
commit a55ac3c300c189616627c05d924c40a8b55bfafa
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Thu Aug 26 18:04:26 2010 +0200
mesa: clamp color queries if and only if fragment clamping is enabled
commit 9940a3e31c2fb76cc3d28b15ea78dde369825107
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Wed Aug 25 00:00:16 2010 +0200
mesa: introduce derived _ClampXxxColor state resolving FIXED_ONLY
To do this, we make ClampColor call FLUSH_VERTICES with the appropriate
_NEW flag.
We introduce _NEW_FRAG_CLAMP since fragment clamping has wide-ranging
effects, despite being in the Color attrib group.
This may be easily changed by s/_NEW_FRAG_CLAMP/_NEW_COLOR/g
commit 6244c446e3beed5473b4e811d10787e4019f59d6
Author: Luca Barbieri <luca at luca-barbieri.com>
Date: Thu Aug 26 17:58:24 2010 +0200
mesa: add unclamped color parameters
---
docs/ARB_color_buffer_float.txt | 4 ++
src/mapi/glapi/gen/ARB_color_buffer_float.xml | 25 ++++++++++++++
src/mapi/glapi/gen/Makefile | 1 +
src/mapi/glapi/gen/gl_API.xml | 1 +
src/mesa/drivers/dri/i915/i915_fragprog.c | 2 +-
src/mesa/drivers/dri/i965/brw_program.c | 2 +-
src/mesa/main/api_exec.c | 2 +
src/mesa/main/attrib.c | 21 +++++++-----
src/mesa/main/blend.c | 37 +++++++++++++-------
src/mesa/main/clear.c | 20 ++++++++---
src/mesa/main/colortab.c | 7 +++-
src/mesa/main/dlist.c | 27 +++++++++++++++
src/mesa/main/extensions.c | 1 +
src/mesa/main/ff_fragment_shader.cpp | 4 +-
src/mesa/main/fog.c | 5 +++
src/mesa/main/get.c | 45 ++++++++++++++++++++++--
src/mesa/main/mtypes.h | 20 ++++++++++-
src/mesa/main/pack.c | 11 ------
src/mesa/main/state.c | 40 +++++++++++++++++++++-
src/mesa/main/texenv.c | 21 +++++++----
src/mesa/main/texparam.c | 21 +++++++++--
src/mesa/main/version.c | 2 +
src/mesa/program/arbprogparse.c | 5 ++-
src/mesa/program/prog_statevars.c | 32 ++++++++++++++++--
src/mesa/program/prog_statevars.h | 1 +
src/mesa/program/programopt.c | 5 ++-
src/mesa/program/programopt.h | 2 +-
27 files changed, 294 insertions(+), 70 deletions(-)
create mode 100644 docs/ARB_color_buffer_float.txt
create mode 100644 src/mapi/glapi/gen/ARB_color_buffer_float.xml
diff --git a/docs/ARB_color_buffer_float.txt b/docs/ARB_color_buffer_float.txt
new file mode 100644
index 0000000..e501120
--- /dev/null
+++ b/docs/ARB_color_buffer_float.txt
@@ -0,0 +1,4 @@
+Known issues in the ARB_color_buffer_float implementation:
+- Rendering to multiple render targets, some fixed-point, some floating-point, with FIXED_ONLY fragment clamping and polygon smooth enabled may write incorrect values to the fixed point buffers (depends on spec interpretation)
+- For fragment programs with ARB_fog_* options, colors are clamped before fog application regardless of the fragment clamping setting (this depends on spec interpretation)
+
diff --git a/src/mapi/glapi/gen/ARB_color_buffer_float.xml b/src/mapi/glapi/gen/ARB_color_buffer_float.xml
new file mode 100644
index 0000000..7acf271
--- /dev/null
+++ b/src/mapi/glapi/gen/ARB_color_buffer_float.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="GL_ARB_color_buffer_float" number="39">
+
+ <enum name="RGBA_FLOAT_MODE_ARB" value="0x8820"/>
+ <enum name="CLAMP_VERTEX_COLOR_ARB" value="0x891A"/>
+ <enum name="CLAMP_FRAGMENT_COLOR_ARB" value="0x891B"/>
+ <enum name="CLAMP_READ_COLOR_ARB" value="0x891C"/>
+ <enum name="FIXED_ONLY_ARB" value="0x891D"/>
+
+ <function name="ClampColorARB" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="clamp" type="GLenum"/>
+ <glx rop="234"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/Makefile b/src/mapi/glapi/gen/Makefile
index 1f4642a..e1754b1 100644
--- a/src/mapi/glapi/gen/Makefile
+++ b/src/mapi/glapi/gen/Makefile
@@ -72,6 +72,7 @@ XORG_OUTPUTS = \
API_XML = \
gl_API.xml \
+ ARB_color_buffer_float.xml \
ARB_copy_buffer.xml \
ARB_depth_clamp.xml \
ARB_draw_buffers_blend.xml \
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 56c0ec7..cb20ac7 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -7979,6 +7979,7 @@
<xi:include href="ARB_geometry_shader4.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<xi:include href="ARB_color_buffer_float.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- Non-ARB extensions sorted by extension number. -->
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 2bfe665..89de2a8 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -1291,7 +1291,7 @@ i915ProgramStringNotify(struct gl_context * ctx,
*/
if (p->FragProg.FogOption) {
/* add extra instructions to do fog, then turn off FogOption field */
- _mesa_append_fog_code(ctx, &p->FragProg);
+ _mesa_append_fog_code(ctx, &p->FragProg, TRUE);
p->FragProg.FogOption = GL_NONE;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index ee68095..2132b82 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -135,7 +135,7 @@ static GLboolean brwProgramStringNotify( struct gl_context *ctx,
struct gl_shader_program *shader_program;
if (fprog->FogOption) {
- _mesa_append_fog_code(ctx, fprog);
+ _mesa_append_fog_code(ctx, fprog, TRUE);
fprog->FogOption = GL_NONE;
}
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index 4da4893..f760370 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -691,6 +691,8 @@ _mesa_create_exec_table(void)
SET_FramebufferTextureFaceARB(exec, _mesa_FramebufferTextureFaceARB);
#endif
+ SET_ClampColorARB(exec, _mesa_ClampColorARB);
+
/* GL_EXT_texture_integer */
SET_ClearColorIiEXT(exec, _mesa_ClearColorIiEXT);
SET_ClearColorIuiEXT(exec, _mesa_ClearColorIuiEXT);
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index ae7f633..340c06c 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -879,10 +879,10 @@ _mesa_PopAttrib(void)
color = (const struct gl_colorbuffer_attrib *) attr->data;
_mesa_ClearIndex((GLfloat) color->ClearIndex);
- _mesa_ClearColor(color->ClearColor[0],
- color->ClearColor[1],
- color->ClearColor[2],
- color->ClearColor[3]);
+ _mesa_ClearColor(color->ClearColorUnclamped[0],
+ color->ClearColorUnclamped[1],
+ color->ClearColorUnclamped[2],
+ color->ClearColorUnclamped[3]);
_mesa_IndexMask(color->IndexMask);
if (!ctx->Extensions.EXT_draw_buffers2) {
_mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0),
@@ -930,7 +930,7 @@ _mesa_PopAttrib(void)
_mesa_DrawBuffer(color->DrawBuffer[0]);
}
_mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
- _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
+ _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped);
if (ctx->Color.BlendEnabled != color->BlendEnabled) {
if (ctx->Extensions.EXT_draw_buffers2) {
GLuint i;
@@ -976,16 +976,18 @@ _mesa_PopAttrib(void)
color->Blend[0].EquationA);
}
}
- _mesa_BlendColor(color->BlendColor[0],
- color->BlendColor[1],
- color->BlendColor[2],
- color->BlendColor[3]);
+ _mesa_BlendColor(color->BlendColorUnclamped[0],
+ color->BlendColorUnclamped[1],
+ color->BlendColorUnclamped[2],
+ color->BlendColorUnclamped[3]);
_mesa_LogicOp(color->LogicOp);
_mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
color->ColorLogicOpEnabled);
_mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
color->IndexLogicOpEnabled);
_mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
+ _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, color->ClampFragmentColor);
+ _mesa_ClampColorARB(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor);
}
break;
case GL_CURRENT_BIT:
@@ -1108,6 +1110,7 @@ _mesa_PopAttrib(void)
/* materials */
memcpy(&ctx->Light.Material, &light->Material,
sizeof(struct gl_material));
+ _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, light->ClampVertexColor);
}
break;
case GL_LINE_BIT:
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index c74a168..95c101c 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -513,19 +513,24 @@ _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- tmp[0] = CLAMP( red, 0.0F, 1.0F );
- tmp[1] = CLAMP( green, 0.0F, 1.0F );
- tmp[2] = CLAMP( blue, 0.0F, 1.0F );
- tmp[3] = CLAMP( alpha, 0.0F, 1.0F );
+ tmp[0] = red;
+ tmp[1] = green;
+ tmp[2] = blue;
+ tmp[3] = alpha;
- if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
+ if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped))
return;
FLUSH_VERTICES(ctx, _NEW_COLOR);
- COPY_4FV( ctx->Color.BlendColor, tmp );
+ COPY_4FV( ctx->Color.BlendColorUnclamped, tmp );
+
+ ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F);
+ ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F);
+ ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F);
+ ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F);
if (ctx->Driver.BlendColor)
- (*ctx->Driver.BlendColor)(ctx, tmp);
+ (*ctx->Driver.BlendColor)(ctx, ctx->Color.BlendColor);
}
@@ -558,17 +563,16 @@ _mesa_AlphaFunc( GLenum func, GLclampf ref )
case GL_NOTEQUAL:
case GL_GEQUAL:
case GL_ALWAYS:
- ref = CLAMP(ref, 0.0F, 1.0F);
-
- if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRef == ref)
+ if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
return; /* no change */
FLUSH_VERTICES(ctx, _NEW_COLOR);
ctx->Color.AlphaFunc = func;
- ctx->Color.AlphaRef = ref;
+ ctx->Color.AlphaRefUnclamped = ref;
+ ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F);
if (ctx->Driver.AlphaFunc)
- ctx->Driver.AlphaFunc(ctx, func, ref);
+ ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef);
return;
default:
@@ -737,7 +741,7 @@ _mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
}
-extern void GLAPIENTRY
+void GLAPIENTRY
_mesa_ClampColorARB(GLenum target, GLenum clamp)
{
GET_CURRENT_CONTEXT(ctx);
@@ -751,12 +755,15 @@ _mesa_ClampColorARB(GLenum target, GLenum clamp)
switch (target) {
case GL_CLAMP_VERTEX_COLOR_ARB:
+ FLUSH_VERTICES(ctx, _NEW_LIGHT);
ctx->Light.ClampVertexColor = clamp;
break;
case GL_CLAMP_FRAGMENT_COLOR_ARB:
+ FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
ctx->Color.ClampFragmentColor = clamp;
break;
case GL_CLAMP_READ_COLOR_ARB:
+ FLUSH_VERTICES(ctx, _NEW_COLOR);
ctx->Color.ClampReadColor = clamp;
break;
default:
@@ -789,6 +796,7 @@ void _mesa_init_color( struct gl_context * ctx )
memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
ctx->Color.ClearIndex = 0;
ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
+ ASSIGN_4V( ctx->Color.ClearColorUnclamped, 0, 0, 0, 0 );
ctx->Color.AlphaEnabled = GL_FALSE;
ctx->Color.AlphaFunc = GL_ALWAYS;
ctx->Color.AlphaRef = 0;
@@ -802,6 +810,7 @@ void _mesa_init_color( struct gl_context * ctx )
ctx->Color.Blend[i].EquationA = GL_FUNC_ADD;
}
ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( ctx->Color.BlendColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
ctx->Color.IndexLogicOpEnabled = GL_FALSE;
ctx->Color.ColorLogicOpEnabled = GL_FALSE;
ctx->Color._LogicOpEnabled = GL_FALSE;
@@ -816,7 +825,9 @@ void _mesa_init_color( struct gl_context * ctx )
}
ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
+ ctx->Color._ClampFragmentColor = GL_TRUE;
ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
+ ctx->Color._ClampReadColor = GL_TRUE;
}
/*@}*/
diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c
index 43a9ccc..fa95e45 100644
--- a/src/mesa/main/clear.c
+++ b/src/mesa/main/clear.c
@@ -78,19 +78,27 @@ _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- tmp[0] = CLAMP(red, 0.0F, 1.0F);
- tmp[1] = CLAMP(green, 0.0F, 1.0F);
- tmp[2] = CLAMP(blue, 0.0F, 1.0F);
- tmp[3] = CLAMP(alpha, 0.0F, 1.0F);
+ tmp[0] = red;
+ tmp[1] = green;
+ tmp[2] = blue;
+ tmp[3] = alpha;
- if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))
+ if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped))
return; /* no change */
FLUSH_VERTICES(ctx, _NEW_COLOR);
- COPY_4V(ctx->Color.ClearColor, tmp);
+ COPY_4V(ctx->Color.ClearColorUnclamped, tmp);
+
+ ctx->Color.ClearColor[0] = CLAMP(tmp[0], 0.0F, 1.0F);
+ ctx->Color.ClearColor[1] = CLAMP(tmp[1], 0.0F, 1.0F);
+ ctx->Color.ClearColor[2] = CLAMP(tmp[2], 0.0F, 1.0F);
+ ctx->Color.ClearColor[3] = CLAMP(tmp[3], 0.0F, 1.0F);
if (ctx->Driver.ClearColor) {
/* it's OK to call glClearColor in CI mode but it should be a NOP */
+ /* we pass the clamped color, since all drivers that need this don't
+ * support GL_ARB_color_buffer_float
+ */
(*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor);
}
}
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index d0c8657..35b3096 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -516,6 +516,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
struct gl_color_table *table = NULL;
GLfloat rgba[MAX_COLOR_TABLE_SIZE][4];
+ GLbitfield transferOps = 0;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->NewState) {
@@ -618,8 +619,12 @@ _mesa_GetColorTable( GLenum target, GLenum format,
if (!data)
return;
+ /* TODO: is this correct? */
+ if(ctx->Color._ClampReadColor)
+ transferOps |= IMAGE_CLAMP_BIT;
+
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
- format, type, data, &ctx->Pack, 0x0);
+ format, type, data, &ctx->Pack, transferOps);
_mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 0112d9d..f3c77f2 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -388,6 +388,9 @@ typedef enum
OPCODE_UNIFORM_3UIV,
OPCODE_UNIFORM_4UIV,
+ /* GL_ARB_color_buffer_float */
+ OPCODE_CLAMP_COLOR,
+
/* GL_EXT_framebuffer_blit */
OPCODE_BLIT_FRAMEBUFFER,
@@ -6887,6 +6890,22 @@ save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
}
static void GLAPIENTRY
+save_ClampColorARB(GLenum target, GLenum clamp)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_CLAMP_COLOR, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].e = clamp;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ClampColorARB(ctx->Exec, (target, clamp));
+ }
+}
+
+static void GLAPIENTRY
save_UseShaderProgramEXT(GLenum type, GLuint program)
{
GET_CURRENT_CONTEXT(ctx);
@@ -8071,6 +8090,10 @@ execute_list(struct gl_context *ctx, GLuint list)
(n[1].i, n[2].i, n[3].b, n[4].data));
break;
+ case OPCODE_CLAMP_COLOR:
+ CALL_ClampColorARB(ctx->Exec, (n[1].e, n[2].e));
+ break;
+
case OPCODE_TEX_BUMP_PARAMETER_ATI:
{
GLfloat values[4];
@@ -9868,6 +9891,10 @@ _mesa_create_save_table(void)
SET_UseShaderProgramEXT(table, save_UseShaderProgramEXT);
SET_ActiveProgramEXT(table, save_ActiveProgramEXT);
+ /* GL_ARB_color_buffer_float */
+ SET_ClampColorARB(table, save_ClampColorARB);
+ SET_ClampColor(table, save_ClampColorARB);
+
/* GL 3.0 */
#if 0
SET_ClearBufferiv(table, save_ClearBufferiv);
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 4b6e91c..a95cc9d 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -79,6 +79,7 @@ static const struct extension extension_table[] = {
/* ARB Extensions */
{ "GL_ARB_ES2_compatibility", o(ARB_ES2_compatibility), GL, 2009 },
{ "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 },
+ { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 },
{ "GL_ARB_copy_buffer", o(ARB_copy_buffer), GL, 2008 },
{ "GL_ARB_depth_buffer_float", o(ARB_depth_buffer_float), GL, 2008 },
{ "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL, 2003 },
diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp
index 9be5317..bf65a4f 100644
--- a/src/mesa/main/ff_fragment_shader.cpp
+++ b/src/mesa/main/ff_fragment_shader.cpp
@@ -726,7 +726,7 @@ static struct ureg register_input( struct texenv_fragment_program *p, GLuint inp
}
else {
GLuint idx = frag_to_vert_attrib( input );
- return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx );
+ return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, idx );
}
}
@@ -1563,7 +1563,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key,
p.program->Base.NumInstructions);
if (key->num_draw_buffers && p.program->FogOption) {
- _mesa_append_fog_code(ctx, p.program);
+ _mesa_append_fog_code(ctx, p.program, GL_FALSE);
p.program->FogOption = GL_NONE;
}
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
index 4392322..88aa31a 100644
--- a/src/mesa/main/fog.c
+++ b/src/mesa/main/fog.c
@@ -150,6 +150,10 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params )
if (TEST_EQ_4V(ctx->Fog.Color, params))
return;
FLUSH_VERTICES(ctx, _NEW_FOG);
+ ctx->Fog.ColorUnclamped[0] = params[0];
+ ctx->Fog.ColorUnclamped[1] = params[1];
+ ctx->Fog.ColorUnclamped[2] = params[2];
+ ctx->Fog.ColorUnclamped[3] = params[3];
ctx->Fog.Color[0] = CLAMP(params[0], 0.0F, 1.0F);
ctx->Fog.Color[1] = CLAMP(params[1], 0.0F, 1.0F);
ctx->Fog.Color[2] = CLAMP(params[2], 0.0F, 1.0F);
@@ -189,6 +193,7 @@ void _mesa_init_fog( struct gl_context * ctx )
ctx->Fog.Enabled = GL_FALSE;
ctx->Fog.Mode = GL_EXP;
ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( ctx->Fog.ColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
ctx->Fog.Index = 0.0;
ctx->Fog.Density = 1.0;
ctx->Fog.Start = 0.0;
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 7d1a5cf..146ac0f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -131,6 +131,7 @@ enum value_extra {
EXTRA_VERSION_32,
EXTRA_VERSION_ES2,
EXTRA_NEW_BUFFERS,
+ EXTRA_NEW_FRAG_CLAMP,
EXTRA_VALID_DRAW_BUFFER,
EXTRA_VALID_TEXTURE_UNIT,
EXTRA_FLUSH_CURRENT,
@@ -223,6 +224,11 @@ static const int extra_new_buffers[] = {
EXTRA_END
};
+static const int extra_new_frag_clamp[] = {
+ EXTRA_NEW_FRAG_CLAMP,
+ EXTRA_END
+};
+
static const int extra_valid_draw_buffer[] = {
EXTRA_VALID_DRAW_BUFFER,
EXTRA_END
@@ -374,7 +380,7 @@ static const struct value_desc values[] = {
{ GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA },
{ GL_BLEND_SRC, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
{ GL_BLUE_BITS, BUFFER_INT(Visual.blueBits), extra_new_buffers },
- { GL_COLOR_CLEAR_VALUE, CONTEXT_FIELD(Color.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA },
+ { GL_COLOR_CLEAR_VALUE, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
{ GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
{ GL_CULL_FACE, CONTEXT_BOOL(Polygon.CullFlag), NO_EXTRA },
{ GL_CULL_FACE_MODE, CONTEXT_ENUM(Polygon.CullFaceMode), NO_EXTRA },
@@ -511,7 +517,7 @@ static const struct value_desc values[] = {
{ GL_LIGHT_MODEL_TWO_SIDE, CONTEXT_BOOL(Light.Model.TwoSide), NO_EXTRA },
{ GL_ALPHA_TEST, CONTEXT_BOOL(Color.AlphaEnabled), NO_EXTRA },
{ GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA },
- { GL_ALPHA_TEST_REF, CONTEXT_FIELD(Color.AlphaRef, TYPE_FLOATN), NO_EXTRA },
+ { GL_ALPHA_TEST_REF, LOC_CUSTOM, TYPE_FLOATN, 0, extra_new_frag_clamp },
{ GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
{ GL_CLIP_PLANE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), NO_EXTRA },
{ GL_CLIP_PLANE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), NO_EXTRA },
@@ -530,7 +536,7 @@ static const struct value_desc values[] = {
extra_flush_current_valid_texture_unit },
{ GL_DISTANCE_ATTENUATION_EXT, CONTEXT_FLOAT3(Point.Params[0]), NO_EXTRA },
{ GL_FOG, CONTEXT_BOOL(Fog.Enabled), NO_EXTRA },
- { GL_FOG_COLOR, CONTEXT_FIELD(Fog.Color[0], TYPE_FLOATN_4), NO_EXTRA },
+ { GL_FOG_COLOR, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
{ GL_FOG_DENSITY, CONTEXT_FLOAT(Fog.Density), NO_EXTRA },
{ GL_FOG_END, CONTEXT_FLOAT(Fog.End), NO_EXTRA },
{ GL_FOG_HINT, CONTEXT_ENUM(Hint.Fog), NO_EXTRA },
@@ -674,7 +680,7 @@ static const struct value_desc values[] = {
/* GL_ARB_draw_buffers */
{ GL_MAX_DRAW_BUFFERS_ARB, CONTEXT_INT(Const.MaxDrawBuffers), NO_EXTRA },
- { GL_BLEND_COLOR_EXT, CONTEXT_FIELD(Color.BlendColor[0], TYPE_FLOATN_4), NO_EXTRA },
+ { GL_BLEND_COLOR_EXT, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
/* GL_ARB_fragment_program */
{ GL_MAX_TEXTURE_IMAGE_UNITS_ARB, /* == GL_MAX_TEXTURE_IMAGE_UNITS_NV */
CONTEXT_INT(Const.MaxTextureImageUnits),
@@ -1219,6 +1225,9 @@ static const struct value_desc values[] = {
CONTEXT_INT(Const.MaxVertexVaryingComponents),
extra_ARB_geometry_shader4 },
+ /* GL_ARB_color_buffer_float */
+ { GL_RGBA_FLOAT_MODE_ARB, BUFFER_FIELD(Visual.floatMode, TYPE_BOOLEAN), 0 },
+
/* GL_EXT_gpu_shader4 / GL 3.0 */
{ GL_MIN_PROGRAM_TEXEL_OFFSET,
CONTEXT_INT(Const.MinProgramTexelOffset),
@@ -1633,6 +1642,30 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
v->value_int = ctx->Array.ArrayObj->PointSize.BufferObj->Name;
break;
+ case GL_FOG_COLOR:
+ if(ctx->Color._ClampFragmentColor)
+ COPY_4FV(v->value_float_4, ctx->Fog.Color);
+ else
+ COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
+ break;
+ case GL_COLOR_CLEAR_VALUE:
+ if(ctx->Color._ClampFragmentColor)
+ COPY_4FV(v->value_float_4, ctx->Color.ClearColor);
+ else
+ COPY_4FV(v->value_float_4, ctx->Color.ClearColorUnclamped);
+ break;
+ case GL_BLEND_COLOR_EXT:
+ if(ctx->Color._ClampFragmentColor)
+ COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
+ else
+ COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped);
+ break;
+ case GL_ALPHA_TEST_REF:
+ if(ctx->Color._ClampFragmentColor)
+ v->value_float = ctx->Color.AlphaRef;
+ else
+ v->value_float = ctx->Color.AlphaRefUnclamped;
+ break;
case GL_MAX_VERTEX_UNIFORM_VECTORS:
v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4;
break;
@@ -1687,6 +1720,10 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
enabled++;
}
break;
+ case EXTRA_NEW_FRAG_CLAMP:
+ if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
+ _mesa_update_state(ctx);
+ break;
case EXTRA_VERSION_ES2:
if (ctx->API == API_OPENGLES2) {
total++;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 831774f..c6598ea 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -691,7 +691,8 @@ struct gl_accum_attrib
struct gl_colorbuffer_attrib
{
GLuint ClearIndex; /**< Index to use for glClear */
- GLclampf ClearColor[4]; /**< Color to use for glClear */
+ GLfloat ClearColorUnclamped[4]; /**< Color to use for glClear*/
+ GLclampf ClearColor[4]; /**< Color to use for glClear */
GLuint IndexMask; /**< Color index write mask */
GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */
@@ -704,6 +705,7 @@ struct gl_colorbuffer_attrib
/*@{*/
GLboolean AlphaEnabled; /**< Alpha test enabled flag */
GLenum AlphaFunc; /**< Alpha test function */
+ GLfloat AlphaRefUnclamped;
GLclampf AlphaRef; /**< Alpha reference value */
/*@}*/
@@ -712,7 +714,14 @@ struct gl_colorbuffer_attrib
*/
/*@{*/
GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */
+
+ /* NOTE: this does _not_ depend on fragment clamping or any other clamping control,
+ * only on the fixed-pointness of the render target.
+ * The query does however depend on fragment color clamping.
+ */
+ GLfloat BlendColorUnclamped[4]; /**< Blending color */
GLfloat BlendColor[4]; /**< Blending color */
+
struct
{
GLenum SrcRGB; /**< RGB blend source term */
@@ -741,7 +750,9 @@ struct gl_colorbuffer_attrib
GLboolean DitherFlag; /**< Dither enable flag */
GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
+ GLboolean _ClampFragmentColor; /** < with GL_FIXED_ONLY_ARB resolved */
GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */
+ GLboolean _ClampReadColor; /** < with GL_FIXED_ONLY_ARB resolved */
GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */
};
@@ -840,6 +851,7 @@ struct gl_eval_attrib
struct gl_fog_attrib
{
GLboolean Enabled; /**< Fog enabled flag */
+ GLfloat ColorUnclamped[4]; /**< Fog color */
GLfloat Color[4]; /**< Fog color */
GLfloat Density; /**< Density >= 0.0 */
GLfloat Start; /**< Start distance in eye coords */
@@ -921,6 +933,7 @@ struct gl_light_attrib
GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */
GLboolean ColorMaterialEnabled;
GLenum ClampVertexColor;
+ GLboolean _ClampVertexColor;
struct gl_light EnabledList; /**< List sentinel */
@@ -1396,7 +1409,8 @@ struct gl_texture_unit
GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */
GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */
- GLfloat EnvColor[4];
+ GLclampf EnvColor[4];
+ GLfloat EnvColorUnclamped[4];
struct gl_texgen GenS;
struct gl_texgen GenT;
@@ -2704,6 +2718,7 @@ struct gl_extensions
GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
GLboolean ARB_ES2_compatibility;
GLboolean ARB_blend_func_extended;
+ GLboolean ARB_color_buffer_float;
GLboolean ARB_copy_buffer;
GLboolean ARB_depth_buffer_float;
GLboolean ARB_depth_clamp;
@@ -2933,6 +2948,7 @@ struct gl_matrix_stack
#define _NEW_PROGRAM (1 << 26) /**< New program/shader state */
#define _NEW_PROGRAM_CONSTANTS (1 << 27)
#define _NEW_BUFFER_OBJECT (1 << 28)
+#define _NEW_FRAG_CLAMP (1 << 29)
#define _NEW_ALL ~0
/*@}*/
diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index 512835c..0215458 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -504,17 +504,6 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
luminance = NULL;
}
- /* XXX
- * This test should probably go away. Have the caller set/clear the
- * IMAGE_CLAMP_BIT as needed.
- */
- if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
- if (!intDstFormat) {
- /* need to clamp to [0, 1] */
- transferOps |= IMAGE_CLAMP_BIT;
- }
- }
-
if (transferOps) {
_mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
}
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 19c9bba..eab58ce 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -445,6 +445,35 @@ update_color(struct gl_context *ctx)
ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx);
}
+static void
+update_clamp_fragment_color(struct gl_context *ctx)
+{
+ if(ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB)
+ ctx->Color._ClampFragmentColor = !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
+ else
+ ctx->Color._ClampFragmentColor = ctx->Color.ClampFragmentColor;
+}
+
+static void
+update_clamp_vertex_color(struct gl_context *ctx)
+{
+ if(ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB)
+ ctx->Light._ClampVertexColor = !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
+ else
+ ctx->Light._ClampVertexColor = ctx->Light.ClampVertexColor;
+}
+
+static void
+update_clamp_read_color(struct gl_context *ctx)
+{
+ if(ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB)
+ ctx->Color._ClampReadColor = !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode;
+ else
+ ctx->Color._ClampReadColor = ctx->Color.ClampReadColor;
+}
+
+
+
/*
* Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
@@ -565,7 +594,7 @@ _mesa_update_state_locked( struct gl_context *ctx )
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG |
_NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE |
- _NEW_PROGRAM);
+ _NEW_PROGRAM | _NEW_FRAG_CLAMP);
}
if (ctx->VertexProgram._MaintainTnlProgram) {
prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
@@ -599,6 +628,9 @@ _mesa_update_state_locked( struct gl_context *ctx )
if (new_state & _NEW_LIGHT)
_mesa_update_lighting( ctx );
+ if (new_state & (_NEW_LIGHT | _NEW_BUFFERS))
+ update_clamp_vertex_color(ctx);
+
if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
_mesa_update_stencil( ctx );
@@ -617,6 +649,12 @@ _mesa_update_state_locked( struct gl_context *ctx )
if (new_state & _NEW_COLOR)
update_color( ctx );
+ if (new_state & (_NEW_COLOR | _NEW_BUFFERS))
+ update_clamp_read_color(ctx);
+
+ if(new_state & (_NEW_FRAG_CLAMP | _NEW_BUFFERS))
+ update_clamp_fragment_color(ctx);
+
#if 0
if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
| _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 45a2e19..9228e35 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -35,6 +35,7 @@
#include "main/enums.h"
#include "main/macros.h"
#include "main/mtypes.h"
+#include "main/state.h"
#include "main/texenv.h"
#include "main/texstate.h"
@@ -94,15 +95,14 @@ set_env_color(struct gl_context *ctx,
struct gl_texture_unit *texUnit,
const GLfloat *color)
{
- GLfloat tmp[4];
- tmp[0] = CLAMP(color[0], 0.0F, 1.0F);
- tmp[1] = CLAMP(color[1], 0.0F, 1.0F);
- tmp[2] = CLAMP(color[2], 0.0F, 1.0F);
- tmp[3] = CLAMP(color[3], 0.0F, 1.0F);
- if (TEST_EQ_4V(tmp, texUnit->EnvColor))
+ if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped))
return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- COPY_4FV(texUnit->EnvColor, tmp);
+ COPY_4FV(texUnit->EnvColorUnclamped, color);
+ texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F);
+ texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F);
+ texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F);
+ texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F);
}
@@ -758,7 +758,12 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
- COPY_4FV( params, texUnit->EnvColor );
+ if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
+ _mesa_update_state(ctx);
+ if(ctx->Color._ClampFragmentColor)
+ COPY_4FV( params, texUnit->EnvColor );
+ else
+ COPY_4FV( params, texUnit->EnvColorUnclamped );
}
else {
GLint val = get_texenvi(ctx, texUnit, pname);
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index 6e14fac..adb6bce 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -38,6 +38,7 @@
#include "main/macros.h"
#include "main/mfeatures.h"
#include "main/mtypes.h"
+#include "main/state.h"
#include "main/texcompress.h"
#include "main/texparam.h"
#include "main/teximage.h"
@@ -1107,10 +1108,22 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
*params = ENUM_TO_FLOAT(obj->WrapR);
break;
case GL_TEXTURE_BORDER_COLOR:
- params[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
- params[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
- params[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
- params[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
+ if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
+ _mesa_update_state_locked(ctx);
+ if(ctx->Color._ClampFragmentColor)
+ {
+ params[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
+ params[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
+ params[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
+ params[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
+ }
+ else
+ {
+ params[0] = obj->BorderColor.f[0];
+ params[1] = obj->BorderColor.f[1];
+ params[2] = obj->BorderColor.f[2];
+ params[3] = obj->BorderColor.f[3];
+ }
break;
case GL_TEXTURE_RESIDENT:
{
diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c
index a10b86e..956c7b9 100644
--- a/src/mesa/main/version.c
+++ b/src/mesa/main/version.c
@@ -89,6 +89,8 @@ compute_version(struct gl_context *ctx)
ctx->Extensions.EXT_pixel_buffer_object &&
ctx->Extensions.EXT_texture_sRGB);
const GLboolean ver_3_0 = (ver_2_1 &&
+ ctx->Extensions.ARB_color_buffer_float &&
+ ctx->Extensions.ARB_depth_buffer_float &&
ctx->Extensions.ARB_half_float_pixel &&
ctx->Extensions.ARB_map_buffer_range &&
ctx->Extensions.ARB_texture_float &&
diff --git a/src/mesa/program/arbprogparse.c b/src/mesa/program/arbprogparse.c
index ca63e72..7f778c3 100644
--- a/src/mesa/program/arbprogparse.c
+++ b/src/mesa/program/arbprogparse.c
@@ -144,7 +144,10 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
* from the fragment shader.
*/
if (program->FogOption != GL_NONE) {
- _mesa_append_fog_code(ctx, program);
+ /* XXX: we should somehow recompile this to remove clamping if disabled
+ * On the ATI driver, this is unclampled if fragment clamping is disabled
+ */
+ _mesa_append_fog_code(ctx, program, GL_TRUE);
program->FogOption = GL_NONE;
}
diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c
index c310acb..384aa2c 100644
--- a/src/mesa/program/prog_statevars.c
+++ b/src/mesa/program/prog_statevars.c
@@ -237,11 +237,17 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
{
/* state[1] is the texture unit */
const GLuint unit = (GLuint) state[1];
- COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
+ if(ctx->Color._ClampFragmentColor)
+ COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
+ else
+ COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped);
}
return;
case STATE_FOG_COLOR:
- COPY_4V(value, ctx->Fog.Color);
+ if(ctx->Color._ClampFragmentColor)
+ COPY_4V(value, ctx->Fog.Color);
+ else
+ COPY_4V(value, ctx->Fog.ColorUnclamped);
return;
case STATE_FOG_PARAMS:
value[0] = ctx->Fog.Density;
@@ -399,6 +405,22 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
}
return;
+ case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
+ {
+ const GLuint idx = (GLuint) state[2];
+ if(ctx->Light._ClampVertexColor &&
+ (idx == VERT_ATTRIB_COLOR0 ||
+ idx == VERT_ATTRIB_COLOR1)) {
+ value[0] = CLAMP(ctx->Current.Attrib[idx][0], 0.0f, 1.0f);
+ value[1] = CLAMP(ctx->Current.Attrib[idx][1], 0.0f, 1.0f);
+ value[2] = CLAMP(ctx->Current.Attrib[idx][2], 0.0f, 1.0f);
+ value[3] = CLAMP(ctx->Current.Attrib[idx][3], 0.0f, 1.0f);
+ }
+ else
+ COPY_4V(value, ctx->Current.Attrib[idx]);
+ }
+ return;
+
case STATE_NORMAL_SCALE:
ASSIGN_4V(value,
ctx->_ModelViewInvScale,
@@ -649,10 +671,12 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
return _NEW_LIGHT;
case STATE_TEXGEN:
- case STATE_TEXENV_COLOR:
return _NEW_TEXTURE;
+ case STATE_TEXENV_COLOR:
+ return _NEW_TEXTURE | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
case STATE_FOG_COLOR:
+ return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP;
case STATE_FOG_PARAMS:
return _NEW_FOG;
@@ -688,6 +712,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
switch (state[1]) {
case STATE_CURRENT_ATTRIB:
return _NEW_CURRENT_ATTRIB;
+ case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED:
+ return _NEW_CURRENT_ATTRIB | _NEW_LIGHT | _NEW_BUFFERS;
case STATE_NORMAL_SCALE:
return _NEW_MODELVIEW;
diff --git a/src/mesa/program/prog_statevars.h b/src/mesa/program/prog_statevars.h
index f2407af..9fe8d81 100644
--- a/src/mesa/program/prog_statevars.h
+++ b/src/mesa/program/prog_statevars.h
@@ -106,6 +106,7 @@ typedef enum gl_state_index_ {
STATE_INTERNAL, /* Mesa additions */
STATE_CURRENT_ATTRIB, /* ctx->Current vertex attrib value */
+ STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, /* ctx->Current vertex attrib value after passthrough vertex processing */
STATE_NORMAL_SCALE,
STATE_TEXRECT_SCALE,
STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */
diff --git a/src/mesa/program/programopt.c b/src/mesa/program/programopt.c
index f92881f..5ad9571 100644
--- a/src/mesa/program/programopt.c
+++ b/src/mesa/program/programopt.c
@@ -238,7 +238,7 @@ _mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog)
* to vertex programs too.
*/
void
-_mesa_append_fog_code(struct gl_context *ctx, struct gl_fragment_program *fprog)
+_mesa_append_fog_code(struct gl_context *ctx, struct gl_fragment_program *fprog, GLboolean saturate)
{
static const gl_state_index fogPStateOpt[STATE_LENGTH]
= { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 };
@@ -290,7 +290,7 @@ _mesa_append_fog_code(struct gl_context *ctx, struct gl_fragment_program *fprog)
/* change the instruction to write to colorTemp w/ clamping */
inst->DstReg.File = PROGRAM_TEMPORARY;
inst->DstReg.Index = colorTemp;
- inst->SaturateMode = SATURATE_ZERO_ONE;
+ inst->SaturateMode = saturate;
/* don't break (may be several writes to result.color) */
}
inst++;
@@ -300,6 +300,7 @@ _mesa_append_fog_code(struct gl_context *ctx, struct gl_fragment_program *fprog)
_mesa_init_instructions(inst, 5);
/* emit instructions to compute fog blending factor */
+ /* this is always clamped to [0, 1] regardless of fragment clamping */
if (fprog->FogOption == GL_LINEAR) {
/* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */
inst->Opcode = OPCODE_MAD;
diff --git a/src/mesa/program/programopt.h b/src/mesa/program/programopt.h
index ef6f1bd..79631aa 100644
--- a/src/mesa/program/programopt.h
+++ b/src/mesa/program/programopt.h
@@ -32,7 +32,7 @@ extern void
_mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog);
extern void
-_mesa_append_fog_code(struct gl_context *ctx, struct gl_fragment_program *fprog);
+_mesa_append_fog_code(struct gl_context *ctx, struct gl_fragment_program *fprog, GLboolean saturate);
extern void
_mesa_count_texture_indirections(struct gl_program *prog);
--
1.7.1
More information about the mesa-dev
mailing list