summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300/r300_emit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_emit.c')
-rw-r--r--src/gallium/drivers/r300/r300_emit.c399
1 files changed, 286 insertions, 113 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 258c38fefdc..98a39390bf9 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -31,16 +31,18 @@
#include "r300_screen.h"
#include "r300_state_derived.h"
#include "r300_state_inlines.h"
+#include "r300_texture.h"
#include "r300_vs.h"
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend)
{
CS_LOCALS(r300);
- BEGIN_CS(7);
- OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 2);
+ BEGIN_CS(8);
+ OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
OUT_CS(blend->blend_control);
OUT_CS(blend->alpha_blend_control);
+ OUT_CS(blend->color_channel_mask);
OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither);
END_CS;
@@ -101,19 +103,23 @@ void r300_emit_dsa_state(struct r300_context* r300,
struct r300_screen* r300screen = r300_screen(r300->context.screen);
CS_LOCALS(r300);
- BEGIN_CS(r300screen->caps->is_r500 ? 8 : 8);
+ BEGIN_CS(r300screen->caps->is_r500 ? 10 : 8);
OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
- /* XXX figure out the r300 counterpart for this */
- if (r300screen->caps->is_r500) {
- /* OUT_CS_REG(R500_FG_ALPHA_VALUE, dsa->alpha_reference); */
- }
+
+ /* not needed since we use the 8bit alpha ref */
+ /*if (r300screen->caps->is_r500) {
+ OUT_CS_REG(R500_FG_ALPHA_VALUE, dsa->alpha_reference);
+ }*/
+
OUT_CS_REG_SEQ(R300_ZB_CNTL, 3);
OUT_CS(dsa->z_buffer_control);
OUT_CS(dsa->z_stencil_control);
OUT_CS(dsa->stencil_ref_mask);
OUT_CS_REG(R300_ZB_ZTOP, r300->ztop_state.z_buffer_top);
+
+ /* XXX it seems r3xx doesn't support STENCILREFMASK_BF */
if (r300screen->caps->is_r500) {
- /* OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); */
+ OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf);
}
END_CS;
}
@@ -123,7 +129,9 @@ static const float * get_shader_constant(
struct rc_constant * constant,
struct r300_constant_buffer * externals)
{
- static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+ static float vec[4] = { 0.0, 0.0, 0.0, 1.0 };
+ struct pipe_texture *tex;
+
switch(constant->Type) {
case RC_CONSTANT_EXTERNAL:
return externals->constants[constant->u.External];
@@ -131,11 +139,31 @@ static const float * get_shader_constant(
case RC_CONSTANT_IMMEDIATE:
return constant->u.Immediate;
+ case RC_CONSTANT_STATE:
+ switch (constant->u.State[0]) {
+ /* Factor for converting rectangle coords to
+ * normalized coords. Should only show up on non-r500. */
+ case RC_STATE_R300_TEXRECT_FACTOR:
+ tex = &r300->textures[constant->u.State[1]]->tex;
+ vec[0] = 1.0 / tex->width0;
+ vec[1] = 1.0 / tex->height0;
+ break;
+
+ default:
+ debug_printf("r300: Implementation error: "
+ "Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
+ }
+ break;
+
default:
- debug_printf("r300: Implementation error: Unhandled constant type %i\n",
- constant->Type);
- return zero;
+ debug_printf("r300: Implementation error: "
+ "Unhandled constant type %d\n", constant->Type);
}
+
+ /* This should either be (0, 0, 0, 1), which should be a relatively safe
+ * RGBA or STRQ value, or it could be one of the RC_CONSTANT_STATE
+ * state factors. */
+ return vec;
}
/* Convert a normal single-precision float into the 7.16 format
@@ -173,18 +201,15 @@ static uint32_t pack_float24(float f)
}
void r300_emit_fragment_program_code(struct r300_context* r300,
- struct rX00_fragment_program_code* generic_code,
- struct r300_constant_buffer* externals)
+ struct rX00_fragment_program_code* generic_code)
{
struct r300_fragment_program_code * code = &generic_code->code.r300;
- struct rc_constant_list * constants = &generic_code->constants;
int i;
CS_LOCALS(r300);
BEGIN_CS(15 +
code->alu.length * 4 +
- (code->tex.length ? (1 + code->tex.length) : 0) +
- (constants->Count ? (1 + constants->Count * 4) : 0));
+ (code->tex.length ? (1 + code->tex.length) : 0));
OUT_CS_REG(R300_US_CONFIG, code->config);
OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
@@ -216,32 +241,41 @@ void r300_emit_fragment_program_code(struct r300_context* r300,
OUT_CS(code->tex.inst[i]);
}
- if (constants->Count) {
- OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4);
- for(i = 0; i < constants->Count; ++i) {
- const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
- OUT_CS(pack_float24(data[0]));
- OUT_CS(pack_float24(data[1]));
- OUT_CS(pack_float24(data[2]));
- OUT_CS(pack_float24(data[3]));
- }
- }
+ END_CS;
+}
+
+void r300_emit_fs_constant_buffer(struct r300_context* r300,
+ struct rc_constant_list* constants)
+{
+ int i;
+ CS_LOCALS(r300);
+
+ if (constants->Count == 0)
+ return;
+ BEGIN_CS(constants->Count * 4 + 1);
+ OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4);
+ for(i = 0; i < constants->Count; ++i) {
+ const float * data = get_shader_constant(r300,
+ &constants->Constants[i],
+ &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+ OUT_CS(pack_float24(data[0]));
+ OUT_CS(pack_float24(data[1]));
+ OUT_CS(pack_float24(data[2]));
+ OUT_CS(pack_float24(data[3]));
+ }
END_CS;
}
void r500_emit_fragment_program_code(struct r300_context* r300,
- struct rX00_fragment_program_code* generic_code,
- struct r300_constant_buffer* externals)
+ struct rX00_fragment_program_code* generic_code)
{
struct r500_fragment_program_code * code = &generic_code->code.r500;
- struct rc_constant_list * constants = &generic_code->constants;
int i;
CS_LOCALS(r300);
BEGIN_CS(13 +
- ((code->inst_end + 1) * 6) +
- (constants->Count ? (3 + (constants->Count * 4)) : 0));
+ ((code->inst_end + 1) * 6));
OUT_CS_REG(R500_US_CONFIG, 0);
OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
OUT_CS_REG(R500_US_CODE_RANGE,
@@ -261,18 +295,30 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
OUT_CS(code->inst[i].inst5);
}
- if (constants->Count) {
- OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
- OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
- for (i = 0; i < constants->Count; i++) {
- const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
- OUT_CS_32F(data[0]);
- OUT_CS_32F(data[1]);
- OUT_CS_32F(data[2]);
- OUT_CS_32F(data[3]);
- }
- }
+ END_CS;
+}
+
+void r500_emit_fs_constant_buffer(struct r300_context* r300,
+ struct rc_constant_list* constants)
+{
+ int i;
+ CS_LOCALS(r300);
+
+ if (constants->Count == 0)
+ return;
+ BEGIN_CS(constants->Count * 4 + 3);
+ OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
+ OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
+ for (i = 0; i < constants->Count; i++) {
+ const float * data = get_shader_constant(r300,
+ &constants->Constants[i],
+ &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+ OUT_CS_32F(data[0]);
+ OUT_CS_32F(data[1]);
+ OUT_CS_32F(data[2]);
+ OUT_CS_32F(data[3]);
+ }
END_CS;
}
@@ -280,48 +326,50 @@ void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb)
{
struct r300_texture* tex;
- unsigned pixpitch;
+ struct pipe_surface* surf;
int i;
CS_LOCALS(r300);
BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);
+ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
+ R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
+ R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
+ OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
+
for (i = 0; i < fb->nr_cbufs; i++) {
- tex = (struct r300_texture*)fb->cbufs[i]->texture;
+ surf = fb->cbufs[i];
+ tex = (struct r300_texture*)surf->texture;
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size;
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
- OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
- OUT_CS_RELOC(tex->buffer, pixpitch |
+ OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] |
r300_translate_colorformat(tex->tex.format), 0,
RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),
- r300_translate_out_fmt(fb->cbufs[i]->format));
+ r300_translate_out_fmt(surf->format));
}
if (fb->zsbuf) {
- tex = (struct r300_texture*)fb->zsbuf->texture;
+ surf = fb->zsbuf;
+ tex = (struct r300_texture*)surf->texture;
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
- pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size;
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(tex->buffer, pixpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level], 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
}
- OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
- R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
- R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
- OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
- R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
END_CS;
}
@@ -457,7 +505,7 @@ void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)
{
CS_LOCALS(r300);
- BEGIN_CS(20);
+ BEGIN_CS(22);
OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size);
OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2);
@@ -473,6 +521,7 @@ void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)
OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config);
OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value);
OUT_CS_REG(R300_GA_COLOR_CONTROL, rs->color_control);
+ OUT_CS_REG(R300_GA_POLY_MODE, rs->polygon_mode);
END_CS;
}
@@ -483,6 +532,8 @@ void r300_emit_rs_block_state(struct r300_context* r300,
struct r300_screen* r300screen = r300_screen(r300->context.screen);
CS_LOCALS(r300);
+ DBG(r300, DBG_DRAW, "r300: RS emit:\n");
+
BEGIN_CS(21);
if (r300screen->caps->is_r500) {
OUT_CS_REG_SEQ(R500_RS_IP_0, 8);
@@ -491,7 +542,7 @@ void r300_emit_rs_block_state(struct r300_context* r300,
}
for (i = 0; i < 8; i++) {
OUT_CS(rs->ip[i]);
- /* debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); */
+ DBG(r300, DBG_DRAW, " : ip %d: 0x%08x\n", i, rs->ip[i]);
}
OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
@@ -505,11 +556,11 @@ void r300_emit_rs_block_state(struct r300_context* r300,
}
for (i = 0; i < 8; i++) {
OUT_CS(rs->inst[i]);
- /* debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); */
+ DBG(r300, DBG_DRAW, " : inst %d: 0x%08x\n", i, rs->inst[i]);
}
- /* debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count,
- * rs->inst_count); */
+ DBG(r300, DBG_DRAW, " : count: 0x%08x inst_count: 0x%08x\n",
+ rs->count, rs->inst_count);
END_CS;
}
@@ -531,15 +582,31 @@ void r300_emit_texture(struct r300_context* r300,
struct r300_texture* tex,
unsigned offset)
{
+ uint32_t filter0 = sampler->filter0;
+ uint32_t format0 = tex->state.format0;
+ unsigned min_level, max_level;
CS_LOCALS(r300);
+ /* to emulate 1D textures through 2D ones correctly */
+ if (tex->tex.target == PIPE_TEXTURE_1D) {
+ filter0 &= ~R300_TX_WRAP_T_MASK;
+ filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
+ }
+
+ /* determine min/max levels */
+ /* the MAX_MIP level is the largest (finest) one */
+ max_level = MIN2(sampler->max_lod, tex->tex.last_level);
+ min_level = MIN2(sampler->min_lod, max_level);
+ format0 |= R300_TX_NUM_LEVELS(max_level);
+ filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
+
BEGIN_CS(16);
- OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), sampler->filter0 |
+ OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 |
(offset << 28));
OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1);
OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color);
- OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), tex->state.format0);
+ OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), format0);
OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1);
OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2);
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1);
@@ -548,7 +615,52 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
-void r300_emit_vertex_buffer(struct r300_context* r300)
+/* XXX I can't read this and that's not good */
+void r300_emit_aos(struct r300_context* r300, unsigned offset)
+{
+ struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_element *velem = r300->vertex_element;
+ CS_LOCALS(r300);
+ int i;
+ unsigned aos_count = r300->vertex_element_count;
+
+ unsigned packet_size = (aos_count * 3 + 1) / 2;
+ BEGIN_CS(2 + packet_size + aos_count * 2);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
+ OUT_CS(aos_count);
+ for (i = 0; i < aos_count - 1; i += 2) {
+ int buf_num1 = velem[i].vertex_buffer_index;
+ int buf_num2 = velem[i+1].vertex_buffer_index;
+ assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
+ assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0);
+ OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) |
+ (pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22));
+ OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset +
+ offset * vbuf[buf_num1].stride);
+ OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset +
+ offset * vbuf[buf_num2].stride);
+ }
+ if (aos_count & 1) {
+ int buf_num = velem[i].vertex_buffer_index;
+ assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
+ OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6));
+ OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset +
+ offset * vbuf[buf_num].stride);
+ }
+
+ /* XXX bare CS reloc */
+ for (i = 0; i < aos_count; i++) {
+ cs_winsys->write_cs_reloc(cs_winsys,
+ vbuf[velem[i].vertex_buffer_index].buffer,
+ RADEON_GEM_DOMAIN_GTT,
+ 0,
+ 0);
+ cs_count -= 2;
+ }
+ END_CS;
+}
+#if 0
+void r300_emit_draw_packet(struct r300_context* r300)
{
CS_LOCALS(r300);
@@ -571,12 +683,15 @@ void r300_emit_vertex_buffer(struct r300_context* r300)
OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS;
}
+#endif
void r300_emit_vertex_format_state(struct r300_context* r300)
{
int i;
CS_LOCALS(r300);
+ DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n");
+
BEGIN_CS(26);
OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info->vinfo.size);
@@ -586,33 +701,42 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
OUT_CS(r300->vertex_info->vinfo.hwfmt[2]);
OUT_CS(r300->vertex_info->vinfo.hwfmt[3]);
- /* for (i = 0; i < 4; i++) {
- * debug_printf("hwfmt%d: 0x%08x\n", i,
- * r300->vertex_info->vinfo.hwfmt[i]);
- * } */
+ for (i = 0; i < 4; i++) {
+ DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i,
+ r300->vertex_info->vinfo.hwfmt[i]);
+ }
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
for (i = 0; i < 8; i++) {
OUT_CS(r300->vertex_info->vap_prog_stream_cntl[i]);
- /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i,
- * r300->vertex_info->vap_prog_stream_cntl[i]); */
+ DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i,
+ r300->vertex_info->vap_prog_stream_cntl[i]);
}
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
for (i = 0; i < 8; i++) {
OUT_CS(r300->vertex_info->vap_prog_stream_cntl_ext[i]);
- /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i,
- * r300->vertex_info->vap_prog_stream_cntl_ext[i]); */
+ DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i,
+ r300->vertex_info->vap_prog_stream_cntl_ext[i]);
}
END_CS;
}
+
void r300_emit_vertex_program_code(struct r300_context* r300,
- struct r300_vertex_program_code* code,
- struct r300_constant_buffer* constants)
+ struct r300_vertex_program_code* code)
{
int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
unsigned instruction_count = code->length / 4;
+
+ int vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72;
+ int input_count = MAX2(util_bitcount(code->InputsRead), 1);
+ int output_count = MAX2(util_bitcount(code->OutputsWritten), 1);
+ int temp_count = MAX2(code->num_temporaries, 1);
+ int pvs_num_slots = MIN3(vtx_mem_size / input_count,
+ vtx_mem_size / output_count, 10);
+ int pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6);
+
CS_LOCALS(r300);
if (!r300screen->caps->has_tcl) {
@@ -621,17 +745,11 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
return;
}
- if (code->constants.Count) {
- BEGIN_CS(14 + code->length + (code->constants.Count * 4));
- } else {
- BEGIN_CS(11 + code->length);
- }
-
+ BEGIN_CS(9 + code->length);
/* R300_VAP_PVS_CODE_CNTL_0
* R300_VAP_PVS_CONST_CNTL
* R300_VAP_PVS_CODE_CNTL_1
- * See the r5xx docs for instructions on how to use these.
- * XXX these could be optimized to select better values... */
+ * See the r5xx docs for instructions on how to use these. */
OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
OUT_CS(R300_PVS_FIRST_INST(0) |
R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
@@ -644,32 +762,51 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
for (i = 0; i < code->length; i++)
OUT_CS(code->body.d[i]);
- if (code->constants.Count) {
- OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
- (r300screen->caps->is_r500 ?
- R500_PVS_CONST_START : R300_PVS_CONST_START));
- OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4);
- for (i = 0; i < code->constants.Count; i++) {
- const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants);
- OUT_CS_32F(data[0]);
- OUT_CS_32F(data[1]);
- OUT_CS_32F(data[2]);
- OUT_CS_32F(data[3]);
- }
- }
-
- OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) |
- R300_PVS_NUM_CNTLRS(5) |
+ OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(pvs_num_slots) |
+ R300_PVS_NUM_CNTLRS(pvs_num_controllers) |
R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) |
- R300_PVS_VF_MAX_VTX_NUM(12));
- OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
+ R300_PVS_VF_MAX_VTX_NUM(12) |
+ (r300screen->caps->is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0));
END_CS;
}
void r300_emit_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs)
{
- r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);
+ r300_emit_vertex_program_code(r300, &vs->code);
+}
+
+void r300_emit_vs_constant_buffer(struct r300_context* r300,
+ struct rc_constant_list* constants)
+{
+ int i;
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ CS_LOCALS(r300);
+
+ if (!r300screen->caps->has_tcl) {
+ debug_printf("r300: Implementation error: emit_vertex_shader called,"
+ " but has_tcl is FALSE!\n");
+ return;
+ }
+
+ if (constants->Count == 0)
+ return;
+
+ BEGIN_CS(constants->Count * 4 + 3);
+ OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+ (r300screen->caps->is_r500 ?
+ R500_PVS_CONST_START : R300_PVS_CONST_START));
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4);
+ for (i = 0; i < constants->Count; i++) {
+ const float * data = get_shader_constant(r300,
+ &constants->Constants[i],
+ &r300->shader_constants[PIPE_SHADER_VERTEX]);
+ OUT_CS_32F(data[0]);
+ OUT_CS_32F(data[1]);
+ OUT_CS_32F(data[2]);
+ OUT_CS_32F(data[3]);
+ }
+ END_CS;
}
void r300_emit_viewport_state(struct r300_context* r300,
@@ -694,13 +831,31 @@ void r300_emit_viewport_state(struct r300_context* r300,
END_CS;
}
+void r300_emit_texture_count(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ BEGIN_CS(2);
+ OUT_CS_REG(R300_TX_ENABLE, (1 << r300->texture_count) - 1);
+ END_CS;
+
+}
+
void r300_flush_textures(struct r300_context* r300)
{
CS_LOCALS(r300);
- BEGIN_CS(4);
+ BEGIN_CS(2);
OUT_CS_REG(R300_TX_INVALTAGS, 0);
- OUT_CS_REG(R300_TX_ENABLE, (1 << r300->texture_count) - 1);
+ END_CS;
+}
+
+static void r300_flush_pvs(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ BEGIN_CS(2);
+ OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
END_CS;
}
@@ -716,8 +871,6 @@ void r300_emit_dirty_state(struct r300_context* r300)
return;
}
- r300_update_derived_state(r300);
-
/* Clean out BOs. */
r300->winsys->reset_bos(r300->winsys);
@@ -747,7 +900,7 @@ validate:
for (i = 0; i < r300->texture_count; i++) {
tex = r300->textures[i];
if (!tex)
- continue;
+ continue;
if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
r300->context.flush(&r300->context, 0, NULL);
@@ -768,7 +921,7 @@ validate:
goto validate;
}
} else {
- debug_printf("No VBO while emitting dirty state!\n");
+ // debug_printf("No VBO while emitting dirty state!\n");
}
if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
@@ -808,13 +961,22 @@ validate:
if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
if (r300screen->caps->is_r500) {
- r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+ r500_emit_fragment_program_code(r300, &r300->fs->code);
} else {
- r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+ r300_emit_fragment_program_code(r300, &r300->fs->code);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
}
+ if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
+ if (r300screen->caps->is_r500) {
+ r500_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+ } else {
+ r300_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+ }
+ r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ }
+
if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) {
r300_emit_fb_state(r300, &r300->framebuffer_state);
r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
@@ -838,6 +1000,8 @@ validate:
/* Samplers and textures are tracked separately but emitted together. */
if (r300->dirty_state &
(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) {
+ r300_emit_texture_count(r300);
+
for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) {
if (r300->dirty_state &
((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) {
@@ -868,17 +1032,26 @@ validate:
r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;
}
+ if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) {
+ r300_flush_pvs(r300);
+ }
+
if (r300->dirty_state & R300_NEW_VERTEX_SHADER) {
r300_emit_vertex_shader(r300, r300->vs);
r300->dirty_state &= ~R300_NEW_VERTEX_SHADER;
}
+ if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
+ r300_emit_vs_constant_buffer(r300, &r300->vs->code.constants);
+ r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
+ }
+
/* XXX
assert(r300->dirty_state == 0);
*/
/* Finally, emit the VBO. */
- r300_emit_vertex_buffer(r300);
+ //r300_emit_vertex_buffer(r300);
r300->dirty_hw++;
}