aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker/st_mesa_to_tgsi.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-01-23 03:11:17 +0100
committerMarek Olšák <[email protected]>2012-01-25 12:35:18 +0100
commitbc1c8369384b5e16547c5bf9728aa78f8dfd66cc (patch)
treea09267d88b2c604491a607467e28a7f8fbae4146 /src/mesa/state_tracker/st_mesa_to_tgsi.c
parentc2e2b58a58880c9b9f189fc154205e99144e9502 (diff)
st/mesa: do vertex and fragment color clamping in shaders
For ARB_color_buffer_float. Most hardware can't do it and st/mesa is the perfect place for a fallback. The exceptions are: - r500 (vertex clamp only) - nv50 (both) - nvc0 (both) - softpipe (both) We also have to take into account that r300 can do CLAMPED vertex colors only, while r600 can do UNCLAMPED vertex colors only. The difference can be expressed with the two new CAPs.
Diffstat (limited to 'src/mesa/state_tracker/st_mesa_to_tgsi.c')
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 0764234bd4b..fc77089e733 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -306,7 +306,8 @@ st_translate_texture_target( GLuint textarget,
static struct ureg_dst
translate_dst( struct st_translate *t,
const struct prog_dst_register *DstReg,
- boolean saturate )
+ boolean saturate,
+ boolean clamp_color)
{
struct ureg_dst dst = dst_register( t,
DstReg->File,
@@ -317,6 +318,27 @@ translate_dst( struct st_translate *t,
if (saturate)
dst = ureg_saturate( dst );
+ else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) {
+ /* Clamp colors for ARB_color_buffer_float. */
+ switch (t->procType) {
+ case TGSI_PROCESSOR_VERTEX:
+ /* XXX if the geometry shader is present, this must be done there
+ * instead of here. */
+ if (DstReg->Index == VERT_RESULT_COL0 ||
+ DstReg->Index == VERT_RESULT_COL1 ||
+ DstReg->Index == VERT_RESULT_BFC0 ||
+ DstReg->Index == VERT_RESULT_BFC1) {
+ dst = ureg_saturate(dst);
+ }
+ break;
+
+ case TGSI_PROCESSOR_FRAGMENT:
+ if (DstReg->Index >= FRAG_RESULT_COLOR) {
+ dst = ureg_saturate(dst);
+ }
+ break;
+ }
+ }
if (DstReg->RelAddr)
dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) );
@@ -662,7 +684,8 @@ translate_opcode( unsigned op )
static void
compile_instruction(
struct st_translate *t,
- const struct prog_instruction *inst )
+ const struct prog_instruction *inst,
+ boolean clamp_dst_color_output)
{
struct ureg_program *ureg = t->ureg;
GLuint i;
@@ -677,7 +700,8 @@ compile_instruction(
if (num_dst)
dst[0] = translate_dst( t,
&inst->DstReg,
- inst->SaturateMode );
+ inst->SaturateMode,
+ clamp_dst_color_output);
for (i = 0; i < num_src; i++)
src[i] = translate_src( t, &inst->SrcReg[i] );
@@ -1016,7 +1040,8 @@ st_translate_mesa_program(
const GLuint outputMapping[],
const ubyte outputSemanticName[],
const ubyte outputSemanticIndex[],
- boolean passthrough_edgeflags )
+ boolean passthrough_edgeflags,
+ boolean clamp_color)
{
struct st_translate translate, *t;
unsigned i;
@@ -1233,7 +1258,7 @@ st_translate_mesa_program(
*/
for (i = 0; i < program->NumInstructions; i++) {
set_insn_start( t, ureg_get_instruction_number( ureg ));
- compile_instruction( t, &program->Instructions[i] );
+ compile_instruction( t, &program->Instructions[i], clamp_color );
if (t->prevInstWrotePointSize && program->Id) {
/* The previous instruction wrote to the (fake) vertex point size