diff options
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.h | 83 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_fragprog.c | 92 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r500_fragprog.c | 98 |
3 files changed, 176 insertions, 97 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 3ac87d173b1..2d51bad52e4 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -654,83 +654,7 @@ struct r300_vertex_program_cont { #define PFS_NUM_TEMP_REGS 32 #define PFS_NUM_CONST_REGS 16 -/* Mapping Mesa registers to R300 temporaries */ -struct reg_acc { - int reg; /* Assigned hw temp */ - unsigned int refcount; /* Number of uses by mesa program */ -}; - -/** - * Describe the current lifetime information for an R300 temporary - */ -struct reg_lifetime { - /* Index of the first slot where this register is free in the sense - that it can be used as a new destination register. - This is -1 if the register has been assigned to a Mesa register - and the last access to the register has not yet been emitted */ - int free; - - /* Index of the first slot where this register is currently reserved. - This is used to stop e.g. a scalar operation from being moved - before the allocation time of a register that was first allocated - for a vector operation. */ - int reserved; - - /* Index of the first slot in which the register can be used as a - source without losing the value that is written by the last - emitted instruction that writes to the register */ - int vector_valid; - int scalar_valid; - - /* Index to the slot where the register was last read. - This is also the first slot in which the register may be written again */ - int vector_lastread; - int scalar_lastread; -}; - -/** - * Store usage information about an ALU instruction slot during the - * compilation of a fragment program. - */ -#define SLOT_SRC_VECTOR (1<<0) -#define SLOT_SRC_SCALAR (1<<3) -#define SLOT_SRC_BOTH (SLOT_SRC_VECTOR | SLOT_SRC_SCALAR) -#define SLOT_OP_VECTOR (1<<16) -#define SLOT_OP_SCALAR (1<<17) -#define SLOT_OP_BOTH (SLOT_OP_VECTOR | SLOT_OP_SCALAR) - -struct r300_pfs_compile_slot { - /* Bitmask indicating which parts of the slot are used, using SLOT_ constants - defined above */ - unsigned int used; - - /* Selected sources */ - int vsrc[3]; - int ssrc[3]; -}; - -/** - * Store information during compilation of fragment programs. - */ -struct r300_pfs_compile_state { - int nrslots; /* number of ALU slots used so far */ - - /* Track which (parts of) slots are already filled with instructions */ - struct r300_pfs_compile_slot slot[PFS_MAX_ALU_INST]; - - /* Track the validity of R300 temporaries */ - struct reg_lifetime hwtemps[PFS_NUM_TEMP_REGS]; - - /* Used to map Mesa's inputs/temps onto hardware temps */ - int temp_in_use; - struct reg_acc temps[PFS_NUM_TEMP_REGS]; - struct reg_acc inputs[32]; /* don't actually need 32... */ - - /* Track usage of hardware temps, for register allocation, - * indirection detection, etc. */ - GLuint used_in_node; - GLuint dest_in_node; -}; +struct r300_pfs_compile_state; /** * Store everything about a fragment program that is needed @@ -789,13 +713,15 @@ struct r300_fragment_program { GLuint optimization; }; +struct r500_pfs_compile_state; + struct r500_fragment_program { struct gl_fragment_program mesa_program; GLcontext *ctx; GLboolean translated; GLboolean error; - struct r300_pfs_compile_state *cs; + struct r500_pfs_compile_state *cs; struct { GLuint inst0; @@ -840,7 +766,6 @@ struct r300_state { struct r300_texture_state texture; int sw_tcl_inputs[VERT_ATTRIB_MAX]; struct r300_vertex_shader_state vertex_shader; - struct r300_pfs_compile_state pfs_compile; struct r300_dma_region aos[R300_MAX_AOS_ARRAYS]; int aos_count; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 54b80d20a16..df8ab47b0f8 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -52,6 +52,85 @@ #include "r300_reg.h" #include "r300_state.h" +/* Mapping Mesa registers to R300 temporaries */ +struct reg_acc { + int reg; /* Assigned hw temp */ + unsigned int refcount; /* Number of uses by mesa program */ +}; + +/** + * Describe the current lifetime information for an R300 temporary + */ +struct reg_lifetime { + /* Index of the first slot where this register is free in the sense + that it can be used as a new destination register. + This is -1 if the register has been assigned to a Mesa register + and the last access to the register has not yet been emitted */ + int free; + + /* Index of the first slot where this register is currently reserved. + This is used to stop e.g. a scalar operation from being moved + before the allocation time of a register that was first allocated + for a vector operation. */ + int reserved; + + /* Index of the first slot in which the register can be used as a + source without losing the value that is written by the last + emitted instruction that writes to the register */ + int vector_valid; + int scalar_valid; + + /* Index to the slot where the register was last read. + This is also the first slot in which the register may be written again */ + int vector_lastread; + int scalar_lastread; +}; + +/** + * Store usage information about an ALU instruction slot during the + * compilation of a fragment program. + */ +#define SLOT_SRC_VECTOR (1<<0) +#define SLOT_SRC_SCALAR (1<<3) +#define SLOT_SRC_BOTH (SLOT_SRC_VECTOR | SLOT_SRC_SCALAR) +#define SLOT_OP_VECTOR (1<<16) +#define SLOT_OP_SCALAR (1<<17) +#define SLOT_OP_BOTH (SLOT_OP_VECTOR | SLOT_OP_SCALAR) + +struct r300_pfs_compile_slot { + /* Bitmask indicating which parts of the slot are used, using SLOT_ constants + defined above */ + unsigned int used; + + /* Selected sources */ + int vsrc[3]; + int ssrc[3]; +}; + +/** + * Store information during compilation of fragment programs. + */ +struct r300_pfs_compile_state { + int nrslots; /* number of ALU slots used so far */ + + /* Track which (parts of) slots are already filled with instructions */ + struct r300_pfs_compile_slot slot[PFS_MAX_ALU_INST]; + + /* Track the validity of R300 temporaries */ + struct reg_lifetime hwtemps[PFS_NUM_TEMP_REGS]; + + /* Used to map Mesa's inputs/temps onto hardware temps */ + int temp_in_use; + struct reg_acc temps[PFS_NUM_TEMP_REGS]; + struct reg_acc inputs[32]; /* don't actually need 32... */ + + /* Track usage of hardware temps, for register allocation, + * indirection detection, etc. */ + GLuint used_in_node; + GLuint dest_in_node; +}; + + /* * Usefull macros and values */ @@ -2093,7 +2172,7 @@ static void insert_wpos(struct gl_program *prog) */ static void init_program(r300ContextPtr r300, struct r300_fragment_program *fp) { - struct r300_pfs_compile_state *cs = NULL; + COMPILE_STATE; struct gl_fragment_program *mp = &fp->mesa_program; struct prog_instruction *fpi; GLuint InputsRead = mp->Base.InputsRead; @@ -2105,7 +2184,6 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *fp) driQueryOptioni(&r300->radeon.optionCache, "fp_optimization"); fp->translated = GL_FALSE; fp->error = GL_FALSE; - fp->cs = cs = &(R300_CONTEXT(fp->ctx)->state.pfs_compile); fp->WritesDepth = GL_FALSE; fp->tex.length = 0; fp->cur_node = 0; @@ -2227,13 +2305,11 @@ static void update_params(struct r300_fragment_program *fp) void r300TranslateFragmentShader(r300ContextPtr r300, struct r300_fragment_program *fp) { - - struct r300_pfs_compile_state *cs = NULL; - if (!fp->translated) { + struct r300_pfs_compile_state cs; + fp->cs = &cs; init_program(r300, fp); - cs = fp->cs; if (parse_program(fp) == GL_FALSE) { dump_program(fp); @@ -2242,11 +2318,11 @@ void r300TranslateFragmentShader(r300ContextPtr r300, /* Finish off */ fp->node[fp->cur_node].alu_end = - cs->nrslots - fp->node[fp->cur_node].alu_offset - 1; + cs.nrslots - fp->node[fp->cur_node].alu_offset - 1; if (fp->node[fp->cur_node].tex_end < 0) fp->node[fp->cur_node].tex_end = 0; fp->alu_offset = 0; - fp->alu_end = cs->nrslots - 1; + fp->alu_end = cs.nrslots - 1; fp->tex_offset = 0; fp->tex_end = fp->tex.length ? fp->tex.length - 1 : 0; assert(fp->node[fp->cur_node].alu_end >= 0); diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c index 26513e74aec..70e45f3ea87 100644 --- a/src/mesa/drivers/dri/r300/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/r500_fragprog.c @@ -57,6 +57,85 @@ #include "r300_reg.h" #include "r300_state.h" +/* Mapping Mesa registers to R500 temporaries */ +struct reg_acc { + int reg; /* Assigned hw temp */ + unsigned int refcount; /* Number of uses by mesa program */ +}; + +/** + * Describe the current lifetime information for an R300 temporary + */ +struct reg_lifetime { + /* Index of the first slot where this register is free in the sense + that it can be used as a new destination register. + This is -1 if the register has been assigned to a Mesa register + and the last access to the register has not yet been emitted */ + int free; + + /* Index of the first slot where this register is currently reserved. + This is used to stop e.g. a scalar operation from being moved + before the allocation time of a register that was first allocated + for a vector operation. */ + int reserved; + + /* Index of the first slot in which the register can be used as a + source without losing the value that is written by the last + emitted instruction that writes to the register */ + int vector_valid; + int scalar_valid; + + /* Index to the slot where the register was last read. + This is also the first slot in which the register may be written again */ + int vector_lastread; + int scalar_lastread; +}; + +/** + * Store usage information about an ALU instruction slot during the + * compilation of a fragment program. + */ +#define SLOT_SRC_VECTOR (1<<0) +#define SLOT_SRC_SCALAR (1<<3) +#define SLOT_SRC_BOTH (SLOT_SRC_VECTOR | SLOT_SRC_SCALAR) +#define SLOT_OP_VECTOR (1<<16) +#define SLOT_OP_SCALAR (1<<17) +#define SLOT_OP_BOTH (SLOT_OP_VECTOR | SLOT_OP_SCALAR) + +struct r500_pfs_compile_slot { + /* Bitmask indicating which parts of the slot are used, using SLOT_ constants + defined above */ + unsigned int used; + + /* Selected sources */ + int vsrc[3]; + int ssrc[3]; +}; + +/** + * Store information during compilation of fragment programs. + */ +struct r500_pfs_compile_state { + int nrslots; /* number of ALU slots used so far */ + + /* Track which (parts of) slots are already filled with instructions */ + struct r500_pfs_compile_slot slot[PFS_MAX_ALU_INST]; + + /* Track the validity of R300 temporaries */ + struct reg_lifetime hwtemps[PFS_NUM_TEMP_REGS]; + + /* Used to map Mesa's inputs/temps onto hardware temps */ + int temp_in_use; + struct reg_acc temps[PFS_NUM_TEMP_REGS]; + struct reg_acc inputs[32]; /* don't actually need 32... */ + + /* Track usage of hardware temps, for register allocation, + * indirection detection, etc. */ + GLuint used_in_node; + GLuint dest_in_node; +}; + + /* * Useful macros and values */ @@ -66,7 +145,7 @@ fp->error = GL_TRUE; \ } while(0) -#define COMPILE_STATE struct r300_pfs_compile_state *cs = fp->cs +#define COMPILE_STATE struct r500_pfs_compile_state *cs = fp->cs #define R500_US_NUM_TEMP_REGS 128 #define R500_US_NUM_CONST_REGS 256 @@ -293,7 +372,7 @@ static void emit_tex(struct r500_fragment_program *fp, fp->inst[counter].inst1 = R500_TEX_ID(fpi->TexSrcUnit) | R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED; - + if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) fp->inst[counter].inst1 |= R500_TEX_UNSCALED; @@ -1227,7 +1306,7 @@ static GLboolean parse_program(struct r500_fragment_program *fp) static void init_program(r300ContextPtr r300, struct r500_fragment_program *fp) { - struct r300_pfs_compile_state *cs = NULL; + struct r500_pfs_compile_state *cs = fp->cs; struct gl_fragment_program *mp = &fp->mesa_program; struct prog_instruction *fpi; GLuint InputsRead = mp->Base.InputsRead; @@ -1239,7 +1318,6 @@ static void init_program(r300ContextPtr r300, struct r500_fragment_program *fp) driQueryOptioni(&r300->radeon.optionCache, "fp_optimization"); fp->translated = GL_FALSE; fp->error = GL_FALSE; - fp->cs = cs = &(R300_CONTEXT(fp->ctx)->state.pfs_compile); fp->const_nr = 0; /* Size of pixel stack, plus 1. */ fp->max_temp_idx = 1; @@ -1420,23 +1498,21 @@ static void dumb_shader(struct r500_fragment_program *fp) void r500TranslateFragmentShader(r300ContextPtr r300, struct r500_fragment_program *fp) { - - struct r300_pfs_compile_state *cs = NULL; - if (!fp->translated) { + struct r500_pfs_compile_state cs; + fp->cs = &cs; init_program(r300, fp); - cs = fp->cs; if (parse_program(fp) == GL_FALSE) { ERROR("Huh. Couldn't parse program. There should be additional errors explaining why.\nUsing dumb shader...\n"); dumb_shader(fp); fp->inst_offset = 0; - fp->inst_end = cs->nrslots - 1; + fp->inst_end = cs.nrslots - 1; return; } fp->inst_offset = 0; - fp->inst_end = cs->nrslots - 1; + fp->inst_end = cs.nrslots - 1; fp->translated = GL_TRUE; if (RADEON_DEBUG & DEBUG_PIXEL) { @@ -1449,6 +1525,8 @@ void r500TranslateFragmentShader(r300ContextPtr r300, r300UpdateStateParameters(fp->ctx, _NEW_PROGRAM); + + fp->cs = 0; } update_params(fp); |