diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_shader.c | 29 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_shader.h | 6 | 
2 files changed, 31 insertions, 4 deletions
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c index 1b02239ee7..7257638dbe 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -59,6 +59,12 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,              }              break;          case TGSI_FILE_OUTPUT: +            /* Depth write. Mark the position of the output so we can +             * identify it later. */ +            if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { +                assembler->depth_output = decl->DeclarationRange.First; +            } +            break;          case TGSI_FILE_CONSTANT:              break;          case TGSI_FILE_TEMPORARY: @@ -120,6 +126,14 @@ static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,      return 0;  } +static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, +                                      struct tgsi_dst_register* dst) +{ +    return (assembler->writes_depth && +            (dst->File == TGSI_FILE_OUTPUT) && +            (dst->Index == assembler->depth_output)); +} +  static INLINE unsigned r500_fix_swiz(unsigned s)  {      /* For historical reasons, the swizzle values x, y, z, w, and 0 are @@ -302,16 +316,21 @@ static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,      int i = fs->instruction_count;      if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { -        fs->instructions[i].inst0 = R500_INST_TYPE_OUT | -        R500_ALU_OMASK(dst->DstRegister.WriteMask); +        fs->instructions[i].inst0 = R500_INST_TYPE_OUT; +        if (r300_fs_is_depr(assembler, dst)) { +            fs->instructions[i].inst4 = R500_W_OMASK; +        } else { +            fs->instructions[i].inst0 |= +                R500_ALU_OMASK(dst->DstRegister.WriteMask); +        }      } else {          fs->instructions[i].inst0 = R500_INST_TYPE_ALU | -        R500_ALU_WMASK(dst->DstRegister.WriteMask); +            R500_ALU_WMASK(dst->DstRegister.WriteMask);      }      fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT; -    fs->instructions[i].inst4 = +    fs->instructions[i].inst4 |=          R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));      fs->instructions[i].inst5 =          R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister)); @@ -581,6 +600,8 @@ void r300_translate_fragment_shader(struct r300_context* r300,      }      /* Setup starting offset for immediates. */      assembler->imm_offset = consts->user_count; +    /* Enable depth writes, if needed. */ +    assembler->writes_depth = fs->info.writes_z;      /* Make sure we start at the beginning of the shader. */      if (is_r500) { diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h index 185fdd90f0..f4fb31d86c 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r300_state_shader.h @@ -57,6 +57,7 @@  #define R500_TEX_WMASK(x) ((x) << 11)  #define R500_ALU_WMASK(x) ((x) << 11)  #define R500_ALU_OMASK(x) ((x) << 15) +#define R500_W_OMASK (1 << 31)  /* TGSI constants. TGSI is like XML: If it can't solve your problems, you're   * not using enough of it. */ @@ -99,6 +100,11 @@ struct r300_fs_asm {      unsigned imm_offset;      /* Number of immediate constants. */      unsigned imm_count; +    /* Are depth writes enabled? */ +    boolean writes_depth; +    /* Depth write offset. This is the TGSI output that corresponds to +     * depth writes. */ +    unsigned depth_output;  };  void r300_translate_fragment_shader(struct r300_context* r300,  | 
