Commit e5c6a92a authored by Marek Olšák's avatar Marek Olšák

mesa: implement clamping controls (ARB_color_buffer_float)

Squashed commit of the following:

Author: Marek Olšák <maraeo@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 b2f6ddf9
Author: Luca Barbieri <luca@luca-barbieri.com>
Date:   Tue Aug 31 16:50:57 2010 +0200

    mesa: document known possible deviations from ARB_color_buffer_float

commit 5458935b
Author: Luca Barbieri <luca@luca-barbieri.com>
Date:   Tue Aug 24 21:54:56 2010 +0200

    mesa: expose GL_ARB_color_buffer_float

commit aef5c3c6
Author: Luca Barbieri <luca@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 3a9cb5e5
Author: Luca Barbieri <luca@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 de26f9e4
Author: Luca Barbieri <luca@luca-barbieri.com>
Date:   Thu Aug 26 18:05:53 2010 +0200

    mesa: restore color clamps on glPopAttrib

commit a55ac3c3
Author: Luca Barbieri <luca@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 9940a3e3
Author: Luca Barbieri <luca@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 6244c446
Author: Luca Barbieri <luca@luca-barbieri.com>
Date:   Thu Aug 26 17:58:24 2010 +0200

    mesa: add unclamped color parameters
parent 3bdd12ec
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)
<?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>
......@@ -69,6 +69,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 \
......
......@@ -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. -->
......
......@@ -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;
}
}
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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:
......
......@@ -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;
}
/*@}*/
......@@ -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);
}
}
......
......@@ -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);
}
......
......@@ -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,
......@@ -6886,6 +6889,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)
{
......@@ -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);
......
......@@ -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 },
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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++;
......
......@@ -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
/*@}*/
......
......@@ -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);
}
......
......@@ -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))
......
......@@ -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);
......
......@@ -38,6 +38,7 @@
#include "main/macros.h"