Mesa (master): r300g: implement fragment color clamping in the shader

Marek Olšák mareko at kemper.freedesktop.org
Sat Mar 12 07:50:59 UTC 2011


Module: Mesa
Branch: master
Commit: 4b92c688a45480027390764b06077105298666c3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4b92c688a45480027390764b06077105298666c3

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sat Mar 12 06:11:18 2011 +0100

r300g: implement fragment color clamping in the shader

This finishes the implementation of the fragment color clamp control
for ARB_color_buffer_float. I don't wanna keep this stuff in a branch...

---

 src/gallium/drivers/r300/r300_context.h            |    2 +
 src/gallium/drivers/r300/r300_fs.c                 |    2 +
 src/gallium/drivers/r300/r300_state.c              |    6 +++++
 src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c |   21 ++++++++++++++++++++
 src/mesa/drivers/dri/r300/compiler/radeon_code.h   |    2 +
 5 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 76ea5ee..1624708 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -65,6 +65,8 @@ struct r300_aa_state {
 };
 
 struct r300_blend_state {
+    struct pipe_blend_state state;
+
     uint32_t cb[8];
     uint32_t cb_no_readwrite[8];
 };
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index cec7473..4c502fe 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -149,6 +149,8 @@ static void get_external_state(
     unsigned i;
     unsigned char *swizzle;
 
+    state->frag_clamp = 0;
+
     for (i = 0; i < texstate->sampler_state_count; i++) {
         struct r300_sampler_state *s = texstate->sampler_states[i];
         struct r300_sampler_view *v = texstate->sampler_views[i];
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 49c2b88..f0830e1 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -195,6 +195,8 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
     boolean clamp = TRUE;
     CB_LOCALS;
 
+    blend->state = *state;
+
     if (state->rt[0].blend_enable)
     {
         unsigned eqRGB = state->rt[0].rgb_func;
@@ -377,6 +379,10 @@ static void r300_bind_blend_state(struct pipe_context* pipe,
     struct r300_context* r300 = r300_context(pipe);
 
     UPDATE_STATE(state, r300->blend_state);
+
+    if (r300->fs.state && r300_pick_fragment_shader(r300)) {
+        r300_mark_fs_code_dirty(r300);
+    }
 }
 
 /* Free blend state. */
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
index 1616306..9286733 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
@@ -78,12 +78,32 @@ static void rc_rewrite_depth_out(struct radeon_compiler *cc, void *user)
 	}
 }
 
+static int radeon_saturate_output(
+		struct radeon_compiler * c,
+		struct rc_instruction * inst,
+		void* data)
+{
+	const struct rc_opcode_info *info = rc_get_opcode_info(inst->U.I.Opcode);
+
+	if (!info->HasDstReg || inst->U.I.DstReg.File != RC_FILE_OUTPUT)
+		return 0;
+
+	inst->U.I.SaturateMode = RC_SATURATE_ZERO_ONE;
+	return 1;
+}
+
 void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 {
 	int is_r500 = c->Base.is_r500;
 	int opt = !c->Base.disable_optimizations;
+	int sat_out = c->state.frag_clamp;
 
 	/* Lists of instruction transformations. */
+	struct radeon_program_transformation saturate_output[] = {
+		{ &radeon_saturate_output, c },
+		{ 0, 0 }
+	};
+
 	struct radeon_program_transformation rewrite_tex[] = {
 		{ &radeonTransformTEX, c },
 		{ 0, 0 }
@@ -113,6 +133,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 		{"unroll loops",		1, is_r500,	rc_unroll_loops,		NULL},
 		{"transform loops",		1, !is_r500,	rc_transform_loops,		NULL},
 		{"emulate branches",		1, !is_r500,	rc_emulate_branches,		NULL},
+		{"saturate output writes",	1, sat_out,	rc_local_transform,		saturate_output},
 		{"transform TEX",		1, 1,		rc_local_transform,		rewrite_tex},
 		{"native rewrite",		1, is_r500,	rc_local_transform,		native_rewrite_r500},
 		{"native rewrite",		1, !is_r500,	rc_local_transform,		native_rewrite_r300},
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
index d145166..35360aa 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
@@ -173,6 +173,8 @@ struct r300_fragment_program_external_state {
 		 * RC_STATE_R300_TEXSCALE_FACTOR. */
 		unsigned clamp_and_scale_before_fetch : 1;
 	} unit[16];
+
+	unsigned frag_clamp:1;
 };
 
 




More information about the mesa-commit mailing list