summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_state.c')
-rw-r--r--src/gallium/drivers/r300/r300_state.c143
1 files changed, 104 insertions, 39 deletions
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index d7d654dc31..f396b42e95 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -715,6 +715,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
{
struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
+ unsigned coord_index;
/* Copy rasterizer state for Draw. */
rs->rs = *state;
@@ -807,6 +808,32 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->color_control = R300_SHADE_MODEL_SMOOTH;
}
+ /* Point sprites */
+ if (state->sprite_coord_enable) {
+ coord_index = ffs(state->sprite_coord_enable)-1;
+
+ SCREEN_DBG(r300screen, DBG_DRAW,
+ "r300: point sprite: shader coord=%d\n", coord_index);
+
+ rs->stuffing_enable =
+ R300_GB_POINT_STUFF_ENABLE |
+ R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (coord_index*2));
+
+ rs->point_texcoord_left = 0.0f;
+ rs->point_texcoord_right = 1.0f;
+
+ switch (state->sprite_coord_mode) {
+ case PIPE_SPRITE_COORD_UPPER_LEFT:
+ rs->point_texcoord_top = 0.0f;
+ rs->point_texcoord_bottom = 1.0f;
+ break;
+ case PIPE_SPRITE_COORD_LOWER_LEFT:
+ rs->point_texcoord_top = 1.0f;
+ rs->point_texcoord_bottom = 0.0f;
+ break;
+ }
+ }
+
return (void*)rs;
}
@@ -816,6 +843,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
boolean scissor_was_enabled = r300->scissor_enabled;
+ int last_sprite_coord_index = r300->sprite_coord_index;
if (r300->draw) {
draw_flush(r300->draw);
@@ -825,17 +853,22 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
r300->scissor_enabled = rs->rs.scissor;
+ r300->sprite_coord_index = ffs(rs->rs.sprite_coord_enable)-1;
} else {
r300->polygon_offset_enabled = FALSE;
r300->scissor_enabled = FALSE;
+ r300->sprite_coord_index = -1;
}
UPDATE_STATE(state, r300->rs_state);
- r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
+ r300->rs_state.size = 24 + (r300->polygon_offset_enabled ? 5 : 0);
if (scissor_was_enabled != r300->scissor_enabled) {
r300->scissor_state.dirty = TRUE;
}
+ if (last_sprite_coord_index != r300->sprite_coord_index) {
+ r300->rs_block_state.dirty = TRUE;
+ }
}
/* Free rasterizer state. */
@@ -940,6 +973,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
+ struct r300_texture *texture;
unsigned i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
boolean dirty_tex = FALSE;
@@ -951,15 +985,18 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
for (i = 0; i < count; i++) {
if (state->fragment_sampler_views[i] != views[i]) {
- struct r300_texture *texture;
-
pipe_sampler_view_reference(&state->fragment_sampler_views[i],
views[i]);
- dirty_tex = TRUE;
- texture = (struct r300_texture *)views[i]->texture;
+ if (!views[i]) {
+ continue;
+ }
+
+ /* A new sampler view (= texture)... */
+ dirty_tex = TRUE;
/* R300-specific - set the texrect factor in the fragment shader */
+ texture = (struct r300_texture *)views[i]->texture;
if (!is_r500 && texture->is_npot) {
/* XXX It would be nice to re-emit just 1 constant,
* XXX not all of them */
@@ -1002,7 +1039,6 @@ r300_create_sampler_view(struct pipe_context *pipe,
return view;
}
-
static void
r300_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
@@ -1072,26 +1108,62 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
- int i;
- unsigned max_index = (1 << 24) - 1;
- boolean any_user_buffer = false;
+ struct pipe_vertex_buffer *vbo;
+ unsigned i, max_index = (1 << 24) - 1;
+ boolean any_user_buffer = FALSE;
if (count == r300->vertex_buffer_count &&
- memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0)
+ memcmp(r300->vertex_buffer, buffers,
+ sizeof(struct pipe_vertex_buffer) * count) == 0) {
return;
+ }
+ /* Check if the stride is aligned to the size of DWORD. */
for (i = 0; i < count; i++) {
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer);
- if (r300_buffer_is_user_buffer(buffers[i].buffer))
- any_user_buffer = true;
- max_index = MIN2(buffers[i].max_index, max_index);
+ if (buffers[i].buffer) {
+ if (buffers[i].stride % 4 != 0) {
+ // XXX Shouldn't we align the buffer?
+ fprintf(stderr, "r300_set_vertex_buffers: "
+ "Unaligned buffer stride %i isn't supported.\n",
+ buffers[i].stride);
+ assert(0);
+ abort();
+ }
+ }
}
- for ( ; i < r300->vertex_buffer_count; i++)
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
+ for (i = 0; i < count; i++) {
+ /* Why, yes, I AM casting away constness. How did you know? */
+ vbo = (struct pipe_vertex_buffer*)&buffers[i];
+
+ /* Reference our buffer. */
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
+
+ /* Skip NULL buffers */
+ if (!buffers[i].buffer) {
+ continue;
+ }
+
+ if (r300_buffer_is_user_buffer(vbo->buffer)) {
+ any_user_buffer = TRUE;
+ }
+
+ if (vbo->max_index == ~0) {
+ /* Bogus value from broken state tracker; hax it. */
+ vbo->max_index =
+ (vbo->buffer->size - vbo->buffer_offset) / vbo->stride;
+ }
+
+ max_index = MIN2(vbo->max_index, max_index);
+ }
+
+ for (; i < r300->vertex_buffer_count; i++) {
+ /* Dereference any old buffers. */
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
+ }
memcpy(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count);
+ sizeof(struct pipe_vertex_buffer) * count);
r300->vertex_buffer_count = count;
r300->vertex_buffer_max_index = max_index;
@@ -1103,22 +1175,6 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
}
}
-static boolean r300_validate_aos(struct r300_context *r300)
-{
- struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->velems->velem;
- int i;
-
- /* Check if formats and strides are aligned to the size of DWORD. */
- for (i = 0; i < r300->velems->count; i++) {
- if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
- util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
static void r300_draw_emit_attrib(struct r300_context* r300,
enum attrib_emit emit,
enum interp_mode interp,
@@ -1288,6 +1344,7 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
struct r300_context *r300 = r300_context(pipe);
struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_vertex_element_state *velems;
+ unsigned i, size;
assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
@@ -1296,6 +1353,20 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
if (r300screen->caps->has_tcl) {
+ /* Check if the format is aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ size = util_format_get_blocksize(attribs[i].src_format);
+
+ if (size % 4 != 0) {
+ /* 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(attribs[i].src_format), size);
+ assert(0);
+ abort();
+ }
+ }
+
r300_vertex_psc(velems);
} else {
memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
@@ -1324,12 +1395,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
}
- if (!r300_validate_aos(r300)) {
- /* XXX We should fallback using draw. */
- assert(0);
- abort();
- }
-
UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
}