diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_state.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index c5e313ce43..3cdcf94274 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -30,7 +30,6 @@ #include "tgsi/tgsi_parse.h" #include "pipe/p_config.h" -#include "pipe/internal/p_winsys_screen.h" #include "r300_context.h" #include "r300_reg.h" @@ -488,20 +487,30 @@ static void struct r300_context* r300 = r300_context(pipe); uint32_t zbuffer_bpp = 0; + r300->fb_state.size = (10 * state->nr_cbufs) + + (2 * (4 - state->nr_cbufs)) + + (state->zsbuf ? 10 : 0) + 6; + + if (state->nr_cbufs > 4) { + debug_printf("r300: Implementation error: Too many MRTs in %s, " + "refusing to bind framebuffer state!\n", __FUNCTION__); + return; + } + if (r300->draw) { draw_flush(r300->draw); } - r300->framebuffer_state = *state; + r300->fb_state.state = state; /* Don't rely on the order of states being set for the first time. */ - r300->dirty_state |= R300_NEW_FRAMEBUFFERS; - + /* XXX wait what */ r300->blend_state.dirty = TRUE; r300->dsa_state.dirty = TRUE; + r300->fb_state.dirty = TRUE; r300->scissor_state.dirty = TRUE; - /* Polyfon offset depends on the zbuffer bit depth. */ + /* Polygon offset depends on the zbuffer bit depth. */ if (state->zsbuf && r300->polygon_offset_enabled) { switch (util_format_get_blocksize(state->zsbuf->texture->format)) { case 2: @@ -552,7 +561,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300_pick_fragment_shader(r300); if (r300->vs && r300_vertex_shader_setup_wpos(r300)) { - r300->dirty_state |= R300_NEW_VERTEX_FORMAT; + r300->vertex_format_state.dirty = TRUE; } r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -720,7 +729,6 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) r300->viewport_state.dirty = TRUE; /* XXX Clean these up when we move to atom emits */ - r300->dirty_state |= R300_NEW_RS_BLOCK; if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) { r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -921,7 +929,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, draw_set_vertex_buffers(r300->draw, count, buffers); } - r300->dirty_state |= R300_NEW_VERTEX_FORMAT; + r300->vertex_format_state.dirty = TRUE; +} + +static boolean r300_validate_aos(struct r300_context *r300) +{ + struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; + struct pipe_vertex_element *velem = r300->vertex_element; + int i; + + /* Check if formats and strides are aligned to the size of DWORD. */ + for (i = 0; i < r300->vertex_element_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_set_vertex_elements(struct pipe_context* pipe, @@ -939,6 +963,12 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, count, elements); } + + if (!r300_validate_aos(r300)) { + /* XXX We should fallback using draw. */ + assert(0); + abort(); + } } static void* r300_create_vs_state(struct pipe_context* pipe, @@ -979,9 +1009,10 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300_vertex_shader_setup_wpos(r300); } + r300->vertex_format_state.dirty = TRUE; + r300->dirty_state |= - R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS | - R300_NEW_VERTEX_FORMAT; + R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, |