diff options
Diffstat (limited to 'src/mesa/drivers/dri/r300')
32 files changed, 2183 insertions, 2136 deletions
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 0dff9a1273..bdb09624be 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -37,6 +37,7 @@ RADEON_COMMON_SOURCES = \ DRIVER_SOURCES = \ radeon_screen.c \ r300_context.c \ + r300_draw.c \ r300_ioctl.c \ r300_cmdbuf.c \ r300_state.c \ @@ -48,6 +49,7 @@ DRIVER_SOURCES = \ radeon_program_pair.c \ radeon_nqssadce.c \ r300_vertprog.c \ + r300_fragprog_common.c \ r300_fragprog.c \ r300_fragprog_swizzle.c \ r300_fragprog_emit.c \ diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index c575c9ac49..0261a5b1d8 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -55,9 +55,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "radeon_reg.h" -#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 -# define RADEON_ONE_REG_WR (1 << 15) - /** # of dwords reserved for additional instructions that may need to be written * during flushing. */ @@ -71,7 +68,6 @@ static unsigned packet0_count(r300ContextPtr r300, uint32_t *pkt) drm_r300_cmd_header_t *t = (drm_r300_cmd_header_t*)pkt; return t->packet0.count; } - return 0; } #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count) @@ -83,7 +79,7 @@ void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom) BATCH_LOCALS(&r300->radeon); drm_r300_cmd_header_t cmd; uint32_t addr, ndw, i; - + if (!r300->radeon.radeonScreen->kernel_mm) { uint32_t dwords; dwords = (*atom->check) (ctx, atom); @@ -92,7 +88,7 @@ void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom) END_BATCH(); return; } - + cmd.u = atom->cmd[0]; addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo; ndw = cmd.vpu.count * 4; @@ -111,7 +107,7 @@ void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom) } else { BEGIN_BATCH_NO_AUTOSTATE(5 + ndw); } - OUT_BATCH_REGVAL(R300_VAP_PVS_UPLOAD_ADDRESS, addr); + OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr); OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR); for (i = 0; i < ndw; i++) { OUT_BATCH(atom->cmd[i+1]); @@ -175,7 +171,7 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom) for(i = 0; i < numtmus; ++i) { radeonTexObj *t = r300->hw.textures[i]; - + if (!t) notexture = 1; } @@ -183,30 +179,75 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom) if (r300->radeon.radeonScreen->kernel_mm && notexture) { return; } - BEGIN_BATCH_NO_AUTOSTATE(4 * numtmus); for(i = 0; i < numtmus; ++i) { radeonTexObj *t = r300->hw.textures[i]; - OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); if (t && !t->image_override) { + BEGIN_BATCH_NO_AUTOSTATE(4); + OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + END_BATCH(); } else if (!t) { - OUT_BATCH(r300->radeon.radeonScreen->texOffset[0]); + /* Texture unit hasn't a texture bound nothings to do */ } else { /* override cases */ if (t->bo) { + BEGIN_BATCH_NO_AUTOSTATE(4); + OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); OUT_BATCH_RELOC(t->tile_bits, t->bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + END_BATCH(); } else if (!r300->radeon.radeonScreen->kernel_mm) { + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); OUT_BATCH(t->override_offset); - } - else - OUT_BATCH(r300->radeon.radeonScreen->texOffset[0]); + END_BATCH(); + } else { + /* Texture unit hasn't a texture bound nothings to do */ + } } } - END_BATCH(); } } +void r300_emit_scissor(GLcontext *ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + BATCH_LOCALS(&r300->radeon); + unsigned x1, y1, x2, y2; + struct radeon_renderbuffer *rrb; + + if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) { + return; + } + rrb = radeon_get_colorbuffer(&r300->radeon); + if (!rrb || !rrb->bo) { + fprintf(stderr, "no rrb\n"); + return; + } + if (r300->radeon.state.scissor.enabled) { + x1 = r300->radeon.state.scissor.rect.x1; + y1 = r300->radeon.state.scissor.rect.y1; + x2 = r300->radeon.state.scissor.rect.x2 - 1; + y2 = r300->radeon.state.scissor.rect.y2 - 1; + } else { + x1 = 0; + y1 = 0; + x2 = rrb->width - 1; + y2 = rrb->height - 1; + } + if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { + x1 += R300_SCISSORS_OFFSET; + y1 += R300_SCISSORS_OFFSET; + x2 += R300_SCISSORS_OFFSET; + y2 += R300_SCISSORS_OFFSET; + } + BEGIN_BATCH_NO_AUTOSTATE(3); + OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); + OUT_BATCH((x1 << R300_SCISSORS_X_SHIFT)|(y1 << R300_SCISSORS_Y_SHIFT)); + OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT)); + END_BATCH(); +} + static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) { r300ContextPtr r300 = R300_CONTEXT(ctx); @@ -215,6 +256,7 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) uint32_t cbpitch; uint32_t offset = r300->radeon.state.color.draw_offset; uint32_t dw = 6; + int i; rrb = radeon_get_colorbuffer(&r300->radeon); if (!rrb || !rrb->bo) { @@ -247,16 +289,39 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) BEGIN_BATCH_NO_AUTOSTATE(3); OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); OUT_BATCH(0); - OUT_BATCH((rrb->width << R300_SCISSORS_X_SHIFT) | - (rrb->height << R300_SCISSORS_Y_SHIFT)); + OUT_BATCH(((rrb->width - 1) << R300_SCISSORS_X_SHIFT) | + ((rrb->height - 1) << R300_SCISSORS_Y_SHIFT)); + END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(16); + for (i = 0; i < 4; i++) { + OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2); + OUT_BATCH((0 << R300_CLIPRECT_X_SHIFT) | (0 << R300_CLIPRECT_Y_SHIFT)); + OUT_BATCH(((rrb->width - 1) << R300_CLIPRECT_X_SHIFT) | ((rrb->height - 1) << R300_CLIPRECT_Y_SHIFT)); + } + OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1); + OUT_BATCH(0xAAAA); + OUT_BATCH_REGSEQ(R300_SC_SCREENDOOR, 1); + OUT_BATCH(0xffffff); END_BATCH(); } else { BEGIN_BATCH_NO_AUTOSTATE(3); OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); OUT_BATCH((R300_SCISSORS_OFFSET << R300_SCISSORS_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_SCISSORS_Y_SHIFT)); - OUT_BATCH(((rrb->width + R300_SCISSORS_OFFSET) << R300_SCISSORS_X_SHIFT) | - ((rrb->height + R300_SCISSORS_OFFSET) << R300_SCISSORS_Y_SHIFT)); + OUT_BATCH(((rrb->width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) | + ((rrb->height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT)); + END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(16); + for (i = 0; i < 4; i++) { + OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2); + OUT_BATCH((R300_SCISSORS_OFFSET << R300_CLIPRECT_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_CLIPRECT_Y_SHIFT)); + OUT_BATCH(((R300_SCISSORS_OFFSET + rrb->width - 1) << R300_CLIPRECT_X_SHIFT) | + ((R300_SCISSORS_OFFSET + rrb->height - 1) << R300_CLIPRECT_Y_SHIFT)); + } + OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1); + OUT_BATCH(0xAAAA); + OUT_BATCH_REGSEQ(R300_SC_SCREENDOOR, 1); + OUT_BATCH(0xffffff); END_BATCH(); } } @@ -280,7 +345,7 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom) if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ zbpitch |= R300_DEPTHMICROTILE_TILED; } - + BEGIN_BATCH_NO_AUTOSTATE(6); OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1); OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); @@ -288,6 +353,46 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom) END_BATCH(); } +static void emit_gb_misc(GLcontext *ctx, struct radeon_state_atom * atom) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + BATCH_LOCALS(&r300->radeon); + if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) { + BEGIN_BATCH_NO_AUTOSTATE(4); + OUT_BATCH(atom->cmd[0]); + OUT_BATCH(atom->cmd[1]); + OUT_BATCH(atom->cmd[2]); + OUT_BATCH(atom->cmd[3]); + END_BATCH(); + } +} + +static void emit_threshold_misc(GLcontext *ctx, struct radeon_state_atom * atom) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + BATCH_LOCALS(&r300->radeon); + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + BEGIN_BATCH_NO_AUTOSTATE(3); + OUT_BATCH(atom->cmd[0]); + OUT_BATCH(atom->cmd[1]); + OUT_BATCH(atom->cmd[2]); + END_BATCH(); + } +} + +static void emit_shade_misc(GLcontext *ctx, struct radeon_state_atom * atom) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + BATCH_LOCALS(&r300->radeon); + + if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) { + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH(atom->cmd[0]); + OUT_BATCH(atom->cmd[1]); + END_BATCH(); + } +} + static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom) { r300ContextPtr r300 = R300_CONTEXT(ctx); @@ -372,12 +477,10 @@ int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom) void r300InitCmdBuf(r300ContextPtr r300) { int mtu; - int has_tcl = 1; + int has_tcl; int is_r500 = 0; - int i; - if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) - has_tcl = 0; + has_tcl = r300->options.hw_tcl_enabled; if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) is_r500 = 1; @@ -444,7 +547,10 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE(gb_enable, always, 2, 0); r300->hw.gb_enable.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_ENABLE, 1); ALLOC_STATE(gb_misc, always, R300_GB_MISC_CMDSIZE, 0); - r300->hw.gb_misc.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_MSPOS0, 5); + r300->hw.gb_misc.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_MSPOS0, 3); + r300->hw.gb_misc.emit = emit_gb_misc; + ALLOC_STATE(gb_misc2, always, R300_GB_MISC2_CMDSIZE, 0); + r300->hw.gb_misc2.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x401C, 2); ALLOC_STATE(txe, always, R300_TXE_CMDSIZE, 0); r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_ENABLE, 1); ALLOC_STATE(ga_point_s0, always, 5, 0); @@ -459,8 +565,11 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.lcntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_CNTL, 1); ALLOC_STATE(ga_line_stipple, always, 4, 0); r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_STIPPLE_VALUE, 3); - ALLOC_STATE(shade, always, 5, 0); - r300->hw.shade.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_ENHANCE, 4); + ALLOC_STATE(shade, always, 2, 0); + r300->hw.shade.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_ENHANCE, 1); + r300->hw.shade.emit = emit_shade_misc; + ALLOC_STATE(shade2, always, 4, 0); + r300->hw.shade2.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x4278, 3); ALLOC_STATE(polygon_mode, always, 4, 0); r300->hw.polygon_mode.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POLY_MODE, 3); ALLOC_STATE(fogp, always, 3, 0); @@ -479,19 +588,12 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE(rc, always, R300_RC_CMDSIZE, 0); r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_COUNT, 2); if (is_r500) { - ALLOC_STATE(ri, always, R500_RI_CMDSIZE, 0); + ALLOC_STATE(ri, variable, R500_RI_CMDSIZE, 0); r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_IP_0, 16); - for (i = 0; i < 8; i++) { - r300->hw.ri.cmd[R300_RI_CMD_0 + i +1] = - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | - (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); - } ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, 1); } else { - ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); + ALLOC_STATE(ri, variable, R300_RI_CMDSIZE, 0); r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_IP_0, 8); ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, 1); @@ -567,8 +669,9 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DITHER_CTL, 9); ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0); r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_AARESOLVE_CTL, 1); - ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0); - r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); + ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0); + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); + r300->hw.rb3d_discard_src_pixel_lte_threshold.emit = emit_threshold_misc; ALLOC_STATE(zs, always, R300_ZS_CMDSIZE, 0); r300->hw.zs.cmd[R300_ZS_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_CNTL, 3); @@ -582,8 +685,8 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.zb.emit = emit_zb_offset; ALLOC_STATE(zb_depthclearvalue, always, 2, 0); r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_DEPTHCLEARVALUE, 1); - ALLOC_STATE(unk4F30, always, 3, 0); - r300->hw.unk4F30.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x4F30, 2); + ALLOC_STATE(zb_zmask, always, 3, 0); + r300->hw.zb_zmask.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_ZMASK_OFFSET, 2); ALLOC_STATE(zb_hiz_offset, always, 2, 0); r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_OFFSET, 1); ALLOC_STATE(zb_hiz_pitch, always, 2, 0); diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h index 3786813de3..53bcc0eeb4 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h @@ -39,6 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_context.h" extern void r300InitCmdBuf(r300ContextPtr r300); +void r300_emit_scissor(GLcontext *ctx); void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom); int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 5f279d6629..394521a051 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -64,6 +64,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_ioctl.h" #include "r300_tex.h" #include "r300_emit.h" +#include "r300_render.h" #include "r300_swtcl.h" #include "radeon_bocs_wrapper.h" @@ -72,10 +73,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ -/* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */ -int future_hw_tcl_on = 1; -int hw_tcl_on = 1; - #define need_GL_VERSION_2_0 #define need_GL_ARB_point_parameters #define need_GL_ARB_vertex_program @@ -127,6 +124,7 @@ const struct dri_extension card_extensions[] = { {"GL_EXT_texture_lod_bias", NULL}, {"GL_EXT_texture_mirror_clamp", NULL}, {"GL_EXT_texture_rectangle", NULL}, + {"GL_EXT_vertex_array_bgra", NULL}, {"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions}, {"GL_ATI_texture_env_combine3", NULL}, {"GL_ATI_texture_mirror_once", NULL}, @@ -154,16 +152,8 @@ const struct dri_extension gl_20_extension[] = { {"GL_VERSION_2_0", GL_VERSION_2_0_functions }, }; - -extern struct tnl_pipeline_stage _r300_render_stage; -extern const struct tnl_pipeline_stage _r300_tcl_stage; - static const struct tnl_pipeline_stage *r300_pipeline[] = { - /* Try and go straight to t&l - */ - &_r300_tcl_stage, - /* Catch any t&l fallbacks */ &_tnl_vertex_transform_stage, @@ -172,6 +162,7 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = { &_tnl_fog_coordinate_stage, &_tnl_texgen_stage, &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, &_tnl_vertex_program_stage, /* Try again to go to tcl? @@ -191,17 +182,6 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = { 0, }; -static void r300RunPipeline(GLcontext * ctx) -{ - _mesa_lock_context_textures(ctx); - - if (ctx->NewState) - _mesa_update_state_locked(ctx); - - _tnl_run_pipeline(ctx); - _mesa_unlock_context_textures(ctx); -} - static void r300_get_lock(radeonContextPtr rmesa) { drm_radeon_sarea_t *sarea = rmesa->sarea; @@ -211,7 +191,7 @@ static void r300_get_lock(radeonContextPtr rmesa) if (!rmesa->radeonScreen->kernel_mm) radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom); } -} +} static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa) { @@ -246,9 +226,9 @@ static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon) { r300ContextPtr r300 = (r300ContextPtr)radeon; BATCH_LOCALS(radeon); - + r300->vap_flush_needed = GL_TRUE; - + cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); BEGIN_BATCH_NO_AUTOSTATE(2); OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH); @@ -275,6 +255,112 @@ static void r300_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = r300_fallback; } +static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + + ctx->Const.MaxTextureImageUnits = + driQueryOptioni(&r300->radeon.optionCache, "texture_image_units"); + ctx->Const.MaxTextureCoordUnits = + driQueryOptioni(&r300->radeon.optionCache, "texture_coord_units"); + ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits, + ctx->Const.MaxTextureCoordUnits); + + ctx->Const.MaxTextureMaxAnisotropy = 16.0; + ctx->Const.MaxTextureLodBias = 16.0; + + if (screen->chip_family >= CHIP_FAMILY_RV515) + ctx->Const.MaxTextureLevels = 13; + else + ctx->Const.MaxTextureLevels = 12; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = R300_POINTSIZE_MAX; + ctx->Const.MaxPointSizeAA = R300_POINTSIZE_MAX; + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = R300_LINESIZE_MAX; + ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX; + + ctx->Const.MaxDrawBuffers = 1; + + /* currently bogus data */ + if (r300->options.hw_tcl_enabled) { + ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4; + ctx->Const.VertexProgram.MaxNativeInstructions = + VSF_MAX_FRAGMENT_LENGTH / 4; + ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */ + ctx->Const.VertexProgram.MaxTemps = 32; + ctx->Const.VertexProgram.MaxNativeTemps = + /*VSF_MAX_FRAGMENT_TEMPS */ 32; + ctx->Const.VertexProgram.MaxNativeParameters = 256; /* r420 */ + ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; + } + + if (screen->chip_family >= CHIP_FAMILY_RV515) { + ctx->Const.FragmentProgram.MaxNativeTemps = R500_PFS_NUM_TEMP_REGS; + ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */ + ctx->Const.FragmentProgram.MaxNativeParameters = R500_PFS_NUM_CONST_REGS; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = R500_PFS_MAX_INST; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = R500_PFS_MAX_INST; + ctx->Const.FragmentProgram.MaxNativeInstructions = R500_PFS_MAX_INST; + ctx->Const.FragmentProgram.MaxNativeTexIndirections = R500_PFS_MAX_INST; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; + } else { + ctx->Const.FragmentProgram.MaxNativeTemps = R300_PFS_NUM_TEMP_REGS; + ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */ + ctx->Const.FragmentProgram.MaxNativeParameters = R300_PFS_NUM_CONST_REGS; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = R300_PFS_MAX_ALU_INST; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = R300_PFS_MAX_TEX_INST; + ctx->Const.FragmentProgram.MaxNativeInstructions = R300_PFS_MAX_ALU_INST + R300_PFS_MAX_TEX_INST; + ctx->Const.FragmentProgram.MaxNativeTexIndirections = R300_PFS_MAX_TEX_INDIRECT; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; + } +} + +static void r300ParseOptions(r300ContextPtr r300, radeonScreenPtr screen) +{ + struct r300_options options = { 0 }; + + driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache, + screen->driScreen->myNum, "r300"); + + r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, "def_max_anisotropy"); + + options.stencil_two_side_disabled = driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side"); + options.s3tc_force_enabled = driQueryOptionb(&r300->radeon.optionCache, "force_s3tc_enable"); + options.s3tc_force_disabled = driQueryOptionb(&r300->radeon.optionCache, "disable_s3tc"); + + if (!(screen->chip_flags & RADEON_CHIPSET_TCL) || driQueryOptioni(&r300->radeon.optionCache, "tcl_mode") == DRI_CONF_TCL_SW) + options.hw_tcl_enabled = 0; + else + options.hw_tcl_enabled = 1; + + options.conformance_mode = !driQueryOptionb(&r300->radeon.optionCache, "disable_lowimpact_fallback"); + + r300->options = options; +} + +static void r300InitGLExtensions(GLcontext *ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + + driInitExtensions(ctx, card_extensions, GL_TRUE); + if (r300->radeon.radeonScreen->kernel_mm) + driInitExtensions(ctx, mm_extensions, GL_FALSE); + + if (r300->options.stencil_two_side_disabled) + _mesa_disable_extension(ctx, "GL_EXT_stencil_two_side"); + + if (ctx->Mesa_DXTn && !r300->options.s3tc_force_enabled) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(ctx, "GL_S3_s3tc"); + } else if (r300->options.s3tc_force_disabled) { + _mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + } +} /* Create the device specific rendering context. */ @@ -287,33 +373,19 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, struct dd_function_table functions; r300ContextPtr r300; GLcontext *ctx; - int tcl_mode; assert(glVisual); assert(driContextPriv); assert(screen); - /* Allocate the R300 context */ r300 = (r300ContextPtr) CALLOC(sizeof(*r300)); if (!r300) return GL_FALSE; - if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) - hw_tcl_on = future_hw_tcl_on = 0; + r300ParseOptions(r300, screen); r300_init_vtbl(&r300->radeon); - /* Parse configuration files. - * Do this here so that initialMaxAnisotropy is set before we create - * the default textures. - */ - driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache, - screen->driScreen->myNum, "r300"); - r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, - "def_max_anisotropy"); - /* Init default driver functions then plug in our R300-specific functions - * (the texture functions are especially important) - */ _mesa_init_driver_functions(&functions); r300InitIoctlFuncs(&functions); r300InitStateFuncs(&functions); @@ -327,46 +399,15 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, return GL_FALSE; } - /* Init r300 context data */ - /* Set the maximum texture size small enough that we can guarentee that - * all texture units can bind a maximal texture and have them both in - * texturable memory at once. - */ - ctx = r300->radeon.glCtx; - ctx->Const.MaxTextureImageUnits = - driQueryOptioni(&r300->radeon.optionCache, "texture_image_units"); - ctx->Const.MaxTextureCoordUnits = - driQueryOptioni(&r300->radeon.optionCache, "texture_coord_units"); - ctx->Const.MaxTextureUnits = - MIN2(ctx->Const.MaxTextureImageUnits, - ctx->Const.MaxTextureCoordUnits); - ctx->Const.MaxTextureMaxAnisotropy = 16.0; - ctx->Const.MaxTextureLodBias = 16.0; - - if (screen->chip_family >= CHIP_FAMILY_RV515) - ctx->Const.MaxTextureLevels = 13; - else - ctx->Const.MaxTextureLevels = 12; - - ctx->Const.MinPointSize = 1.0; - ctx->Const.MinPointSizeAA = 1.0; - ctx->Const.MaxPointSize = R300_POINTSIZE_MAX; - ctx->Const.MaxPointSizeAA = R300_POINTSIZE_MAX; + r300->fallback = 0; + if (r300->options.hw_tcl_enabled) + ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - ctx->Const.MinLineWidth = 1.0; - ctx->Const.MinLineWidthAA = 1.0; - ctx->Const.MaxLineWidth = R300_LINESIZE_MAX; - ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX; - - /* Needs further modifications */ -#if 0 - ctx->Const.MaxArrayLockSize = - ( /*512 */ RADEON_BUFFER_SIZE * 16 * 1024) / (4 * 4); -#endif + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->Const.MaxDrawBuffers = 1; + r300InitConstValues(ctx, screen); /* Initialize the software rasterizer and helper modules. */ @@ -375,16 +416,12 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); _swsetup_Wakeup(ctx); - _ae_create_context(ctx); /* Install the customized pipeline: */ _tnl_destroy_pipeline(ctx); _tnl_install_pipeline(ctx, r300_pipeline); - - /* Try and keep materials and vertices separate: - */ -/* _tnl_isolate_materials(ctx, GL_TRUE); */ + TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; /* Configure swrast and TNL to match hardware characteristics: */ @@ -393,80 +430,25 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _tnl_allow_pixel_fog(ctx, GL_FALSE); _tnl_allow_vertex_fog(ctx, GL_TRUE); - /* currently bogus data */ - if (screen->chip_flags & RADEON_CHIPSET_TCL) { - ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4; - ctx->Const.VertexProgram.MaxNativeInstructions = - VSF_MAX_FRAGMENT_LENGTH / 4; - ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */ - ctx->Const.VertexProgram.MaxTemps = 32; - ctx->Const.VertexProgram.MaxNativeTemps = - /*VSF_MAX_FRAGMENT_TEMPS */ 32; - ctx->Const.VertexProgram.MaxNativeParameters = 256; /* r420 */ - ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; - } - - ctx->Const.FragmentProgram.MaxNativeTemps = PFS_NUM_TEMP_REGS; - ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */ - ctx->Const.FragmentProgram.MaxNativeParameters = PFS_NUM_CONST_REGS; - ctx->Const.FragmentProgram.MaxNativeAluInstructions = PFS_MAX_ALU_INST; - ctx->Const.FragmentProgram.MaxNativeTexInstructions = PFS_MAX_TEX_INST; - ctx->Const.FragmentProgram.MaxNativeInstructions = - PFS_MAX_ALU_INST + PFS_MAX_TEX_INST; - ctx->Const.FragmentProgram.MaxNativeTexIndirections = - PFS_MAX_TEX_INDIRECT; - ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */ - ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - - driInitExtensions(ctx, card_extensions, GL_TRUE); - if (r300->radeon.radeonScreen->kernel_mm) - driInitExtensions(ctx, mm_extensions, GL_FALSE); - - if (driQueryOptionb - (&r300->radeon.optionCache, "disable_stencil_two_side")) - _mesa_disable_extension(ctx, "GL_EXT_stencil_two_side"); - - if (r300->radeon.glCtx->Mesa_DXTn - && !driQueryOptionb(&r300->radeon.optionCache, "disable_s3tc")) { - _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); - _mesa_enable_extension(ctx, "GL_S3_s3tc"); - } else - if (driQueryOptionb(&r300->radeon.optionCache, "force_s3tc_enable")) - { - _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + if (r300->options.hw_tcl_enabled) { + r300InitDraw(ctx); + } else { + r300InitSwtcl(ctx); } - r300->disable_lowimpact_fallback = - driQueryOptionb(&r300->radeon.optionCache, - "disable_lowimpact_fallback"); radeon_fbo_init(&r300->radeon); - radeonInitSpanFuncs( ctx ); + radeonInitSpanFuncs( ctx ); r300InitCmdBuf(r300); r300InitState(r300); - if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) - r300InitSwtcl(ctx); - - TNL_CONTEXT(ctx)->Driver.RunPipeline = r300RunPipeline; + r300InitShaderFunctions(r300); - tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode"); - if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) { - fprintf(stderr, "disabling 3D acceleration\n"); -#if R200_MERGED - FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1); -#endif - } - if (tcl_mode == DRI_CONF_TCL_SW || - !(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { - if (r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { - r300->radeon.radeonScreen->chip_flags &= - ~RADEON_CHIPSET_TCL; - fprintf(stderr, "Disabling HW TCL support\n"); - } - TCL_FALLBACK(r300->radeon.glCtx, - RADEON_TCL_FALLBACK_TCL_DISABLE, 1); + if (screen->chip_family == CHIP_FAMILY_RS600 || screen->chip_family == CHIP_FAMILY_RS690 || + screen->chip_family == CHIP_FAMILY_RS740) { + r300->radeon.texture_row_align = 64; } + r300InitGLExtensions(ctx); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 602f86ba66..026c33c67c 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -37,24 +37,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __R300_CONTEXT_H__ #define __R300_CONTEXT_H__ -#include "tnl/t_vertex.h" #include "drm.h" #include "radeon_drm.h" #include "dri_util.h" -#include "texmem.h" #include "radeon_common.h" -#include "main/macros.h" #include "main/mtypes.h" -#include "main/colormac.h" +#include "shader/prog_instruction.h" struct r300_context; typedef struct r300_context r300ContextRec; typedef struct r300_context *r300ContextPtr; -#include "main/mm.h" - /* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html . I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble with other compilers ... GLUE! @@ -72,8 +67,6 @@ typedef struct r300_context *r300ContextPtr; } #include "r300_vertprog.h" -#include "r500_fragprog.h" - /* The blit width for texture uploads @@ -81,9 +74,6 @@ typedef struct r300_context *r300ContextPtr; #define R300_BLIT_WIDTH_BYTES 1024 #define R300_MAX_TEXTURE_UNITS 8 -struct r300_texture_state { - int tc_count; /* number of incoming texture coordinates from VAP */ -}; #define R300_VPT_CMD_0 0 @@ -126,9 +116,11 @@ struct r300_texture_state { #define R300_GB_MISC_MSPOS_0 1 #define R300_GB_MISC_MSPOS_1 2 #define R300_GB_MISC_TILE_CONFIG 3 -#define R300_GB_MISC_SELECT 4 -#define R300_GB_MISC_AA_CONFIG 5 -#define R300_GB_MISC_CMDSIZE 6 +#define R300_GB_MISC_CMDSIZE 4 +#define R300_GB_MISC2_CMD_0 0 +#define R300_GB_MISC2_SELECT 1 +#define R300_GB_MISC2_AA_CONFIG 2 +#define R300_GB_MISC2_CMDSIZE 3 #define R300_TXE_CMD_0 0 #define R300_TXE_ENABLE 1 @@ -303,7 +295,7 @@ struct r300_texture_state { struct r300_hw_state { struct radeon_state_atom vpt; /* viewport (1D98) */ struct radeon_state_atom vap_cntl; - struct radeon_state_atom vap_index_offset; /* 0x208c r5xx only */ + struct radeon_state_atom vap_index_offset; /* 0x208c r5xx only */ struct radeon_state_atom vof; /* VAP output format register 0x2090 */ struct radeon_state_atom vte; /* (20B0) */ struct radeon_state_atom vap_vf_max_vtx_indx; /* Maximum Vertex Indx Clamp (2134) */ @@ -317,6 +309,7 @@ struct r300_hw_state { struct radeon_state_atom pvs; /* pvs_cntl (22D0) */ struct radeon_state_atom gb_enable; /* (4008) */ struct radeon_state_atom gb_misc; /* Multisampling position shifts ? (4010) */ + struct radeon_state_atom gb_misc2; /* Multisampling position shifts ? (4010) */ struct radeon_state_atom ga_point_s0; /* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) (4200) */ struct radeon_state_atom ga_triangle_stipple; /* (4214) */ struct radeon_state_atom ps; /* pointsize (421C) */ @@ -324,6 +317,7 @@ struct r300_hw_state { struct radeon_state_atom lcntl; /* line control */ struct radeon_state_atom ga_line_stipple; /* (4260) */ struct radeon_state_atom shade; + struct radeon_state_atom shade2; struct radeon_state_atom polygon_mode; struct radeon_state_atom fogp; /* fog parameters (4294) */ struct radeon_state_atom ga_soft_reset; /* (429C) */ @@ -361,7 +355,7 @@ struct r300_hw_state { struct radeon_state_atom zstencil_format; struct radeon_state_atom zb; /* z buffer (4F20) */ struct radeon_state_atom zb_depthclearvalue; /* (4F28) */ - struct radeon_state_atom unk4F30; /* (4F30) */ + struct radeon_state_atom zb_zmask; /* (4F30) */ struct radeon_state_atom zb_hiz_offset; /* (4F44) */ struct radeon_state_atom zb_hiz_pitch; /* (4F54) */ @@ -405,73 +399,55 @@ struct r300_hw_state { #define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0) #define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1) -struct r300_vertex_shader_fragment { - int length; - union { - GLuint d[VSF_MAX_FRAGMENT_LENGTH]; - float f[VSF_MAX_FRAGMENT_LENGTH]; - GLuint i[VSF_MAX_FRAGMENT_LENGTH]; - } body; -}; - -struct r300_vertex_shader_state { - struct r300_vertex_shader_fragment program; -}; - -extern int hw_tcl_on; - #define COLOR_IS_RGBA #define TAG(x) r300##x #include "tnl_dd/t_dd_vertex.h" #undef TAG -//#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current) -#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp) - -/* Should but doesnt work */ -//#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->curr_vp) - -/* r300_vertex_shader_state and r300_vertex_program should probably be merged together someday. - * Keeping them them seperate for now should ensure fixed pipeline keeps functioning properly. - */ - -struct r300_vertex_program_key { - GLuint InputsRead; - GLuint OutputsWritten; - GLuint OutputsAdded; -}; - struct r300_vertex_program { struct r300_vertex_program *next; - struct r300_vertex_program_key key; - int translated; - struct r300_vertex_shader_fragment program; + struct r300_vertex_program_key { + GLuint InputsRead; + GLuint OutputsWritten; + GLuint OutputsAdded; + } key; + + struct r300_vertex_shader_hw_code { + int length; + union { + GLuint d[VSF_MAX_FRAGMENT_LENGTH]; + float f[VSF_MAX_FRAGMENT_LENGTH]; + } body; + } hw_code; + + GLboolean translated; + GLboolean error; int pos_end; int num_temporaries; /* Number of temp vars used by program */ int wpos_idx; int inputs[VERT_ATTRIB_MAX]; int outputs[VERT_RESULT_MAX]; - int native; - int ref_count; - int use_ref_count; }; struct r300_vertex_program_cont { struct gl_vertex_program mesa_program; /* Must be first */ - struct r300_vertex_shader_fragment params; struct r300_vertex_program *progs; }; -#define PFS_MAX_ALU_INST 64 -#define PFS_MAX_TEX_INST 64 -#define PFS_MAX_TEX_INDIRECT 4 -#define PFS_NUM_TEMP_REGS 32 -#define PFS_NUM_CONST_REGS 16 +#define R300_PFS_MAX_ALU_INST 64 +#define R300_PFS_MAX_TEX_INST 32 +#define R300_PFS_MAX_TEX_INDIRECT 4 +#define R300_PFS_NUM_TEMP_REGS 32 +#define R300_PFS_NUM_CONST_REGS 32 -struct r300_pfs_compile_state; +#define R500_PFS_MAX_INST 512 +#define R500_PFS_NUM_TEMP_REGS 128 +#define R500_PFS_NUM_CONST_REGS 256 +struct r300_pfs_compile_state; +struct r500_pfs_compile_state; /** * Stores state that influences the compilation of a fragment program. @@ -514,7 +490,7 @@ struct r300_fragment_program_node { struct r300_fragment_program_code { struct { int length; /**< total # of texture instructions used */ - GLuint inst[PFS_MAX_TEX_INST]; + GLuint inst[R300_PFS_MAX_TEX_INST]; } tex; struct { @@ -524,7 +500,7 @@ struct r300_fragment_program_code { GLuint inst1; GLuint inst2; GLuint inst3; - } inst[PFS_MAX_ALU_INST]; + } inst[R300_PFS_MAX_ALU_INST]; } alu; struct r300_fragment_program_node node[4]; @@ -535,53 +511,12 @@ struct r300_fragment_program_code { * Remember which program register a given hardware constant * belongs to. */ - struct prog_src_register constant[PFS_NUM_CONST_REGS]; + struct prog_src_register constant[R300_PFS_NUM_CONST_REGS]; int const_nr; int max_temp_idx; }; -/** - * Store everything about a fragment program that is needed - * to render with that program. - */ -struct r300_fragment_program { - struct gl_fragment_program mesa_program; - - GLboolean translated; - GLboolean error; - - struct r300_fragment_program_external_state state; - struct r300_fragment_program_code code; - - GLboolean WritesDepth; - GLuint optimization; -}; - -struct r500_pfs_compile_state; - -struct r500_fragment_program_external_state { - struct { - /** - * If the sampler is used as a shadow sampler, - * this field is: - * 0 - GL_LUMINANCE - * 1 - GL_INTENSITY - * 2 - GL_ALPHA - * depending on the depth texture mode. - */ - GLuint depth_texture_mode : 2; - - /** - * If the sampler is used as a shadow sampler, - * this field is (texture_compare_func - GL_NEVER). - * [e.g. if compare function is GL_LEQUAL, this field is 3] - * - * Otherwise, this field is 0. - */ - GLuint texture_compare_func : 3; - } unit[16]; -}; struct r500_fragment_program_code { struct { @@ -591,7 +526,7 @@ struct r500_fragment_program_code { GLuint inst3; GLuint inst4; GLuint inst5; - } inst[512]; + } inst[R500_PFS_MAX_INST]; int inst_offset; int inst_end; @@ -600,47 +535,41 @@ struct r500_fragment_program_code { * Remember which program register a given hardware constant * belongs to. */ - struct prog_src_register constant[PFS_NUM_CONST_REGS]; + struct prog_src_register constant[R500_PFS_NUM_CONST_REGS]; int const_nr; int max_temp_idx; }; -struct r500_fragment_program { - struct gl_fragment_program mesa_program; +/** +* Store everything about a fragment program that is needed +* to render with that program. +*/ +struct r300_fragment_program { + struct gl_fragment_program Base; - GLcontext *ctx; GLboolean translated; GLboolean error; - struct r500_fragment_program_external_state state; - struct r500_fragment_program_code code; + struct r300_fragment_program_external_state state; + union rX00_fragment_program_code { + struct r300_fragment_program_code r300; + struct r500_fragment_program_code r500; + } code; GLboolean writes_depth; - GLuint optimization; }; -#define R300_MAX_AOS_ARRAYS 16 - -#define REG_COORDS 0 -#define REG_COLOR0 1 -#define REG_TEX0 2 - -struct r300_state { - struct r300_texture_state texture; - int sw_tcl_inputs[VERT_ATTRIB_MAX]; - struct r300_vertex_shader_state vertex_shader; - - - DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for. - They are the same as tnl->render_inputs for fixed pipeline */ - +struct r300_fragment_program_compiler { + r300ContextPtr r300; + struct r300_fragment_program *fp; + union rX00_fragment_program_code *code; + struct gl_program *program; }; -#define R300_FALLBACK_NONE 0 -#define R300_FALLBACK_TCL 1 -#define R300_FALLBACK_RAST 2 +#define R300_MAX_AOS_ARRAYS 16 + /* r300_swtcl.c */ @@ -654,18 +583,44 @@ struct r300_swtcl_info { * Offset of the 3UB specular color data within a hardware (swtcl) vertex. */ GLuint specoffset; +}; - struct vertex_attribute{ - GLuint attr; - GLubyte format; - GLubyte dst_loc; - GLuint swizzle; - GLubyte write_mask; - } vert_attrs[VERT_ATTRIB_MAX]; +struct r300_vtable { + void (* SetupRSUnit)(GLcontext *ctx); + void (* SetupFragmentShaderTextures)(GLcontext *ctx, int *tmu_mappings); + GLboolean (* BuildFragmentProgramHwCode)(struct r300_fragment_program_compiler *compiler); + void (* FragmentProgramDump)(union rX00_fragment_program_code *code); + void (* SetupPixelShader)(GLcontext *ctx); +}; - GLubyte vertex_attr_count; +struct r300_vertex_buffer { + struct vertex_attribute { + /* generic */ + GLubyte element; + GLvoid *data; + GLboolean free_needed; + GLuint stride; + GLuint dwords; + GLubyte size; /* number of components */ + + /* hw specific */ + uint32_t data_type:4; + uint32_t dst_loc:5; + uint32_t _signed:1; + uint32_t normalize:1; + uint32_t swizzle:12; + uint32_t write_mask:4; + } attribs[VERT_ATTRIB_MAX]; + + GLubyte num_attribs; }; +struct r300_index_buffer { + GLvoid *ptr; + GLboolean is_32bit; + GLboolean free_needed; + GLuint count; +}; /** * \brief R300 context structure. @@ -673,10 +628,10 @@ struct r300_swtcl_info { struct r300_context { struct radeon_context radeon; /* parent class, must be first */ + struct r300_vtable vtbl; + struct r300_hw_state hw; - struct r300_state state; - struct gl_vertex_program *curr_vp; struct r300_vertex_program *selected_vp; /* Vertex buffers @@ -684,10 +639,22 @@ struct r300_context { GLvector4f dummy_attrib[_TNL_ATTRIB_MAX]; GLvector4f *temp_attrib[_TNL_ATTRIB_MAX]; - GLboolean disable_lowimpact_fallback; - + struct r300_options { + uint32_t conformance_mode:1; + uint32_t hw_tcl_enabled:1; + uint32_t s3tc_force_enabled:1; + uint32_t s3tc_force_disabled:1; + uint32_t stencil_two_side_disabled:1; + } options; + struct r300_swtcl_info swtcl; + struct r300_vertex_buffer vbuf; + struct r300_index_buffer ind_buf; GLboolean vap_flush_needed; + + uint32_t fallback; + + DECLARE_RENDERINPUTS(render_inputs_bitset); }; #define R300_CONTEXT(ctx) ((r300ContextPtr)(ctx->DriverCtx)) @@ -703,10 +670,9 @@ extern int r300VertexProgUpdateParams(GLcontext * ctx, struct r300_vertex_program_cont *vp, float *dst); -#define RADEON_D_CAPTURE 0 -#define RADEON_D_PLAYBACK 1 -#define RADEON_D_PLAYBACK_RAW 2 -#define RADEON_D_T 3 +extern void r300InitShaderFunctions(r300ContextPtr r300); + +extern void r300InitDraw(GLcontext *ctx); #define r300PackFloat32 radeonPackFloat32 #define r300PackFloat24 radeonPackFloat24 diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c new file mode 100644 index 0000000000..cc5650fb7c --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -0,0 +1,475 @@ +/************************************************************************** + * + * Copyright 2009 Maciej Cencora + * + * 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 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 ITS 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 <stdlib.h> + +#include "main/glheader.h" +#include "main/context.h" +#include "main/state.h" +#include "main/api_validate.h" +#include "main/enums.h" + +#include "r300_reg.h" +#include "r300_context.h" +#include "r300_emit.h" +#include "r300_render.h" +#include "r300_state.h" +#include "r300_tex.h" + +#include "tnl/tnl.h" +#include "tnl/t_vp_build.h" +#include "vbo/vbo_context.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" + +static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf, struct gl_buffer_object **bo, GLuint *nr_bo) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_index_buffer *ind_buf = &r300->ind_buf; + GLvoid *src_ptr; + + if (!mesa_ind_buf) { + ind_buf->ptr = NULL; + return; + } + + ind_buf->count = mesa_ind_buf->count; + if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) { + bo[*nr_bo] = mesa_ind_buf->obj; + (*nr_bo)++; + ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj); + assert(mesa_ind_buf->obj->Pointer != NULL); + } + src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr); + + if (mesa_ind_buf->type == GL_UNSIGNED_BYTE) { + GLubyte *in = (GLubyte *)src_ptr; + GLuint *out = _mesa_malloc(sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1)); + int i; + + ind_buf->ptr = out; + + for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) { + *out++ = in[i] | in[i + 1] << 16; + } + + if (i < mesa_ind_buf->count) { + *out++ = in[i]; + } + + ind_buf->free_needed = GL_TRUE; + ind_buf->is_32bit = GL_FALSE; + } else if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) { +#if MESA_BIG_ENDIAN + GLushort *in = (GLushort *)src_ptr; + GLuint *out = _mesa_malloc(sizeof(GLushort) * + ((mesa_ind_buf->count + 1) & ~1)); + int i; + + ind_buf->ptr = out; + + for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) { + *out++ = in[i] | in[i + 1] << 16; + } + + if (i < mesa_ind_buf->count) { + *out++ = in[i]; + } + + ind_buf->free_needed = GL_TRUE; +#else + ind_buf->ptr = src_ptr; + ind_buf->free_needed = GL_FALSE; +#endif + ind_buf->is_32bit = GL_FALSE; + } else { + ind_buf->ptr = src_ptr; + ind_buf->free_needed = GL_FALSE; + ind_buf->is_32bit = GL_TRUE; + } +} + +static int getTypeSize(GLenum type) +{ + switch (type) { + case GL_DOUBLE: + return sizeof(GLdouble); + case GL_FLOAT: + return sizeof(GLfloat); + case GL_INT: + return sizeof(GLint); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_BYTE: + return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + default: + assert(0); + return 0; + } +} + +#define CONVERT( TYPE, MACRO ) do { \ + GLuint i, j, sz; \ + sz = input->Size; \ + if (input->Normalized) { \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)src_ptr; \ + for (j = 0; j < sz; j++) { \ + *dst_ptr++ = MACRO(*in); \ + in++; \ + } \ + src_ptr += stride; \ + } \ + } else { \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)src_ptr; \ + for (j = 0; j < sz; j++) { \ + *dst_ptr++ = (GLfloat)(*in); \ + in++; \ + } \ + src_ptr += stride; \ + } \ + } \ +} while (0) + +static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const struct gl_client_array *input, struct gl_buffer_object **bo, GLuint *nr_bo) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_vertex_buffer *vbuf = &r300->vbuf; + struct vertex_attribute r300_attr; + const void *src_ptr; + GLenum type; + GLuint stride; + + if (input->BufferObj->Name) { + if (!input->BufferObj->Pointer) { + bo[*nr_bo] = input->BufferObj; + (*nr_bo)++; + ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj); + assert(input->BufferObj->Pointer != NULL); + } + + src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr); + } else + src_ptr = input->Ptr; + + stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB; + + if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT || +#if MESA_BIG_ENDIAN + getTypeSize(input->Type) != 4 || +#endif + stride < 4) { + if (RADEON_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "%s: Converting vertex attributes, attribute data format %x,", __FUNCTION__, input->Type); + fprintf(stderr, "stride %d, components %d\n", stride, input->Size); + } + + GLfloat *dst_ptr, *tmp; + tmp = dst_ptr = _mesa_malloc(sizeof(GLfloat) * input->Size * count); + + switch (input->Type) { + case GL_DOUBLE: + CONVERT(GLdouble, (GLfloat)); + break; + case GL_UNSIGNED_INT: + CONVERT(GLuint, UINT_TO_FLOAT); + break; + case GL_INT: + CONVERT(GLint, INT_TO_FLOAT); + break; + case GL_UNSIGNED_SHORT: + CONVERT(GLushort, USHORT_TO_FLOAT); + break; + case GL_SHORT: + CONVERT(GLshort, SHORT_TO_FLOAT); + break; + case GL_UNSIGNED_BYTE: + assert(input->Format != GL_BGRA); + CONVERT(GLubyte, UBYTE_TO_FLOAT); + break; + case GL_BYTE: + CONVERT(GLbyte, BYTE_TO_FLOAT); + break; + default: + assert(0); + break; + } + + type = GL_FLOAT; + r300_attr.free_needed = GL_TRUE; + r300_attr.data = tmp; + r300_attr.stride = sizeof(GLfloat) * input->Size; + r300_attr.dwords = input->Size; + } else { + type = input->Type; + r300_attr.free_needed = GL_FALSE; + r300_attr.data = (GLvoid *)src_ptr; + r300_attr.stride = stride; + r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4; + } + + r300_attr.size = input->Size; + r300_attr.element = attr; + r300_attr.dst_loc = vbuf->num_attribs; + + switch (type) { + case GL_FLOAT: + switch (input->Size) { + case 1: r300_attr.data_type = R300_DATA_TYPE_FLOAT_1; break; + case 2: r300_attr.data_type = R300_DATA_TYPE_FLOAT_2; break; + case 3: r300_attr.data_type = R300_DATA_TYPE_FLOAT_3; break; + case 4: r300_attr.data_type = R300_DATA_TYPE_FLOAT_4; break; + } + r300_attr._signed = 0; + r300_attr.normalize = 0; + break; + case GL_SHORT: + r300_attr._signed = 1; + r300_attr.normalize = input->Normalized; + switch (input->Size) { + case 1: + case 2: + r300_attr.data_type = R300_DATA_TYPE_SHORT_2; + break; + case 3: + case 4: + r300_attr.data_type = R300_DATA_TYPE_SHORT_4; + break; + } + break; + case GL_BYTE: + r300_attr._signed = 1; + r300_attr.normalize = input->Normalized; + r300_attr.data_type = R300_DATA_TYPE_BYTE; + break; + case GL_UNSIGNED_SHORT: + r300_attr._signed = 0; + r300_attr.normalize = input->Normalized; + switch (input->Size) { + case 1: + case 2: + r300_attr.data_type = R300_DATA_TYPE_SHORT_2; + break; + case 3: + case 4: + r300_attr.data_type = R300_DATA_TYPE_SHORT_4; + break; + } + break; + case GL_UNSIGNED_BYTE: + r300_attr._signed = 0; + r300_attr.normalize = input->Normalized; + if (input->Format == GL_BGRA) + r300_attr.data_type = R300_DATA_TYPE_D3DCOLOR; + else + r300_attr.data_type = R300_DATA_TYPE_BYTE; + break; + + default: + case GL_DOUBLE: + case GL_INT: + case GL_UNSIGNED_INT: + assert(0); + break; + } + + switch (input->Size) { + case 4: + r300_attr.swizzle = SWIZZLE_XYZW; + break; + case 3: + r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); + break; + case 2: + r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE); + break; + case 1: + r300_attr.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE); + break; + } + + r300_attr.write_mask = MASK_XYZW; + + vbuf->attribs[vbuf->num_attribs] = r300_attr; + ++vbuf->num_attribs; +} + +static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count, struct gl_buffer_object **bo, GLuint *nr_bo) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_vertex_buffer *vbuf = &r300->vbuf; + + { + int i, tmp; + + tmp = r300->selected_vp->key.InputsRead; + i = 0; + vbuf->num_attribs = 0; + while (tmp) { + /* find first enabled bit */ + while (!(tmp & 1)) { + tmp >>= 1; + ++i; + } + + r300TranslateAttrib(ctx, i, count, arrays[i], bo, nr_bo); + + tmp >>= 1; + ++i; + } + } + + r300SwitchFallback(ctx, R300_FALLBACK_AOS_LIMIT, vbuf->num_attribs > R300_MAX_AOS_ARRAYS); + if (r300->fallback) + return; + + { + int i; + + for (i = 0; i < vbuf->num_attribs; i++) { + rcommon_emit_vector(ctx, &r300->radeon.tcl.aos[i], + vbuf->attribs[i].data, vbuf->attribs[i].dwords, + vbuf->attribs[i].stride, count); + } + + r300->radeon.tcl.aos_count = vbuf->num_attribs; + } +} + +static void r300FreeData(GLcontext *ctx, struct gl_buffer_object **bo, GLuint nr_bo) +{ + { + struct r300_vertex_buffer *vbuf = &R300_CONTEXT(ctx)->vbuf; + int i; + + for (i = 0; i < vbuf->num_attribs; i++) { + if (vbuf->attribs[i].free_needed) + _mesa_free(vbuf->attribs[i].data); + } + } + + { + struct r300_index_buffer *ind_buf = &R300_CONTEXT(ctx)->ind_buf; + if (ind_buf->free_needed) + _mesa_free(ind_buf->ptr); + } + + { + int i; + + for (i = 0; i < nr_bo; ++i) { + ctx->Driver.UnmapBuffer(ctx, 0, bo[i]); + } + } +} + +static GLboolean r300TryDrawPrims(GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ) +{ + struct r300_context *r300 = R300_CONTEXT(ctx); + struct gl_buffer_object *bo[VERT_ATTRIB_MAX+1]; + GLuint i, nr_bo = 0; + + if (ctx->NewState) + _mesa_update_state( ctx ); + + if (r300->options.hw_tcl_enabled) + _tnl_UpdateFixedFunctionProgram(ctx); + + r300UpdateShaders(r300); + + r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, !r300ValidateBuffers(ctx)); + + r300FixupIndexBuffer(ctx, ib, bo, &nr_bo); + + r300SetVertexFormat(ctx, arrays, max_index + 1, bo, &nr_bo); + + if (r300->fallback) + return GL_FALSE; + + r300SetupVAP(ctx, r300->selected_vp->key.InputsRead, r300->selected_vp->key.OutputsWritten); + + r300UpdateShaderStates(r300); + + r300EmitCacheFlush(r300); + radeonEmitState(&r300->radeon); + + for (i = 0; i < nr_prims; ++i) { + r300RunRenderPrimitive(ctx, prim[i].start, prim[i].start + prim[i].count, prim[i].mode); + } + + r300EmitCacheFlush(r300); + + radeonReleaseArrays(ctx, ~0); + + r300FreeData(ctx, bo, nr_bo); + + return GL_TRUE; +} + +/* TODO: rebase if number of indices in any of primitives is > 8192 for 32bit indices or 16384 for 16bit indices */ + +static void r300DrawPrims(GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index) +{ + GLboolean retval; + + if (min_index) { + vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims ); + return; + } + + /* Make an attempt at drawing */ + retval = r300TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + + /* If failed run tnl pipeline - it should take care of fallbacks */ + if (!retval) + _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); +} + +void r300InitDraw(GLcontext *ctx) +{ + struct vbo_context *vbo = vbo_context(ctx); + + vbo->draw_prims = r300DrawPrims; +} diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index 4fd6ba9b91..c3817721dc 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -31,6 +31,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * \file * * \author Keith Whitwell <keith@tungstengraphics.com> + * \author Maciej Cencora <m.cencora@gmail.com> */ #include "main/glheader.h" @@ -49,74 +50,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_emit.h" #include "r300_ioctl.h" - - -#if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \ - SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \ - SWIZZLE_Z != R300_INPUT_ROUTE_SELECT_Z || \ - SWIZZLE_W != R300_INPUT_ROUTE_SELECT_W || \ - SWIZZLE_ZERO != R300_INPUT_ROUTE_SELECT_ZERO || \ - SWIZZLE_ONE != R300_INPUT_ROUTE_SELECT_ONE -#error Cannot change these! -#endif - -#define DEBUG_ALL DEBUG_VERTS - -#define DW_SIZE(x) ((inputs[tab[(x)]] << R300_DST_VEC_LOC_SHIFT) | \ - (attribptr[tab[(x)]]->size - 1) << R300_DATA_TYPE_0_SHIFT) - -GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, - int *inputs, GLint * tab, GLuint nr) -{ - GLuint i, dw; - - /* type, inputs, stop bit, size */ - for (i = 0; i < nr; i += 2) { - /* make sure input is valid, would lockup the gpu */ - assert(inputs[tab[i]] != -1); - dw = (R300_SIGNED | DW_SIZE(i)); - if (i + 1 == nr) { - dw |= R300_LAST_VEC << R300_DATA_TYPE_0_SHIFT; - } else { - assert(inputs[tab[i + 1]] != -1); - dw |= (R300_SIGNED | - DW_SIZE(i + 1)) << R300_DATA_TYPE_1_SHIFT; - if (i + 2 == nr) { - dw |= R300_LAST_VEC << R300_DATA_TYPE_1_SHIFT; - } - } - dst[i >> 1] = dw; - } - - return (nr + 1) >> 1; -} - -static GLuint r300VAPInputRoute1Swizzle(int swizzle[4]) -{ - return (swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | - (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | - (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | - (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT); -} - -GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) -{ - GLuint i, dw; - - for (i = 0; i < nr; i += 2) { - dw = (r300VAPInputRoute1Swizzle(swizzle[i]) | - ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | - R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE0_SHIFT; - if (i + 1 < nr) { - dw |= (r300VAPInputRoute1Swizzle(swizzle[i + 1]) | - ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | - R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE1_SHIFT; - } - dst[i >> 1] = dw; - } - - return (nr + 1) >> 1; -} +#include "r300_render.h" +#include "r300_swtcl.h" GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead) { @@ -127,7 +62,6 @@ GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead) GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); GLuint i, vic_1 = 0; if (InputsRead & (1 << VERT_ATTRIB_POS)) @@ -139,213 +73,99 @@ GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) if (InputsRead & (1 << VERT_ATTRIB_COLOR0)) vic_1 |= R300_INPUT_CNTL_COLOR; - rmesa->state.texture.tc_count = 0; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) if (InputsRead & (1 << (VERT_ATTRIB_TEX0 + i))) { - rmesa->state.texture.tc_count++; vic_1 |= R300_INPUT_CNTL_TC0 << i; } return vic_1; } -GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten) +GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) { GLuint ret = 0; - if (OutputsWritten & (1 << VERT_RESULT_HPOS)) + if (vp_writes & (1 << VERT_RESULT_HPOS)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; - if (OutputsWritten & (1 << VERT_RESULT_COL0)) + if (vp_writes & (1 << VERT_RESULT_COL0) && fp_reads & FRAG_BIT_COL0) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT; - if (OutputsWritten & (1 << VERT_RESULT_COL1)) + if (vp_writes & (1 << VERT_RESULT_COL1) && fp_reads & FRAG_BIT_COL1) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT; - if (OutputsWritten & (1 << VERT_RESULT_BFC0) - || OutputsWritten & (1 << VERT_RESULT_BFC1)) - ret |= - R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT | - R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT | - R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; + /* Two sided lighting works only if all 4 colors are written */ + if (vp_writes & (1 << VERT_RESULT_BFC0) || vp_writes & (1 << VERT_RESULT_BFC1)) + ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; - if (OutputsWritten & (1 << VERT_RESULT_PSIZ)) + if (vp_writes & (1 << VERT_RESULT_PSIZ)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; return ret; } -GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten) +GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) { GLuint i, ret = 0, first_free_texcoord = 0; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (OutputsWritten & (1 << (VERT_RESULT_TEX0 + i))) { - ret |= (4 << (3 * i)); + if (vp_writes & (1 << (VERT_RESULT_TEX0 + i)) && fp_reads & FRAG_BIT_TEX(i)) { + ret |= (4 << (3 * first_free_texcoord)); ++first_free_texcoord; } } - if (OutputsWritten & (1 << VERT_RESULT_FOGC)) { - if (first_free_texcoord > 8) { - fprintf(stderr, "\tout of free texcoords to write fog coord\n"); - _mesa_exit(-1); - } - ret |= 1 << (3 * first_free_texcoord); + if (fp_reads & FRAG_BIT_WPOS) { + ret |= (4 << (3 * first_free_texcoord)); + ++first_free_texcoord; + } + + if (vp_writes & (1 << VERT_RESULT_FOGC) && fp_reads & FRAG_BIT_FOGC) { + ret |= 4 << (3 * first_free_texcoord); + } + + if (first_free_texcoord > 8) { + fprintf(stderr, "\tout of free texcoords\n"); + _mesa_exit(-1); } return ret; } -/* Emit vertex data to GART memory - * Route inputs to the vertex processor - * This function should never return R300_FALLBACK_TCL when using software tcl. - */ -int r300EmitArrays(GLcontext * ctx) +GLboolean r300EmitArrays(GLcontext * ctx) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *vb = &tnl->vb; - GLuint nr; - GLuint count = vb->Count; - GLuint i; - GLuint InputsRead = 0, OutputsWritten = 0; - int *inputs = NULL; - int vir_inputs[VERT_ATTRIB_MAX]; - GLint tab[VERT_ATTRIB_MAX]; - int swizzle[VERT_ATTRIB_MAX][4]; - struct r300_vertex_program *prog = - (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); - - if (hw_tcl_on) { - inputs = prog->inputs; - InputsRead = prog->key.InputsRead; - OutputsWritten = prog->key.OutputsWritten; - } else { - inputs = rmesa->state.sw_tcl_inputs; - - DECLARE_RENDERINPUTS(render_inputs_bitset); - RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset); - - vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr; - - assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)); - assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_NORMAL) == 0); - - if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) { - InputsRead |= 1 << VERT_ATTRIB_POS; - OutputsWritten |= 1 << VERT_RESULT_HPOS; - } + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_vertex_buffer *vbuf = &r300->vbuf; + GLuint InputsRead, OutputsWritten; - if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0)) { - InputsRead |= 1 << VERT_ATTRIB_COLOR0; - OutputsWritten |= 1 << VERT_RESULT_COL0; - } + r300ChooseSwtclVertexFormat(ctx, &InputsRead, &OutputsWritten); - if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR1)) { - InputsRead |= 1 << VERT_ATTRIB_COLOR1; - OutputsWritten |= 1 << VERT_RESULT_COL1; - } + r300SwitchFallback(ctx, R300_FALLBACK_AOS_LIMIT, vbuf->num_attribs > R300_MAX_AOS_ARRAYS); + if (r300->fallback & R300_RASTER_FALLBACK_MASK) + return GL_FALSE; - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_TEX(i))) { - InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i); - OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); - } - } + { + struct vertex_buffer *mesa_vb = &TNL_CONTEXT(ctx)->vb; + GLuint attr, i; - for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) { - if (InputsRead & (1 << i)) { - inputs[i] = nr++; - } else { - inputs[i] = -1; - } + for (i = 0; i < vbuf->num_attribs; i++) { + attr = vbuf->attribs[i].element; + rcommon_emit_vector(ctx, &r300->radeon.tcl.aos[i], mesa_vb->AttribPtr[attr]->data, + mesa_vb->AttribPtr[attr]->size, mesa_vb->AttribPtr[attr]->stride, mesa_vb->Count); } - /* Fixed, apply to vir0 only */ - memcpy(vir_inputs, inputs, VERT_ATTRIB_MAX * sizeof(int)); - inputs = vir_inputs; - if (InputsRead & VERT_ATTRIB_POS) - inputs[VERT_ATTRIB_POS] = 0; - if (InputsRead & (1 << VERT_ATTRIB_COLOR0)) - inputs[VERT_ATTRIB_COLOR0] = 2; - if (InputsRead & (1 << VERT_ATTRIB_COLOR1)) - inputs[VERT_ATTRIB_COLOR1] = 3; - for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) - if (InputsRead & (1 << i)) - inputs[i] = 6 + (i - VERT_ATTRIB_TEX0); - - RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset); - } + r300->radeon.tcl.aos_count = vbuf->num_attribs; - assert(InputsRead); - assert(OutputsWritten); - - for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) { - if (InputsRead & (1 << i)) { - tab[nr++] = i; - } + /* Fill index buffer info */ + r300->ind_buf.ptr = mesa_vb->Elts; + r300->ind_buf.is_32bit = GL_TRUE; + r300->ind_buf.free_needed = GL_FALSE; } - if (nr > R300_MAX_AOS_ARRAYS) { - return R300_FALLBACK_TCL; - } - - for (i = 0; i < nr; i++) { - int ci; - - swizzle[i][0] = SWIZZLE_ZERO; - swizzle[i][1] = SWIZZLE_ZERO; - swizzle[i][2] = SWIZZLE_ZERO; - swizzle[i][3] = SWIZZLE_ONE; + r300SetupVAP(ctx, InputsRead, OutputsWritten); - for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) { - swizzle[i][ci] = ci; - } - rcommon_emit_vector(ctx, &rmesa->radeon.tcl.aos[i], - vb->AttribPtr[tab[i]]->data, - vb->AttribPtr[tab[i]]->size, - vb->AttribPtr[tab[i]]->stride, count); - } - - /* Setup INPUT_ROUTE. */ - if (rmesa->radeon.radeonScreen->kernel_mm) { - R300_STATECHANGE(rmesa, vir[0]); - rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; - rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; - rmesa->hw.vir[0].cmd[0] |= - (r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], - vb->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16; - R300_STATECHANGE(rmesa, vir[1]); - rmesa->hw.vir[1].cmd[0] |= - (r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, - nr) & 0x3FFF) << 16; - } else { - R300_STATECHANGE(rmesa, vir[0]); - ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = - r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], - vb->AttribPtr, inputs, tab, nr); - R300_STATECHANGE(rmesa, vir[1]); - ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = - r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, - nr); - } - - /* Setup INPUT_CNTL. */ - R300_STATECHANGE(rmesa, vic); - rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); - rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); - - /* Setup OUTPUT_VTX_FMT. */ - R300_STATECHANGE(rmesa, vof); - rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = - r300VAPOutputCntl0(ctx, OutputsWritten); - rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = - r300VAPOutputCntl1(ctx, OutputsWritten); - - rmesa->radeon.tcl.aos_count = nr; - - return R300_FALLBACK_NONE; + return GL_TRUE; } void r300EmitCacheFlush(r300ContextPtr rmesa) diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index 80c22d5e9a..2fb8b82d3a 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -216,19 +216,16 @@ void static INLINE cp_wait(radeonContextPtr radeon, unsigned char flags) } } -extern int r300EmitArrays(GLcontext * ctx); +extern GLboolean r300EmitArrays(GLcontext * ctx); extern int r300PrimitiveType(r300ContextPtr rmesa, int prim); extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim); extern void r300EmitCacheFlush(r300ContextPtr rmesa); -extern GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, - int *inputs, GLint * tab, GLuint nr); -extern GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr); extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead); extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead); -extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten); -extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten); +extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads); +extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads); #endif diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 32182bb667..55c1cfe631 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -25,32 +25,12 @@ * */ -/** - * \file - * - * Fragment program compiler. Perform transformations on the intermediate - * representation until the program is in a form where we can translate - * it more or less directly into machine-readable form. - * - * \author Ben Skeggs <darktama@iinet.net.au> - * \author Jerome Glisse <j.glisse@gmail.com> - */ +#include "r300_fragprog.h" -#include "main/glheader.h" -#include "main/macros.h" -#include "main/enums.h" -#include "shader/prog_instruction.h" #include "shader/prog_parameter.h" -#include "shader/prog_print.h" #include "r300_context.h" -#include "r300_fragprog.h" #include "r300_fragprog_swizzle.h" -#include "r300_state.h" - -#include "radeon_nqssadce.h" -#include "radeon_program_alu.h" - static void reset_srcreg(struct prog_src_register* reg) { @@ -81,7 +61,7 @@ static struct prog_src_register shadow_ambient(struct gl_program *program, int t * \todo If/when r5xx uses the radeon_program architecture, this can probably * be reused. */ -static GLboolean transform_TEX( +GLboolean r300_transform_TEX( struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data) { @@ -160,6 +140,8 @@ static GLboolean transform_TEX( inst.DstReg.Index = tempreg; inst.DstReg.WriteMask = WRITEMASK_XYZW; destredirect = GL_TRUE; + } else if (inst.SaturateMode) { + destredirect = GL_TRUE; } } @@ -175,7 +157,7 @@ static GLboolean transform_TEX( inst.SrcReg[0].File = PROGRAM_TEMPORARY; inst.SrcReg[0].Index = tmpreg; } - + tgt = radeonAppendInstructions(t->Program, 1); _mesa_copy_instructions(tgt, &inst, 1); @@ -214,9 +196,9 @@ static GLboolean transform_TEX( * r < tex <=> -tex+r < 0 * r >= tex <=> not (-tex+r < 0 */ if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL) - tgt[1].SrcReg[2].NegateBase = tgt[0].SrcReg[2].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[2].Negate = tgt[0].SrcReg[2].Negate ^ NEGATE_XYZW; else - tgt[1].SrcReg[0].NegateBase = tgt[0].SrcReg[0].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[0].Negate = tgt[0].SrcReg[0].Negate ^ NEGATE_XYZW; tgt[2].Opcode = OPCODE_CMP; tgt[2].DstReg = orig_inst->DstReg; @@ -239,6 +221,7 @@ static GLboolean transform_TEX( tgt->Opcode = OPCODE_MOV; tgt->DstReg = orig_inst->DstReg; + tgt->SaturateMode = inst.SaturateMode; tgt->SrcReg[0].File = PROGRAM_TEMPORARY; tgt->SrcReg[0].Index = inst.DstReg.Index; } @@ -246,241 +229,10 @@ static GLboolean transform_TEX( return GL_TRUE; } - -static void update_params(r300ContextPtr r300, struct r300_fragment_program *fp) -{ - struct gl_fragment_program *mp = &fp->mesa_program; - - /* Ask Mesa nicely to fill in ParameterValues for us */ - if (mp->Base.Parameters) - _mesa_load_state_parameters(r300->radeon.glCtx, mp->Base.Parameters); -} - - -/** - * Transform the program to support fragment.position. - * - * Introduce a small fragment at the start of the program that will be - * the only code that directly reads the FRAG_ATTRIB_WPOS input. - * All other code pieces that reference that input will be rewritten - * to read from a newly allocated temporary. - * - * \todo if/when r5xx supports the radeon_program architecture, this is a - * likely candidate for code sharing. - */ -static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) -{ - GLuint InputsRead = compiler->fp->mesa_program.Base.InputsRead; - - if (!(InputsRead & FRAG_BIT_WPOS)) - return; - - static gl_state_index tokens[STATE_LENGTH] = { - STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0 - }; - struct prog_instruction *fpi; - GLuint window_index; - int i = 0; - GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY); - - _mesa_insert_instructions(compiler->program, 0, 3); - fpi = compiler->program->Instructions; - - /* perspective divide */ - fpi[i].Opcode = OPCODE_RCP; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_W; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; - fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW; - i++; - - fpi[i].Opcode = OPCODE_MUL; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; - fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[1].Index = tempregi; - fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW; - i++; - - /* viewport transformation */ - window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens); - - fpi[i].Opcode = OPCODE_MAD; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[0].Index = tempregi; - fpi[i].SrcReg[0].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - - fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR; - fpi[i].SrcReg[1].Index = window_index; - fpi[i].SrcReg[1].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - - fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR; - fpi[i].SrcReg[2].Index = window_index; - fpi[i].SrcReg[2].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - i++; - - for (; i < compiler->program->NumInstructions; ++i) { - int reg; - for (reg = 0; reg < 3; reg++) { - if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT && - fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) { - fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[reg].Index = tempregi; - } - } - } -} - - -static void nqssadce_init(struct nqssadce_state* s) -{ - s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW; - s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W; -} - - -static GLuint build_dtm(GLuint depthmode) -{ - switch(depthmode) { - default: - case GL_LUMINANCE: return 0; - case GL_INTENSITY: return 1; - case GL_ALPHA: return 2; - } -} - -static GLuint build_func(GLuint comparefunc) -{ - return comparefunc - GL_NEVER; -} - - -/** - * Collect all external state that is relevant for compiling the given - * fragment program. - */ -static void build_state( - r300ContextPtr r300, - struct r300_fragment_program *fp, - struct r300_fragment_program_external_state *state) -{ - int unit; - - _mesa_bzero(state, sizeof(*state)); - - for(unit = 0; unit < 16; ++unit) { - if (fp->mesa_program.Base.ShadowSamplers & (1 << unit)) { - struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current; - - state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); - state->unit[unit].texture_compare_func = build_func(tex->CompareFunc); - } - } -} - - -void r300TranslateFragmentShader(r300ContextPtr r300, - struct r300_fragment_program *fp) -{ - struct r300_fragment_program_external_state state; - - build_state(r300, fp, &state); - if (_mesa_memcmp(&fp->state, &state, sizeof(state))) { - /* TODO: cache compiled programs */ - fp->translated = GL_FALSE; - _mesa_memcpy(&fp->state, &state, sizeof(state)); - } - - if (!fp->translated) { - struct r300_fragment_program_compiler compiler; - - compiler.r300 = r300; - compiler.fp = fp; - compiler.code = &fp->code; - compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Fragment Program: Initial program:\n"); - _mesa_print_program(compiler.program); - } - - insert_WPOS_trailer(&compiler); - - struct radeon_program_transformation transformations[] = { - { &transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformTrigSimple, 0 } - }; - radeonLocalTransform( - r300->radeon.glCtx, - compiler.program, - 3, transformations); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Fragment Program: After native rewrite:\n"); - _mesa_print_program(compiler.program); - } - - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &r300FPIsNativeSwizzle, - .BuildSwizzle = &r300FPBuildSwizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(r300->radeon.glCtx, compiler.program, &nqssadce); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: after NqSSA-DCE:\n"); - _mesa_print_program(compiler.program); - } - - if (!r300FragmentProgramEmit(&compiler)) - fp->error = GL_TRUE; - - /* Subtle: Rescue any parameters that have been added during transformations */ - _mesa_free_parameter_list(fp->mesa_program.Base.Parameters); - fp->mesa_program.Base.Parameters = compiler.program->Parameters; - compiler.program->Parameters = 0; - - _mesa_reference_program(r300->radeon.glCtx, &compiler.program, NULL); - - if (!fp->error) - fp->translated = GL_TRUE; - if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) - r300FragmentProgramDump(fp, &fp->code); - r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM); - } - - update_params(r300, fp); -} - /* just some random things... */ -void r300FragmentProgramDump( - struct r300_fragment_program *fp, - struct r300_fragment_program_code *code) +void r300FragmentProgramDump(union rX00_fragment_program_code *c) { + struct r300_fragment_program_code *code = &c->r300; int n, i, j; static int pc = 0; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index 94fb554fb3..5ce6f33cee 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -33,9 +33,6 @@ #ifndef __R300_FRAGPROG_H_ #define __R300_FRAGPROG_H_ -#include "main/glheader.h" -#include "main/macros.h" -#include "main/enums.h" #include "shader/program.h" #include "shader/prog_instruction.h" @@ -105,28 +102,10 @@ #endif -struct r300_fragment_program; +extern GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler); -extern void r300TranslateFragmentShader(r300ContextPtr r300, - struct r300_fragment_program *fp); +extern void r300FragmentProgramDump(union rX00_fragment_program_code *c); - -/** - * Used internally by the r300 fragment program code to store compile-time - * only data. - */ -struct r300_fragment_program_compiler { - r300ContextPtr r300; - struct r300_fragment_program *fp; - struct r300_fragment_program_code *code; - struct gl_program *program; -}; - -extern GLboolean r300FragmentProgramEmit(struct r300_fragment_program_compiler *compiler); - - -extern void r300FragmentProgramDump( - struct r300_fragment_program *fp, - struct r300_fragment_program_code *code); +extern GLboolean r300_transform_TEX(struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data); #endif diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c new file mode 100644 index 0000000000..abc8757ba1 --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. + * + */ + +/** + * \file + * + * Fragment program compiler. Perform transformations on the intermediate + * representation until the program is in a form where we can translate + * it more or less directly into machine-readable form. + * + * \author Ben Skeggs <darktama@iinet.net.au> + * \author Jerome Glisse <j.glisse@gmail.com> + */ + +#include "r300_fragprog_common.h" + +#include "shader/program.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" + +#include "r300_state.h" +#include "r300_fragprog.h" +#include "r300_fragprog_swizzle.h" +#include "r500_fragprog.h" + +#include "radeon_program.h" +#include "radeon_program_alu.h" + +static void update_params(GLcontext *ctx, struct gl_fragment_program *fp) +{ + /* Ask Mesa nicely to fill in ParameterValues for us */ + if (fp->Base.Parameters) + _mesa_load_state_parameters(ctx, fp->Base.Parameters); +} + +static void nqssadce_init(struct nqssadce_state* s) +{ + s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW; + s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W; +} + +/** + * Transform the program to support fragment.position. + * + * Introduce a small fragment at the start of the program that will be + * the only code that directly reads the FRAG_ATTRIB_WPOS input. + * All other code pieces that reference that input will be rewritten + * to read from a newly allocated temporary. + * + */ +static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) +{ + GLuint InputsRead = compiler->fp->Base.Base.InputsRead; + + if (!(InputsRead & FRAG_BIT_WPOS)) + return; + + static gl_state_index tokens[STATE_LENGTH] = { + STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0 + }; + struct prog_instruction *fpi; + GLuint window_index; + int i = 0; + GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY); + + _mesa_insert_instructions(compiler->program, 0, 3); + fpi = compiler->program->Instructions; + + /* perspective divide */ + fpi[i].Opcode = OPCODE_RCP; + + fpi[i].DstReg.File = PROGRAM_TEMPORARY; + fpi[i].DstReg.Index = tempregi; + fpi[i].DstReg.WriteMask = WRITEMASK_W; + fpi[i].DstReg.CondMask = COND_TR; + + fpi[i].SrcReg[0].File = PROGRAM_INPUT; + fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; + fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW; + i++; + + fpi[i].Opcode = OPCODE_MUL; + + fpi[i].DstReg.File = PROGRAM_TEMPORARY; + fpi[i].DstReg.Index = tempregi; + fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; + fpi[i].DstReg.CondMask = COND_TR; + + fpi[i].SrcReg[0].File = PROGRAM_INPUT; + fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; + fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; + + fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY; + fpi[i].SrcReg[1].Index = tempregi; + fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW; + i++; + + /* viewport transformation */ + window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens); + + fpi[i].Opcode = OPCODE_MAD; + + fpi[i].DstReg.File = PROGRAM_TEMPORARY; + fpi[i].DstReg.Index = tempregi; + fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; + fpi[i].DstReg.CondMask = COND_TR; + + fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY; + fpi[i].SrcReg[0].Index = tempregi; + fpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); + + fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR; + fpi[i].SrcReg[1].Index = window_index; + fpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); + + fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR; + fpi[i].SrcReg[2].Index = window_index; + fpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); + i++; + + for (; i < compiler->program->NumInstructions; ++i) { + int reg; + for (reg = 0; reg < 3; reg++) { + if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT && + fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) { + fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY; + fpi[i].SrcReg[reg].Index = tempregi; + } + } + } +} + +static GLuint build_dtm(GLuint depthmode) +{ + switch(depthmode) { + default: + case GL_LUMINANCE: return 0; + case GL_INTENSITY: return 1; + case GL_ALPHA: return 2; + } +} + +static GLuint build_func(GLuint comparefunc) +{ + return comparefunc - GL_NEVER; +} + +/** + * Collect all external state that is relevant for compiling the given + * fragment program. + */ +static void build_state( + r300ContextPtr r300, + struct r300_fragment_program *fp, + struct r300_fragment_program_external_state *state) +{ + int unit; + + _mesa_bzero(state, sizeof(*state)); + + for(unit = 0; unit < 16; ++unit) { + if (fp->Base.Base.ShadowSamplers & (1 << unit)) { + struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current; + + state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); + state->unit[unit].texture_compare_func = build_func(tex->CompareFunc); + } + } +} + +void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp; + struct r300_fragment_program_external_state state; + + build_state(r300, r300_fp, &state); + if (_mesa_memcmp(&r300_fp->state, &state, sizeof(state))) { + /* TODO: cache compiled programs */ + r300_fp->translated = GL_FALSE; + _mesa_memcpy(&r300_fp->state, &state, sizeof(state)); + } + + if (!r300_fp->translated) { + struct r300_fragment_program_compiler compiler; + + compiler.r300 = r300; + compiler.fp = r300_fp; + compiler.code = &r300_fp->code; + compiler.program = _mesa_clone_program(ctx, &fp->Base); + + if (RADEON_DEBUG & DEBUG_PIXEL) { + fflush(stdout); + _mesa_printf("Fragment Program: Initial program:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } + + insert_WPOS_trailer(&compiler); + + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct radeon_program_transformation transformations[] = { + { &r500_transform_TEX, &compiler }, + { &radeonTransformALU, 0 }, + { &radeonTransformDeriv, 0 }, + { &radeonTransformTrigScale, 0 } + }; + radeonLocalTransform(ctx, compiler.program, 4, transformations); + } else { + struct radeon_program_transformation transformations[] = { + { &r300_transform_TEX, &compiler }, + { &radeonTransformALU, 0 }, + { &radeonTransformTrigSimple, 0 } + }; + radeonLocalTransform(ctx, compiler.program, 3, transformations); + } + + if (RADEON_DEBUG & DEBUG_PIXEL) { + _mesa_printf("Fragment Program: After native rewrite:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } + + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadce_init, + .IsNativeSwizzle = &r500FPIsNativeSwizzle, + .BuildSwizzle = &r500FPBuildSwizzle, + .RewriteDepthOut = GL_TRUE + }; + radeonNqssaDce(ctx, compiler.program, &nqssadce); + } else { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadce_init, + .IsNativeSwizzle = &r300FPIsNativeSwizzle, + .BuildSwizzle = &r300FPBuildSwizzle, + .RewriteDepthOut = GL_TRUE + }; + radeonNqssaDce(ctx, compiler.program, &nqssadce); + } + + if (RADEON_DEBUG & DEBUG_PIXEL) { + _mesa_printf("Compiler: after NqSSA-DCE:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } + + if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler)) + r300_fp->error = GL_TRUE; + + /* Subtle: Rescue any parameters that have been added during transformations */ + _mesa_free_parameter_list(fp->Base.Parameters); + fp->Base.Parameters = compiler.program->Parameters; + compiler.program->Parameters = 0; + + _mesa_reference_program(ctx, &compiler.program, NULL); + + r300_fp->translated = GL_TRUE; + + r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + + if (r300_fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) + r300->vtbl.FragmentProgramDump(&r300_fp->code); + } + + update_params(ctx, fp); +} diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.h b/src/mesa/drivers/dri/r300/r300_fragprog_common.h new file mode 100644 index 0000000000..85ea86fecb --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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_FRAGPROG_COMMON_H_ +#define __R300_FRAGPROG_COMMON_H_ + +#include "main/mtypes.h" + +extern void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp); + +#endif diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/r300_fragprog_emit.c index 9f0b7e3534..b75656e7ee 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_emit.c @@ -47,7 +47,7 @@ #define PROG_CODE \ struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)data; \ - struct r300_fragment_program_code *code = c->code + struct r300_fragment_program_code *code = &c->code->r300 #define error(fmt, args...) do { \ fprintf(stderr, "%s::%s(): " fmt "\n", \ @@ -66,7 +66,7 @@ static GLboolean emit_const(void* data, GLuint file, GLuint index, GLuint *hwind } if (*hwindex >= code->const_nr) { - if (*hwindex >= PFS_NUM_CONST_REGS) { + if (*hwindex >= R300_PFS_NUM_CONST_REGS) { error("Out of hw constants!\n"); return GL_FALSE; } @@ -138,7 +138,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst) { PROG_CODE; - if (code->alu.length >= PFS_MAX_ALU_INST) { + if (code->alu.length >= R300_PFS_MAX_ALU_INST) { error("Too many ALU instructions"); return GL_FALSE; } @@ -201,7 +201,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst) if (inst->Alpha.DepthWriteMask) { code->alu.inst[ip].inst3 |= R300_ALU_DSTA_DEPTH; code->node[code->cur_node].flags |= R300_W_OUT; - c->fp->WritesDepth = GL_TRUE; + c->fp->writes_depth = GL_TRUE; } return GL_TRUE; @@ -213,7 +213,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst) */ static GLboolean finish_node(struct r300_fragment_program_compiler *c) { - struct r300_fragment_program_code *code = c->code; + struct r300_fragment_program_code *code = &c->code->r300; struct r300_fragment_program_node *node = &code->node[code->cur_node]; if (node->alu_end < 0) { @@ -275,7 +275,7 @@ static GLboolean emit_tex(void* data, struct prog_instruction* inst) { PROG_CODE; - if (code->tex.length >= PFS_MAX_TEX_INST) { + if (code->tex.length >= R300_PFS_MAX_TEX_INST) { error("Too many TEX instructions"); return GL_FALSE; } @@ -318,16 +318,16 @@ static const struct radeon_pair_handler pair_handler = { .EmitPaired = &emit_alu, .EmitTex = &emit_tex, .BeginTexBlock = &begin_tex, - .MaxHwTemps = PFS_NUM_TEMP_REGS + .MaxHwTemps = R300_PFS_NUM_TEMP_REGS }; /** * Final compilation step: Turn the intermediate radeon_program into * machine-readable instructions. */ -GLboolean r300FragmentProgramEmit(struct r300_fragment_program_compiler *compiler) +GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler) { - struct r300_fragment_program_code *code = compiler->code; + struct r300_fragment_program_code *code = &compiler->code->r300; _mesa_bzero(code, sizeof(struct r300_fragment_program_code)); code->node[0].alu_end = -1; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c b/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c index a86d2bd471..fc9d855bce 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c @@ -92,7 +92,7 @@ static const struct swizzle_data* lookup_native_swizzle(GLuint swizzle) GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) { if (reg.Abs) - reg.NegateBase = 0; + reg.Negate = NEGATE_NONE; if (opcode == OPCODE_KIL || opcode == OPCODE_TEX || @@ -100,7 +100,7 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) opcode == OPCODE_TXP) { int j; - if (reg.Abs || reg.NegateBase != (15*reg.NegateAbs)) + if (reg.Abs || reg.Negate) return GL_FALSE; for(j = 0; j < 4; ++j) { @@ -121,7 +121,7 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) if (GET_SWZ(reg.Swizzle, j) != SWIZZLE_NIL) relevant |= 1 << j; - if ((reg.NegateBase & relevant) && (reg.NegateBase & relevant) != relevant) + if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant)) return GL_FALSE; if (!lookup_native_swizzle(reg.Swizzle)) @@ -137,13 +137,12 @@ GLboolean r300FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src) { if (src.Abs) - src.NegateBase = 0; + src.Negate = NEGATE_NONE; while(dst.WriteMask) { const struct swizzle_data *best_swizzle = 0; GLuint best_matchcount = 0; GLuint best_matchmask = 0; - GLboolean rgbnegate; int i, comp; for(i = 0; i < num_native_swizzles; ++i) { @@ -157,6 +156,11 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, if (swz == SWIZZLE_NIL) continue; if (swz == GET_SWZ(sd->hash, comp)) { + /* check if the negate bit of current component + * is the same for already matched components */ + if (matchmask && (!!(src.Negate & matchmask) != !!(src.Negate & (1 << comp)))) + continue; + matchcount++; matchmask |= 1 << comp; } @@ -170,13 +174,6 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, } } - if ((src.NegateBase & best_matchmask) != 0) { - best_matchmask &= src.NegateBase; - rgbnegate = !src.NegateAbs; - } else { - rgbnegate = src.NegateAbs; - } - struct prog_instruction *inst; _mesa_insert_instructions(s->Program, s->IP, 1); @@ -185,6 +182,7 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, inst->DstReg = dst; inst->DstReg.WriteMask &= (best_matchmask | WRITEMASK_W); inst->SrcReg[0] = src; + inst->SrcReg[0].Negate = (best_matchmask & src.Negate) ? NEGATE_XYZW : NEGATE_NONE; /* Note: We rely on NqSSA/DCE to set unused swizzle components to NIL */ dst.WriteMask &= ~inst->DstReg.WriteMask; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index a7f5121da7..104079b4db 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -79,7 +79,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, { BATCH_LOCALS(&r300->radeon); GLcontext *ctx = r300->radeon.glCtx; - __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); GLuint cbpitch = 0; r300ContextPtr rmesa = r300; @@ -200,7 +200,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); } - + r300EmitCacheFlush(rmesa); cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); @@ -213,14 +213,13 @@ static void r300EmitClearState(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); BATCH_LOCALS(&r300->radeon); - __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); int i; - int has_tcl = 1; + int has_tcl; int is_r500 = 0; GLuint vap_cntl; - if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) - has_tcl = 0; + has_tcl = r300->options.hw_tcl_enabled; if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) is_r500 = 1; @@ -448,7 +447,7 @@ static void r300EmitClearState(GLcontext * ctx) R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | R500_ALU_RGBA_A_SWIZ_0; - + r500fp.cmd[7] = 0; emit_r500fp(ctx, &r500fp); } @@ -542,9 +541,9 @@ static void r300EmitClearState(GLcontext * ctx) } static void r300KernelClear(GLcontext *ctx, GLuint flags) -{ +{ r300ContextPtr r300 = R300_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); struct radeon_framebuffer *rfb = dPriv->driverPrivate; struct radeon_renderbuffer *rrb; struct radeon_renderbuffer *rrbd; @@ -566,7 +565,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags) r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL); bits = 0; } - + if (flags & BUFFER_BIT_FRONT_LEFT) { rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); @@ -591,7 +590,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags) static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield swrast_mask = 0, tri_mask = 0; int i; diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index ed552d09bb..c22616b95f 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -2432,6 +2432,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Z Buffer Clear Value */ #define R300_ZB_DEPTHCLEARVALUE 0x4f28 +#define R300_ZB_ZMASK_OFFSET 0x4f30 +#define R300_ZB_ZMASK_PITCH 0x4f34 +#define R300_ZB_ZMASK_WRINDEX 0x4f38 +#define R300_ZB_ZMASK_DWORD 0x4f3c +#define R300_ZB_ZMASK_RDINDEX 0x4f40 + /* Hierarchical Z Memory Offset */ #define R300_ZB_HIZ_OFFSET 0x4f44 @@ -3172,6 +3178,9 @@ enum { # define R300_W_SRC_RAS (1 << 2) +/* Packet0 field ordering to write all values to the same reg */ +#define RADEON_ONE_REG_WR (1 << 15) + /* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. * Two parameter dwords: * 0. VAP_VTX_FMT: The first parameter is not written to hardware diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 924305dd12..1356305a21 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -50,6 +50,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * no bugs... */ +#include "r300_render.h" + #include "main/glheader.h" #include "main/state.h" #include "main/imports.h" @@ -72,8 +74,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_reg.h" #include "r300_tex.h" #include "r300_emit.h" -#include "r300_fragprog.h" -extern int future_hw_tcl_on; +#include "r300_fragprog_common.h" +#include "r300_swtcl.h" /** * \brief Convert a OpenGL primitive type into a R300 primitive type. @@ -170,16 +172,19 @@ int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) return num_verts - verts_off; } -static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts) +static void r300EmitElts(GLcontext * ctx, unsigned long n_elts) { r300ContextPtr rmesa = R300_CONTEXT(ctx); void *out; + GLuint size; + + size = ((rmesa->ind_buf.is_32bit ? 4 : 2) * n_elts + 3) & ~3; radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo, - &rmesa->radeon.tcl.elt_dma_offset, n_elts * 4, 4); + &rmesa->radeon.tcl.elt_dma_offset, size, 4); radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); out = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; - memcpy(out, elts, n_elts * 4); + memcpy(out, rmesa->ind_buf.ptr, size); radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo); } @@ -187,14 +192,23 @@ static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type) { BATCH_LOCALS(&rmesa->radeon); + r300_emit_scissor(rmesa->radeon.glCtx); if (vertex_count > 0) { + int size; + BEGIN_BATCH(10); OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0); - OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | - ((vertex_count + 0) << 16) | - type | + if (rmesa->ind_buf.is_32bit) { + size = vertex_count; + OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | + ((vertex_count + 0) << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); - + } else { + size = (vertex_count + 1) >> 1; + OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | + ((vertex_count + 0) << 16) | type); + } + if (!rmesa->radeon.radeonScreen->kernel_mm) { OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) | @@ -203,13 +217,13 @@ static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type) rmesa->radeon.tcl.elt_dma_bo, rmesa->radeon.tcl.elt_dma_offset, RADEON_GEM_DOMAIN_GTT, 0, 0); - OUT_BATCH(vertex_count); + OUT_BATCH(size); } else { OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) | (R300_VAP_PORT_IDX0 >> 2)); OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset); - OUT_BATCH(vertex_count); + OUT_BATCH(size); radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, rmesa->radeon.tcl.elt_dma_bo, RADEON_GEM_DOMAIN_GTT, 0, 0); @@ -224,12 +238,12 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) uint32_t voffset; int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; int i; - + if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr, offset); - + if (!rmesa->radeon.radeonScreen->kernel_mm) { BEGIN_BATCH(sz+2+(nr * 2)); OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1); @@ -240,7 +254,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) (rmesa->radeon.tcl.aos[i].stride << 8) | (rmesa->radeon.tcl.aos[i + 1].components << 16) | (rmesa->radeon.tcl.aos[i + 1].stride << 24)); - + voffset = rmesa->radeon.tcl.aos[i + 0].offset + offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; OUT_BATCH_RELOC(voffset, @@ -256,7 +270,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) RADEON_GEM_DOMAIN_GTT, 0, 0); } - + if (nr & 1) { OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); @@ -280,7 +294,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) (rmesa->radeon.tcl.aos[i].stride << 8) | (rmesa->radeon.tcl.aos[i + 1].components << 16) | (rmesa->radeon.tcl.aos[i + 1].stride << 24)); - + voffset = rmesa->radeon.tcl.aos[i + 0].offset + offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; OUT_BATCH(voffset); @@ -288,7 +302,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; OUT_BATCH(voffset); } - + if (nr & 1) { OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); @@ -327,18 +341,18 @@ static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type) { BATCH_LOCALS(&rmesa->radeon); + r300_emit_scissor(rmesa->radeon.glCtx); BEGIN_BATCH(3); OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type); END_BATCH(); } -static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, - int start, int end, int prim) +void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim) { + r300ContextPtr rmesa = R300_CONTEXT(ctx); + BATCH_LOCALS(&rmesa->radeon); int type, num_verts; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *vb = &tnl->vb; type = r300PrimitiveType(rmesa, prim); num_verts = r300NumVerts(rmesa, end - start, prim); @@ -350,9 +364,9 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, * This is supposed to ensure that we can get all rendering * commands into a single command buffer. */ - rcommonEnsureCmdBufSpace(&rmesa->radeon, 64, __FUNCTION__); + rcommonEnsureCmdBufSpace(&rmesa->radeon, 128, __FUNCTION__); - if (vb->Elts) { + if (rmesa->ind_buf.ptr) { if (num_verts > 65535) { /* not implemented yet */ WARN_ONCE("Too many elts\n"); @@ -369,8 +383,14 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, * allocating the index array might actually evict the vertex * arrays. *sigh* */ - r300EmitElts(ctx, vb->Elts, num_verts); + r300EmitElts(ctx, num_verts); r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); + if (rmesa->radeon.radeonScreen->kernel_mm) { + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH_REGSEQ(R300_VAP_VF_MAX_VTX_INDX, 1); + OUT_BATCH(rmesa->radeon.tcl.aos[0].count); + END_BATCH(); + } r300FireEB(rmesa, num_verts, type); } else { r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); @@ -379,8 +399,7 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, COMMIT_BATCH(); } -static GLboolean r300RunRender(GLcontext * ctx, - struct tnl_pipeline_stage *stage) +static void r300RunRender(GLcontext * ctx, struct tnl_pipeline_stage *stage) { r300ContextPtr rmesa = R300_CONTEXT(ctx); int i; @@ -391,8 +410,7 @@ static GLboolean r300RunRender(GLcontext * ctx, fprintf(stderr, "%s\n", __FUNCTION__); r300UpdateShaders(rmesa); - if (r300EmitArrays(ctx)) - return GL_TRUE; + r300EmitArrays(ctx); r300UpdateShaderStates(rmesa); @@ -403,77 +421,104 @@ static GLboolean r300RunRender(GLcontext * ctx, GLuint prim = _tnl_translate_prim(&vb->Primitive[i]); GLuint start = vb->Primitive[i].start; GLuint end = vb->Primitive[i].start + vb->Primitive[i].count; - r300RunRenderPrimitive(rmesa, ctx, start, end, prim); + r300RunRenderPrimitive(ctx, start, end, prim); } r300EmitCacheFlush(rmesa); radeonReleaseArrays(ctx, ~0); +} - return GL_FALSE; + +static const char *getFallbackString(uint32_t bit) +{ + switch (bit) { + case R300_FALLBACK_VERTEX_PROGRAM : + return "vertex program"; + case R300_FALLBACK_LINE_SMOOTH: + return "smooth lines"; + case R300_FALLBACK_POINT_SMOOTH: + return "smooth points"; + case R300_FALLBACK_POLYGON_SMOOTH: + return "smooth polygons"; + case R300_FALLBACK_LINE_STIPPLE: + return "line stipple"; + case R300_FALLBACK_POLYGON_STIPPLE: + return "polygon stipple"; + case R300_FALLBACK_STENCIL_TWOSIDE: + return "two-sided stencil"; + case R300_FALLBACK_RENDER_MODE: + return "render mode != GL_RENDER"; + case R300_FALLBACK_FRAGMENT_PROGRAM: + return "fragment program"; + case R300_FALLBACK_AOS_LIMIT: + return "aos limit"; + case R300_FALLBACK_INVALID_BUFFERS: + return "invalid buffers"; + default: + return "unknown"; + } } -#define FALLBACK_IF(expr) \ - do { \ - if (expr) { \ - if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \ - WARN_ONCE("Software fallback:%s\n", \ - #expr); \ - return R300_FALLBACK_RAST; \ - } \ - } while(0) - -static int r300Fallback(GLcontext * ctx) +void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode) { - r300ContextPtr r300 = R300_CONTEXT(ctx); - const unsigned back = ctx->Stencil._BackFace; + TNLcontext *tnl = TNL_CONTEXT(ctx); + r300ContextPtr rmesa = R300_CONTEXT(ctx); + uint32_t old_fallback = rmesa->fallback; + static uint32_t fallback_warn = 0; - FALLBACK_IF(r300->radeon.Fallback); - /* Do we need to use new-style shaders? - * Also is there a better way to do this? */ - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - struct r500_fragment_program *fp = (struct r500_fragment_program *) - (char *)ctx->FragmentProgram._Current; - if (fp) { - if (!fp->translated) { - r500TranslateFragmentShader(r300, fp); - FALLBACK_IF(!fp->translated); + if (mode) { + if ((fallback_warn & bit) == 0) { + _mesa_fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit)); + fallback_warn |= bit; + } + rmesa->fallback |= bit; + + /* update only if we change from no tcl fallbacks to some tcl fallbacks */ + if (rmesa->options.hw_tcl_enabled) { + if (((old_fallback & R300_TCL_FALLBACK_MASK) == 0) && + ((bit & R300_TCL_FALLBACK_MASK) > 0)) { + R300_STATECHANGE(rmesa, vap_cntl_status); + rmesa->hw.vap_cntl_status.cmd[1] |= R300_VAP_TCL_BYPASS; } } + + /* update only if we change from no raster fallbacks to some raster fallbacks */ + if (((old_fallback & R300_RASTER_FALLBACK_MASK) == 0) && + ((bit & R300_RASTER_FALLBACK_MASK) > 0)) { + + radeon_firevertices(&rmesa->radeon); + rmesa->radeon.swtcl.RenderIndex = ~0; + _swsetup_Wakeup( ctx ); + } } else { - struct r300_fragment_program *fp = (struct r300_fragment_program *) - (char *)ctx->FragmentProgram._Current; - if (fp) { - if (!fp->translated) { - r300TranslateFragmentShader(r300, fp); - FALLBACK_IF(!fp->translated); + rmesa->fallback &= ~bit; + + /* update only if we have disabled all tcl fallbacks */ + if (rmesa->options.hw_tcl_enabled) { + if ((old_fallback & R300_RASTER_FALLBACK_MASK) == bit) { + R300_STATECHANGE(rmesa, vap_cntl_status); + rmesa->hw.vap_cntl_status.cmd[1] &= ~R300_VAP_TCL_BYPASS; } } - } - FALLBACK_IF(ctx->RenderMode != GL_RENDER); - - /* If GL_EXT_stencil_two_side is disabled, this fallback check can - * be removed. - */ - FALLBACK_IF(ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back] - || ctx->Stencil.ValueMask[0] != - ctx->Stencil.ValueMask[back] - || ctx->Stencil.WriteMask[0] != - ctx->Stencil.WriteMask[back]); - - if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) - FALLBACK_IF(ctx->Point.PointSprite); - - if (!r300->disable_lowimpact_fallback) { - FALLBACK_IF(ctx->Polygon.StippleFlag); - FALLBACK_IF(ctx->Multisample._Enabled); - FALLBACK_IF(ctx->Line.StippleFlag); - FALLBACK_IF(ctx->Line.SmoothFlag); - FALLBACK_IF(ctx->Point.SmoothFlag); + /* update only if we have disabled all raster fallbacks */ + if ((old_fallback & R300_RASTER_FALLBACK_MASK) == bit) { + _swrast_flush( ctx ); + + tnl->Driver.Render.Start = r300RenderStart; + tnl->Driver.Render.Finish = r300RenderFinish; + tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = r300ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + } } - - return R300_FALLBACK_NONE; + } static GLboolean r300RunNonTCLRender(GLcontext * ctx, @@ -484,49 +529,15 @@ static GLboolean r300RunNonTCLRender(GLcontext * ctx, if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); - if (r300Fallback(ctx) >= R300_FALLBACK_RAST) + if (rmesa->fallback & R300_RASTER_FALLBACK_MASK) return GL_TRUE; - if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) - return GL_TRUE; - - if (!r300ValidateBuffers(ctx)) - return GL_TRUE; - - return r300RunRender(ctx, stage); -} - -static GLboolean r300RunTCLRender(GLcontext * ctx, - struct tnl_pipeline_stage *stage) -{ - r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct r300_vertex_program *vp; - - hw_tcl_on = future_hw_tcl_on; - - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (hw_tcl_on == GL_FALSE) - return GL_TRUE; - - if (r300Fallback(ctx) >= R300_FALLBACK_TCL) { - hw_tcl_on = GL_FALSE; + if (rmesa->options.hw_tcl_enabled == GL_FALSE) return GL_TRUE; - } - if (!r300ValidateBuffers(ctx)) - return GL_TRUE; - - r300UpdateShaders(rmesa); - - vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); - if (vp->native == GL_FALSE) { - hw_tcl_on = GL_FALSE; - return GL_TRUE; - } + r300RunRender(ctx, stage); - return r300RunRender(ctx, stage); + return GL_FALSE; } const struct tnl_pipeline_stage _r300_render_stage = { @@ -537,12 +548,3 @@ const struct tnl_pipeline_stage _r300_render_stage = { NULL, r300RunNonTCLRender }; - -const struct tnl_pipeline_stage _r300_tcl_stage = { - "r300 Hardware Transform, Clipping and Lighting", - NULL, - NULL, - NULL, - NULL, - r300RunTCLRender -}; diff --git a/src/mesa/drivers/dri/r300/r300_render.h b/src/mesa/drivers/dri/r300/r300_render.h new file mode 100644 index 0000000000..ec785474a6 --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_render.h @@ -0,0 +1,69 @@ +/* + * Copyright 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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_RENDER_H__ +#define __R300_RENDER_H__ + +#include "main/mtypes.h" + +#define R300_FALLBACK_VERTEX_PROGRAM (1 << 0) +#define R300_TCL_FALLBACK_MASK 0x0000ffff + +#define R300_FALLBACK_LINE_SMOOTH (1 << 16) +#define R300_FALLBACK_POINT_SMOOTH (1 << 17) +#define R300_FALLBACK_POLYGON_SMOOTH (1 << 18) +#define R300_FALLBACK_LINE_STIPPLE (1 << 19) +#define R300_FALLBACK_POLYGON_STIPPLE (1 << 20) +#define R300_FALLBACK_STENCIL_TWOSIDE (1 << 21) +#define R300_FALLBACK_RENDER_MODE (1 << 22) +#define R300_FALLBACK_FRAGMENT_PROGRAM (1 << 23) +#define R300_FALLBACK_AOS_LIMIT (1 << 30) +#define R300_FALLBACK_INVALID_BUFFERS (1 << 31) +#define R300_RASTER_FALLBACK_MASK 0xffff0000 + +#define MASK_XYZW (R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W) +#define MASK_X R300_WRITE_ENA_X +#define MASK_Y R300_WRITE_ENA_Y +#define MASK_Z R300_WRITE_ENA_Z +#define MASK_W R300_WRITE_ENA_W + +#if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \ + SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \ + SWIZZLE_Z != R300_INPUT_ROUTE_SELECT_Z || \ + SWIZZLE_W != R300_INPUT_ROUTE_SELECT_W || \ + SWIZZLE_ZERO != R300_INPUT_ROUTE_SELECT_ZERO || \ + SWIZZLE_ONE != R300_INPUT_ROUTE_SELECT_ONE +#error Cannot change these! +#endif + +extern const struct tnl_pipeline_stage _r300_render_stage; + +extern void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode); + +extern void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim); + +#endif diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index f30fd986e0..0133b83796 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -1,18 +1,42 @@ +/* + * Copyright 2009 Maciej Cencora <m.cencora@gmail.com> + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 "main/glheader.h" #include "shader/program.h" #include "tnl/tnl.h" #include "r300_context.h" -#include "r300_fragprog.h" +#include "r300_fragprog_common.h" static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, GLuint id) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); struct r300_vertex_program_cont *vp; - struct r300_fragment_program *r300_fp; - struct r500_fragment_program *r500_fp; + struct r300_fragment_program *fp; switch (target) { case GL_VERTEX_STATE_PROGRAM_NV: @@ -20,28 +44,12 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, vp = CALLOC_STRUCT(r300_vertex_program_cont); return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); - case GL_FRAGMENT_PROGRAM_ARB: - if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - r500_fp = CALLOC_STRUCT(r500_fragment_program); - r500_fp->ctx = ctx; - return _mesa_init_fragment_program(ctx, &r500_fp->mesa_program, - target, id); - } else { - r300_fp = CALLOC_STRUCT(r300_fragment_program); - return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program, - target, id); - } case GL_FRAGMENT_PROGRAM_NV: - if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - r500_fp = CALLOC_STRUCT(r500_fragment_program); - return _mesa_init_fragment_program(ctx, &r500_fp->mesa_program, - target, id); - } else { - r300_fp = CALLOC_STRUCT(r300_fragment_program); - return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program, - target, id); - } + case GL_FRAGMENT_PROGRAM_ARB: + fp = CALLOC_STRUCT(r300_fragment_program); + return _mesa_init_fragment_program(ctx, &fp->Base, target, id); + default: _mesa_problem(ctx, "Bad target in r300NewProgram"); } @@ -57,20 +65,15 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog) static void r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); struct r300_vertex_program_cont *vp = (void *)prog; struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog; - struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)prog; switch (target) { case GL_VERTEX_PROGRAM_ARB: vp->progs = NULL; break; case GL_FRAGMENT_PROGRAM_ARB: - if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) - r500_fp->translated = GL_FALSE; - else - r300_fp->translated = GL_FALSE; + r300_fp->translated = GL_FALSE; break; } @@ -81,7 +84,14 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) static GLboolean r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) { - return GL_TRUE; + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct r300_fragment_program *fp = (struct r300_fragment_program *)prog; + if (!fp->translated) + r300TranslateFragmentShader(ctx, &fp->Base); + + return !fp->error; + } else + return GL_TRUE; } void r300InitShaderFuncs(struct dd_function_table *functions) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 46c3df7099..c0eda977db 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -53,20 +53,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "shader/prog_statevars.h" #include "vbo/vbo.h" #include "tnl/tnl.h" +#include "tnl/t_vp_build.h" #include "r300_context.h" #include "r300_ioctl.h" #include "r300_state.h" #include "r300_reg.h" #include "r300_emit.h" -#include "r300_fragprog.h" #include "r300_tex.h" +#include "r300_fragprog_common.h" +#include "r300_fragprog.h" +#include "r500_fragprog.h" +#include "r300_render.h" +#include "r300_vertprog.h" #include "drirenderbuffer.h" -extern int future_hw_tcl_on; -extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx); - static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4]) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -365,7 +367,7 @@ static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) GLint *ip; /* no VAP UCP on non-TCL chipsets */ - if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + if (!rmesa->options.hw_tcl_enabled) return; p = (GLint) plane - (GLint) GL_CLIP_PLANE0; @@ -384,7 +386,7 @@ static void r300SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state) GLuint p; /* no VAP UCP on non-TCL chipsets */ - if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + if (!r300->options.hw_tcl_enabled) return; p = cap - GL_CLIP_PLANE0; @@ -450,28 +452,22 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state) static GLboolean current_fragment_program_writes_depth(GLcontext* ctx) { - r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { - struct r300_fragment_program *fp = (struct r300_fragment_program *) - (char *)ctx->FragmentProgram._Current; - return (fp && fp->WritesDepth); - } else { - struct r500_fragment_program* fp = - (struct r500_fragment_program*)(char*) - ctx->FragmentProgram._Current; - return (fp && fp->writes_depth); - } + return (fp && fp->writes_depth); } static void r300SetEarlyZState(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); GLuint topZ = R300_ZTOP_ENABLE; + GLuint w_fmt, fgdepthsrc; if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS) topZ = R300_ZTOP_DISABLE; - if (current_fragment_program_writes_depth(ctx)) + else if (current_fragment_program_writes_depth(ctx)) + topZ = R300_ZTOP_DISABLE; + else if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->UsesKill) topZ = R300_ZTOP_DISABLE; if (topZ != r300->hw.zstencil_format.cmd[2]) { @@ -482,6 +478,26 @@ static void r300SetEarlyZState(GLcontext * ctx) R300_STATECHANGE(r300, zstencil_format); r300->hw.zstencil_format.cmd[2] = topZ; } + + /* w_fmt value is set to get best performance + * see p.130 R5xx 3D acceleration guide v1.3 */ + if (current_fragment_program_writes_depth(ctx)) { + fgdepthsrc = R300_FG_DEPTH_SRC_SHADER; + w_fmt = R300_W_FMT_W24 | R300_W_SRC_US; + } else { + fgdepthsrc = R300_FG_DEPTH_SRC_SCAN; + w_fmt = R300_W_FMT_W0 | R300_W_SRC_US; + } + + if (w_fmt != r300->hw.us_out_fmt.cmd[5]) { + R300_STATECHANGE(r300, us_out_fmt); + r300->hw.us_out_fmt.cmd[5] = w_fmt; + } + + if (fgdepthsrc != r300->hw.fg_depth_src.cmd[1]) { + R300_STATECHANGE(r300, fg_depth_src); + r300->hw.fg_depth_src.cmd[1] = fgdepthsrc; + } } static void r300SetAlphaState(GLcontext * ctx) @@ -532,8 +548,6 @@ static void r300SetAlphaState(GLcontext * ctx) R300_STATECHANGE(r300, at); r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc; r300->hw.at.cmd[R300_AT_UNKNOWN] = 0; - - r300SetEarlyZState(ctx); } static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) @@ -581,14 +595,28 @@ static void r300SetDepthState(GLcontext * ctx) r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(ctx->Depth.Func) << R300_Z_FUNC_SHIFT; } +} - r300SetEarlyZState(ctx); +static void r300CatchStencilFallback(GLcontext *ctx) +{ + const unsigned back = ctx->Stencil._BackFace; + + if (ctx->Stencil._Enabled && (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back] + || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[back] + || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[back])) { + r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_TRUE); + } else { + r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_FALSE); + } } static void r300SetStencilState(GLcontext * ctx, GLboolean state) { r300ContextPtr r300 = R300_CONTEXT(ctx); GLboolean hw_stencil = GL_FALSE; + + r300CatchStencilFallback(ctx); + if (ctx->DrawBuffer) { struct radeon_renderbuffer *rrbStencil = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); @@ -604,10 +632,6 @@ static void r300SetStencilState(GLcontext * ctx, GLboolean state) r300->hw.zs.cmd[R300_ZS_CNTL_0] &= ~R300_STENCIL_ENABLE; } - } else { -#if R200_MERGED - FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state); -#endif } } @@ -740,7 +764,12 @@ static void r300ColorMask(GLcontext * ctx, static void r300PointSize(GLcontext * ctx, GLfloat size) { r300ContextPtr r300 = R300_CONTEXT(ctx); - /* same size limits for AA, non-AA points */ + + /* We need to clamp to user defined range here, because + * the HW clamping happens only for per vertex point size. */ + size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize); + + /* same size limits for AA, non-AA points */ size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); R300_STATECHANGE(r300, ps); @@ -833,29 +862,33 @@ static void r300ShadeModel(GLcontext * ctx, GLenum mode) R300_STATECHANGE(rmesa, shade); rmesa->hw.shade.cmd[1] = 0x00000002; + R300_STATECHANGE(rmesa, shade2); switch (mode) { case GL_FLAT: - rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_FLAT; + rmesa->hw.shade2.cmd[1] = R300_RE_SHADE_MODEL_FLAT; break; case GL_SMOOTH: - rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_SMOOTH; + rmesa->hw.shade2.cmd[1] = R300_RE_SHADE_MODEL_SMOOTH; break; default: return; } - rmesa->hw.shade.cmd[3] = 0x00000000; - rmesa->hw.shade.cmd[4] = 0x00000000; + rmesa->hw.shade2.cmd[2] = 0x00000000; + rmesa->hw.shade2.cmd[3] = 0x00000000; } static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - GLuint refmask = - ((ctx->Stencil.Ref[0] & 0xff) << R300_STENCILREF_SHIFT) - | ((ctx->Stencil.ValueMask[0] & 0xff) << R300_STENCILMASK_SHIFT); - const unsigned back = ctx->Stencil._BackFace; + GLuint refmask; GLuint flag; + const unsigned back = ctx->Stencil._BackFace; + + r300CatchStencilFallback(ctx); + + refmask = ((ctx->Stencil.Ref[0] & 0xff) << R300_STENCILREF_SHIFT) + | ((ctx->Stencil.ValueMask[0] & 0xff) << R300_STENCILMASK_SHIFT); R300_STATECHANGE(rmesa, zs); rmesa->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_FRONT_BACK; @@ -883,6 +916,8 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) { r300ContextPtr rmesa = R300_CONTEXT(ctx); + r300CatchStencilFallback(ctx); + R300_STATECHANGE(rmesa, zs); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_STENCILREF_MASK << @@ -899,6 +934,8 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, r300ContextPtr rmesa = R300_CONTEXT(ctx); const unsigned back = ctx->Stencil._BackFace; + r300CatchStencilFallback(ctx); + R300_STATECHANGE(rmesa, zs); /* It is easier to mask what's left.. */ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= @@ -927,16 +964,10 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, * Window position and viewport transformation */ -/* - * To correctly position primitives: - */ -#define SUBPIXEL_X 0.125 -#define SUBPIXEL_Y 0.125 - static void r300UpdateWindow(GLcontext * ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; + __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon); GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; const GLfloat *v = ctx->Viewport._WindowMap.m; @@ -953,9 +984,9 @@ static void r300UpdateWindow(GLcontext * ctx) } GLfloat sx = v[MAT_SX]; - GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; + GLfloat tx = v[MAT_TX] + xoffset; GLfloat sy = v[MAT_SY] * y_scale; - GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y; + GLfloat ty = (v[MAT_TY] * y_scale) + y_bias; GLfloat sz = v[MAT_SZ] * depthScale; GLfloat tz = v[MAT_TZ] * depthScale; @@ -989,13 +1020,13 @@ static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) void r300UpdateViewportOffset(GLcontext * ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = ((radeonContextPtr) rmesa)->dri.drawable; + __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon); GLfloat xoffset = (GLfloat) dPriv->x; GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; - GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; - GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y; + GLfloat tx = v[MAT_TX] + xoffset; + GLfloat ty = (-v[MAT_TY]) + yoffset; if (rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] != r300PackFloat32(tx) || rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] != r300PackFloat32(ty)) { @@ -1021,12 +1052,14 @@ r300FetchStateParameter(GLcontext * ctx, switch (state[0]) { case STATE_INTERNAL: switch (state[1]) { - case STATE_R300_WINDOW_DIMENSION: - value[0] = r300->radeon.dri.drawable->w * 0.5f; /* width*0.5 */ - value[1] = r300->radeon.dri.drawable->h * 0.5f; /* height*0.5 */ - value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */ - value[3] = 1.0F; /* not used */ - break; + case STATE_R300_WINDOW_DIMENSION: { + __DRIdrawablePrivate * drawable = radeon_get_drawable(&r300->radeon); + value[0] = drawable->w * 0.5f; /* width*0.5 */ + value[1] = drawable->h * 0.5f; /* height*0.5 */ + value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */ + value[3] = 1.0F; /* not used */ + break; + } case STATE_R300_TEXRECT_FACTOR:{ struct gl_texture_object *t = @@ -1066,14 +1099,14 @@ void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) struct gl_program_parameter_list *paramList; GLuint i; - if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM))) + if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))) return; fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current; if (!fp) return; - paramList = fp->mesa_program.Base.Parameters; + paramList = fp->Base.Base.Parameters; if (!paramList) return; @@ -1192,9 +1225,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) { r300ContextPtr r300 = R300_CONTEXT(ctx); int i; - struct r300_fragment_program *fp = (struct r300_fragment_program *) - (char *)ctx->FragmentProgram._Current; - struct r300_fragment_program_code *code = &fp->code; + struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + struct r300_fragment_program_code *code = &fp->code.r300; R300_STATECHANGE(r300, fpt); @@ -1235,9 +1267,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) { int i; - struct r500_fragment_program *fp = (struct r500_fragment_program *) - (char *)ctx->FragmentProgram._Current; - struct r500_fragment_program_code *code = &fp->code; + struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + struct r500_fragment_program_code *code = &fp->code.r500; /* find all the texture instructions and relocate the texture units */ for (i = 0; i < code->inst_end + 1; i++) { @@ -1388,11 +1419,8 @@ static void r300SetupTextures(GLcontext * ctx) r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); - if (!fp) /* should only happenen once, just after context is created */ - return; - if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { - if (fp->mesa_program.UsesKill && last_hw_tmu < 0) { + if (fp->Base.UsesKill && last_hw_tmu < 0) { // The KILL operation requires the first texture unit // to be enabled. r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; @@ -1400,9 +1428,8 @@ static void r300SetupTextures(GLcontext * ctx) r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1); } - r300SetupFragmentShaderTextures(ctx, tmu_mappings); - } else - r500SetupFragmentShaderTextures(ctx, tmu_mappings); + } + r300->vtbl.SetupFragmentShaderTextures(ctx, tmu_mappings); if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n", @@ -1421,26 +1448,21 @@ union r300_outputs_written { static void r300SetupRSUnit(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; union r300_outputs_written OutputsWritten; GLuint InputsRead; int fp_reg, high_rr; int col_ip, tex_ip; int rs_tex_count = 0; - int i, count, col_fmt; + int i, col_fmt, hw_tcl_on; + + hw_tcl_on = r300->options.hw_tcl_enabled; if (hw_tcl_on) - OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; + OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten; else - RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset); + RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); - if (ctx->FragmentProgram._Current) - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - else { - fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); - return; /* This should only ever happen once.. */ - } + InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); @@ -1459,15 +1481,7 @@ static void r300SetupRSUnit(GLcontext * ctx) if (InputsRead & FRAG_BIT_COL0) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) { - count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size; - if (count == 4) - col_fmt = R300_RS_COL_FMT_RGBA; - else if (count == 3) - col_fmt = R300_RS_COL_FMT_RGB1; - else - col_fmt = R300_RS_COL_FMT_0001; - - r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R300_RS_COL_PTR(col_ip) | R300_RS_COL_FMT(col_fmt); + r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R300_RS_COL_PTR(col_ip) | R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); r300->hw.rr.cmd[R300_RR_INST_0 + col_ip] = R300_RS_INST_COL_ID(col_ip) | R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_reg); InputsRead &= ~FRAG_BIT_COL0; ++col_ip; @@ -1479,15 +1493,7 @@ static void r300SetupRSUnit(GLcontext * ctx) if (InputsRead & FRAG_BIT_COL1) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) { - count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size; - if (count == 4) - col_fmt = R300_RS_COL_FMT_RGBA; - else if (count == 3) - col_fmt = R300_RS_COL_FMT_RGB1; - else - col_fmt = R300_RS_COL_FMT_0001; - - r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R300_RS_COL_PTR(col_ip) | R300_RS_COL_FMT(col_fmt); + r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R300_RS_COL_PTR(col_ip) | R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); r300->hw.rr.cmd[R300_RR_INST_0 + col_ip] = R300_RS_INST_COL_ID(col_ip) | R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_reg); InputsRead &= ~FRAG_BIT_COL1; ++col_ip; @@ -1497,6 +1503,7 @@ static void r300SetupRSUnit(GLcontext * ctx) } } + /* We always route 4 texcoord components */ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (! ( InputsRead & FRAG_BIT_TEX(i) ) ) continue; @@ -1506,26 +1513,10 @@ static void r300SetupRSUnit(GLcontext * ctx) continue; } - int swiz; - - /* with TCL we always seem to route 4 components */ - if (hw_tcl_on) - count = 4; - else - count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size; - - switch(count) { - case 4: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break; - case 3: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(R300_RS_SEL_K1); break; - default: - case 1: - case 2: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); break; - }; - - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= swiz | R300_RS_TEX_PTR(rs_tex_count); + r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count); r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg); InputsRead &= ~(FRAG_BIT_TEX0 << i); - rs_tex_count += count; + rs_tex_count += 4; ++tex_ip; ++fp_reg; } @@ -1545,7 +1536,7 @@ static void r300SetupRSUnit(GLcontext * ctx) r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count); r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg); InputsRead &= ~FRAG_BIT_FOGC; - rs_tex_count += 1; + rs_tex_count += 4; ++tex_ip; ++fp_reg; } else { @@ -1555,7 +1546,8 @@ static void r300SetupRSUnit(GLcontext * ctx) /* Setup default color if no color or tex was set */ if (rs_tex_count == 0 && col_ip == 0) { - r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(0) | R300_RS_COL_FMT(R300_RS_COL_FMT_0001); + r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_ADDR(0); + r300->hw.ri.cmd[R300_RI_INTERP_0] = R300_RS_COL_PTR(0) | R300_RS_COL_FMT(R300_RS_COL_FMT_0001); ++col_ip; } @@ -1564,6 +1556,7 @@ static void r300SetupRSUnit(GLcontext * ctx) r300->hw.rc.cmd[2] |= high_rr - 1; r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, high_rr); + r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_IP_0, high_rr); if (InputsRead) WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); @@ -1572,26 +1565,21 @@ static void r300SetupRSUnit(GLcontext * ctx) static void r500SetupRSUnit(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; union r300_outputs_written OutputsWritten; GLuint InputsRead; int fp_reg, high_rr; int col_ip, tex_ip; int rs_tex_count = 0; - int i, count, col_fmt; + int i, col_fmt, hw_tcl_on; + + hw_tcl_on = r300->options.hw_tcl_enabled; if (hw_tcl_on) - OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; + OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten; else - RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset); + RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); - if (ctx->FragmentProgram._Current) - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - else { - fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); - return; /* This should only ever happen once.. */ - } + InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); @@ -1610,15 +1598,7 @@ static void r500SetupRSUnit(GLcontext * ctx) if (InputsRead & FRAG_BIT_COL0) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) { - count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size; - if (count == 4) - col_fmt = R300_RS_COL_FMT_RGBA; - else if (count == 3) - col_fmt = R300_RS_COL_FMT_RGB1; - else - col_fmt = R300_RS_COL_FMT_0001; - - r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R500_RS_COL_PTR(col_ip) | R500_RS_COL_FMT(col_fmt); + r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R500_RS_COL_PTR(col_ip) | R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); r300->hw.rr.cmd[R300_RR_INST_0 + col_ip] = R500_RS_INST_COL_ID(col_ip) | R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(fp_reg); InputsRead &= ~FRAG_BIT_COL0; ++col_ip; @@ -1630,15 +1610,7 @@ static void r500SetupRSUnit(GLcontext * ctx) if (InputsRead & FRAG_BIT_COL1) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) { - count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size; - if (count == 4) - col_fmt = R300_RS_COL_FMT_RGBA; - else if (count == 3) - col_fmt = R300_RS_COL_FMT_RGB1; - else - col_fmt = R300_RS_COL_FMT_0001; - - r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R500_RS_COL_PTR(col_ip) | R500_RS_COL_FMT(col_fmt); + r300->hw.ri.cmd[R300_RI_INTERP_0 + col_ip] = R500_RS_COL_PTR(col_ip) | R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); r300->hw.rr.cmd[R300_RR_INST_0 + col_ip] = R500_RS_INST_COL_ID(col_ip) | R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(fp_reg); InputsRead &= ~FRAG_BIT_COL1; ++col_ip; @@ -1648,7 +1620,7 @@ static void r500SetupRSUnit(GLcontext * ctx) } } - + /* We always route 4 texcoord components */ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (! ( InputsRead & FRAG_BIT_TEX(i) ) ) continue; @@ -1658,55 +1630,37 @@ static void r500SetupRSUnit(GLcontext * ctx) continue; } - int swiz = 0; - - /* with TCL we always seem to route 4 components */ - if (hw_tcl_on) - count = 4; - else - count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size; - - if (count == 4) { - swiz |= (rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT; - swiz |= (rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT; - swiz |= (rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT; - swiz |= (rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT; - } else if (count == 3) { - swiz |= (rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT; - swiz |= (rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT; - swiz |= (rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT; - swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT; - } else if (count == 2) { - swiz |= (rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT; - swiz |= (rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT; - swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT; - swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT; - } else if (count == 1) { - swiz |= (rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT; - swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT; - swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT; - swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT; - } else { - swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT; - swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT; - swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT; - swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT; - } + r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) | + ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) | + ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) | + ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT); - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= swiz; r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); InputsRead &= ~(FRAG_BIT_TEX0 << i); - rs_tex_count += count; + rs_tex_count += 4; + ++tex_ip; + ++fp_reg; + } + + if (InputsRead & FRAG_BIT_WPOS) { + r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) | + ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) | + ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) | + ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT); + + r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); + InputsRead &= ~FRAG_BIT_WPOS; + rs_tex_count += 4; ++tex_ip; ++fp_reg; } if (InputsRead & FRAG_BIT_FOGC) { if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) | - ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) | - ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) | - ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT); + r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= (rs_tex_count << R500_RS_IP_TEX_PTR_S_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); InputsRead &= ~FRAG_BIT_FOGC; @@ -1718,87 +1672,27 @@ static void r500SetupRSUnit(GLcontext * ctx) } } - if (InputsRead & FRAG_BIT_WPOS) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) | - ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) | - ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) | - ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT); - - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_WPOS; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } - /* Setup default color if no color or tex was set */ if (rs_tex_count == 0 && col_ip == 0) { - r300->hw.rr.cmd[R300_RR_INST_0] |= R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(0) | R500_RS_COL_FMT(R300_RS_COL_FMT_0001); + r300->hw.rr.cmd[R300_RR_INST_0] = R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_ADDR(0); + r300->hw.ri.cmd[R300_RI_INTERP_0] = R500_RS_COL_PTR(0) | R500_RS_COL_FMT(R300_RS_COL_FMT_0001); ++col_ip; } high_rr = (col_ip > tex_ip) ? col_ip : tex_ip; - r300->hw.rc.cmd[1] |= (rs_tex_count << R300_IT_COUNT_SHIFT) | (col_ip << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; - r300->hw.rc.cmd[2] |= 0xC0 | (high_rr - 1); + r300->hw.rc.cmd[1] = (rs_tex_count << R300_IT_COUNT_SHIFT) | (col_ip << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; + r300->hw.rc.cmd[2] = 0xC0 | (high_rr - 1); r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, high_rr); + r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_IP_0, high_rr); if (InputsRead) WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); } - - - -#define bump_vpu_count(ptr, new_count) do{\ - drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\ - int _nc=(new_count)/4; \ - assert(_nc < 256); \ - if(_nc>_p->vpu.count)_p->vpu.count=_nc;\ - }while(0) - -static INLINE void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf) -{ - int i; - - if (vsf->length == 0) - return; - - if (vsf->length & 0x3) { - fprintf(stderr, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n"); - _mesa_exit(-1); - } - - switch ((dest >> 8) & 0xf) { - case 0: - R300_STATECHANGE(r300, vpi); - for (i = 0; i < vsf->length; i++) - r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r300->hw.vpi.cmd, vsf->length + 4 * (dest & 0xff)); - break; - - case 2: - R300_STATECHANGE(r300, vpp); - for (i = 0; i < vsf->length; i++) - r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r300->hw.vpp.cmd, vsf->length + 4 * (dest & 0xff)); - break; - case 4: - R300_STATECHANGE(r300, vps); - for (i = 0; i < vsf->length; i++) - r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r300->hw.vps.cmd, vsf->length + 4 * (dest & 0xff)); - break; - default: - fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest); - _mesa_exit(-1); - } -} - #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c)) - -static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, +void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, GLuint output_count, GLuint temp_count) { int vtx_mem_size; @@ -1822,7 +1716,7 @@ static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, pvs_num_cntrls = MIN2(6, vtx_mem_size/temp_count); R300_STATECHANGE(rmesa, vap_cntl); - if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + if (rmesa->options.hw_tcl_enabled) { rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] = (pvs_num_slots << R300_PVS_NUM_SLOTS_SHIFT) | (pvs_num_cntrls << R300_PVS_NUM_CNTLRS_SHIFT) | @@ -1852,115 +1746,6 @@ static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, } -static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa) -{ - struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader); - GLuint o_reg = 0; - GLuint i_reg = 0; - int i; - int inst_count = 0; - int param_count = 0; - int program_end = 0; - - for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) { - if (rmesa->state.sw_tcl_inputs[i] != -1) { - prog->program.body.i[program_end + 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, GL_FALSE, GL_FALSE, o_reg++, VSF_FLAG_ALL, PVS_DST_REG_OUT); - prog->program.body.i[program_end + 1] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - program_end += 4; - i_reg++; - } - } - - prog->program.length = program_end; - - r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, - &(prog->program)); - inst_count = (prog->program.length / 4) - 1; - - r300VapCntl(rmesa, i_reg, o_reg, 0); - - R300_STATECHANGE(rmesa, pvs); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = - (0 << R300_PVS_FIRST_INST_SHIFT) | - (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | - (inst_count << R300_PVS_LAST_INST_SHIFT); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = - (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | - (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = - (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); -} - -static int bit_count (int x) -{ - x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U); - x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U); - x = (x >> 16) + (x & 0xffff); - x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); - return (x >> 8) + (x & 0x00ff); -} - -static void r300SetupRealVertexProgram(r300ContextPtr rmesa) -{ - GLcontext *ctx = rmesa->radeon.glCtx; - struct r300_vertex_program *prog = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); - int inst_count = 0; - int param_count = 0; - - /* FIXME: r300SetupVertexProgramFragment */ - R300_STATECHANGE(rmesa, vpp); - param_count = - r300VertexProgUpdateParams(ctx, - (struct r300_vertex_program_cont *) - ctx->VertexProgram._Current, - (float *)&rmesa->hw.vpp. - cmd[R300_VPP_PARAM_0]); - bump_vpu_count(rmesa->hw.vpp.cmd, param_count); - param_count /= 4; - - r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, &(prog->program)); - inst_count = (prog->program.length / 4) - 1; - - r300VapCntl(rmesa, bit_count(prog->key.InputsRead), - bit_count(prog->key.OutputsWritten), prog->num_temporaries); - - R300_STATECHANGE(rmesa, pvs); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = - (0 << R300_PVS_FIRST_INST_SHIFT) | - (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | - (inst_count << R300_PVS_LAST_INST_SHIFT); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = - (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | - (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = - (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); -} - - -static void r300SetupVertexProgram(r300ContextPtr rmesa) -{ - GLcontext *ctx = rmesa->radeon.glCtx; - - /* Reset state, in case we don't use something */ - ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0; - ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; - ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; - - /* Not sure why this doesnt work... - 0x400 area might have something to do with pixel shaders as it appears right after pfs programming. - 0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */ - //setup_vertex_shader_fragment(rmesa, 0x406, &unk4); - if (hw_tcl_on && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated) { - r300SetupRealVertexProgram(rmesa); - } else { - /* FIXME: This needs to be replaced by vertex shader generation code. */ - r300SetupDefaultVertexProgram(rmesa); - } - -} - /** * Enable/Disable states. * @@ -1975,14 +1760,6 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) state ? "GL_TRUE" : "GL_FALSE"); switch (cap) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* empty */ - break; - case GL_FOG: - /* empty */ - break; case GL_ALPHA_TEST: r300SetAlphaState(ctx); break; @@ -2000,14 +1777,31 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE5: r300SetClipPlaneState(ctx, cap, state); break; + case GL_CULL_FACE: + r300UpdateCulling(ctx); + break; case GL_DEPTH_TEST: r300SetDepthState(ctx); break; - case GL_STENCIL_TEST: - r300SetStencilState(ctx, state); + case GL_LINE_SMOOTH: + if (rmesa->options.conformance_mode) + r300SwitchFallback(ctx, R300_FALLBACK_LINE_SMOOTH, ctx->Line.SmoothFlag); break; - case GL_CULL_FACE: - r300UpdateCulling(ctx); + case GL_LINE_STIPPLE: + if (rmesa->options.conformance_mode) + r300SwitchFallback(ctx, R300_FALLBACK_LINE_STIPPLE, ctx->Line.StippleFlag); + break; + case GL_POINT_SMOOTH: + if (rmesa->options.conformance_mode) + r300SwitchFallback(ctx, R300_FALLBACK_POINT_SMOOTH, ctx->Point.SmoothFlag); + break; + case GL_POLYGON_SMOOTH: + if (rmesa->options.conformance_mode) + r300SwitchFallback(ctx, R300_FALLBACK_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag); + break; + case GL_POLYGON_STIPPLE: + if (rmesa->options.conformance_mode) + r300SwitchFallback(ctx, R300_FALLBACK_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); break; case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_OFFSET_LINE: @@ -2019,6 +1813,9 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) rmesa->radeon.state.scissor.enabled = state; radeonUpdateScissor( ctx ); break; + case GL_STENCIL_TEST: + r300SetStencilState(ctx, state); + break; default: break; } @@ -2030,10 +1827,9 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) static void r300ResetHwState(r300ContextPtr r300) { GLcontext *ctx = r300->radeon.glCtx; - int has_tcl = 1; + int has_tcl; - if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) - has_tcl = 0; + has_tcl = r300->options.hw_tcl_enabled; if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "%s\n", __FUNCTION__); @@ -2138,8 +1934,8 @@ static void r300ResetHwState(r300ContextPtr r300) } /* XXX: Enable anti-aliasing? */ - r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = GB_AA_CONFIG_AA_DISABLE; - r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0; + r300->hw.gb_misc2.cmd[R300_GB_MISC2_AA_CONFIG] = GB_AA_CONFIG_AA_DISABLE; + r300->hw.gb_misc2.cmd[R300_GB_MISC2_SELECT] = 0; r300->hw.ga_point_s0.cmd[1] = r300PackFloat32(0.0); r300->hw.ga_point_s0.cmd[2] = r300PackFloat32(0.0); @@ -2210,8 +2006,8 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.rb3d_aaresolve_ctl.cmd[1] = 0; - r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; - r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; r300->hw.zb_depthclearvalue.cmd[1] = 0; @@ -2220,8 +2016,8 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.zstencil_format.cmd[4] = 0x00000000; r300SetEarlyZState(ctx); - r300->hw.unk4F30.cmd[1] = 0; - r300->hw.unk4F30.cmd[2] = 0; + r300->hw.zb_zmask.cmd[1] = 0; + r300->hw.zb_zmask.cmd[2] = 0; r300->hw.zb_hiz_offset.cmd[1] = 0; @@ -2241,14 +2037,20 @@ static void r300ResetHwState(r300ContextPtr r300) void r300UpdateShaders(r300ContextPtr rmesa) { GLcontext *ctx; - struct r300_vertex_program *vp; + struct r300_fragment_program *fp; int i; ctx = rmesa->radeon.glCtx; + fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - if (rmesa->radeon.NewGLState && hw_tcl_on) { - rmesa->radeon.NewGLState = 0; + /* should only happenen once, just after context is created */ + /* TODO: shouldn't we fallback to sw here? */ + if (!fp) { + _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); + return; + } + if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) { for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i]; @@ -2264,20 +2066,16 @@ void r300UpdateShaders(r300ContextPtr rmesa) } r300SelectVertexShader(rmesa); - vp = (struct r300_vertex_program *) - CURRENT_VERTEX_SHADER(ctx); - /*if (vp->translated == GL_FALSE) - r300TranslateVertexShader(vp); */ - if (vp->translated == GL_FALSE) { - fprintf(stderr, "Failing back to sw-tcl\n"); - hw_tcl_on = future_hw_tcl_on = 0; - r300ResetHwState(rmesa); - - r300UpdateStateParameters(ctx, _NEW_PROGRAM); - return; - } + r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error); } - r300UpdateStateParameters(ctx, _NEW_PROGRAM); + + if (!fp->translated || rmesa->radeon.NewGLState) + r300TranslateFragmentShader(ctx, ctx->FragmentProgram._Current); + + r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error); + + r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + rmesa->radeon.NewGLState = 0; } static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, @@ -2301,26 +2099,14 @@ static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, } -static void r300SetupPixelShader(r300ContextPtr rmesa) +static void r300SetupPixelShader(GLcontext *ctx) { - GLcontext *ctx = rmesa->radeon.glCtx; - struct r300_fragment_program *fp = (struct r300_fragment_program *) - (char *)ctx->FragmentProgram._Current; + r300ContextPtr rmesa = R300_CONTEXT(ctx); + struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; struct r300_fragment_program_code *code; int i, k; - if (!fp) /* should only happenen once, just after context is created */ - return; - - r300TranslateFragmentShader(rmesa, fp); - if (!fp->translated) { - fprintf(stderr, "%s: No valid fragment shader, exiting\n", - __FUNCTION__); - return; - } - code = &fp->code; - - r300SetupTextures(ctx); + code = &fp->code.r300; R300_STATECHANGE(rmesa, fpi[0]); R300_STATECHANGE(rmesa, fpi[1]); @@ -2363,7 +2149,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4); for (i = 0; i < code->const_nr; i++) { const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->mesa_program.Base, code->constant[i]); + &fp->Base.Base, code->constant[i]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(constant[0]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(constant[1]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]); @@ -2385,29 +2171,17 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\ } while(0) -static void r500SetupPixelShader(r300ContextPtr rmesa) +static void r500SetupPixelShader(GLcontext *ctx) { - GLcontext *ctx = rmesa->radeon.glCtx; - struct r500_fragment_program *fp = (struct r500_fragment_program *) - (char *)ctx->FragmentProgram._Current; + r300ContextPtr rmesa = R300_CONTEXT(ctx); + struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; int i; struct r500_fragment_program_code *code; - if (!fp) /* should only happenen once, just after context is created */ - return; - ((drm_r300_cmd_header_t *) rmesa->hw.r500fp.cmd)->r500fp.count = 0; ((drm_r300_cmd_header_t *) rmesa->hw.r500fp_const.cmd)->r500fp.count = 0; - r500TranslateFragmentShader(rmesa, fp); - if (!fp->translated) { - fprintf(stderr, "%s: No valid fragment shader, exiting\n", - __FUNCTION__); - return; - } - code = &fp->code; - - r300SetupTextures(ctx); + code = &fp->code.r500; R300_STATECHANGE(rmesa, fp); rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = code->max_temp_idx; @@ -2437,57 +2211,96 @@ static void r500SetupPixelShader(r300ContextPtr rmesa) R300_STATECHANGE(rmesa, r500fp_const); for (i = 0; i < code->const_nr; i++) { const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->mesa_program.Base, code->constant[i]); + &fp->Base.Base, code->constant[i]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(constant[0]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(constant[1]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(constant[2]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat32(constant[3]); } bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, code->const_nr * 4); +} + +void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten) +{ + r300ContextPtr rmesa = R300_CONTEXT( ctx ); + struct vertex_attribute *attrs = rmesa->vbuf.attribs; + int i, j, reg_count; + uint32_t *vir0 = &rmesa->hw.vir[0].cmd[1]; + uint32_t *vir1 = &rmesa->hw.vir[1].cmd[1]; + + for (i = 0; i < R300_VIR_CMDSIZE-1; ++i) + vir0[i] = vir1[i] = 0; + + for (i = 0, j = 0; i < rmesa->vbuf.num_attribs; ++i) { + int tmp; + + tmp = attrs[i].data_type | (attrs[i].dst_loc << R300_DST_VEC_LOC_SHIFT); + if (attrs[i]._signed) + tmp |= R300_SIGNED; + if (attrs[i].normalize) + tmp |= R300_NORMALIZE; + + if (i % 2 == 0) { + vir0[j] = tmp << R300_DATA_TYPE_0_SHIFT; + vir1[j] = attrs[i].swizzle | (attrs[i].write_mask << R300_WRITE_ENA_SHIFT); + } else { + vir0[j] |= tmp << R300_DATA_TYPE_1_SHIFT; + vir1[j] |= (attrs[i].swizzle | (attrs[i].write_mask << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE1_SHIFT; + ++j; + } + } + reg_count = (rmesa->vbuf.num_attribs + 1) >> 1; + if (rmesa->vbuf.num_attribs % 2 != 0) { + vir0[reg_count-1] |= R300_LAST_VEC << R300_DATA_TYPE_0_SHIFT; + } else { + vir0[reg_count-1] |= R300_LAST_VEC << R300_DATA_TYPE_1_SHIFT; + } + + R300_STATECHANGE(rmesa, vir[0]); + R300_STATECHANGE(rmesa, vir[1]); + R300_STATECHANGE(rmesa, vof); + R300_STATECHANGE(rmesa, vic); + + if (rmesa->radeon.radeonScreen->kernel_mm) { + rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; + rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; + rmesa->hw.vir[0].cmd[0] |= (reg_count & 0x3FFF) << 16; + rmesa->hw.vir[1].cmd[0] |= (reg_count & 0x3FFF) << 16; + } else { + ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = reg_count; + ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = reg_count; + } + + rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); + rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); + rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead); } void r300UpdateShaderStates(r300ContextPtr rmesa) { GLcontext *ctx; ctx = rmesa->radeon.glCtx; + struct r300_fragment_program *r300_fp; - r300SetEarlyZState(ctx); + r300_fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - /* w_fmt value is set to get best performance - * see p.130 R5xx 3D acceleration guide v1.3 */ - GLuint w_fmt, fgdepthsrc; - if (current_fragment_program_writes_depth(ctx)) { - fgdepthsrc = R300_FG_DEPTH_SRC_SHADER; - w_fmt = R300_W_FMT_W24 | R300_W_SRC_US; - } else { - fgdepthsrc = R300_FG_DEPTH_SRC_SCAN; - w_fmt = R300_W_FMT_W0 | R300_W_SRC_US; - } + /* should only happenen once, just after context is created */ + if (!r300_fp) + return; - if (w_fmt != rmesa->hw.us_out_fmt.cmd[5]) { - R300_STATECHANGE(rmesa, us_out_fmt); - rmesa->hw.us_out_fmt.cmd[5] = w_fmt; - } + r300SetEarlyZState(ctx); - if (fgdepthsrc != rmesa->hw.fg_depth_src.cmd[1]) { - R300_STATECHANGE(rmesa, fg_depth_src); - rmesa->hw.fg_depth_src.cmd[1] = fgdepthsrc; - } + r300SetupTextures(ctx); - if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) - r500SetupPixelShader(rmesa); - else - r300SetupPixelShader(rmesa); + rmesa->vtbl.SetupPixelShader(ctx); - if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) - r500SetupRSUnit(ctx); - else - r300SetupRSUnit(ctx); + rmesa->vtbl.SetupRSUnit(ctx); - if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + if (rmesa->options.hw_tcl_enabled) { r300SetupVertexProgram(rmesa); - + } } /** @@ -2501,9 +2314,8 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _swsetup_InvalidateState(ctx, new_state); _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); - _ae_invalidate_state(ctx, new_state); - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { _mesa_update_framebuffer(ctx); /* this updates the DrawBuffer's Width/Height if it's a FBO */ _mesa_update_draw_buffer_bounds(ctx); @@ -2523,34 +2335,12 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) */ void r300InitState(r300ContextPtr r300) { - memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); - r300ResetHwState(r300); } static void r300RenderMode(GLcontext * ctx, GLenum mode) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); - (void)rmesa; - (void)mode; -} - -void r300UpdateClipPlanes( GLcontext *ctx ) -{ - r300ContextPtr rmesa = R300_CONTEXT(ctx); - GLuint p; - - for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { - if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { - GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; - - R300_STATECHANGE( rmesa, vpucp[p] ); - rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0]; - rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1]; - rmesa->hw.vpucp[p].cmd[R300_VPUCP_Z] = ip[2]; - rmesa->hw.vpucp[p].cmd[R300_VPUCP_W] = ip[3]; - } - } + r300SwitchFallback(ctx, R300_FALLBACK_RENDER_MODE, ctx->RenderMode != GL_RENDER); } /** @@ -2598,3 +2388,20 @@ void r300InitStateFuncs(struct dd_function_table *functions) functions->DrawBuffer = radeonDrawBuffer; functions->ReadBuffer = radeonReadBuffer; } + +void r300InitShaderFunctions(r300ContextPtr r300) +{ + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + r300->vtbl.SetupRSUnit = r500SetupRSUnit; + r300->vtbl.SetupPixelShader = r500SetupPixelShader; + r300->vtbl.SetupFragmentShaderTextures = r500SetupFragmentShaderTextures; + r300->vtbl.BuildFragmentProgramHwCode = r500BuildFragmentProgramHwCode; + r300->vtbl.FragmentProgramDump = r500FragmentProgramDump; + } else { + r300->vtbl.SetupRSUnit = r300SetupRSUnit; + r300->vtbl.SetupPixelShader = r300SetupPixelShader; + r300->vtbl.SetupFragmentShaderTextures = r300SetupFragmentShaderTextures; + r300->vtbl.BuildFragmentProgramHwCode = r300BuildFragmentProgramHwCode; + r300->vtbl.FragmentProgramDump = r300FragmentProgramDump; + } +} diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h index 247a20ee51..2328289420 100644 --- a/src/mesa/drivers/dri/r300/r300_state.h +++ b/src/mesa/drivers/dri/r300/r300_state.h @@ -50,16 +50,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. r300->radeon.hw.is_dirty = GL_TRUE; \ } while(0) -// r300_state.c -extern int future_hw_tcl_on; -void _tnl_UpdateFixedFunctionProgram (GLcontext * ctx); void r300UpdateViewportOffset (GLcontext * ctx); void r300UpdateDrawBuffer (GLcontext * ctx); void r300UpdateStateParameters (GLcontext * ctx, GLuint new_state); void r300UpdateShaders (r300ContextPtr rmesa); void r300UpdateShaderStates (r300ContextPtr rmesa); void r300InitState (r300ContextPtr r300); -void r300UpdateClipPlanes (GLcontext * ctx); void r300InitStateFuncs (struct dd_function_table *functions); +void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, GLuint output_count, GLuint temp_count); +void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten); #endif /* __R300_STATE_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index 03c1521de7..ce4179208e 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -34,9 +34,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" +#include "r300_state.h" #include "r300_swtcl.h" #include "r300_emit.h" #include "r300_tex.h" +#include "r300_render.h" #define EMIT_ATTR( ATTR, STYLE ) \ do { \ @@ -53,199 +55,130 @@ do { \ rmesa->radeon.swtcl.vertex_attr_count++; \ } while (0) -#define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask) \ +#define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask, _normalize) \ do { \ - attrs[num_attrs].attr = (_attr); \ - attrs[num_attrs].format = (_format); \ + attrs[num_attrs].element = (_attr); \ + attrs[num_attrs].data_type = (_format); \ attrs[num_attrs].dst_loc = (_dst_loc); \ attrs[num_attrs].swizzle = (_swizzle); \ attrs[num_attrs].write_mask = (_write_mask); \ + attrs[num_attrs]._signed = 0; \ + attrs[num_attrs].normalize = (_normalize); \ ++num_attrs; \ } while (0) -static void r300SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten, GLuint vap_out_fmt_1) +void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_OutputsWritten) { r300ContextPtr rmesa = R300_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - struct vertex_attribute *attrs = rmesa->swtcl.vert_attrs; - int vte = 0; - int i, j, reg_count; - uint32_t *vir0 = &rmesa->hw.vir[0].cmd[1]; - uint32_t *vir1 = &rmesa->hw.vir[1].cmd[1]; - - for (i = 0; i < R300_VIR_CMDSIZE-1; ++i) - vir0[i] = vir1[i] = 0; - - for (i = 0, j = 0; i < rmesa->radeon.swtcl.vertex_attr_count; ++i) { - int tmp, data_format; - switch (attrs[i].format) { - case EMIT_1F: - data_format = R300_DATA_TYPE_FLOAT_1; - break; - case EMIT_2F: - data_format = R300_DATA_TYPE_FLOAT_2; - break; - case EMIT_3F: - data_format = R300_DATA_TYPE_FLOAT_3; - break; - case EMIT_4F: - data_format = R300_DATA_TYPE_FLOAT_4; - break; - case EMIT_4UB_4F_RGBA: - case EMIT_4UB_4F_ABGR: - data_format = R300_DATA_TYPE_BYTE | R300_NORMALIZE; - break; - default: - fprintf(stderr, "%s: Invalid data format type", __FUNCTION__); - _mesa_exit(-1); - break; - } - - tmp = data_format | (attrs[i].dst_loc << R300_DST_VEC_LOC_SHIFT); - if (i % 2 == 0) { - vir0[j] = tmp << R300_DATA_TYPE_0_SHIFT; - vir1[j] = attrs[i].swizzle | (attrs[i].write_mask << R300_WRITE_ENA_SHIFT); - } else { - vir0[j] |= tmp << R300_DATA_TYPE_1_SHIFT; - vir1[j] |= (attrs[i].swizzle | (attrs[i].write_mask << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE1_SHIFT; - ++j; - } - } - - reg_count = (rmesa->radeon.swtcl.vertex_attr_count + 1) >> 1; - if (rmesa->radeon.swtcl.vertex_attr_count % 2 != 0) { - vir0[reg_count-1] |= R300_LAST_VEC << R300_DATA_TYPE_0_SHIFT; - } else { - vir0[reg_count-1] |= R300_LAST_VEC << R300_DATA_TYPE_1_SHIFT; - } - - R300_STATECHANGE(rmesa, vir[0]); - R300_STATECHANGE(rmesa, vir[1]); - R300_STATECHANGE(rmesa, vof); - R300_STATECHANGE(rmesa, vte); - R300_STATECHANGE(rmesa, vic); - - if (rmesa->radeon.radeonScreen->kernel_mm) { - rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; - rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; - rmesa->hw.vir[0].cmd[0] |= (reg_count & 0x3FFF) << 16; - rmesa->hw.vir[1].cmd[0] |= (reg_count & 0x3FFF) << 16; - } else { - ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = reg_count; - ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = reg_count; - } - - rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); - rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten); - /** - * Can't use r300VAPOutputCntl1 function because it assumes - * that all texture coords have 4 components and that's the case - * for HW TCL path, but not for SW TCL. - */ - rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_out_fmt_1; - - vte = rmesa->hw.vte.cmd[1]; - vte &= ~(R300_VTX_XY_FMT | R300_VTX_Z_FMT | R300_VTX_W0_FMT); - /* Important: - */ - if ( VB->NdcPtr != NULL ) { - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - vte |= R300_VTX_XY_FMT | R300_VTX_Z_FMT; - } - else { - VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr; - vte |= R300_VTX_W0_FMT; - } - - assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); - - rmesa->hw.vte.cmd[1] = vte; - rmesa->hw.vte.cmd[2] = rmesa->radeon.swtcl.vertex_size; -} - - -static void r300SetVertexFormat( GLcontext *ctx ) -{ - r300ContextPtr rmesa = R300_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - int first_free_tex = 0, vap_out_fmt_1 = 0; + int first_free_tex = 0; GLuint InputsRead = 0; GLuint OutputsWritten = 0; int num_attrs = 0; - struct vertex_attribute *attrs = rmesa->swtcl.vert_attrs; + GLuint fp_reads = ctx->FragmentProgram._Current->Base.InputsRead; + struct vertex_attribute *attrs = rmesa->vbuf.attribs; rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0; rmesa->radeon.swtcl.vertex_attr_count = 0; - if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS)) { - InputsRead |= 1 << VERT_ATTRIB_POS; - OutputsWritten |= 1 << VERT_RESULT_HPOS; - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); - ADD_ATTR(VERT_ATTRIB_POS, EMIT_4F, SWTCL_OVM_POS, SWIZZLE_XYZW, MASK_XYZW); - rmesa->swtcl.coloroffset = 4; - } + /* We always want non Ndc coords format */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr; + + /* Always write position vector */ + InputsRead |= 1 << VERT_ATTRIB_POS; + OutputsWritten |= 1 << VERT_RESULT_HPOS; + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); + ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_POS, SWIZZLE_XYZW, MASK_XYZW, 0); + rmesa->swtcl.coloroffset = 4; - if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0)) { + if (fp_reads & FRAG_BIT_COL0) { InputsRead |= 1 << VERT_ATTRIB_COLOR0; OutputsWritten |= 1 << VERT_RESULT_COL0; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA ); - ADD_ATTR(VERT_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW); + ADD_ATTR(VERT_ATTRIB_COLOR0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW, 1); #else EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR ); - ADD_ATTR(VERT_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW); + ADD_ATTR(VERT_ATTRIB_COLOR0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW, 1); #endif } - if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 )) { + if (fp_reads & FRAG_BIT_COL1) { GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); InputsRead |= 1 << VERT_ATTRIB_COLOR1; OutputsWritten |= 1 << VERT_RESULT_COL1; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA ); - ADD_ATTR(VERT_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR1, swiz, MASK_XYZW); + ADD_ATTR(VERT_ATTRIB_COLOR1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR1, swiz, MASK_XYZW, 1); #else EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR ); - ADD_ATTR(VERT_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR1, swiz, MASK_XYZW); + ADD_ATTR(VERT_ATTRIB_COLOR1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR1, swiz, MASK_XYZW, 1); #endif rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1; } + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { + VB->AttribPtr[VERT_ATTRIB_GENERIC0] = VB->ColorPtr[1]; + OutputsWritten |= 1 << VERT_RESULT_BFC0; +#if MESA_LITTLE_ENDIAN + EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_RGBA ); + ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1); +#else + EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_ABGR ); + ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1); +#endif + if (fp_reads & FRAG_BIT_COL1) { + VB->AttribPtr[VERT_ATTRIB_GENERIC1] = VB->SecondaryColorPtr[1]; + GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); + OutputsWritten |= 1 << VERT_RESULT_BFC1; +#if MESA_LITTLE_ENDIAN + EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_RGBA ); + ADD_ATTR(VERT_ATTRIB_GENERIC1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR3, swiz, MASK_XYZW, 1); +#else + EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_ABGR ); + ADD_ATTR(VERT_ATTRIB_GENERIC1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR3, swiz, MASK_XYZW, 1); +#endif + } + } + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE )) { GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO); InputsRead |= 1 << VERT_ATTRIB_POINT_SIZE; OutputsWritten |= 1 << VERT_RESULT_PSIZ; EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F ); - ADD_ATTR(VERT_ATTRIB_POINT_SIZE, EMIT_1F, SWTCL_OVM_POINT_SIZE, swiz, MASK_X); + ADD_ATTR(VERT_ATTRIB_POINT_SIZE, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_POINT_SIZE, swiz, MASK_X, 0); } - if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { - int i, size; - GLuint swiz, mask, format; + /** + * Sending only one texcoord component may lead to lock up, + * so for all textures always output 4 texcoord components to RS. + */ + { + int i; + GLuint swiz, format, hw_format; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) { + if (fp_reads & FRAG_BIT_TEX(i)) { switch (VB->TexCoordPtr[i]->size) { case 1: + format = EMIT_1F; + hw_format = R300_DATA_TYPE_FLOAT_1; + swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE); + break; case 2: format = EMIT_2F; - swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO); - mask = MASK_X | MASK_Y; - size = 2; + hw_format = R300_DATA_TYPE_FLOAT_2; + swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE); break; case 3: format = EMIT_3F; - swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - mask = MASK_X | MASK_Y | MASK_Z; - size = 3; + hw_format = R300_DATA_TYPE_FLOAT_3; + swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); break; case 4: format = EMIT_4F; + hw_format = R300_DATA_TYPE_FLOAT_4; swiz = SWIZZLE_XYZW; - mask = MASK_XYZW; - size = 4; break; default: continue; @@ -253,15 +186,14 @@ static void r300SetVertexFormat( GLcontext *ctx ) InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i); OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); EMIT_ATTR(_TNL_ATTRIB_TEX(i), format); - ADD_ATTR(VERT_ATTRIB_TEX0 + i, format, SWTCL_OVM_TEX(i), swiz, mask); - vap_out_fmt_1 |= size << (i * 3); + ADD_ATTR(VERT_ATTRIB_TEX0 + i, hw_format, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0); ++first_free_tex; } } } /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */ - if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS) && (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) { + if (fp_reads & FRAG_BIT_WPOS) { if (first_free_tex >= ctx->Const.MaxTextureUnits) { fprintf(stderr, "\tout of free texcoords to write w pos\n"); _mesa_exit(-1); @@ -270,12 +202,11 @@ static void r300SetVertexFormat( GLcontext *ctx ) InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex); OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex); EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); - ADD_ATTR(VERT_ATTRIB_POS, EMIT_4F, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW); - vap_out_fmt_1 |= 4 << (first_free_tex * 3); + ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW, 0); ++first_free_tex; } - if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_FOG)) { + if (fp_reads & FRAG_BIT_FOGC) { if (first_free_tex >= ctx->Const.MaxTextureUnits) { fprintf(stderr, "\tout of free texcoords to write fog coordinate\n"); _mesa_exit(-1); @@ -285,12 +216,24 @@ static void r300SetVertexFormat( GLcontext *ctx ) OutputsWritten |= 1 << VERT_RESULT_FOGC; GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO); EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F ); - ADD_ATTR(VERT_ATTRIB_FOG, EMIT_1F, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_X); - vap_out_fmt_1 |= 1 << (first_free_tex * 3); + ADD_ATTR(VERT_ATTRIB_FOG, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0); } R300_NEWPRIM(rmesa); - r300SwtclVAPSetup(ctx, InputsRead, OutputsWritten, vap_out_fmt_1); + rmesa->vbuf.num_attribs = num_attrs; + *_InputsRead = InputsRead; + *_OutputsWritten = OutputsWritten; + + RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset); +} + +static void r300PrepareVertices(GLcontext *ctx) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLuint InputsRead, OutputsWritten; + + r300ChooseSwtclVertexFormat(ctx, &InputsRead, &OutputsWritten); + r300SetupVAP(ctx, InputsRead, OutputsWritten); rmesa->radeon.swtcl.vertex_size = _tnl_install_attrs( ctx, @@ -299,8 +242,6 @@ static void r300SetVertexFormat( GLcontext *ctx ) NULL, 0 ); rmesa->radeon.swtcl.vertex_size /= 4; - - RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, tnl->render_inputs_bitset); } @@ -318,7 +259,6 @@ static GLuint reduced_prim[] = { }; static void r300RasterPrimitive( GLcontext *ctx, GLuint prim ); -static void r300RenderPrimitive( GLcontext *ctx, GLenum prim ); /*********************************************************************** * Emit primitives as inline vertices * @@ -366,9 +306,8 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim ); * Build render functions from dd templates * ***********************************************************************/ -#define R300_TWOSIDE_BIT 0x01 -#define R300_UNFILLED_BIT 0x02 -#define R300_MAX_TRIFUNC 0x04 +#define R300_UNFILLED_BIT 0x01 +#define R300_MAX_TRIFUNC 0x02 static struct { tnl_points_func points; @@ -379,9 +318,9 @@ static struct { #define DO_FALLBACK 0 #define DO_UNFILLED (IND & R300_UNFILLED_BIT) -#define DO_TWOSIDE (IND & R300_TWOSIDE_BIT) +#define DO_TWOSIDE 0 #define DO_FLAT 0 -#define DO_OFFSET 0 +#define DO_OFFSET 0 #define DO_TRI 1 #define DO_QUAD 1 #define DO_LINE 1 @@ -469,26 +408,15 @@ do { \ #define TAG(x) x #include "tnl_dd/t_dd_tritmp.h" -#define IND (R300_TWOSIDE_BIT) -#define TAG(x) x##_twoside -#include "tnl_dd/t_dd_tritmp.h" - #define IND (R300_UNFILLED_BIT) #define TAG(x) x##_unfilled #include "tnl_dd/t_dd_tritmp.h" -#define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT) -#define TAG(x) x##_twoside_unfilled -#include "tnl_dd/t_dd_tritmp.h" - - static void init_rast_tab( void ) { init(); - init_twoside(); init_unfilled(); - init_twoside_unfilled(); } /**********************************************************************/ @@ -540,7 +468,6 @@ static void r300ChooseRenderState( GLcontext *ctx ) GLuint index = 0; GLuint flags = ctx->_TriangleCaps; - if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT; if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT; if (index != rmesa->radeon.swtcl.RenderIndex) { @@ -565,12 +492,12 @@ static void r300ChooseRenderState( GLcontext *ctx ) } -static void r300RenderStart(GLcontext *ctx) +void r300RenderStart(GLcontext *ctx) { r300ContextPtr rmesa = R300_CONTEXT( ctx ); r300ChooseRenderState(ctx); - r300SetVertexFormat(ctx); + r300PrepareVertices(ctx); r300ValidateBuffers(ctx); @@ -585,7 +512,7 @@ static void r300RenderStart(GLcontext *ctx) } } -static void r300RenderFinish(GLcontext *ctx) +void r300RenderFinish(GLcontext *ctx) { } @@ -599,7 +526,7 @@ static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim ) } } -static void r300RenderPrimitive(GLcontext *ctx, GLenum prim) +void r300RenderPrimitive(GLcontext *ctx, GLenum prim) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -611,7 +538,7 @@ static void r300RenderPrimitive(GLcontext *ctx, GLenum prim) r300RasterPrimitive( ctx, reduced_prim[prim] ); } -static void r300ResetLineStipple(GLcontext *ctx) +void r300ResetLineStipple(GLcontext *ctx) { } @@ -647,7 +574,6 @@ void r300InitSwtcl(GLcontext *ctx) _tnl_invalidate_vertices( ctx, ~0 ); _tnl_need_projected_coords( ctx, GL_FALSE ); - r300ChooseRenderState(ctx); } void r300DestroySwtcl(GLcontext *ctx) @@ -692,6 +618,7 @@ void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset) rmesa->radeon.hw.max_state_size + (12*sizeof(int)), __FUNCTION__); radeonEmitState(&rmesa->radeon); + r300_emit_scissor(ctx); r300EmitVertexAOS(rmesa, rmesa->radeon.swtcl.vertex_size, rmesa->radeon.dma.current, diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.h b/src/mesa/drivers/dri/r300/r300_swtcl.h index ebc99c9e8a..c271d26546 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.h +++ b/src/mesa/drivers/dri/r300/r300_swtcl.h @@ -39,24 +39,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "r300_context.h" -#define MASK_XYZW (R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W) -#define MASK_X R300_WRITE_ENA_X -#define MASK_Y R300_WRITE_ENA_Y -#define MASK_Z R300_WRITE_ENA_Z -#define MASK_W R300_WRITE_ENA_W - /* * Here are definitions of OVM locations of vertex attributes for non TCL hw */ #define SWTCL_OVM_POS 0 #define SWTCL_OVM_COLOR0 2 #define SWTCL_OVM_COLOR1 3 +#define SWTCL_OVM_COLOR2 4 +#define SWTCL_OVM_COLOR3 5 #define SWTCL_OVM_TEX(n) ((n) + 6) #define SWTCL_OVM_POINT_SIZE 15 +extern void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *InputsRead, GLuint *OutputsWritten); extern void r300InitSwtcl( GLcontext *ctx ); extern void r300DestroySwtcl( GLcontext *ctx ); +extern void r300RenderStart(GLcontext *ctx); +extern void r300RenderFinish(GLcontext *ctx); +extern void r300RenderPrimitive(GLcontext *ctx, GLenum prim); +extern void r300ResetLineStipple(GLcontext *ctx); + extern void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset); + #endif diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index cf4cad73d2..6d6a90aa88 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -117,6 +117,7 @@ static const struct tx_table { _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)), _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)), _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)), + _ASSIGN(S8_Z24, R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8)), _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)), /* *INDENT-ON* */ }; @@ -431,7 +432,6 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo radeon_miptree_unreference(rImage->mt); rImage->mt = NULL; } - fprintf(stderr,"settexbuf %dx%d@%d %d targ %x format %x\n", rb->width, rb->height, rb->cpp, rb->pitch, target, format); _mesa_init_teximage_fields(radeon->glCtx, target, texImage, rb->width, rb->height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; @@ -449,7 +449,10 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo pitch_val = rb->pitch; switch (rb->cpp) { case 4: - t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); + if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); + else + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); t->pp_txfilter |= tx_table[2].filter; pitch_val /= 4; break; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 50806575ce..c41a8fdd62 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -34,10 +34,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" +#include "shader/prog_print.h" #include "shader/prog_statevars.h" #include "tnl/tnl.h" #include "r300_context.h" +#include "r300_state.h" /* TODO: Get rid of t_src_class call */ #define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \ @@ -64,7 +66,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. int u_temp_used = (VSF_MAX_FRAGMENT_TEMPS - 1) - u_temp_i; \ if((vp->num_temporaries + u_temp_used) > VSF_MAX_FRAGMENT_TEMPS) { \ WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_used); \ - vp->native = GL_FALSE; \ + vp->error = GL_TRUE; \ } \ u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \ } while (0) @@ -214,21 +216,8 @@ static void vp_dump_inputs(struct r300_vertex_program *vp, char *caller) static unsigned long t_src_index(struct r300_vertex_program *vp, struct prog_src_register *src) { - int i; - int max_reg = -1; - if (src->File == PROGRAM_INPUT) { - if (vp->inputs[src->Index] != -1) - return vp->inputs[src->Index]; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) - if (vp->inputs[i] > max_reg) - max_reg = vp->inputs[i]; - - vp->inputs[src->Index] = max_reg + 1; - - //vp_dump_inputs(vp, __FUNCTION__); - + assert(vp->inputs[src->Index] != -1); return vp->inputs[src->Index]; } else { if (src->Index < 0) { @@ -245,7 +234,7 @@ static unsigned long t_src_index(struct r300_vertex_program *vp, static unsigned long t_src(struct r300_vertex_program *vp, struct prog_src_register *src) { - /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, + /* src->Negate uses the NEGATE_ flags from program_instruction.h, * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. */ return PVS_SRC_OPERAND(t_src_index(vp, src), @@ -254,13 +243,13 @@ static unsigned long t_src(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src->Swizzle, 2)), t_swizzle(GET_SWZ(src->Swizzle, 3)), t_src_class(src->File), - src->NegateBase) | (src->RelAddr << 4); + src->Negate) | (src->RelAddr << 4); } static unsigned long t_src_scalar(struct r300_vertex_program *vp, struct prog_src_register *src) { - /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, + /* src->Negate uses the NEGATE_ flags from program_instruction.h, * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. */ return PVS_SRC_OPERAND(t_src_index(vp, src), @@ -269,8 +258,7 @@ static unsigned long t_src_scalar(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src->Swizzle, 0)), t_swizzle(GET_SWZ(src->Swizzle, 0)), t_src_class(src->File), - src-> - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src->RelAddr << 4); } @@ -307,7 +295,7 @@ static GLuint *r300TranslateOpcodeABS(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 3)), t_src_class(src[0].File), (!src[0]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[3] = 0; @@ -369,8 +357,7 @@ static GLuint *r300TranslateOpcodeDP3(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 2)), SWIZZLE_ZERO, t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), @@ -378,8 +365,7 @@ static GLuint *r300TranslateOpcodeDP3(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 1)), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), SWIZZLE_ZERO, t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + src[1].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[3] = __CONST(1, SWIZZLE_ZERO); @@ -422,8 +408,7 @@ static GLuint *r300TranslateOpcodeDPH(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 2)), PVS_SRC_SELECT_FORCE_1, t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = t_src(vp, &src[1]); inst[3] = __CONST(1, SWIZZLE_ZERO); @@ -519,7 +504,7 @@ static GLuint *r300TranslateOpcodeFLR(struct r300_vertex_program *vp, PVS_SRC_SELECT_W, PVS_SRC_REG_TEMPORARY, /* Not 100% sure about this */ (!src[0]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE /*VSF_FLAG_ALL */ ); inst[3] = __CONST(0, SWIZZLE_ZERO); (*u_temp_i)--; @@ -564,8 +549,7 @@ static GLuint *r300TranslateOpcodeLG2(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 0)), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = __CONST(0, SWIZZLE_ZERO); inst[3] = __CONST(0, SWIZZLE_ZERO); @@ -592,24 +576,21 @@ static GLuint *r300TranslateOpcodeLIT(struct r300_vertex_program *vp, PVS_SRC_SELECT_FORCE_0, // Z t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W PVS_SRC_SELECT_FORCE_0, // Z t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X PVS_SRC_SELECT_FORCE_0, // Z t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); return inst; @@ -837,7 +818,7 @@ static GLuint *r300TranslateOpcodeSUB(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 3)), t_src_class(src[1].File), (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[3] = 0; #else @@ -857,7 +838,7 @@ static GLuint *r300TranslateOpcodeSUB(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 3)), t_src_class(src[1].File), (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); #endif @@ -905,16 +886,14 @@ static GLuint *r300TranslateOpcodeXPD(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // Z t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // X t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[1].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[3] = __CONST(1, SWIZZLE_ZERO); inst += 4; @@ -931,15 +910,14 @@ static GLuint *r300TranslateOpcodeXPD(struct r300_vertex_program *vp, t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W t_src_class(src[1].File), (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // Z t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); inst[3] = PVS_SRC_OPERAND(*u_temp_i, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, @@ -954,11 +932,17 @@ static GLuint *r300TranslateOpcodeXPD(struct r300_vertex_program *vp, static void t_inputs_outputs(struct r300_vertex_program *vp) { int i; - int cur_reg = 0; + int cur_reg; - for (i = 0; i < VERT_ATTRIB_MAX; i++) - vp->inputs[i] = -1; + cur_reg = -1; + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (vp->key.InputsRead & (1 << i)) + vp->inputs[i] = ++cur_reg; + else + vp->inputs[i] = -1; + } + cur_reg = 0; for (i = 0; i < VERT_RESULT_MAX; i++) vp->outputs[i] = -1; @@ -972,26 +956,36 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) vp->outputs[VERT_RESULT_PSIZ] = cur_reg++; } + /* If we're writing back facing colors we need to send + * four colors to make front/back face colors selection work. + * If the vertex program doesn't write all 4 colors, lets + * pretend it does by skipping output index reg so the colors + * get written into appropriate output vectors. + */ if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) { vp->outputs[VERT_RESULT_COL0] = cur_reg++; + } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) || + vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + cur_reg++; } if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) { - vp->outputs[VERT_RESULT_COL1] = - vp->outputs[VERT_RESULT_COL0] + 1; - cur_reg = vp->outputs[VERT_RESULT_COL1] + 1; + vp->outputs[VERT_RESULT_COL1] = cur_reg++; + } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) || + vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + cur_reg++; } if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { - vp->outputs[VERT_RESULT_BFC0] = - vp->outputs[VERT_RESULT_COL0] + 2; - cur_reg = vp->outputs[VERT_RESULT_BFC0] + 2; + vp->outputs[VERT_RESULT_BFC0] = cur_reg++; + } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + cur_reg++; } if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { - vp->outputs[VERT_RESULT_BFC1] = - vp->outputs[VERT_RESULT_COL0] + 3; - cur_reg = vp->outputs[VERT_RESULT_BFC1] + 1; + vp->outputs[VERT_RESULT_BFC1] = cur_reg++; + } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { + cur_reg++; } for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) { @@ -1018,14 +1012,13 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp, struct prog_src_register src[3]; vp->pos_end = 0; /* Not supported yet */ - vp->program.length = 0; - /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */ + vp->hw_code.length = 0; vp->translated = GL_TRUE; - vp->native = GL_TRUE; + vp->error = GL_FALSE; t_inputs_outputs(vp); - for (inst = vp->program.body.i; vpi->Opcode != OPCODE_END; + for (inst = vp->hw_code.body.d; vpi->Opcode != OPCODE_END; vpi++, inst += 4) { FREE_TEMPS(); @@ -1187,38 +1180,15 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp, &u_temp_i); break; default: - assert(0); + vp->error = GL_TRUE; break; } } - /* Some outputs may be artificially added, to match the inputs - of the fragment program. Blank the outputs here. */ - for (i = 0; i < VERT_RESULT_MAX; i++) { - if (vp->key.OutputsAdded & (1 << i)) { - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - vp->outputs[i], - VSF_FLAG_ALL, - PVS_DST_REG_OUT); - inst[1] = __CONST(0, SWIZZLE_ZERO); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - inst += 4; - } + vp->hw_code.length = (inst - vp->hw_code.body.d); + if (vp->hw_code.length >= VSF_MAX_FRAGMENT_LENGTH) { + vp->error = GL_TRUE; } - - vp->program.length = (inst - vp->program.body.i); - if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) { - vp->program.length = 0; - vp->native = GL_FALSE; - } -#if 0 - fprintf(stderr, "hw program:\n"); - for (i = 0; i < vp->program.length; i++) - fprintf(stderr, "%08x\n", vp->program.body.d[i]); -#endif } /* DP4 version seems to trigger some hw peculiarity */ @@ -1397,6 +1367,49 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key pos_as_texcoord(vp, &mesa_vp->Base); } + if (RADEON_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "Vertex program after native rewrite:\n"); + _mesa_print_program(&mesa_vp->Base); + fflush(stdout); + } + + /* Some outputs may be artificially added, to match the inputs of the fragment program. + * Issue 16 of vertex program spec says that all vertex attributes that are unwritten by + * vertex program are undefined, so just use MOV [vertex_result], CONST[0] + */ + { + int i, count = 0; + for (i = 0; i < VERT_RESULT_MAX; ++i) { + if (vp->key.OutputsAdded & (1 << i)) { + ++count; + } + } + + if (count > 0) { + struct prog_instruction *inst; + + _mesa_insert_instructions(&mesa_vp->Base, mesa_vp->Base.NumInstructions - 1, count); + inst = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions - 1 - count]; + + for (i = 0; i < VERT_RESULT_MAX; ++i) { + if (vp->key.OutputsAdded & (1 << i)) { + inst->Opcode = OPCODE_MOV; + + inst->DstReg.File = PROGRAM_OUTPUT; + inst->DstReg.Index = i; + inst->DstReg.WriteMask = WRITEMASK_XYZW; + inst->DstReg.CondMask = COND_TR; + + inst->SrcReg[0].File = PROGRAM_CONSTANT; + inst->SrcReg[0].Index = 0; + inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; + + ++inst; + } + } + } + } + assert(mesa_vp->Base.NumInstructions); vp->num_temporaries = mesa_vp->Base.NumTemporaries; r300TranslateVertexShader(vp, mesa_vp->Base.Instructions); @@ -1443,7 +1456,12 @@ void r300SelectVertexShader(r300ContextPtr r300) wpos_idx = i; } - add_outputs(&wanted_key, VERT_RESULT_HPOS); + if (vpc->mesa_program.IsPositionInvariant) { + wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); + wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS); + } else { + add_outputs(&wanted_key, VERT_RESULT_HPOS); + } if (InputsRead & FRAG_BIT_COL0) { add_outputs(&wanted_key, VERT_RESULT_COL0); @@ -1453,27 +1471,103 @@ void r300SelectVertexShader(r300ContextPtr r300) add_outputs(&wanted_key, VERT_RESULT_COL1); } + if (InputsRead & FRAG_BIT_FOGC) { + add_outputs(&wanted_key, VERT_RESULT_FOGC); + } + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (InputsRead & (FRAG_BIT_TEX0 << i)) { add_outputs(&wanted_key, VERT_RESULT_TEX0 + i); } } - if (vpc->mesa_program.IsPositionInvariant) { - /* we wan't position don't we ? */ - wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); - } - for (vp = vpc->progs; vp; vp = vp->next) if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { r300->selected_vp = vp; return; } - //_mesa_print_program(&vpc->mesa_program.Base); + + if (RADEON_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "Initial vertex program:\n"); + _mesa_print_program(&vpc->mesa_program.Base); + fflush(stdout); + } vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); vp->next = vpc->progs; vpc->progs = vp; r300->selected_vp = vp; } + +#define bump_vpu_count(ptr, new_count) do { \ + drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr)); \ + int _nc=(new_count)/4; \ + assert(_nc < 256); \ + if(_nc>_p->vpu.count)_p->vpu.count=_nc; \ + } while(0) + +static void r300EmitVertexProgram(r300ContextPtr r300, int dest, struct r300_vertex_shader_hw_code *code) +{ + int i; + + assert((code->length > 0) && (code->length % 4 == 0)); + + switch ((dest >> 8) & 0xf) { + case 0: + R300_STATECHANGE(r300, vpi); + for (i = 0; i < code->length; i++) + r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (code->body.d[i]); + bump_vpu_count(r300->hw.vpi.cmd, code->length + 4 * (dest & 0xff)); + break; + case 2: + R300_STATECHANGE(r300, vpp); + for (i = 0; i < code->length; i++) + r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (code->body.d[i]); + bump_vpu_count(r300->hw.vpp.cmd, code->length + 4 * (dest & 0xff)); + break; + case 4: + R300_STATECHANGE(r300, vps); + for (i = 0; i < code->length; i++) + r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (code->body.d[i]); + bump_vpu_count(r300->hw.vps.cmd, code->length + 4 * (dest & 0xff)); + break; + default: + fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest); + _mesa_exit(-1); + } +} + +void r300SetupVertexProgram(r300ContextPtr rmesa) +{ + GLcontext *ctx = rmesa->radeon.glCtx; + struct r300_vertex_program *prog = rmesa->selected_vp; + int inst_count = 0; + int param_count = 0; + + /* Reset state, in case we don't use something */ + ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0; + ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; + ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; + + R300_STATECHANGE(rmesa, vpp); + param_count = r300VertexProgUpdateParams(ctx, + (struct r300_vertex_program_cont *) + ctx->VertexProgram._Current, + (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); + bump_vpu_count(rmesa->hw.vpp.cmd, param_count); + param_count /= 4; + + r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->hw_code)); + inst_count = (prog->hw_code.length / 4) - 1; + + r300VapCntl(rmesa, _mesa_bitcount(prog->key.InputsRead), + _mesa_bitcount(prog->key.OutputsWritten), prog->num_temporaries); + + R300_STATECHANGE(rmesa, pvs); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | + (inst_count << R300_PVS_LAST_INST_SHIFT); + + rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); +} diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h index 2f35f02bc8..b552e3fb1b 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.h +++ b/src/mesa/drivers/dri/r300/r300_vertprog.h @@ -32,4 +32,6 @@ #endif +void r300SetupVertexProgram(r300ContextPtr rmesa); + #endif diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c index 07a2a7b17c..4d58cf2162 100644 --- a/src/mesa/drivers/dri/r300/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/r500_fragprog.c @@ -27,10 +27,6 @@ #include "r500_fragprog.h" -#include "radeon_nqssadce.h" -#include "radeon_program_alu.h" - - static void reset_srcreg(struct prog_src_register* reg) { _mesa_bzero(reg, sizeof(*reg)); @@ -58,12 +54,12 @@ static struct prog_src_register shadow_ambient(struct gl_program *program, int t * - introduce a temporary register when write masks are needed * */ -static GLboolean transform_TEX( +GLboolean r500_transform_TEX( struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data) { - struct r500_fragment_program_compiler *compiler = - (struct r500_fragment_program_compiler*)data; + struct r300_fragment_program_compiler *compiler = + (struct r300_fragment_program_compiler*)data; struct prog_instruction inst = *orig_inst; struct prog_instruction* tgt; GLboolean destredirect = GL_FALSE; @@ -156,9 +152,9 @@ static GLboolean transform_TEX( * r < tex <=> -tex+r < 0 * r >= tex <=> not (-tex+r < 0 */ if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL) - tgt[1].SrcReg[2].NegateBase = tgt[0].SrcReg[2].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[2].Negate = tgt[0].SrcReg[2].Negate ^ NEGATE_XYZW; else - tgt[1].SrcReg[0].NegateBase = tgt[0].SrcReg[0].NegateBase ^ NEGATE_XYZW; + tgt[1].SrcReg[0].Negate = tgt[0].SrcReg[0].Negate ^ NEGATE_XYZW; tgt[2].Opcode = OPCODE_CMP; tgt[2].DstReg = orig_inst->DstReg; @@ -188,121 +184,7 @@ static GLboolean transform_TEX( return GL_TRUE; } - -static void update_params(r300ContextPtr r300, struct r500_fragment_program *fp) -{ - struct gl_fragment_program *mp = &fp->mesa_program; - - /* Ask Mesa nicely to fill in ParameterValues for us */ - if (mp->Base.Parameters) - _mesa_load_state_parameters(r300->radeon.glCtx, mp->Base.Parameters); -} - - -/** - * Transform the program to support fragment.position. - * - * Introduce a small fragment at the start of the program that will be - * the only code that directly reads the FRAG_ATTRIB_WPOS input. - * All other code pieces that reference that input will be rewritten - * to read from a newly allocated temporary. - * - * \todo if/when r5xx supports the radeon_program architecture, this is a - * likely candidate for code sharing. - */ -static void insert_WPOS_trailer(struct r500_fragment_program_compiler *compiler) -{ - GLuint InputsRead = compiler->fp->mesa_program.Base.InputsRead; - - if (!(InputsRead & FRAG_BIT_WPOS)) - return; - - static gl_state_index tokens[STATE_LENGTH] = { - STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0 - }; - struct prog_instruction *fpi; - GLuint window_index; - int i = 0; - GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY); - - _mesa_insert_instructions(compiler->program, 0, 3); - fpi = compiler->program->Instructions; - - /* perspective divide */ - fpi[i].Opcode = OPCODE_RCP; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_W; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; - fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW; - i++; - - fpi[i].Opcode = OPCODE_MUL; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; - fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[1].Index = tempregi; - fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW; - i++; - - /* viewport transformation */ - window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens); - - fpi[i].Opcode = OPCODE_MAD; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[0].Index = tempregi; - fpi[i].SrcReg[0].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - - fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR; - fpi[i].SrcReg[1].Index = window_index; - fpi[i].SrcReg[1].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - - fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR; - fpi[i].SrcReg[2].Index = window_index; - fpi[i].SrcReg[2].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - i++; - - for (; i < compiler->program->NumInstructions; ++i) { - int reg; - for (reg = 0; reg < 3; reg++) { - if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT && - fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) { - fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[reg].Index = tempregi; - } - } - } -} - - -static void nqssadce_init(struct nqssadce_state* s) -{ - s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW; - s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W; -} - -static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) +GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) { GLuint relevant; int i; @@ -314,33 +196,30 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) if (reg.Abs) return GL_FALSE; - if (reg.NegateAbs) - reg.NegateBase ^= 15; + if (opcode == OPCODE_KIL && (reg.Swizzle != SWIZZLE_NOOP || reg.Negate != NEGATE_NONE)) + return GL_FALSE; - if (opcode == OPCODE_KIL) { - if (reg.Swizzle != SWIZZLE_NOOP) - return GL_FALSE; - } else { - for(i = 0; i < 4; ++i) { - GLuint swz = GET_SWZ(reg.Swizzle, i); - if (swz == SWIZZLE_NIL) { - reg.NegateBase &= ~(1 << i); - continue; - } - if (swz >= 4) - return GL_FALSE; + if (reg.Negate) + reg.Negate ^= NEGATE_XYZW; + + for(i = 0; i < 4; ++i) { + GLuint swz = GET_SWZ(reg.Swizzle, i); + if (swz == SWIZZLE_NIL) { + reg.Negate &= ~(1 << i); + continue; } + if (swz >= 4) + return GL_FALSE; } - if (reg.NegateBase) + if (reg.Negate) return GL_FALSE; return GL_TRUE; } else if (opcode == OPCODE_DDX || opcode == OPCODE_DDY) { /* DDX/MDH and DDY/MDV explicitly ignore incoming swizzles; * if it doesn't fit perfectly into a .xyzw case... */ - if (reg.Swizzle == SWIZZLE_NOOP && !reg.Abs - && !reg.NegateBase && !reg.NegateAbs) + if (reg.Swizzle == SWIZZLE_NOOP && !reg.Abs && !reg.Negate) return GL_TRUE; return GL_FALSE; @@ -355,7 +234,7 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) if (swz != SWIZZLE_NIL && swz != SWIZZLE_ZERO) relevant |= 1 << i; } - if ((reg.NegateBase & relevant) && ((reg.NegateBase & relevant) != relevant)) + if ((reg.Negate & relevant) && ((reg.Negate & relevant) != relevant)) return GL_FALSE; return GL_TRUE; @@ -368,8 +247,7 @@ static GLboolean is_native_swizzle(GLuint opcode, struct prog_src_register reg) * The only thing we *cannot* do in an ALU instruction is per-component * negation. Therefore, we split the MOV into two instructions when necessary. */ -static void nqssadce_build_swizzle(struct nqssadce_state *s, - struct prog_dst_register dst, struct prog_src_register src) +void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src) { struct prog_instruction *inst; GLuint negatebase[2] = { 0, 0 }; @@ -379,7 +257,7 @@ static void nqssadce_build_swizzle(struct nqssadce_state *s, GLuint swz = GET_SWZ(src.Swizzle, i); if (swz == SWIZZLE_NIL) continue; - negatebase[GET_BIT(src.NegateBase, i)] |= 1 << i; + negatebase[GET_BIT(src.Negate, i)] |= 1 << i; } _mesa_insert_instructions(s->Program, s->IP, (negatebase[0] ? 1 : 0) + (negatebase[1] ? 1 : 0)); @@ -393,129 +271,12 @@ static void nqssadce_build_swizzle(struct nqssadce_state *s, inst->DstReg = dst; inst->DstReg.WriteMask = negatebase[i]; inst->SrcReg[0] = src; + inst->SrcReg[0].Negate = (i == 0) ? NEGATE_NONE : NEGATE_XYZW; inst++; s->IP++; } } -static GLuint build_dtm(GLuint depthmode) -{ - switch(depthmode) { - default: - case GL_LUMINANCE: return 0; - case GL_INTENSITY: return 1; - case GL_ALPHA: return 2; - } -} - -static GLuint build_func(GLuint comparefunc) -{ - return comparefunc - GL_NEVER; -} - - -/** - * Collect all external state that is relevant for compiling the given - * fragment program. - */ -static void build_state( - r300ContextPtr r300, - struct r500_fragment_program *fp, - struct r500_fragment_program_external_state *state) -{ - int unit; - - _mesa_bzero(state, sizeof(*state)); - - for(unit = 0; unit < 16; ++unit) { - if (fp->mesa_program.Base.ShadowSamplers & (1 << unit)) { - struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current; - - state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); - state->unit[unit].texture_compare_func = build_func(tex->CompareFunc); - } - } -} - -static void dump_program(struct r500_fragment_program_code *code); - -void r500TranslateFragmentShader(r300ContextPtr r300, - struct r500_fragment_program *fp) -{ - struct r500_fragment_program_external_state state; - - build_state(r300, fp, &state); - if (_mesa_memcmp(&fp->state, &state, sizeof(state))) { - /* TODO: cache compiled programs */ - fp->translated = GL_FALSE; - _mesa_memcpy(&fp->state, &state, sizeof(state)); - } - - if (!fp->translated) { - struct r500_fragment_program_compiler compiler; - - compiler.r300 = r300; - compiler.fp = fp; - compiler.code = &fp->code; - compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: Initial program:\n"); - _mesa_print_program(compiler.program); - } - - insert_WPOS_trailer(&compiler); - - struct radeon_program_transformation transformations[] = { - { &transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformDeriv, 0 }, - { &radeonTransformTrigScale, 0 } - }; - radeonLocalTransform(r300->radeon.glCtx, compiler.program, - 4, transformations); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: after native rewrite:\n"); - _mesa_print_program(compiler.program); - } - - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &is_native_swizzle, - .BuildSwizzle = &nqssadce_build_swizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(r300->radeon.glCtx, compiler.program, &nqssadce); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: after NqSSA-DCE:\n"); - _mesa_print_program(compiler.program); - } - - fp->translated = r500FragmentProgramEmit(&compiler); - - /* Subtle: Rescue any parameters that have been added during transformations */ - _mesa_free_parameter_list(fp->mesa_program.Base.Parameters); - fp->mesa_program.Base.Parameters = compiler.program->Parameters; - compiler.program->Parameters = 0; - - _mesa_reference_program(r300->radeon.glCtx, &compiler.program, 0); - - r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - if (fp->translated) { - _mesa_printf("Machine-readable code:\n"); - dump_program(&fp->code); - } - } - - } - - update_params(r300, fp); - -} static char *toswiz(int swiz_val) { switch(swiz_val) { @@ -614,9 +375,9 @@ static char *to_texop(int val) return NULL; } -static void dump_program(struct r500_fragment_program_code *code) +void r500FragmentProgramDump(union rX00_fragment_program_code *c) { - + struct r500_fragment_program_code *code = &c->r500; fprintf(stderr, "R500 Fragment Program:\n--------\n"); int n; diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.h b/src/mesa/drivers/dri/r300/r500_fragprog.h index 1e45538f80..1179bf6607 100644 --- a/src/mesa/drivers/dri/r300/r500_fragprog.h +++ b/src/mesa/drivers/dri/r300/r500_fragprog.h @@ -33,30 +33,20 @@ #ifndef __R500_FRAGPROG_H_ #define __R500_FRAGPROG_H_ -#include "main/glheader.h" -#include "main/macros.h" -#include "main/enums.h" #include "shader/prog_parameter.h" -#include "shader/prog_print.h" -#include "shader/program.h" #include "shader/prog_instruction.h" #include "r300_context.h" -#include "r300_state.h" -#include "radeon_program.h" +#include "radeon_nqssadce.h" -struct r500_fragment_program; +extern GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler); -extern void r500TranslateFragmentShader(r300ContextPtr r300, - struct r500_fragment_program *fp); +extern void r500FragmentProgramDump(union rX00_fragment_program_code *c); -struct r500_fragment_program_compiler { - r300ContextPtr r300; - struct r500_fragment_program *fp; - struct r500_fragment_program_code *code; - struct gl_program *program; -}; +extern GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg); -extern GLboolean r500FragmentProgramEmit(struct r500_fragment_program_compiler *compiler); +extern void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src); + +extern GLboolean r500_transform_TEX(struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data); #endif diff --git a/src/mesa/drivers/dri/r300/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/r500_fragprog_emit.c index 4631235f0d..30f4514897 100644 --- a/src/mesa/drivers/dri/r300/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/r500_fragprog_emit.c @@ -49,8 +49,8 @@ #define PROG_CODE \ - struct r500_fragment_program_compiler *c = (struct r500_fragment_program_compiler*)data; \ - struct r500_fragment_program_code *code = c->code + struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)data; \ + struct r500_fragment_program_code *code = &c->code->r500 #define error(fmt, args...) do { \ fprintf(stderr, "%s::%s(): " fmt "\n", \ @@ -72,7 +72,7 @@ static GLboolean emit_const(void *data, GLuint file, GLuint idx, GLuint *hwindex } if (*hwindex >= code->const_nr) { - if (*hwindex >= PFS_NUM_CONST_REGS) { + if (*hwindex >= R500_PFS_NUM_CONST_REGS) { error("Out of hw constants!\n"); return GL_FALSE; } @@ -299,9 +299,9 @@ static const struct radeon_pair_handler pair_handler = { .MaxHwTemps = 128 }; -GLboolean r500FragmentProgramEmit(struct r500_fragment_program_compiler *compiler) +GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler) { - struct r500_fragment_program_code *code = compiler->code; + struct r500_fragment_program_code *code = &compiler->code->r500; _mesa_bzero(code, sizeof(*code)); code->max_temp_idx = 1; diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.c b/src/mesa/drivers/dri/r300/radeon_nqssadce.c index a083c3d243..4a2e1cba40 100644 --- a/src/mesa/drivers/dri/r300/radeon_nqssadce.c +++ b/src/mesa/drivers/dri/r300/radeon_nqssadce.c @@ -61,12 +61,12 @@ static struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_reg struct prog_src_register tmp = srcreg; int i; tmp.Swizzle = 0; - tmp.NegateBase = 0; + tmp.Negate = NEGATE_NONE; for(i = 0; i < 4; ++i) { GLuint swz = GET_SWZ(swizzle, i); if (swz < 4) { tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3); - tmp.NegateBase |= GET_BIT(srcreg.NegateBase, swz) << i; + tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i; } else { tmp.Swizzle |= swz << (i*3); } @@ -103,9 +103,8 @@ static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s, inst->SrcReg[src].File = PROGRAM_TEMPORARY; inst->SrcReg[src].Index = dstreg.Index; inst->SrcReg[src].Swizzle = 0; - inst->SrcReg[src].NegateBase = 0; + inst->SrcReg[src].Negate = NEGATE_NONE; inst->SrcReg[src].Abs = 0; - inst->SrcReg[src].NegateAbs = 0; for(i = 0; i < 4; ++i) { if (GET_BIT(sourced, i)) inst->SrcReg[src].Swizzle |= i << (3*i); diff --git a/src/mesa/drivers/dri/r300/radeon_program_alu.c b/src/mesa/drivers/dri/r300/radeon_program_alu.c index 1ef71e74dc..8283723bad 100644 --- a/src/mesa/drivers/dri/r300/radeon_program_alu.c +++ b/src/mesa/drivers/dri/r300/radeon_program_alu.c @@ -81,18 +81,6 @@ static struct prog_instruction *emit3(struct gl_program* p, return fpi; } -static void set_swizzle(struct prog_src_register *SrcReg, int coordinate, int swz) -{ - SrcReg->Swizzle &= ~(7 << (3*coordinate)); - SrcReg->Swizzle |= swz << (3*coordinate); -} - -static void set_negate_base(struct prog_src_register *SrcReg, int coordinate, int negate) -{ - SrcReg->NegateBase &= ~(1 << coordinate); - SrcReg->NegateBase |= (negate << coordinate); -} - static struct prog_dst_register dstreg(int file, int index) { struct prog_dst_register dst; @@ -156,15 +144,14 @@ static struct prog_src_register absolute(struct prog_src_register reg) { struct prog_src_register newreg = reg; newreg.Abs = 1; - newreg.NegateBase = 0; - newreg.NegateAbs = 0; + newreg.Negate = NEGATE_NONE; return newreg; } static struct prog_src_register negate(struct prog_src_register reg) { struct prog_src_register newreg = reg; - newreg.NegateAbs = !newreg.NegateAbs; + newreg.Negate = newreg.Negate ^ NEGATE_XYZW; return newreg; } @@ -189,8 +176,7 @@ static void transform_ABS(struct radeon_transform_context* t, { struct prog_src_register src = inst->SrcReg[0]; src.Abs = 1; - src.NegateBase = 0; - src.NegateAbs = 0; + src.Negate = NEGATE_NONE; emit1(t->Program, OPCODE_MOV, inst->SaturateMode, inst->DstReg, src); } @@ -198,18 +184,9 @@ static void transform_DPH(struct radeon_transform_context* t, struct prog_instruction* inst) { struct prog_src_register src0 = inst->SrcReg[0]; - if (src0.NegateAbs) { - if (src0.Abs) { - int tempreg = radeonFindFreeTemporary(t); - emit1(t->Program, OPCODE_MOV, 0, dstreg(PROGRAM_TEMPORARY, tempreg), src0); - src0 = srcreg(src0.File, src0.Index); - } else { - src0.NegateAbs = 0; - src0.NegateBase ^= NEGATE_XYZW; - } - } - set_swizzle(&src0, 3, SWIZZLE_ONE); - set_negate_base(&src0, 3, 0); + src0.Negate &= ~NEGATE_W; + src0.Swizzle &= ~(7 << (3 * 3)); + src0.Swizzle |= SWIZZLE_ONE << (3 * 3); emit2(t->Program, OPCODE_DP4, inst->SaturateMode, inst->DstReg, src0, inst->SrcReg[1]); } @@ -649,7 +626,7 @@ GLboolean radeonTransformDeriv(struct radeon_transform_context* t, B.Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE); - B.NegateBase = NEGATE_XYZW; + B.Negate = NEGATE_XYZW; emit2(t->Program, inst->Opcode, inst->SaturateMode, inst->DstReg, inst->SrcReg[0], B); diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/radeon_program_pair.c index 49aa90dd94..906d36e522 100644 --- a/src/mesa/drivers/dri/r300/radeon_program_pair.c +++ b/src/mesa/drivers/dri/r300/radeon_program_pair.c @@ -255,8 +255,7 @@ static void final_rewrite(struct pair_state *s, struct prog_instruction *inst) inst->SrcReg[2] = inst->SrcReg[1]; inst->SrcReg[1].File = PROGRAM_BUILTIN; inst->SrcReg[1].Swizzle = SWIZZLE_1111; - inst->SrcReg[1].NegateBase = 0; - inst->SrcReg[1].NegateAbs = 0; + inst->SrcReg[1].Negate = NEGATE_NONE; inst->Opcode = OPCODE_MAD; break; case OPCODE_CMP: @@ -610,6 +609,7 @@ static void emit_all_tex(struct pair_state *s) if (s->Debug) { _mesa_printf(" "); _mesa_print_instruction(inst); + fflush(stdout); } s->Error = s->Error || !s->Handler->EmitTex(s->UserData, inst); } @@ -722,7 +722,6 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ if (pairinst->NeedRGB && !pairinst->IsTranscendent) { GLboolean srcrgb = GL_FALSE; GLboolean srcalpha = GL_FALSE; - GLuint negatebase = 0; int j; for(j = 0; j < 3; ++j) { GLuint swz = GET_SWZ(inst->SrcReg[i].Swizzle, j); @@ -730,8 +729,6 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ srcrgb = GL_TRUE; else if (swz < 4) srcalpha = GL_TRUE; - if (swz != SWIZZLE_NIL && GET_BIT(inst->SrcReg[i].NegateBase, j)) - negatebase = 1; } source = alloc_pair_source(s, pair, inst->SrcReg[i], srcrgb, srcalpha); if (source < 0) @@ -739,12 +736,11 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ pair->RGB.Arg[i].Source = source; pair->RGB.Arg[i].Swizzle = inst->SrcReg[i].Swizzle & 0x1ff; pair->RGB.Arg[i].Abs = inst->SrcReg[i].Abs; - pair->RGB.Arg[i].Negate = (negatebase & ~pair->RGB.Arg[i].Abs) ^ inst->SrcReg[i].NegateAbs; + pair->RGB.Arg[i].Negate = !!(inst->SrcReg[i].Negate & (NEGATE_X | NEGATE_Y | NEGATE_Z)); } if (pairinst->NeedAlpha) { GLboolean srcrgb = GL_FALSE; GLboolean srcalpha = GL_FALSE; - GLuint negatebase = GET_BIT(inst->SrcReg[i].NegateBase, pairinst->IsTranscendent ? 0 : 3); GLuint swz = GET_SWZ(inst->SrcReg[i].Swizzle, pairinst->IsTranscendent ? 0 : 3); if (swz < 3) srcrgb = GL_TRUE; @@ -756,7 +752,7 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_ pair->Alpha.Arg[i].Source = source; pair->Alpha.Arg[i].Swizzle = swz; pair->Alpha.Arg[i].Abs = inst->SrcReg[i].Abs; - pair->Alpha.Arg[i].Negate = (negatebase & ~pair->RGB.Arg[i].Abs) ^ inst->SrcReg[i].NegateAbs; + pair->Alpha.Arg[i].Negate = !!(inst->SrcReg[i].Negate & NEGATE_W); } } |