From c4c1774bbb08022846eefd14df683c7644f5e421 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 11 Mar 2009 14:26:25 -0700 Subject: [PATCH] r300-gallium: r500-fs: Add shader dumper and more tex work. --- src/gallium/drivers/r300/Makefile | 1 + src/gallium/drivers/r300/r300_debug.c | 218 +++++++++++++++++++ src/gallium/drivers/r300/r300_debug.h | 31 +++ src/gallium/drivers/r300/r300_state_shader.c | 95 ++++++-- src/gallium/drivers/r300/r300_state_shader.h | 3 + 5 files changed, 335 insertions(+), 13 deletions(-) create mode 100644 src/gallium/drivers/r300/r300_debug.c create mode 100644 src/gallium/drivers/r300/r300_debug.h diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 4c400bff580..0e4e1155325 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ r300_chipset.c \ r300_clear.c \ r300_context.c \ + r300_debug.c \ r300_emit.c \ r300_flush.c \ r300_query.c \ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c new file mode 100644 index 00000000000..4c6d2a24712 --- /dev/null +++ b/src/gallium/drivers/r300/r300_debug.c @@ -0,0 +1,218 @@ +/* + * Copyright 2009 Corbin Simpson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_debug.h" + +static char* r500_fs_swiz[] = { + " R", + " G", + " B", + " A", + " 0", + ".5", + " 1", + " U", +}; + +static char* r500_fs_op_rgb[] = { + "MAD", + "DP3", + "DP4", + "D2A", + "MIN", + "MAX", + "---", + "CND", + "CMP", + "FRC", + "SOP", + "MDH", + "MDV", +}; + +static char* r500_fs_op_alpha[] = { + "MAD", + " DP", + "MIN", + "MAX", + "---", + "CND", + "CMP", + "FRC", + "EX2", + "LN2", + "RCP", + "RSQ", + "SIN", + "COS", + "MDH", + "MDV", +}; + +static char* r500_fs_mask[] = { + "NONE", + "R ", + " G ", + "RG ", + " B ", + "R B ", + " GB ", + "RGB ", + " A", + "R A", + " G A", + "RG A", + " BA", + "R BA", + " GBA", + "RGBA", +}; + +static char* r500_fs_tex[] = { + " NOP", + " LD", + "TEXKILL", + " PROJ", + "LODBIAS", + " LOD", + " DXDY", +}; + +void r500_fs_dump(struct r500_fragment_shader* fs) +{ + int i; + uint32_t inst; + + for (i = 0; i < fs->instruction_count; i++) { + inst = fs->instructions[i].inst0; + debug_printf("%d: 0: CMN_INST 0x%08x:", i, inst); + switch (inst & 0x3) { + case R500_INST_TYPE_ALU: + debug_printf("ALU "); + break; + case R500_INST_TYPE_OUT: + debug_printf("OUT "); + break; + case R500_INST_TYPE_FC: + debug_printf("FC "); + break; + case R500_INST_TYPE_TEX: + debug_printf("TEX "); + break; + } + debug_printf("%s %s %s %s ", + inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "", + inst & R500_INST_LAST ? "LAST" : "", + inst & R500_INST_NOP ? "NOP" : "", + inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : ""); + debug_printf("wmask: %s omask: %s\n", + r500_fs_mask[(inst >> 11) & 0xf], + r500_fs_mask[(inst >> 15) & 0xf]); + switch (inst & 0x3) { + case R500_INST_TYPE_ALU: + case R500_INST_TYPE_OUT: + inst = fs->instructions[i].inst1; + debug_printf(" 1: RGB_ADDR 0x%08x:", inst); + debug_printf("Addr0: %d%c, Addr1: %d%c, " + "Addr2: %d%c, srcp:%d\n", + inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', + (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', + (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', + (inst >> 30)); + + inst = fs->instructions[i].inst2; + debug_printf(" 2: ALPHA_ADDR 0x%08x:", inst); + debug_printf("Addr0: %d%c, Addr1: %d%c, " + "Addr2: %d%c, srcp:%d\n", + inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', + (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', + (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', + (inst >> 30)); + + inst = fs->instructions[i].inst3; + debug_printf(" 3: RGB_INST 0x%08x:", inst); + debug_printf("rgb_A_src:%d %s/%s/%s %d " + "rgb_B_src:%d %s/%s/%s %d\n", + inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7], + r500_fs_swiz[(inst >> 5) & 0x7], + r500_fs_swiz[(inst >> 8) & 0x7], + (inst >> 11) & 0x3, (inst >> 13) & 0x3, + r500_fs_swiz[(inst >> 15) & 0x7], + r500_fs_swiz[(inst >> 18) & 0x7], + r500_fs_swiz[(inst >> 21) & 0x7], + (inst >> 24) & 0x3); + + inst = fs->instructions[i].inst4; + debug_printf(" 4: ALPHA_INST 0x%08x:", inst); + debug_printf("%s dest:%d%s alp_A_src:%d %s %d " + "alp_B_src:%d %s %d w:%d\n", + r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, + inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3, + r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, + (inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7], + (inst >> 24) & 0x3, (inst >> 31) & 0x1); + + inst = fs->instructions[i].inst5; + debug_printf(" 5: RGBA_INST 0x%08x:", inst); + debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d " + "alp_C_src:%d %s %d\n", + r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, + inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3, + r500_fs_swiz[(inst >> 14) & 0x7], + r500_fs_swiz[(inst >> 17) & 0x7], + r500_fs_swiz[(inst >> 20) & 0x7], + (inst >> 23) & 0x3, (inst >> 25) & 0x3, + r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); + break; + case R500_INST_TYPE_FC: + /* XXX don't even bother yet */ + break; + case R500_INST_TYPE_TEX: + inst = fs->instructions[i].inst1; + debug_printf(" 1: TEX_INST 0x%08x: id: %d " + "op:%s, %s, %s %s\n", + inst, (inst >> 16) & 0xf, + r500_fs_tex[(inst >> 22) & 0x7], + (inst & (1 << 25)) ? "ACQ" : "", + (inst & (1 << 26)) ? "IGNUNC" : "", + (inst & (1 << 27)) ? "UNSCALED" : "SCALED"); + + inst = fs->instructions[i].inst2; + debug_printf(" 2: TEX_ADDR 0x%08x: " + "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", + inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "", + r500_fs_swiz[(inst >> 8) & 0x7], + r500_fs_swiz[(inst >> 10) & 0x7], + r500_fs_swiz[(inst >> 12) & 0x7], + r500_fs_swiz[(inst >> 14) & 0x7], + (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "", + r500_fs_swiz[(inst >> 24) & 0x7], + r500_fs_swiz[(inst >> 26) & 0x7], + r500_fs_swiz[(inst >> 28) & 0x7], + r500_fs_swiz[(inst >> 30) & 0x7]); + + inst = fs->instructions[i].inst3; + debug_printf(" 3: TEX_DXDY 0x%08x\n", inst); + break; + } + } +} diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h new file mode 100644 index 00000000000..de5d701ed9c --- /dev/null +++ b/src/gallium/drivers/r300/r300_debug.h @@ -0,0 +1,31 @@ +/* + * Copyright 2009 Corbin Simpson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_DEBUG_H +#define R300_DEBUG_H + +#include "r300_reg.h" +#include "r300_state_shader.h" + +void r500_fs_dump(struct r500_fragment_shader* fs); + +#endif /* R300_DEBUG_H */ diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c index 07705adaf40..7629bfb1f43 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -60,6 +60,9 @@ static void r300_fs_declare(struct r300_fs_asm* assembler, break; case TGSI_FILE_OUTPUT: break; + case TGSI_FILE_TEMPORARY: + assembler->temp_count++; + break; default: debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); break; @@ -68,6 +71,41 @@ static void r300_fs_declare(struct r300_fs_asm* assembler, assembler->temp_offset = assembler->color_count + assembler->tex_count; } +static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, + struct tgsi_src_register* src) +{ + switch (src->File) { + case TGSI_FILE_INPUT: + /* XXX may be wrong */ + return src->Index; + break; + case TGSI_FILE_TEMPORARY: + return src->Index + assembler->temp_offset; + break; + default: + debug_printf("r300: fs: Unimplemented src %d\n", src->File); + break; + } + return 0; +} + +static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, + struct tgsi_dst_register* dst) +{ + switch (dst->File) { + case TGSI_FILE_OUTPUT: + return 0; + break; + case TGSI_FILE_TEMPORARY: + return dst->Index + assembler->temp_offset; + break; + default: + debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); + break; + } + return 0; +} + static INLINE unsigned r500_fix_swiz(unsigned s) { /* For historical reasons, the swizzle values x, y, z, w, and 0 are @@ -80,25 +118,31 @@ static INLINE unsigned r500_fix_swiz(unsigned s) } } -static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg) +static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg) { if (reg->SrcRegister.Extended) { return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | - (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6); + (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | + (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9); } else { - return reg->SrcRegister.SwizzleX | (reg->SrcRegister.SwizzleY << 3) | - (reg->SrcRegister.SwizzleZ << 6); + return reg->SrcRegister.SwizzleX | + (reg->SrcRegister.SwizzleY << 3) | + (reg->SrcRegister.SwizzleZ << 6) | + (reg->SrcRegister.SwizzleW << 9); } } +static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg) +{ + /* Only the first 9 bits... */ + return r500_rgba_swiz(reg) & 0x1ff; +} + static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg) { - if (reg->SrcRegister.Extended) { - return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW); - } else { - return reg->SrcRegister.SwizzleW; - } + /* Only the last 3 bits... */ + return r500_rgba_swiz(reg) >> 9; } static INLINE void r500_emit_mov(struct r500_fragment_shader* fs, @@ -107,16 +151,15 @@ static INLINE void r500_emit_mov(struct r500_fragment_shader* fs, struct tgsi_full_dst_register* dst) { int i = fs->instruction_count; + fs->instructions[i].inst0 = R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT | R500_INST_LAST | R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP; fs->instructions[i].inst1 = - R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | - R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST; + R500_RGB_ADDR0(r300_fs_src(assembler, &src->SrcRegister)); fs->instructions[i].inst2 = - R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | - R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST; + R500_ALPHA_ADDR0(r300_fs_src(assembler, &src->SrcRegister)); fs->instructions[i].inst3 = R500_ALU_RGB_SEL_A_SRC0 | R500_SWIZ_RGB_A(r500_rgb_swiz(src)) | R500_ALU_RGB_SEL_B_SRC0 | @@ -132,6 +175,27 @@ static INLINE void r500_emit_mov(struct r500_fragment_shader* fs, fs->instruction_count++; } +static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, + struct r300_fs_asm* assembler, + uint32_t op, + struct tgsi_full_src_register* src, + struct tgsi_full_dst_register* dst) +{ + int i = fs->instruction_count; + + fs->instructions[i].inst0 = R500_INST_TYPE_TEX | + R500_INST_TEX_SEM_WAIT; + fs->instructions[i].inst1 = R500_TEX_ID(0) | + R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED | + R500_TEX_INST_PROJ; + fs->instructions[i].inst2 = + R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) | + R500_SWIZ_TEX_STRQ(r500_rgba_swiz(src)) | + R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) | + R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | + R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; +} + static void r500_fs_instruction(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, struct tgsi_full_instruction* inst) @@ -145,6 +209,10 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, r500_emit_mov(fs, assembler, &inst->FullSrcRegisters[0], &inst->FullDstRegisters[0]); break; + case TGSI_OPCODE_TXP: + r500_emit_tex(fs, assembler, 0, &inst->FullSrcRegisters[0], + &inst->FullDstRegisters[0]); + break; case TGSI_OPCODE_END: break; default: @@ -205,6 +273,7 @@ void r500_translate_fragment_shader(struct r300_context* r300, fs->shader.stack_size = assembler->temp_offset; tgsi_dump(fs->shader.state.tokens); + r500_fs_dump(fs); //r500_copy_passthrough_shader(fs); diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h index 410926a26a5..a74dce47641 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r300_state_shader.h @@ -26,6 +26,7 @@ #include "tgsi/tgsi_parse.h" #include "r300_context.h" +#include "r300_debug.h" #include "r300_reg.h" #include "r300_screen.h" @@ -63,6 +64,8 @@ struct r300_fs_asm { * distinguishing markings, so inputs start at 0 and the first usable * temporary register is after all inputs. */ unsigned temp_offset; + /* Number of requested temporary registers. */ + unsigned temp_count; }; void r300_translate_fragment_shader(struct r300_context* r300, -- 2.30.2