summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_blit.c9
-rw-r--r--src/gallium/drivers/r300/r300_context.c3
-rw-r--r--src/gallium/drivers/r300/r300_context.h17
-rw-r--r--src/gallium/drivers/r300/r300_debug.c1
-rw-r--r--src/gallium/drivers/r300/r300_emit.c26
-rw-r--r--src/gallium/drivers/r300/r300_emit.h3
-rw-r--r--src/gallium/drivers/r300/r300_screen.h1
-rw-r--r--src/gallium/drivers/r300/r300_state.c64
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c118
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h10
-rw-r--r--src/gallium/drivers/r300/r300_texture.c59
-rw-r--r--src/gallium/drivers/r300/r300_vs.c132
-rw-r--r--src/gallium/drivers/r300/r300_vs.h10
13 files changed, 157 insertions, 296 deletions
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 928ad300eee..85c2c149016 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -129,15 +129,16 @@ void r300_surface_copy(struct pipe_context* pipe,
if (dst->texture->format != src->texture->format) {
debug_printf("r300: Implementation error: Format mismatch in %s\n"
" : src: %s dst: %s\n", __FUNCTION__,
- util_format_name(src->texture->format),
- util_format_name(dst->texture->format));
+ util_format_short_name(src->texture->format),
+ util_format_short_name(dst->texture->format));
debug_assert(0);
}
if (!pipe->screen->is_format_supported(pipe->screen,
old_format, src->texture->target,
PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_SAMPLER_VIEW, 0)) {
+ PIPE_BIND_SAMPLER_VIEW, 0) &&
+ util_format_is_plain(old_format)) {
switch (util_format_get_blocksize(old_format)) {
case 1:
new_format = PIPE_FORMAT_I8_UNORM;
@@ -154,7 +155,7 @@ void r300_surface_copy(struct pipe_context* pipe,
default:
debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
"r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
- util_format_name(old_format));
+ util_format_short_name(old_format));
}
}
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 4f721ebb599..e84bce0010f 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -76,7 +76,6 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state);
FREE(r300->textures_state.state);
- FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
FREE(r300->fs_constants.state);
@@ -125,7 +124,6 @@ static void r300_setup_atoms(struct r300_context* r300)
R300_INIT_ATOM(viewport_state, 9);
R300_INIT_ATOM(rs_block_state, 0);
R300_INIT_ATOM(vertex_stream_state, 0);
- R300_INIT_ATOM(vap_output_state, 6);
R300_INIT_ATOM(pvs_flush, 2);
R300_INIT_ATOM(vs_state, 0);
R300_INIT_ATOM(vs_constants, 0);
@@ -149,7 +147,6 @@ static void r300_setup_atoms(struct r300_context* r300)
r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
- r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index a05bf3ce099..e9c8fcdc157 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -119,6 +119,10 @@ struct r300_rs_state {
};
struct r300_rs_block {
+ uint32_t vap_vtx_state_cntl; /* R300_VAP_VTX_STATE_CNTL: 0x2180 */
+ uint32_t vap_vsm_vtx_assm; /* R300_VAP_VSM_VTX_ASSM: 0x2184 */
+ uint32_t vap_out_vtx_fmt[2]; /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */
+
uint32_t ip[8]; /* R300_RS_IP_[0-7], R500_RS_IP_[0-7] */
uint32_t count; /* R300_RS_COUNT */
uint32_t inst_count; /* R300_RS_INST_COUNT */
@@ -190,12 +194,6 @@ struct r300_vertex_stream_state {
unsigned count;
};
-struct r300_vap_output_state {
- uint32_t vap_vtx_state_cntl; /* R300_VAP_VTX_STATE_CNTL: 0x2180 */
- uint32_t vap_vsm_vtx_assm; /* R300_VAP_VSM_VTX_ASSM: 0x2184 */
- uint32_t vap_out_vtx_fmt[2]; /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */
-};
-
struct r300_viewport_state {
float xscale; /* R300_VAP_VPORT_XSCALE: 0x2098 */
float xoffset; /* R300_VAP_VPORT_XOFFSET: 0x209c */
@@ -381,7 +379,7 @@ struct r300_context {
struct r300_atom query_start;
/* Rasterizer state. */
struct r300_atom rs_state;
- /* RS block state. */
+ /* RS block state + VAP (vertex shader) output mapping state. */
struct r300_atom rs_block_state;
/* Scissor state. */
struct r300_atom scissor_state;
@@ -389,8 +387,6 @@ struct r300_context {
struct r300_atom textures_state;
/* Vertex stream formatting state. */
struct r300_atom vertex_stream_state;
- /* VAP (vertex shader) output mapping state. */
- struct r300_atom vap_output_state;
/* Vertex shader. */
struct r300_atom vs_state;
/* Vertex shader constant buffer. */
@@ -424,6 +420,9 @@ struct r300_context {
struct pipe_viewport_state viewport;
+ /* Stream locations for SWTCL. */
+ int stream_loc_notcl[16];
+
/* Flag indicating whether or not the HW is dirty. */
uint32_t dirty_hw;
/* Whether polygon offset is enabled. */
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index 4c2836f36a8..8eb321fa08a 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -37,6 +37,7 @@ static struct debug_option debug_options[] = {
{ "cs", DBG_CS, "Command submissions (for debugging)" },
{ "draw", DBG_DRAW, "Draw and emit (for debugging)" },
{ "tex", DBG_TEX, "Textures (for debugging)" },
+ { "texalloc", DBG_TEXALLOC, "Texture allocation (for debugging)" },
{ "fall", DBG_FALL, "Fallbacks (for debugging)" },
{ "rs", DBG_RS, "Rasterizer (for debugging)" },
{ "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" },
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 92b7517b8d6..23bbc6a99c8 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -717,6 +717,13 @@ void r300_emit_rs_block_state(struct r300_context* r300,
DBG(r300, DBG_DRAW, "r300: RS emit:\n");
BEGIN_CS(size);
+ OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
+ OUT_CS(rs->vap_vtx_state_cntl);
+ OUT_CS(rs->vap_vsm_vtx_assm);
+ OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
+ OUT_CS(rs->vap_out_vtx_fmt[0]);
+ OUT_CS(rs->vap_out_vtx_fmt[1]);
+
if (r300->screen->caps.is_r500) {
OUT_CS_REG_SEQ(R500_RS_IP_0, count);
} else {
@@ -901,25 +908,6 @@ void r300_emit_vertex_stream_state(struct r300_context* r300,
END_CS;
}
-void r300_emit_vap_output_state(struct r300_context* r300,
- unsigned size, void* state)
-{
- struct r300_vap_output_state *vap_out_state =
- (struct r300_vap_output_state*)state;
- CS_LOCALS(r300);
-
- DBG(r300, DBG_DRAW, "r300: VAP emit:\n");
-
- BEGIN_CS(size);
- OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
- OUT_CS(vap_out_state->vap_vtx_state_cntl);
- OUT_CS(vap_out_state->vap_vsm_vtx_assm);
- OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
- OUT_CS(vap_out_state->vap_out_vtx_fmt[0]);
- OUT_CS(vap_out_state->vap_out_vtx_fmt[1]);
- END_CS;
-}
-
void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state)
{
CS_LOCALS(r300);
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index c3eb195d4e7..3c0edf6fdca 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -81,9 +81,6 @@ void r300_emit_vertex_buffer(struct r300_context* r300);
void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state);
-void r300_emit_vap_output_state(struct r300_context* r300,
- unsigned size, void* state);
-
void r300_emit_vs_constants(struct r300_context* r300,
unsigned size, void *state);
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 735c233c9e2..d58aa138a70 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -73,6 +73,7 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
#define DBG_NO_IMMD 0x0000200
#define DBG_STATS 0x0000400
#define DBG_RS 0x0000800
+#define DBG_TEXALLOC 0x0001000
/*@}*/
static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 9319dadfd1e..446422ca0f0 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -538,46 +538,12 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
}
/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
-static void r300_fb_update_tiling_flags(struct r300_context *r300,
+static void r300_fb_set_tiling_flags(struct r300_context *r300,
const struct pipe_framebuffer_state *old_state,
const struct pipe_framebuffer_state *new_state)
{
struct r300_texture *tex;
- unsigned i, j, level;
-
- /* Reset tiling flags for old surfaces to default values. */
- for (i = 0; i < old_state->nr_cbufs; i++) {
- for (j = 0; j < new_state->nr_cbufs; j++) {
- if (old_state->cbufs[i]->texture == new_state->cbufs[j]->texture) {
- break;
- }
- }
- /* If not binding the surface again... */
- if (j != new_state->nr_cbufs) {
- continue;
- }
-
- tex = r300_texture(old_state->cbufs[i]->texture);
-
- if (tex) {
- r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->macrotile);
- }
- }
- if (old_state->zsbuf &&
- (!new_state->zsbuf ||
- old_state->zsbuf->texture != new_state->zsbuf->texture)) {
- tex = r300_texture(old_state->zsbuf->texture);
-
- if (tex) {
- r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->macrotile);
- }
- }
+ unsigned i, level;
/* Set tiling flags for new surfaces. */
for (i = 0; i < new_state->nr_cbufs; i++) {
@@ -585,7 +551,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
level = new_state->cbufs[i]->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[level],
+ tex->pitch[0],
tex->microtile,
tex->mip_macrotile[level]);
}
@@ -594,7 +560,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
level = new_state->zsbuf->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[level],
+ tex->pitch[0],
tex->microtile,
tex->mip_macrotile[level]);
}
@@ -644,7 +610,8 @@ static void
r300->dsa_state.dirty = TRUE;
}
- r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
+ /* The tiling flags are dependent on the surface miplevel, unfortunately. */
+ r300_fb_set_tiling_flags(r300, r300->fb_state.state, state);
memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
@@ -719,10 +686,6 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
r300_mark_fs_code_dirty(r300);
r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
-
- if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) {
- r300->vap_output_state.dirty = TRUE;
- }
}
/* Delete fragment shader state. */
@@ -853,11 +816,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
- /* XXX Disable point sprites until we know what's wrong with them. */
- rs->rs.sprite_coord_enable = 0;
-
/* Point sprites */
- if (rs->rs.sprite_coord_enable) {
+ if (state->sprite_coord_enable) {
rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE;
for (i = 0; i < 8; i++) {
if (state->sprite_coord_enable & (1 << i))
@@ -1357,7 +1317,7 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
/* XXX Shouldn't we align the format? */
fprintf(stderr, "r300_create_vertex_elements_state: "
"Unaligned format %s:%i isn't supported\n",
- util_format_name(*format), size);
+ util_format_short_name(*format), size);
assert(0);
abort();
}
@@ -1428,14 +1388,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
}
r300->vs_state.state = vs;
- // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block
- if (r300->fs.state) {
- r300_vertex_shader_setup_wpos(r300);
- }
- memcpy(r300->vap_output_state.state, &vs->vap_out,
- sizeof(struct r300_vap_output_state));
- r300->vap_output_state.dirty = TRUE;
-
/* The majority of the RS block bits is dependent on the vertex shader. */
r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index ccc4b583a6a..e3adace0faa 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -115,12 +115,11 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
static void r300_swtcl_vertex_psc(struct r300_context *r300)
{
struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state;
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct vertex_info* vinfo = &r300->vertex_info;
+ struct vertex_info* vinfo = &r300->vertex_info;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
- int* vs_output_tab = vs->stream_loc_notcl;
+ int* vs_output_tab = r300->stream_loc_notcl;
/* XXX hax */
memset(vstream, 0, sizeof(struct r300_vertex_stream_state));
@@ -269,21 +268,29 @@ static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
/* Set up the RS block.
*
- * This is the part of the chipset that actually does the rasterization
- * of vertices into fragments. This is also the part of the chipset that
- * locks up if any part of it is even slightly wrong. */
-static void r300_update_rs_block(struct r300_context* r300,
- struct r300_shader_semantics* vs_outputs,
- struct r300_shader_semantics* fs_inputs)
+ * This is the part of the chipset that is responsible for linking vertex
+ * and fragment shaders and stuffed texture coordinates.
+ *
+ * The rasterizer reads data from VAP, which produces vertex shader outputs,
+ * and GA, which produces stuffed texture coordinates. VAP outputs have
+ * precedence over GA. All outputs must be rasterized otherwise it locks up.
+ * If there are more outputs rasterized than is set in VAP/GA, it locks up
+ * too. The funky part is that this info has been pretty much obtained by trial
+ * and error. */
+static void r300_update_rs_block(struct r300_context *r300)
{
- struct r300_rs_block rs = { { 0 } };
- int i, col_count = 0, tex_count = 0, fp_offset = 0, count;
+ struct r300_vertex_shader *vs = r300->vs_state.state;
+ struct r300_shader_semantics *vs_outputs = &vs->outputs;
+ struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs;
+ struct r300_rs_block rs = {0};
+ int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0;
void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
void (*rX00_rs_col_write)(struct r300_rs_block*, int, int);
void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int);
boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
vs_outputs->bcolor[1] != ATTR_UNUSED;
+ int *stream_loc_notcl = r300->stream_loc_notcl;
if (r300->screen->caps.is_r500) {
rX00_rs_col = r500_rs_col;
@@ -297,15 +304,31 @@ static void r300_update_rs_block(struct r300_context* r300,
rX00_rs_tex_write = r300_rs_tex_write;
}
- /* Rasterize colors. */
+ /* The position is always present in VAP. */
+ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
+ rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ stream_loc_notcl[loc++] = 0;
+
+ /* Set up the point size in VAP. */
+ if (vs_outputs->psize != ATTR_UNUSED) {
+ rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+ stream_loc_notcl[loc++] = 1;
+ }
+
+ /* Set up and rasterize colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
vs_outputs->color[1] != ATTR_UNUSED) {
- /* Always rasterize if it's written by the VS,
- * otherwise it locks up. */
+ /* Set up the color in VAP. */
+ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ rs.vap_out_vtx_fmt[0] |=
+ R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
+ stream_loc_notcl[loc++] = 2 + i;
+
+ /* Rasterize it. */
rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
- /* Write it to the FS input register if it's used by the FS. */
+ /* Write it to the FS input register if it's needed by the FS. */
if (fs_inputs->color[i] != ATTR_UNUSED) {
rX00_rs_col_write(&rs, col_count, fp_offset);
fp_offset++;
@@ -328,17 +351,33 @@ static void r300_update_rs_block(struct r300_context* r300,
}
}
+ /* Set up back-face colors. The rasterizer will do the color selection
+ * automatically. */
+ if (any_bcolor_used) {
+ for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+ stream_loc_notcl[loc++] = 4 + i;
+ }
+ }
+
/* Rasterize texture coordinates. */
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+ for (i = 0; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) {
bool sprite_coord = !!(r300->sprite_coord_enable & (1 << i));
if (vs_outputs->generic[i] != ATTR_UNUSED || sprite_coord) {
- /* Always rasterize if it's written by the VS,
- * otherwise it locks up. */
+ if (!sprite_coord) {
+ /* Set up the texture coordinates in VAP. */
+ rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
+ rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
+ stream_loc_notcl[loc++] = 6 + tex_count;
+ }
+
+ /* Rasterize it. */
rX00_rs_tex(&rs, tex_count, tex_count,
sprite_coord ? SWIZ_XY01 : SWIZ_XYZW);
- /* Write it to the FS input register if it's used by the FS. */
+ /* Write it to the FS input register if it's needed by the FS. */
if (fs_inputs->generic[i] != ATTR_UNUSED) {
rX00_rs_tex_write(&rs, tex_count, fp_offset);
fp_offset++;
@@ -365,12 +404,16 @@ static void r300_update_rs_block(struct r300_context* r300,
}
/* Rasterize fog coordinates. */
- if (vs_outputs->fog != ATTR_UNUSED) {
- /* Always rasterize if it's written by the VS,
- * otherwise it locks up. */
+ if (vs_outputs->fog != ATTR_UNUSED && tex_count < 8) {
+ /* Set up the fog coordinates in VAP. */
+ rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
+ rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
+ stream_loc_notcl[loc++] = 6 + tex_count;
+
+ /* Rasterize it. */
rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_X001);
- /* Write it to the FS input register if it's used by the FS. */
+ /* Write it to the FS input register if it's needed by the FS. */
if (fs_inputs->fog != ATTR_UNUSED) {
rX00_rs_tex_write(&rs, tex_count, fp_offset);
fp_offset++;
@@ -391,9 +434,17 @@ static void r300_update_rs_block(struct r300_context* r300,
}
/* Rasterize WPOS. */
- /* If the FS doesn't need it, it's not written by the VS. */
- if (vs_outputs->wpos != ATTR_UNUSED && fs_inputs->wpos != ATTR_UNUSED) {
+ /* Don't set it in VAP if the FS doesn't need it. */
+ if (fs_inputs->wpos != ATTR_UNUSED && tex_count < 8) {
+ /* Set up the WPOS coordinates in VAP. */
+ rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
+ rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
+ stream_loc_notcl[loc++] = 6 + tex_count;
+
+ /* Rasterize it. */
rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW);
+
+ /* Write it to the FS input register. */
rX00_rs_tex_write(&rs, tex_count, fp_offset);
DBG(r300, DBG_RS, "r300: Rasterized WPOS written to FS.\n");
@@ -402,6 +453,11 @@ static void r300_update_rs_block(struct r300_context* r300,
tex_count++;
}
+ /* Invalidate the rest of the no-TCL (GA) stream locations. */
+ for (; loc < 16;) {
+ stream_loc_notcl[loc++] = -1;
+ }
+
/* Rasterize at least one color, or bad things happen. */
if (col_count == 0 && tex_count == 0) {
rX00_rs_col(&rs, 0, 0, SWIZ_0001);
@@ -422,18 +478,10 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Now, after all that, see if we actually need to update the state. */
if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) {
memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block));
- r300->rs_block_state.size = 5 + count*2;
+ r300->rs_block_state.size = 11 + count*2;
}
}
-/* Update the shader-dependant states. */
-static void r300_update_derived_shader_state(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
-
- r300_update_rs_block(r300, &vs->outputs, &r300_fs(r300)->shader->inputs);
-}
-
static void r300_merge_textures_and_samplers(struct r300_context* r300)
{
struct r300_textures_state *state =
@@ -529,7 +577,7 @@ void r300_update_derived_state(struct r300_context* r300)
}
if (r300->rs_block_state.dirty) {
- r300_update_derived_shader_state(r300);
+ r300_update_rs_block(r300);
}
if (r300->draw) {
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index fcbdb91b67e..715601042fa 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -371,7 +371,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
desc = util_format_description(format);
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
- fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_name(format),
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_short_name(format),
__FUNCTION__, __LINE__);
assert(0);
abort();
@@ -394,7 +394,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
break;
default:
fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_name(format), __FUNCTION__, __LINE__);
+ util_format_short_name(format), __FUNCTION__, __LINE__);
assert(0);
abort();
}
@@ -416,7 +416,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
break;
default:
fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_name(format), __FUNCTION__, __LINE__);
+ util_format_short_name(format), __FUNCTION__, __LINE__);
fprintf(stderr, "r300: desc->channel[0].size == %d\n",
desc->channel[0].size);
assert(0);
@@ -425,7 +425,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
break;
default:
fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_name(format), __FUNCTION__, __LINE__);
+ util_format_short_name(format), __FUNCTION__, __LINE__);
assert(0);
abort();
}
@@ -449,7 +449,7 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_name(format), __FUNCTION__, __LINE__);
+ util_format_short_name(format), __FUNCTION__, __LINE__);
return 0;
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 69e6a124458..d6f629cf9c6 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -46,18 +46,6 @@ static const unsigned microblock_table[5][3][2] = {
{{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
};
-/* Return true for non-compressed and non-YUV formats. */
-static boolean r300_format_is_plain(enum pipe_format format)
-{
- const struct util_format_description *desc = util_format_description(format);
-
- if (!format) {
- return FALSE;
- }
-
- return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN;
-}
-
/* Translate a pipe_format into a useful texture format for sampling.
*
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
@@ -585,9 +573,6 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen,
f->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) |
R300_TXO_MICRO_TILE(tex->microtile);
-
- SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
- pt->width0, pt->height0, pt->last_level);
}
static void r300_texture_setup_fb_state(struct r300_screen* screen,
@@ -622,8 +607,8 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
{
struct r300_screen *r300screen = r300_screen(screen);
- SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
- util_format_name(tex->format), util_format_name(new_format));
+ SCREEN_DBG(r300screen, DBG_TEX, "r300: texture_reinterpret_format: %s -> %s\n",
+ util_format_short_name(tex->format), util_format_short_name(new_format));
tex->format = new_format;
@@ -714,7 +699,7 @@ unsigned r300_texture_get_stride(struct r300_screen* screen,
width = u_minify(tex->b.b.width0, level);
- if (r300_format_is_plain(tex->b.b.format)) {
+ if (util_format_is_plain(tex->b.b.format)) {
tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
tex->mip_macrotile[level]);
width = align(width, tile_width);
@@ -732,7 +717,7 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
height = u_minify(tex->b.b.height0, level);
- if (r300_format_is_plain(tex->b.b.format)) {
+ if (util_format_is_plain(tex->b.b.format)) {
tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
tex->mip_macrotile[level]);
height = align(height, tile_height);
@@ -774,8 +759,8 @@ static void r300_setup_miptree(struct r300_screen* screen,
unsigned stride, size, layer_size, nblocksy, i;
boolean rv350_mode = screen->caps.is_rv350;
- SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
- util_format_name(base->format));
+ SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Making miptree for texture, format %s\n",
+ util_format_short_name(base->format));
for (i = 0; i <= base->last_level; i++) {
/* Let's see if this miplevel can be macrotiled. */
@@ -801,7 +786,7 @@ static void r300_setup_miptree(struct r300_screen* screen,
tex->hwpitch[i] =
tex->pitch[i] * util_format_get_blockwidth(base->format);
- SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
+ SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
"(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
i, u_minify(base->width0, i), u_minify(base->height0, i),
u_minify(base->depth0, i), stride, tex->size,
@@ -825,7 +810,7 @@ static void r300_setup_tiling(struct pipe_screen *screen,
boolean is_zb = util_format_is_depth_or_stencil(format);
boolean dbg_no_tiling = SCREEN_DBG_ON(r300_screen(screen), DBG_NO_TILING);
- if (!r300_format_is_plain(format)) {
+ if (!util_format_is_plain(format)) {
return;
}
@@ -927,6 +912,17 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
return NULL;
}
+ /* Refuse to create a texture with size 0. */
+ if (!base->width0 ||
+ (!base->height0 && (base->target == PIPE_TEXTURE_2D ||
+ base->target == PIPE_TEXTURE_CUBE)) ||
+ (!base->depth0 && base->target == PIPE_TEXTURE_3D)) {
+ fprintf(stderr, "r300: texture_create: "
+ "Got invalid texture dimensions: %ix%ix%i\n",
+ base->width0, base->height0, base->depth0);
+ return NULL;
+ }
+
tex->b.b = *base;
tex->b.vtbl = &r300_texture_vtbl;
pipe_reference_init(&tex->b.b.reference, 1);
@@ -942,6 +938,15 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
r300_texture_setup_immutable_state(rscreen, tex);
r300_texture_setup_fb_state(rscreen, tex);
+ SCREEN_DBG(rscreen, DBG_TEX,
+ "r300: texture_create: Macro: %s, Micro: %s, Pitch: %i, "
+ "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
+ tex->macrotile ? "YES" : " NO",
+ tex->microtile ? "YES" : " NO",
+ tex->hwpitch[0],
+ base->width0, base->height0, base->depth0, base->last_level,
+ util_format_short_name(base->format));
+
tex->buffer = rws->buffer_create(rws, 2048,
PIPE_BIND_SAMPLER_VIEW, /* XXX */
tex->size);
@@ -1039,6 +1044,14 @@ r300_texture_from_handle(struct pipe_screen* screen,
rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile);
r300_setup_flags(tex);
+ SCREEN_DBG(rscreen, DBG_TEX,
+ "r300: texture_from_handle: Macro: %s, Micro: %s, "
+ "Pitch: % 4i, Dim: %ix%i, Format: %s\n",
+ tex->macrotile ? "YES" : " NO",
+ tex->microtile ? "YES" : " NO",
+ stride / util_format_get_blocksize(base->format),
+ base->width0, base->height0,
+ util_format_short_name(base->format));
/* Enforce microtiled zbuffer. */
override_zb_flags = util_format_is_depth_or_stencil(base->format) &&
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index bfab9c3b014..f3186431e1d 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -22,7 +22,6 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r300_vs.h"
-#include "r300_fs.h"
#include "r300_context.h"
#include "r300_screen.h"
@@ -94,94 +93,6 @@ static void r300_shader_read_vs_outputs(
vs_outputs->wpos = i;
}
-/* This function sets up:
- * - VAP mapping, which maps VS registers to output semantics and
- * at the same time it indicates which attributes are enabled and should
- * be rasterized.
- * - Stream mapping to VS outputs if TCL is not present. */
-static void r300_init_vs_output_mapping(struct r300_vertex_shader* vs)
-{
- struct r300_shader_semantics* vs_outputs = &vs->outputs;
- struct r300_vap_output_state *vap_out = &vs->vap_out;
- int *stream_loc = vs->stream_loc_notcl;
- int i, gen_count, tabi = 0;
- boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
- vs_outputs->bcolor[1] != ATTR_UNUSED;
-
- vap_out->vap_vtx_state_cntl = 0x5555; /* XXX this is classic Mesa bonghits */
-
- /* Position. */
- if (vs_outputs->pos != ATTR_UNUSED) {
- vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
- vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
-
- stream_loc[tabi++] = 0;
- } else {
- assert(0);
- }
-
- /* Point size. */
- if (vs_outputs->psize != ATTR_UNUSED) {
- vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
-
- stream_loc[tabi++] = 1;
- }
-
- /* Colors. */
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
- vs_outputs->color[1] != ATTR_UNUSED) {
- vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
- vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
-
- stream_loc[tabi++] = 2 + i;
- }
- }
-
- /* Back-face colors. */
- if (any_bcolor_used) {
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
- vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
-
- stream_loc[tabi++] = 4 + i;
- }
- }
-
- /* Texture coordinates. */
- gen_count = 0;
- for (i = 0; i < ATTR_GENERIC_COUNT && gen_count < 8; i++) {
- if (vs_outputs->generic[i] != ATTR_UNUSED) {
- vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
- vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
-
- stream_loc[tabi++] = 6 + gen_count;
- gen_count++;
- }
- }
-
- /* Fog coordinates. */
- if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) {
- vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
- vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
-
- stream_loc[tabi++] = 6 + gen_count;
- gen_count++;
- }
-
- /* WPOS. */
- if (gen_count < 8) {
- vs->wpos_tex_output = gen_count;
- stream_loc[tabi++] = 6 + gen_count;
- } else {
- vs_outputs->wpos = ATTR_UNUSED;
- }
-
- for (; tabi < 16;) {
- stream_loc[tabi++] = -1;
- }
-}
-
static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
{
struct r300_vertex_shader * vs = c->UserData;
@@ -246,9 +157,7 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
}
/* WPOS. */
- if (outputs->wpos != ATTR_UNUSED) {
- c->code->outputs[outputs->wpos] = reg++;
- }
+ c->code->outputs[outputs->wpos] = reg++;
}
static void r300_dummy_vertex_shader(
@@ -286,7 +195,6 @@ void r300_translate_vertex_shader(struct r300_context* r300,
tgsi_scan_shader(tokens, &vs->info);
r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
- r300_init_vs_output_mapping(vs);
/* Setup the compiler */
rc_init(&compiler.Base);
@@ -307,16 +215,11 @@ void r300_translate_vertex_shader(struct r300_context* r300,
r300_tgsi_to_rc(&ttr, tokens);
- compiler.RequiredOutputs =
- ~(~0 << (vs->info.num_outputs +
- (vs->outputs.wpos != ATTR_UNUSED ? 1 : 0)));
-
+ compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
/* Insert the WPOS output. */
- if (vs->outputs.wpos != ATTR_UNUSED) {
- rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
- }
+ rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
/* Invoke the compiler */
r3xx_compile_vertex_program(&compiler);
@@ -343,32 +246,3 @@ void r300_translate_vertex_shader(struct r300_context* r300,
/* And, finally... */
rc_destroy(&compiler.Base);
}
-
-boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vap_output_state *vap_out = &vs->vap_out;
- int tex_output = vs->wpos_tex_output;
- uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
-
- if (vs->outputs.wpos == ATTR_UNUSED) {
- return FALSE;
- }
-
- if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) {
- /* Enable WPOS in VAP. */
- if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) {
- vap_out->vap_vsm_vtx_assm |= tex_fmt;
- vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * tex_output));
- return TRUE;
- }
- } else {
- /* Disable WPOS in VAP. */
- if (vap_out->vap_vsm_vtx_assm & tex_fmt) {
- vap_out->vap_vsm_vtx_assm &= ~tex_fmt;
- vap_out->vap_out_vtx_fmt[1] &= ~(4 << (3 * tex_output));
- return TRUE;
- }
- }
- return FALSE;
-}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 56bcc3b70b8..57b3fbca0bb 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -39,7 +39,6 @@ struct r300_vertex_shader {
struct tgsi_shader_info info;
struct r300_shader_semantics outputs;
- struct r300_vap_output_state vap_out;
/* Whether the shader was replaced by a dummy one due to a shader
* compilation failure. */
@@ -49,12 +48,6 @@ struct r300_vertex_shader {
unsigned externals_count;
unsigned immediates_count;
- /* Stream locations for SWTCL or if TCL is bypassed. */
- int stream_loc_notcl[16];
-
- /* Output stream location for WPOS. */
- int wpos_tex_output;
-
/* HWTCL-specific. */
/* Machine code (if translated) */
struct r300_vertex_program_code code;
@@ -67,7 +60,4 @@ void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs,
const struct tgsi_token *tokens);
-/* Return TRUE if VAP (hwfmt) needs to be re-emitted. */
-boolean r300_vertex_shader_setup_wpos(struct r300_context* r300);
-
#endif /* R300_VS_H */