svga: implement TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS

Fixes several colorbuffer tests, including piglit "fbo-drawbuffers-none"
for "gl_FragColor" and "glDrawPixels" cases.

v2: rework patch to only avoid creating extra shader variants when
TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS is not specified.  Per Jose.
Use a write_color0_to_n_cbufs key field to replicate color0 to N
color buffers only when N > 0 and WRITES_ALL_CBUFS is set.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
Brian Paul 2014-01-16 18:32:47 -08:00
parent 384fd64ab1
commit b9f68d927e
4 changed files with 47 additions and 8 deletions

View File

@ -276,6 +276,12 @@ make_fs_key(const struct svga_context *svga,
key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode
== PIPE_SPRITE_COORD_LOWER_LEFT);
/* SVGA_NEW_FRAME_BUFFER */
if (fs->base.info.color0_writes_all_cbufs) {
/* Replicate color0 output to N colorbuffers */
key->write_color0_to_n_cbufs = svga->curr.framebuffer.nr_cbufs;
}
return PIPE_OK;
}
@ -296,6 +302,7 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty)
* SVGA_NEW_RAST
* SVGA_NEW_NEED_SWTNL
* SVGA_NEW_SAMPLER
* SVGA_NEW_FRAME_BUFFER
*/
ret = make_fs_key( svga, fs, &key );
if (ret != PIPE_OK)
@ -335,6 +342,7 @@ struct svga_tracked_state svga_hw_fs =
SVGA_NEW_NEED_SWTNL |
SVGA_NEW_RAST |
SVGA_NEW_SAMPLER |
SVGA_NEW_FRAME_BUFFER |
SVGA_NEW_BLEND),
emit_hw_fs
};

View File

@ -56,6 +56,7 @@ struct svga_fs_compile_key
unsigned light_twoside:1;
unsigned front_ccw:1;
unsigned white_fragments:1;
unsigned write_color0_to_n_cbufs:3;
unsigned num_textures:8;
unsigned num_unnormalized_coords:8;
unsigned sprite_origin_lower_left:1;

View File

@ -327,14 +327,35 @@ ps30_output(struct svga_shader_emitter *emit,
{
switch (semantic.Name) {
case TGSI_SEMANTIC_COLOR:
if (emit->unit == PIPE_SHADER_FRAGMENT &&
emit->key.fkey.white_fragments) {
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
emit->nr_hw_temp++ );
emit->temp_color_output[idx] = emit->output_map[idx];
emit->true_color_output[idx] = dst_register(SVGA3DREG_COLOROUT,
semantic.Index);
if (emit->unit == PIPE_SHADER_FRAGMENT) {
if (emit->key.fkey.white_fragments) {
/* Used for XOR logicop mode */
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
emit->nr_hw_temp++ );
emit->temp_color_output[idx] = emit->output_map[idx];
emit->true_color_output[idx] = dst_register(SVGA3DREG_COLOROUT,
semantic.Index);
}
else if (emit->key.fkey.write_color0_to_n_cbufs) {
/* We'll write color output [0] to all render targets.
* Prepare all the output registers here, but only when the
* semantic.Index == 0 so we don't do this more than once.
*/
if (semantic.Index == 0) {
unsigned i;
for (i = 0; i < emit->key.fkey.write_color0_to_n_cbufs; i++) {
emit->output_map[i] = dst_register(SVGA3DREG_TEMP,
emit->nr_hw_temp++);
emit->temp_color_output[i] = emit->output_map[i];
emit->true_color_output[i] = dst_register(SVGA3DREG_COLOROUT,
i);
}
}
}
else {
emit->output_map[idx] =
dst_register(SVGA3DREG_COLOROUT, semantic.Index);
}
}
else {
emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,

View File

@ -3074,6 +3074,15 @@ emit_ps_postamble(struct svga_shader_emitter *emit)
one ))
return FALSE;
}
else if (emit->unit == PIPE_SHADER_FRAGMENT &&
i < emit->key.fkey.write_color0_to_n_cbufs) {
/* Write temp color output [0] to true output [i] */
if (!submit_op1(emit, inst_token(SVGA3DOP_MOV),
emit->true_color_output[i],
src(emit->temp_color_output[0]))) {
return FALSE;
}
}
else {
if (!submit_op1( emit,
inst_token(SVGA3DOP_MOV),