From 233290f2031057b37fdadb650873b02be307ebc8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 21 Feb 2010 20:49:29 +0100 Subject: r3OOg: support rendering of more than 65535 vertices per draw call (almost) The path for VAP_ALT_NUM_VERTICES is also in place (and tested) but not enabled by default due to the missing support of this reg in the upstream kernel. Also, a non-zero BUFFER_BASE in the INDX_BUFFER packet3 hangs the machine. Am I missing something? Because of this, only draw_arrays can render more than 65535 vertices without the use of VAP_ALT_NUM_VERTICES. --- src/gallium/drivers/r300/r300_render.c | 109 ++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 29 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cd4971ae13..754eb4dc76 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -42,6 +42,9 @@ /* r300_render: Vertex and index buffer primitive emission. */ #define R300_MAX_VBO_SIZE (1024 * 1024) +/* XXX The DRM rejects VAP_ALT_NUM_VERTICES.. */ +//#define ENABLE_ALT_NUM_VERTS + uint32_t r300_translate_primitive(unsigned prim) { switch (prim) { @@ -210,16 +213,28 @@ static void r300_emit_draw_arrays(struct r300_context *r300, unsigned mode, unsigned count) { +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = count > 65535; +#else + boolean alt_num_verts = FALSE; +#endif CS_LOCALS(r300); - BEGIN_CS(8); + if (alt_num_verts) { + assert(count < (1 << 24)); + BEGIN_CS(10); + OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); + } else { + BEGIN_CS(8); + } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | - r300_translate_primitive(mode)); + r300_translate_primitive(mode) | + (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); END_CS; } @@ -234,14 +249,27 @@ static void r300_emit_draw_elements(struct r300_context *r300, { uint32_t count_dwords; uint32_t offset_dwords = indexSize * start / sizeof(uint32_t); +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = count > 65535; +#else + boolean alt_num_verts = FALSE; +#endif CS_LOCALS(r300); - /* XXX most of these are stupid */ - assert(indexSize == 4 || indexSize == 2); assert((start * indexSize) % 4 == 0); - assert(offset_dwords == 0); - BEGIN_CS(14); + /* XXX Non-zero offset locks up. */ + if (offset_dwords != 0) { + return; + } + + if (alt_num_verts) { + assert(count < (1 << 24)); + BEGIN_CS(16); + OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); + } else { + BEGIN_CS(14); + } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex); @@ -251,24 +279,24 @@ static void r300_emit_draw_elements(struct r300_context *r300, count_dwords = count + start; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | R300_VAP_VF_CNTL__INDEX_SIZE_32bit | - r300_translate_primitive(mode)); + r300_translate_primitive(mode) | + (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); } else { count_dwords = (count + start + 1) / 2; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | - r300_translate_primitive(mode)); + r300_translate_primitive(mode) | + (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); } /* INDX_BUFFER is a truly special packet3. * Unlike most other packet3, where the offset is after the count, * the order is reversed, so the relocation ends up carrying the * size of the indexbuf instead of the offset. - * - * XXX Fix offset */ OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2); OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | (0 << R300_INDX_BUFFER_SKIP_SHIFT)); - OUT_CS(offset_dwords); + OUT_CS(offset_dwords << 2); OUT_CS_RELOC(indexBuffer, count_dwords, RADEON_GEM_DOMAIN_GTT, 0, 0); @@ -343,18 +371,18 @@ void r300_draw_range_elements(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); struct pipe_buffer* orgIndexBuffer = indexBuffer; +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = r300_screen(pipe->screen)->caps->is_r500 && + count > 65536; +#else + boolean alt_num_verts = FALSE; +#endif + unsigned short_count; if (!u_trim_pipe_prim(mode, &count)) { return; } - if (count > 65535) { - /* XXX: use aux/indices functions to split this into smaller - * primitives. - */ - return; - } - r300_update_derived_state(r300); r300_emit_buffer_validate(r300); @@ -381,8 +409,19 @@ void r300_draw_range_elements(struct pipe_context* pipe, r300_emit_aos(r300, 0); - r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, - mode, start, count); + if (alt_num_verts || count <= 65535) { + r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, + maxIndex, mode, start, count); + } else { + do { + short_count = MIN2(count, 65534); + r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, + maxIndex, mode, start, short_count); + + start += short_count; + count -= short_count; + } while (count); + } cleanup: if (indexBuffer != orgIndexBuffer) { @@ -404,18 +443,18 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, unsigned start, unsigned count) { struct r300_context* r300 = r300_context(pipe); +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = r300_screen(pipe->screen)->caps->is_r500 && + count > 65536; +#else + boolean alt_num_verts = FALSE; +#endif + unsigned short_count; if (!u_trim_pipe_prim(mode, &count)) { return; } - if (count > 65535) { - /* XXX: driver needs to handle this -- use the functions in - * aux/indices to split this into several smaller primitives. - */ - return; - } - r300_update_derived_state(r300); r300_emit_buffer_validate(r300); @@ -428,8 +467,20 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, } r300_emit_dirty_state(r300); - r300_emit_aos(r300, start); - r300_emit_draw_arrays(r300, mode, count); + + if (alt_num_verts || count <= 65535) { + r300_emit_aos(r300, start); + r300_emit_draw_arrays(r300, mode, count); + } else { + do { + short_count = MIN2(count, 65535); + r300_emit_aos(r300, start); + r300_emit_draw_arrays(r300, mode, short_count); + + start += short_count; + count -= short_count; + } while (count); + } } } -- cgit v1.2.3 From fff5be8e7b4557c221f2425dcafc2e7cbbba76ba Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 12 Feb 2010 15:39:51 +1000 Subject: r300g: rebuild winsys/pipe buffer handling and add buffer map This creates a cleaner winsys and drop the simple screen stuff. It makes r300g use pb_bufmgr structs and adds usage of the cached bufmgr for vertex/index buffers. It also avoids mapping too often. I'm not 100% sure this is perfect but it won't find its own bugs. Signed-off-by: Dave Airlie --- src/gallium/drivers/r300/Makefile | 1 + src/gallium/drivers/r300/r300_context.c | 38 ++- src/gallium/drivers/r300/r300_context.h | 9 +- src/gallium/drivers/r300/r300_cs.h | 22 +- src/gallium/drivers/r300/r300_emit.c | 54 +-- src/gallium/drivers/r300/r300_render.c | 33 +- src/gallium/drivers/r300/r300_screen.c | 38 ++- src/gallium/drivers/r300/r300_screen.h | 2 +- src/gallium/drivers/r300/r300_screen_buffer.c | 222 +++++++++++++ src/gallium/drivers/r300/r300_screen_buffer.h | 85 +++++ src/gallium/drivers/r300/r300_state.c | 25 +- src/gallium/drivers/r300/r300_texture.c | 41 +-- src/gallium/drivers/r300/r300_texture.h | 4 +- src/gallium/drivers/r300/r300_winsys.h | 127 +++++++- src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h | 2 - src/gallium/winsys/drm/radeon/core/Makefile | 2 +- src/gallium/winsys/drm/radeon/core/radeon_buffer.h | 60 ++-- src/gallium/winsys/drm/radeon/core/radeon_drm.c | 134 +++----- src/gallium/winsys/drm/radeon/core/radeon_drm.h | 5 - .../winsys/drm/radeon/core/radeon_drm_buffer.c | 361 +++++++++++++++++++++ src/gallium/winsys/drm/radeon/core/radeon_r300.c | 237 ++++++++++---- src/gallium/winsys/drm/radeon/core/radeon_r300.h | 6 +- src/gallium/winsys/drm/radeon/core/radeon_winsys.h | 86 ++--- 23 files changed, 1247 insertions(+), 347 deletions(-) create mode 100644 src/gallium/drivers/r300/r300_screen_buffer.c create mode 100644 src/gallium/drivers/r300/r300_screen_buffer.h create mode 100644 src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index afddcb161f..5707309bdf 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -14,6 +14,7 @@ C_SOURCES = \ r300_query.c \ r300_render.c \ r300_screen.c \ + r300_screen_buffer.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index f631b4ed27..a8a6a07a84 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -24,6 +24,7 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" +#include "util/u_upload_mgr.h" #include "r300_blit.h" #include "r300_context.h" @@ -54,6 +55,9 @@ static void r300_destroy_context(struct pipe_context* context) FREE(query); } + u_upload_destroy(r300->upload_vb); + u_upload_destroy(r300->upload_ib); + FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); FREE(r300->fb_state.state); @@ -70,11 +74,7 @@ r300_is_texture_referenced(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level) { - struct pipe_buffer* buf = 0; - - r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); - - return pipe->is_buffer_referenced(pipe, buf); + return 0; } static unsigned int @@ -136,14 +136,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, { struct r300_context* r300 = CALLOC_STRUCT(r300_context); struct r300_screen* r300screen = r300_screen(screen); - struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys; + struct r300_winsys_screen *rws = r300screen->rws; if (!r300) return NULL; - r300->winsys = radeon_winsys; + r300->rws = rws; - r300->context.winsys = (struct pipe_winsys*)radeon_winsys; + r300->context.winsys = (struct pipe_winsys*)rws; r300->context.screen = screen; r300->context.priv = priv; @@ -201,11 +201,31 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->invariant_state.dirty = TRUE; - r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); + rws->set_flush_cb(r300->rws, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw++; r300->blitter = util_blitter_create(&r300->context); + r300->upload_ib = u_upload_create(screen, + 32 * 1024, 16, + PIPE_BUFFER_USAGE_INDEX); + + if (r300->upload_ib == NULL) + goto no_upload_ib; + + r300->upload_vb = u_upload_create(screen, + 128 * 1024, 16, + PIPE_BUFFER_USAGE_VERTEX); + if (r300->upload_vb == NULL) + goto no_upload_vb; + return &r300->context; + + // u_upload_destroy(r300->upload_vb); + no_upload_ib: + u_upload_destroy(r300->upload_ib); + no_upload_vb: + FREE(r300); + return NULL; } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 443af4ec2e..749bac0498 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -32,6 +32,7 @@ #include "r300_screen.h" +struct u_upload_mgr; struct r300_context; struct r300_fragment_shader; @@ -238,7 +239,7 @@ struct r300_texture { boolean is_npot; /* Pipe buffer backing this texture. */ - struct pipe_buffer* buffer; + struct r300_winsys_buffer *buffer; /* Registers carrying texture format data. */ struct r300_texture_state state; @@ -265,7 +266,7 @@ struct r300_context { struct pipe_context context; /* The interface to the windowing system, etc. */ - struct radeon_winsys* winsys; + struct r300_winsys_screen *rws; /* Draw module. Used mostly for SW TCL. */ struct draw_context* draw; /* Accelerated blit support. */ @@ -330,6 +331,7 @@ struct r300_context { /* Vertex elements for Gallium. */ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; + bool any_user_vbs; struct pipe_stencil_ref stencil_ref; @@ -343,6 +345,9 @@ struct r300_context { boolean polygon_offset_enabled; /* Z buffer bit depth. */ uint32_t zbuffer_bpp; + + struct u_upload_mgr *upload_vb; + struct u_upload_mgr *upload_ib; }; /* Convenience cast wrapper. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 151f72b0fe..ad07efbffd 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -51,7 +51,7 @@ #define CS_LOCALS(context) \ struct r300_context* const cs_context_copy = (context); \ - struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \ + struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \ int cs_count = 0; (void) cs_count; #define CHECK_CS(size) \ @@ -105,22 +105,34 @@ cs_count--; \ } while (0) -#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ +#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \ "domains (%d, %d, %d)\n", \ bo, offset, rd, wd, flags); \ assert(bo); \ cs_winsys->write_cs_dword(cs_winsys, offset); \ - cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ + r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ cs_count -= 3; \ } while (0) -#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ + +#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \ + DBG(cs_context_copy, DBG_CS, "r300: writing relocation for texture %p, offset %d, " \ + "domains (%d, %d, %d)\n", \ + tex, offset, rd, wd, flags); \ + assert(tex); \ + cs_winsys->write_cs_dword(cs_winsys, offset); \ + r300_texture_write_reloc(cs_winsys, tex, rd, wd, flags); \ + cs_count -= 3; \ +} while (0) + + +#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \ "domains (%d, %d, %d)\n", \ bo, rd, wd, flags); \ assert(bo); \ - cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ + r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ cs_count -= 2; \ } while (0) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f7dcd8dc52..6fb1d7bd92 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,6 +32,8 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" +#include "r300_screen_buffer.h" +#include "r300_state_inlines.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) @@ -418,10 +420,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "cbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level], + OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); @@ -434,12 +436,12 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level], + OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); } @@ -489,13 +491,13 @@ static void r300_emit_query_finish(struct r300_context *r300, /* pipe 3 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), 0, RADEON_GEM_DOMAIN_GTT, 0); case 3: /* pipe 2 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), 0, RADEON_GEM_DOMAIN_GTT, 0); case 2: /* pipe 1 only */ @@ -503,13 +505,13 @@ static void r300_emit_query_finish(struct r300_context *r300, OUT_CS_REG(R300_SU_REG_DEST, 1 << (caps->high_second_pipe ? 3 : 1)); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), 0, RADEON_GEM_DOMAIN_GTT, 0); case 1: /* pipe 0 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), 0, RADEON_GEM_DOMAIN_GTT, 0); break; default: @@ -531,7 +533,7 @@ static void rv530_emit_query_single(struct r300_context *r300, BEGIN_CS(8); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -544,10 +546,10 @@ static void rv530_emit_query_double(struct r300_context *r300, BEGIN_CS(14); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -759,7 +761,7 @@ void r300_emit_texture(struct r300_context* r300, 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); - OUT_CS_RELOC(tex->buffer, + OUT_CS_TEX_RELOC(tex, R300_TXO_MACRO_TILE(tex->macrotile) | R300_TXO_MICRO_TILE(tex->microtile), RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); @@ -800,7 +802,7 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) } for (i = 0; i < aos_count; i++) { - OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, + OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, RADEON_GEM_DOMAIN_GTT, 0, 0); } END_CS; @@ -1012,15 +1014,15 @@ void r300_emit_buffer_validate(struct r300_context *r300) boolean invalid = FALSE; /* Clean out BOs. */ - r300->winsys->reset_bos(r300->winsys); + r300->rws->reset_bos(r300->rws); validate: /* Color buffers... */ for (i = 0; i < fb->nr_cbufs; i++) { tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300_add_texture(r300->rws, tex, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1029,8 +1031,8 @@ validate: if (fb->zsbuf) { tex = (struct r300_texture*)fb->zsbuf->texture; assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300_add_texture(r300->rws, tex, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1040,31 +1042,31 @@ validate: tex = r300->textures[i]; if (!tex) continue; - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { + if (!r300_add_texture(r300->rws, tex, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...occlusion query buffer... */ if (r300->dirty_state & R300_NEW_QUERY) { - if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, - 0, RADEON_GEM_DOMAIN_GTT)) { + if (!r300_add_buffer(r300->rws, r300->oqbo, + 0, RADEON_GEM_DOMAIN_GTT)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...and vertex buffer. */ if (r300->vbo) { - if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300_add_buffer(r300->rws, r300->vbo, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } else { /* debug_printf("No VBO while emitting dirty state!\n"); */ } - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { /* Well, hell. */ @@ -1096,7 +1098,7 @@ void r300_emit_dirty_state(struct r300_context* r300) /* Make sure we have at least 2*1024 spare dwords. */ /* XXX It would be nice to know the number of dwords we really need to * XXX emit. */ - while (!r300->winsys->check_cs(r300->winsys, dwords)) { + while (!r300->rws->check_cs(r300->rws, dwords)) { r300->context.flush(&r300->context, 0, NULL); } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 754eb4dc76..47f5d6f7f1 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -30,10 +30,12 @@ #include "util/u_format.h" #include "util/u_memory.h" +#include "util/u_upload_mgr.h" #include "util/u_prim.h" #include "r300_cs.h" #include "r300_context.h" +#include "r300_screen_buffer.h" #include "r300_emit.h" #include "r300_reg.h" #include "r300_render.h" @@ -297,7 +299,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | (0 << R300_INDX_BUFFER_SKIP_SHIFT)); OUT_CS(offset_dwords << 2); - OUT_CS_RELOC(indexBuffer, count_dwords, + OUT_CS_BUF_RELOC(indexBuffer, count_dwords, RADEON_GEM_DOMAIN_GTT, 0, 0); END_CS; @@ -308,21 +310,28 @@ static boolean r300_setup_vertex_buffers(struct r300_context *r300) struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_buffer *pbuf; + int ret; + + /* upload buffers first */ + if (r300->any_user_vbs) { + ret = r300_upload_user_buffers(r300); + r300->any_user_vbs = false; + } validate: for (int i = 0; i < r300->vertex_element_count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300_add_buffer(r300->rws, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { r300->context.flush(&r300->context, 0, NULL); - return r300->winsys->validate(r300->winsys); + return r300->rws->validate(r300->rws); } return TRUE; @@ -396,15 +405,20 @@ void r300_draw_range_elements(struct pipe_context* pipe, indexSize = 2; } - if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + r300_upload_index_buffer(r300, &indexBuffer, + indexSize, start, count); + + if (!r300_add_buffer(r300->rws, indexBuffer, + RADEON_GEM_DOMAIN_GTT, 0)) { goto cleanup; } - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { goto cleanup; } + u_upload_flush(r300->upload_vb); + u_upload_flush(r300->upload_ib); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); @@ -425,7 +439,7 @@ void r300_draw_range_elements(struct pipe_context* pipe, cleanup: if (indexBuffer != orgIndexBuffer) { - pipe->screen->buffer_destroy(indexBuffer); + pipe_buffer_reference( &indexBuffer, NULL ); } } @@ -466,6 +480,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return; } + u_upload_flush(r300->upload_vb); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 6a55570571..3b70312c82 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -23,7 +23,6 @@ #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" -#include "util/u_simple_screen.h" #include "r300_context.h" #include "r300_screen.h" @@ -32,6 +31,8 @@ #include "radeon_winsys.h" #include "r300_winsys.h" +#include "r300_screen_buffer.h" + /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. * @@ -292,10 +293,11 @@ static void* r300_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; + struct r300_winsys_screen *rws = r300_winsys_screen(screen); char* map; enum pipe_format format = tex->tex.format; - map = pipe_buffer_map(screen, tex->buffer, + map = rws->buffer_map(rws, tex->buffer, pipe_transfer_buffer_flags(transfer)); if (!map) { @@ -311,21 +313,26 @@ static void r300_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; - pipe_buffer_unmap(screen, tex->buffer); + struct r300_winsys_screen *rws = r300_winsys_screen(screen); + rws->buffer_unmap(rws, tex->buffer); } static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); + struct r300_winsys_screen *rws = r300_winsys_screen(pscreen); + + if (rws) + rws->destroy(rws); FREE(r300screen->caps); FREE(r300screen); } -struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) +struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) { - struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); - struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); + struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen); + struct r300_capabilities *caps = CALLOC_STRUCT(r300_capabilities); if (!r300screen || !caps) { FREE(r300screen); @@ -333,16 +340,16 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) return NULL; } - caps->pci_id = radeon_winsys->pci_id; - caps->num_frag_pipes = radeon_winsys->gb_pipes; - caps->num_z_pipes = radeon_winsys->z_pipes; + caps->pci_id = rws->get_value(rws, R300_VID_PCI_ID); + caps->num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES); + caps->num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES); r300_init_debug(r300screen); r300_parse_chipset(caps); r300screen->caps = caps; - r300screen->radeon_winsys = radeon_winsys; - r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys; + r300screen->rws = rws; + r300screen->screen.winsys = (struct pipe_winsys*)rws; r300screen->screen.destroy = r300_destroy_screen; r300screen->screen.get_name = r300_get_name; r300screen->screen.get_vendor = r300_get_vendor; @@ -356,7 +363,12 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) r300screen->screen.transfer_unmap = r300_transfer_unmap; r300_init_screen_texture_functions(&r300screen->screen); - u_simple_screen_init(&r300screen->screen); - + r300_screen_init_buffer_functions(r300screen); return &r300screen->screen; } + +struct r300_winsys_screen * +r300_winsys_screen(struct pipe_screen *screen) +{ + return r300_screen(screen)->rws; +} diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 502fbfa5a2..87fc6190ce 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -33,7 +33,7 @@ struct r300_screen { /* Parent class */ struct pipe_screen screen; - struct radeon_winsys* radeon_winsys; + struct r300_winsys_screen *rws; /* Chipset capabilities */ struct r300_capabilities* caps; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c new file mode 100644 index 0000000000..358582ea21 --- /dev/null +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -0,0 +1,222 @@ +#include + +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" +#include "util/u_upload_mgr.h" + +#include "r300_screen_buffer.h" + +#include "r300_winsys.h" + +int r300_upload_index_buffer(struct r300_context *r300, + struct pipe_buffer **index_buffer, + unsigned index_size, + unsigned start, + unsigned count) +{ + struct pipe_buffer *upload_buffer = NULL; + unsigned index_offset = start * index_size; + int ret = 0; + + if (r300_buffer_is_user_buffer(*index_buffer)) { + ret = u_upload_buffer(r300->upload_ib, + index_offset, + count * index_size, + *index_buffer, + &index_offset, + &upload_buffer); + if (ret) { + goto done; + } + *index_buffer = upload_buffer; + } + done: + // if (upload_buffer) + // pipe_buffer_reference(&upload_buffer, NULL); + return ret; +} + +int r300_upload_user_buffers(struct r300_context *r300) +{ + enum pipe_error ret = PIPE_OK; + int i, nr; + + nr = r300->vertex_buffer_count; + + for (i = 0; i < nr; i++) { + + if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) { + struct pipe_buffer *upload_buffer = NULL; + unsigned offset = 0; + unsigned size = r300->vertex_buffer[i].buffer->size; + unsigned upload_offset; + + ret = u_upload_buffer(r300->upload_vb, + offset, size, + r300->vertex_buffer[i].buffer, + &upload_offset, &upload_buffer); + if (ret) + return ret; + + pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); + r300->vertex_buffer[i].buffer = upload_buffer; + r300->vertex_buffer[i].buffer_offset = upload_offset; + } + } + return ret; +} + +static struct r300_winsys_buffer * +r300_winsys_buffer_create(struct r300_screen *r300screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_winsys_buffer *buf; + + buf = rws->buffer_create(rws, alignment, usage, size); + return buf; +} + +static void r300_winsys_buffer_destroy(struct r300_screen *r300screen, + struct r300_buffer *rbuf) +{ + struct r300_winsys_screen *rws = r300screen->rws; + + if (rbuf->buf) { + rws->buffer_destroy(rbuf->buf); + rbuf->buf = NULL; + } +} + +static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_buffer *rbuf; + + rbuf = CALLOC_STRUCT(r300_buffer); + if (!rbuf) + goto error1; + + rbuf->magic = R300_BUFFER_MAGIC; + + pipe_reference_init(&rbuf->base.reference, 1); + rbuf->base.screen = screen; + rbuf->base.alignment = alignment; + rbuf->base.usage = usage; + rbuf->base.size = size; + + rbuf->buf = r300_winsys_buffer_create(r300screen, + alignment, + usage, + size); + + if (!rbuf->buf) + goto error2; + + return &rbuf->base; +error2: + FREE(rbuf); +error1: + return NULL; +} + + +static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes) +{ + struct r300_buffer *rbuf; + + rbuf = CALLOC_STRUCT(r300_buffer); + if (!rbuf) + goto no_rbuf; + + rbuf->magic = R300_BUFFER_MAGIC; + + pipe_reference_init(&rbuf->base.reference, 1); + rbuf->base.screen = screen; + rbuf->base.alignment = 1; + rbuf->base.usage = 0; + rbuf->base.size = bytes; + + rbuf->user_buffer = ptr; + return &rbuf->base; + +no_rbuf: + return NULL; +} + +static void r300_buffer_destroy(struct pipe_buffer *buf) +{ + struct r300_screen *r300screen = r300_screen(buf->screen); + struct r300_buffer *rbuf = r300_buffer(buf); + + r300_winsys_buffer_destroy(r300screen, rbuf); + FREE(rbuf); +} + +static void * +r300_buffer_map_range(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned length, + unsigned usage ) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_buffer *rbuf = r300_buffer(buf); + void *map; + + if (rbuf->user_buffer) + return rbuf->user_buffer; + + map = rws->buffer_map(rws, rbuf->buf, usage); + + return map; +} + +static void * +r300_buffer_map(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned usage) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_buffer *rbuf = r300_buffer(buf); + void *map; + + if (rbuf->user_buffer) + return rbuf->user_buffer; + + map = rws->buffer_map(rws, rbuf->buf, usage); + + return map; +} + +static void +r300_buffer_unmap(struct pipe_screen *screen, + struct pipe_buffer *buf) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_buffer *rbuf = r300_buffer(buf); + + if (rbuf->buf) + rws->buffer_unmap(rws, rbuf->buf); +} + +void r300_screen_init_buffer_functions(struct r300_screen *r300screen) +{ + r300screen->screen.buffer_create = r300_buffer_create; + r300screen->screen.user_buffer_create = r300_user_buffer_create; + r300screen->screen.buffer_map = r300_buffer_map; + r300screen->screen.buffer_map_range = r300_buffer_map_range; +// r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range; + r300screen->screen.buffer_unmap = r300_buffer_unmap; + r300screen->screen.buffer_destroy = r300_buffer_destroy; +} diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h new file mode 100644 index 0000000000..7c026508b5 --- /dev/null +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -0,0 +1,85 @@ +#ifndef R300_SCREEN_BUFFER_H +#define R300_SCREEN_BUFFER_H +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "r300_screen.h" + +#include "r300_winsys.h" +#include "r300_context.h" + +#define R300_BUFFER_MAGIC 0xabcd1234 + +struct r300_buffer +{ + struct pipe_buffer base; + + uint32_t magic; + + struct r300_winsys_buffer *buf; + + void *user_buffer; +}; + +static INLINE struct r300_buffer * +r300_buffer(struct pipe_buffer *buffer) +{ + if (buffer) { + assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC); + return (struct r300_buffer *)buffer; + } + return NULL; +} + +static INLINE boolean +r300_buffer_is_user_buffer(struct pipe_buffer *buffer) +{ + return r300_buffer(buffer)->user_buffer ? true : false; +} + +static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws, + struct pipe_buffer *buffer, + int rd, int wr) +{ + struct r300_buffer *buf = r300_buffer(buffer); + + if (!buf->buf) + return true; + + return rws->add_buffer(rws, buf->buf, rd, wr); +} + + +static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws, + struct r300_texture *tex, + int rd, int wr) +{ + return rws->add_buffer(rws, tex->buffer, rd, wr); +} + +void r300_screen_init_buffer_functions(struct r300_screen *r300screen); + +static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws, + struct r300_buffer *buf, + uint32_t rd, uint32_t wd, uint32_t flags) +{ + if (!buf->buf) + return; + + rws->write_cs_reloc(rws, buf->buf, rd, wd, flags); +} + +static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws, + struct r300_texture *texture, + uint32_t rd, uint32_t wd, uint32_t flags) +{ + rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags); +} + +int r300_upload_user_buffers(struct r300_context *r300); + +int r300_upload_index_buffer(struct r300_context *r300, + struct pipe_buffer **index_buffer, + unsigned index_size, + unsigned start, + unsigned count); +#endif diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c193..d8a87dec15 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -34,6 +34,7 @@ #include "r300_context.h" #include "r300_reg.h" #include "r300_screen.h" +#include "r300_screen_buffer.h" #include "r300_state_inlines.h" #include "r300_fs.h" #include "r300_vs.h" @@ -521,7 +522,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->cbufs[i]->texture; if (tex) { - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -533,7 +534,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->zsbuf->texture; if (tex) { - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -545,7 +546,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->cbufs[i]->texture; level = new_state->cbufs[i]->level; - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -554,7 +555,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->zsbuf->texture; level = new_state->zsbuf->level; - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -1028,10 +1029,26 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); + boolean any_user_buffer = false; + int i; + + if (count == r300->vertex_buffer_count && + memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0) + return; + + 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; + } + + for ( ; i < r300->vertex_buffer_count; i++) + pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); memcpy(r300->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); r300->vertex_buffer_count = count; + r300->any_user_vbs = any_user_buffer; if (r300->draw) { draw_flush(r300->draw); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index ed2be06254..9016e86ccd 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -731,7 +731,7 @@ static struct pipe_texture* { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); struct r300_screen* rscreen = r300_screen(screen); - struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; if (!tex) { return NULL; @@ -745,13 +745,13 @@ static struct pipe_texture* r300_setup_miptree(rscreen, tex); r300_setup_texture_state(rscreen, tex); - tex->buffer = screen->buffer_create(screen, 2048, - PIPE_BUFFER_USAGE_PIXEL, - tex->size); - winsys->buffer_set_tiling(winsys, tex->buffer, - tex->pitch[0], - tex->microtile != R300_BUFFER_LINEAR, - tex->macrotile != R300_BUFFER_LINEAR); + tex->buffer = rws->buffer_create(rws, 2048, + PIPE_BUFFER_USAGE_PIXEL, + tex->size); + rws->buffer_set_tiling(rws, tex->buffer, + tex->pitch[0], + tex->microtile != R300_BUFFER_LINEAR, + tex->macrotile != R300_BUFFER_LINEAR); if (!tex->buffer) { FREE(tex); @@ -764,9 +764,9 @@ static struct pipe_texture* static void r300_texture_destroy(struct pipe_texture* texture) { struct r300_texture* tex = (struct r300_texture*)texture; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; - pipe_buffer_reference(&tex->buffer, NULL); - + rws->buffer_reference(rws, &tex->buffer, NULL); FREE(tex); } @@ -806,14 +806,14 @@ static void r300_tex_surface_destroy(struct pipe_surface* s) FREE(s); } -static struct pipe_texture* - r300_texture_blanket(struct pipe_screen* screen, - const struct pipe_texture* base, - const unsigned* stride, - struct pipe_buffer* buffer) +struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, + const struct pipe_texture *base, + const unsigned *stride, + struct r300_winsys_buffer *buffer) { struct r300_texture* tex; struct r300_screen* rscreen = r300_screen(screen); + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || @@ -837,7 +837,7 @@ static struct pipe_texture* r300_setup_flags(tex); r300_setup_texture_state(rscreen, tex); - pipe_buffer_reference(&tex->buffer, buffer); + rws->buffer_reference(rws, &tex->buffer, buffer); return (struct pipe_texture*)tex; } @@ -896,7 +896,6 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; screen->tex_surface_destroy = r300_tex_surface_destroy; - screen->texture_blanket = r300_texture_blanket; screen->video_surface_create = r300_video_surface_create; screen->video_surface_destroy= r300_video_surface_destroy; @@ -904,19 +903,23 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct pipe_buffer** buffer, + struct r300_winsys_buffer** buffer, unsigned* stride) { struct r300_texture* tex = (struct r300_texture*)texture; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; + struct r300_winsys_buffer *buf; + if (!tex) { return FALSE; } - pipe_buffer_reference(buffer, tex->buffer); + rws->buffer_reference(rws, &buf, tex->buffer); if (stride) { *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); } + *buffer = buf; return TRUE; } diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 46a5fb6188..97724f790c 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -63,8 +63,8 @@ r300_video_surface(struct pipe_video_surface *pvs) #ifndef R300_WINSYS_H boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, + struct pipe_texture *texture, + struct r300_winsys_buffer** buffer, unsigned* stride); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 40fb8a95ca..c6f9174496 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -23,10 +23,6 @@ #ifndef R300_WINSYS_H #define R300_WINSYS_H -#ifdef __cplusplus -extern "C" { -#endif - /* The public interface header for the r300 pipe driver. * Any winsys hosting this pipe needs to implement r300_winsys and then * call r300_create_screen to start things. */ @@ -34,19 +30,128 @@ extern "C" { #include "pipe/p_defines.h" #include "pipe/p_state.h" -struct radeon_winsys; +struct r300_winsys_screen; /* Creates a new r300 screen. */ -struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); +struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws); + +struct r300_winsys_buffer; boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride); + struct r300_winsys_buffer** buffer, + unsigned *stride); + +enum r300_value_id { + R300_VID_PCI_ID, + R300_VID_GB_PIPES, + R300_VID_Z_PIPES, +}; + +struct r300_winsys_screen { + void (*destroy)(struct r300_winsys_screen *ws); + + /** + * Buffer management. Buffer attributes are mostly fixed over its lifetime. + * + * Remember that gallium gets to choose the interface it needs, and the + * window systems must then implement that interface (rather than the + * other way around...). + * + * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This + * usage argument is only an optimization hint, not a guarantee, therefore + * proper behavior must be observed in all circumstances. + * + * alignment indicates the client's alignment requirements, eg for + * SSE instructions. + */ + struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws, + unsigned alignment, + unsigned usage, + unsigned size); + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags. + */ + void *(*buffer_map)( struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf, + unsigned usage ); + + void (*buffer_unmap)( struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf ); + + void (*buffer_destroy)( struct r300_winsys_buffer *buf ); + + + void (*buffer_reference)(struct r300_winsys_screen *rws, + struct r300_winsys_buffer **pdst, + struct r300_winsys_buffer *src); + + boolean (*buffer_references)(struct r300_winsys_buffer *a, + struct r300_winsys_buffer *b); + + /* Add a pipe_buffer to the list of buffer objects to validate. */ + boolean (*add_buffer)(struct r300_winsys_screen *winsys, + struct r300_winsys_buffer *buf, + uint32_t rd, + uint32_t wd); + + /* Revalidate all currently setup pipe_buffers. + * Returns TRUE if a flush is required. */ + boolean (*validate)(struct r300_winsys_screen* winsys); + + /* Check to see if there's room for commands. */ + boolean (*check_cs)(struct r300_winsys_screen* winsys, int size); + + /* Start a command emit. */ + void (*begin_cs)(struct r300_winsys_screen* winsys, + int size, + const char* file, + const char* function, + int line); + + /* Write a dword to the command buffer. */ + void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword); + + /* Write a relocated dword to the command buffer. */ + void (*write_cs_reloc)(struct r300_winsys_screen *winsys, + struct r300_winsys_buffer *buf, + uint32_t rd, + uint32_t wd, + uint32_t flags); + + /* Finish a command emit. */ + void (*end_cs)(struct r300_winsys_screen* winsys, + const char* file, + const char* function, + int line); + + /* Flush the CS. */ + void (*flush_cs)(struct r300_winsys_screen* winsys); + + /* winsys flush - callback from winsys when flush required */ + void (*set_flush_cb)(struct r300_winsys_screen *winsys, + void (*flush_cb)(void *), void *data); + + void (*reset_bos)(struct r300_winsys_screen *winsys); + + void (*buffer_set_tiling)(struct r300_winsys_screen *winsys, + struct r300_winsys_buffer *buffer, + uint32_t pitch, + boolean microtiled, + boolean macrotiled); + + uint32_t (*get_value)(struct r300_winsys_screen *winsys, + enum r300_value_id vid); +}; -#ifdef __cplusplus -} -#endif +struct r300_winsys_screen * +r300_winsys_screen(struct pipe_screen *screen); +struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, + const struct pipe_texture *base, + const unsigned *stride, + struct r300_winsys_buffer *buffer); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h index c6a7d4a8c5..b36680eb66 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h @@ -32,8 +32,6 @@ i965_libdrm_winsys(struct brw_winsys_screen *iws) return (struct i965_libdrm_winsys *)iws; } -struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id); - void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws); diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/drm/radeon/core/Makefile index 860cbb6dbf..13bbbf730d 100644 --- a/src/gallium/winsys/drm/radeon/core/Makefile +++ b/src/gallium/winsys/drm/radeon/core/Makefile @@ -5,7 +5,7 @@ include $(TOP)/configs/current LIBNAME = radeonwinsys C_SOURCES = \ - radeon_buffer.c \ + radeon_drm_buffer.c \ radeon_drm.c \ radeon_r300.c diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index f1c8fc2a3b..8e0274e33d 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -32,11 +32,11 @@ #include -#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "pipebuffer/pb_buffer.h" +#include "pipebuffer/pb_bufmgr.h" #include "util/u_memory.h" @@ -47,41 +47,41 @@ #include "radeon_winsys.h" -struct radeon_pipe_buffer { - struct pipe_buffer base; - /* Pointer to GPU-backed BO. */ - struct radeon_bo *bo; - /* Pointer to fallback PB buffer. */ - struct pb_buffer *pb; - boolean flinked; - uint32_t flink; -}; #define RADEON_MAX_BOS 24 -struct radeon_winsys_priv { - /* DRM FD */ - int fd; +static INLINE struct pb_buffer * +radeon_pb_buffer(struct r300_winsys_buffer *buffer) +{ + return (struct pb_buffer *)buffer; +} - /* Radeon BO manager. */ - struct radeon_bo_manager* bom; +static INLINE struct r300_winsys_buffer * +radeon_libdrm_winsys_buffer(struct pb_buffer *buffer) +{ + return (struct r300_winsys_buffer *)buffer; +} - /* Radeon CS manager. */ - struct radeon_cs_manager* csm; +struct pb_manager * +radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws); - /* Current CS. */ - struct radeon_cs* cs; +boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd); - /* Flush CB */ - void (*flush_cb)(void *); - void *flush_data; -}; -struct radeon_winsys* radeon_pipe_winsys(int fb); -#if 0 -struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, - uint32_t handle, - enum pipe_format format, - int w, int h, int pitch); -#endif +void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd, + uint32_t flags); + +struct radeon_libdrm_winsys* radeon_pipe_winsys(int fd); + +boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, + uint32_t *handle); +uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf); +struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, + uint32_t handle); + +void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch); + +void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr); #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index 0c0e118ba3..f886fda2f2 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -31,8 +31,22 @@ #include "radeon_drm.h" +static struct radeon_libdrm_winsys * +radeon_winsys_create(int fd) +{ + struct radeon_libdrm_winsys *rws; + + rws = CALLOC_STRUCT(radeon_libdrm_winsys); + if (rws == NULL) { + return NULL; + } + + rws->fd = fd; + return rws; +} + /* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(int fd, struct radeon_winsys* winsys) +static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) { struct drm_radeon_gem_info gem_info = {0}; struct drm_radeon_info info = {0}; @@ -123,62 +137,26 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg) { - struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB); - do_ioctls(drmFB, rwinsys); + struct radeon_libdrm_winsys* rws; + + rws = radeon_winsys_create(drmFB); + if (!rws) + return NULL; + + do_ioctls(drmFB, rws); /* The state tracker can organize a softpipe fallback if no hw * driver is found. */ - if (is_r3xx(rwinsys->pci_id)) { - radeon_setup_winsys(drmFB, rwinsys); - return r300_create_screen(rwinsys); + if (is_r3xx(rws->pci_id)) { + radeon_setup_winsys(drmFB, rws); + return r300_create_screen(&rws->base); } else { - FREE(rwinsys); + FREE(rws); return NULL; } } - -boolean radeon_buffer_from_texture(struct drm_api* api, - struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride) -{ - /* XXX fix this */ - return r300_get_texture_buffer(screen, texture, buffer, stride); -} - -/* Create a buffer from a handle. */ -/* XXX what's up with name? */ -struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, - struct pipe_screen* screen, - const char* name, - unsigned handle) -{ - struct radeon_bo_manager* bom = - ((struct radeon_winsys*)screen->winsys)->priv->bom; - struct radeon_pipe_buffer* radeon_buffer; - struct radeon_bo* bo = NULL; - - bo = radeon_bo_open(bom, handle, 0, 0, 0, 0); - if (bo == NULL) { - return NULL; - } - - radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); - if (radeon_buffer == NULL) { - radeon_bo_unref(bo); - return NULL; - } - - pipe_reference_init(&radeon_buffer->base.reference, 1); - radeon_buffer->base.screen = screen; - radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; - radeon_buffer->bo = bo; - return &radeon_buffer->base; -} - static struct pipe_texture* radeon_texture_from_shared_handle(struct drm_api *api, struct pipe_screen *screen, @@ -187,18 +165,20 @@ radeon_texture_from_shared_handle(struct drm_api *api, unsigned stride, unsigned handle) { - struct pipe_buffer *buffer; + struct pb_buffer *_buf; + struct r300_winsys_buffer *buf; struct pipe_texture *blanket; + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(r300_winsys_screen(screen)); - buffer = radeon_buffer_from_handle(api, screen, name, handle); - if (!buffer) { - return NULL; + _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle); + if (!_buf) { + return NULL; } - blanket = screen->texture_blanket(screen, templ, &stride, buffer); - - pipe_buffer_reference(&buffer, NULL); + buf = radeon_libdrm_winsys_buffer(_buf); + blanket = r300_texture_blanket_winsys_buffer(screen, templ, &stride, buf); + pb_reference(&_buf, NULL); return blanket; } @@ -208,34 +188,14 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - int retval, fd; - struct drm_gem_flink flink; - struct radeon_pipe_buffer* radeon_buffer; - struct pipe_buffer *buffer = NULL; - - if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { + struct r300_winsys_buffer *radeon_buffer; + struct pb_buffer *_buf; + if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { return FALSE; } - radeon_buffer = (struct radeon_pipe_buffer*)buffer; - if (!radeon_buffer->flinked) { - fd = ((struct radeon_winsys*)screen->winsys)->priv->fd; - - flink.handle = radeon_buffer->bo->handle; - - retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - if (retval) { - debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", - retval); - return FALSE; - } - - radeon_buffer->flink = flink.name; - radeon_buffer->flinked = TRUE; - } - - *handle = radeon_buffer->flink; - return TRUE; + _buf = radeon_pb_buffer(radeon_buffer); + return radeon_drm_bufmgr_shared_handle_from_buffer(_buf, handle); } static boolean radeon_local_handle_from_texture(struct drm_api *api, @@ -244,16 +204,18 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - struct pipe_buffer *buffer = NULL; - if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { + struct r300_winsys_buffer *radeon_buffer; + struct pb_buffer *_buf; + + if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { return FALSE; } - *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle; - - pipe_buffer_reference(&buffer, NULL); + _buf = radeon_pb_buffer(radeon_buffer); + *handle = radeon_drm_bufmgr_handle_from_buffer(_buf); - return TRUE; + pb_reference(&_buf, NULL); + return true; } static void radeon_drm_api_destroy(struct drm_api *api) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 8d74cbafc2..2f55061330 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -59,11 +59,6 @@ boolean radeon_buffer_from_texture(struct drm_api* api, struct pipe_buffer** buffer, unsigned* stride); -struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, - struct pipe_screen* screen, - const char* name, - unsigned handle); - boolean radeon_handle_from_buffer(struct drm_api* api, struct pipe_screen* screen, struct pipe_buffer* buffer, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c new file mode 100644 index 0000000000..5f2fd2d7fc --- /dev/null +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c @@ -0,0 +1,361 @@ + +#include "radeon_drm.h" +#include "radeon_bo_gem.h" +#include "radeon_cs_gem.h" + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" +#include "pipebuffer/pb_buffer.h" +#include "pipebuffer/pb_bufmgr.h" + +#include "radeon_winsys.h" +struct radeon_drm_bufmgr; + +struct radeon_drm_buffer { + struct pb_buffer base; + struct radeon_drm_bufmgr *mgr; + + struct radeon_bo *bo; + + boolean flinked; + uint32_t flink; + + boolean mapped; + struct radeon_drm_buffer *next, *prev; +}; + +extern const struct pb_vtbl radeon_drm_buffer_vtbl; + + +static INLINE struct radeon_drm_buffer * +radeon_drm_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &radeon_drm_buffer_vtbl); + return (struct radeon_drm_buffer *)buf; +} + +struct radeon_drm_bufmgr { + struct pb_manager base; + struct radeon_libdrm_winsys *rws; + struct radeon_drm_buffer buffer_map_list; +}; + +static INLINE struct radeon_drm_bufmgr * +radeon_drm_bufmgr(struct pb_manager *mgr) +{ + assert(mgr); + return (struct radeon_drm_bufmgr *)mgr; +} + +static void +radeon_drm_buffer_destroy(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + + if (buf->mapped) { + remove_from_list(buf); + radeon_bo_unmap(buf->bo); + buf->mapped = false; + } + radeon_bo_unref(buf->bo); + + FREE(buf); +} + +static void * +radeon_drm_buffer_map(struct pb_buffer *_buf, + unsigned flags) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + int write; + + if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { + uint32_t domain; + + if (radeon_bo_is_busy(buf->bo, &domain)) + return NULL; + } + + if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) { + buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data); + } + + if (buf->mapped) + return buf->bo->ptr; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { + write = 1; + } + + if (radeon_bo_map(buf->bo, write)) { + return NULL; + } + buf->mapped = true; + insert_at_tail(&buf->mgr->buffer_map_list, buf); + return buf->bo->ptr; +} + +static void +radeon_drm_buffer_unmap(struct pb_buffer *_buf) +{ + (void)_buf; +} + +static void +radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + + +static enum pipe_error +radeon_drm_buffer_validate(struct pb_buffer *_buf, + struct pb_validate *vl, + unsigned flags) +{ + /* Always pinned */ + return PIPE_OK; +} + +static void +radeon_drm_buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ +} + +const struct pb_vtbl radeon_drm_buffer_vtbl = { + radeon_drm_buffer_destroy, + radeon_drm_buffer_map, + radeon_drm_buffer_unmap, + radeon_drm_buffer_validate, + radeon_drm_buffer_fence, + radeon_drm_buffer_get_base_buffer, +}; + + +static uint32_t radeon_domain_from_usage(unsigned usage) +{ + uint32_t domain = 0; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + return domain; +} + +struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, + uint32_t handle) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + struct radeon_libdrm_winsys *rws = mgr->rws; + struct radeon_drm_buffer *buf; + struct radeon_bo *bo; + + bo = radeon_bo_open(rws->bom, handle, 0, + 0, 0, 0); + if (bo == NULL) + return NULL; + + buf = CALLOC_STRUCT(radeon_drm_buffer); + if (!buf) { + radeon_bo_unref(bo); + return NULL; + } + + make_empty_list(buf); + + pipe_reference_init(&buf->base.base.reference, 1); + buf->base.base.alignment = 0; + buf->base.base.usage = PIPE_BUFFER_USAGE_PIXEL; + buf->base.base.size = 0; + buf->base.vtbl = &radeon_drm_buffer_vtbl; + buf->mgr = mgr; + + buf->bo = bo; + + // fprintf(stderr,"hand %p : %d\n", &buf->base, handle); + return &buf->base; + +} + +static struct pb_buffer * +radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr, + pb_size size, + const struct pb_desc *desc) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + struct radeon_libdrm_winsys *rws = mgr->rws; + struct radeon_drm_buffer *buf; + uint32_t domain; + + buf = CALLOC_STRUCT(radeon_drm_buffer); + if (!buf) + goto error1; + + pipe_reference_init(&buf->base.base.reference, 1); + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + buf->base.base.size = size; + buf->base.vtbl = &radeon_drm_buffer_vtbl; + buf->mgr = mgr; + + make_empty_list(buf); + domain = radeon_domain_from_usage(desc->usage); + buf->bo = radeon_bo_open(rws->bom, 0, size, + desc->alignment, domain, 0); + if (buf->bo == NULL) + goto error2; + + // fprintf(stderr,"%p : %d\n", &buf->base, size); + return &buf->base; + + error2: + FREE(buf); + error1: + return NULL; +} + +static void +radeon_drm_bufmgr_flush(struct pb_manager *mgr) +{ + /* NOP */ +} + +static void +radeon_drm_bufmgr_destroy(struct pb_manager *_mgr) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + FREE(mgr); +} + +struct pb_manager * +radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws) +{ + struct radeon_drm_bufmgr *mgr; + + mgr = CALLOC_STRUCT(radeon_drm_bufmgr); + if (!mgr) + return NULL; + + mgr->base.destroy = radeon_drm_bufmgr_destroy; + mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer; + mgr->base.flush = radeon_drm_bufmgr_flush; + + mgr->rws = rws; + make_empty_list(&mgr->buffer_map_list); + return &mgr->base; +} + +uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + + return buf->bo->handle; +} + +boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, + uint32_t *handle) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + struct drm_gem_flink flink; + int retval, fd; + if (!buf->flinked) { + fd = buf->mgr->rws->fd; + flink.handle = buf->bo->handle; + + retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (retval) { + return false; + } + + buf->flinked = TRUE; + buf->flink = flink.name; + } + *handle = buf->flink; + return TRUE; +} + +static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf; + if (_buf->vtbl == &radeon_drm_buffer_vtbl) { + buf = radeon_drm_buffer(_buf); + } else { + struct pb_buffer *base_buf; + pb_size offset; + pb_get_base_buffer(_buf, &base_buf, &offset); + + buf = radeon_drm_buffer(base_buf); + } + return buf; +} + +void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + uint32_t flags = 0; + + if (microtiled) + flags |= RADEON_BO_FLAGS_MICRO_TILE; + if (macrotiled) + flags |= RADEON_BO_FLAGS_MACRO_TILE; + + radeon_bo_set_tiling(buf->bo, flags, pitch); + +} + +boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo, + rd, wd); + + return true; +} + +void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd, + uint32_t flags) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + int retval; + + retval = radeon_cs_write_reloc(buf->mgr->rws->cs, + buf->bo, rd, wd, flags); + if (retval) { + debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", + buf, rd, wd, flags); + } +} + +void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + struct radeon_drm_buffer *rpb, *t_rpb; + + foreach_s(rpb, t_rpb, &mgr->buffer_map_list) { + rpb->mapped = 0; + radeon_bo_unmap(rpb->bo); + remove_from_list(rpb); + } + + make_empty_list(&mgr->buffer_map_list); + + +} diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index d759beaba1..997abb8f5c 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,29 +22,104 @@ #include "radeon_r300.h" -static void radeon_set_flush_cb(struct radeon_winsys *winsys, +static struct r300_winsys_buffer * +radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct pb_desc desc; + struct pb_manager *provider; + struct pb_buffer *buffer; + + memset(&desc, 0, sizeof(desc)); + desc.alignment = alignment; + desc.usage = usage; + + if (usage == PIPE_BUFFER_USAGE_CONSTANT) + provider = ws->mman; + else if (usage == PIPE_BUFFER_USAGE_VERTEX || + usage == PIPE_BUFFER_USAGE_INDEX) + provider = ws->cman; + else + provider = ws->kman; + buffer = provider->create_buffer(provider, size, &desc); + if (!buffer) + return NULL; + + return radeon_libdrm_winsys_buffer(buffer); +} + +static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + + pb_destroy(_buf); +} +static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, + uint32_t pitch, + boolean microtiled, + boolean macrotiled) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch); +} + +static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf, + unsigned usage) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + + return pb_map(_buf, 0); +} + +static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + + pb_unmap(_buf); +} + +static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, + struct r300_winsys_buffer **pdst, + struct r300_winsys_buffer *src) +{ + struct pb_buffer *_src = radeon_pb_buffer(src); + struct pb_buffer *_dst = radeon_pb_buffer(*pdst); + + pb_reference(&_dst, _src); + + *pdst = radeon_libdrm_winsys_buffer(_dst); +} + +static void radeon_set_flush_cb(struct r300_winsys_screen *rws, void (*flush_cb)(void *), void *data) { - winsys->priv->flush_cb = flush_cb; - winsys->priv->flush_data = data; - radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + ws->flush_cb = flush_cb; + ws->flush_data = data; + radeon_cs_space_set_flush(ws->cs, flush_cb, data); } -static boolean radeon_add_buffer(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, +static boolean radeon_add_buffer(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, uint32_t rd, uint32_t wd) { - struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; + struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd); - return TRUE; + return radeon_drm_bufmgr_add_buffer(_buf, rd, wd); } -static boolean radeon_validate(struct radeon_winsys* winsys) +static boolean radeon_validate(struct r300_winsys_screen *rws) { - if (radeon_cs_space_check(winsys->priv->cs) < 0) { + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + if (radeon_cs_space_check(ws->cs) < 0) { return FALSE; } @@ -52,108 +127,146 @@ static boolean radeon_validate(struct radeon_winsys* winsys) return TRUE; } -static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) +static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size) { - struct radeon_cs* cs = winsys->priv->cs; + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct radeon_cs *cs = ws->cs; - return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; + return radeon_validate(rws) && cs->cdw + size <= cs->ndw; } -static void radeon_begin_cs(struct radeon_winsys* winsys, +static void radeon_begin_cs(struct r300_winsys_screen *rws, int size, const char* file, const char* function, int line) { - radeon_cs_begin(winsys->priv->cs, size, file, function, line); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_begin(ws->cs, size, file, function, line); } -static void radeon_write_cs_dword(struct radeon_winsys* winsys, +static void radeon_write_cs_dword(struct r300_winsys_screen *rws, uint32_t dword) { - radeon_cs_write_dword(winsys->priv->cs, dword); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_write_dword(ws->cs, dword); } -static void radeon_write_cs_reloc(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, +static void radeon_write_cs_reloc(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, uint32_t rd, uint32_t wd, uint32_t flags) { - int retval = 0; - struct radeon_pipe_buffer* radeon_buffer = - (struct radeon_pipe_buffer*)pbuffer; - - assert(!radeon_buffer->pb); - - retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, - rd, wd, flags); - - if (retval) { - debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", - pbuffer, rd, wd, flags); - } + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags); } -static void radeon_reset_bos(struct radeon_winsys *winsys) +static void radeon_reset_bos(struct r300_winsys_screen *rws) { - radeon_cs_space_reset_bos(winsys->priv->cs); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_space_reset_bos(ws->cs); } -static void radeon_end_cs(struct radeon_winsys* winsys, +static void radeon_end_cs(struct r300_winsys_screen *rws, const char* file, const char* function, int line) { - radeon_cs_end(winsys->priv->cs, file, function, line); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_end(ws->cs, file, function, line); } -static void radeon_flush_cs(struct radeon_winsys* winsys) +static void radeon_flush_cs(struct r300_winsys_screen *rws) { + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); int retval; /* Don't flush a zero-sized CS. */ - if (!winsys->priv->cs->cdw) { + if (!ws->cs->cdw) { return; } + radeon_drm_bufmgr_flush_maps(ws->kman); /* Emit the CS. */ - retval = radeon_cs_emit(winsys->priv->cs); + retval = radeon_cs_emit(ws->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); - radeon_cs_print(winsys->priv->cs, stderr); + radeon_cs_print(ws->cs, stderr); } /* Reset CS. * Someday, when we care about performance, we should really find a way * to rotate between two or three CS objects so that the GPU can be * spinning through one CS while another one is being filled. */ - radeon_cs_erase(winsys->priv->cs); + radeon_cs_erase(ws->cs); +} + +static uint32_t radeon_get_value(struct r300_winsys_screen *rws, + enum r300_value_id id) +{ + struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; + + switch(id) { + case R300_VID_PCI_ID: + return ws->pci_id; + case R300_VID_GB_PIPES: + return ws->gb_pipes; + case R300_VID_Z_PIPES: + return ws->z_pipes; + } + return 0; +} + +static void +radeon_winsys_destroy(struct r300_winsys_screen *rws) +{ + struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; + radeon_cs_destroy(ws->cs); + + ws->cman->destroy(ws->cman); + ws->kman->destroy(ws->kman); + ws->mman->destroy(ws->mman); + + radeon_bo_manager_gem_dtor(ws->bom); + radeon_cs_manager_gem_dtor(ws->csm); } void -radeon_setup_winsys(int fd, struct radeon_winsys* winsys) +radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) { - struct radeon_winsys_priv* priv = winsys->priv; + ws->csm = radeon_cs_manager_gem_ctor(fd); + + ws->bom = radeon_bo_manager_gem_ctor(fd); + ws->kman = radeon_drm_bufmgr_create(ws); - priv->csm = radeon_cs_manager_gem_ctor(fd); + ws->cman = pb_cache_manager_create(ws->kman, 100000); + ws->mman = pb_malloc_bufmgr_create(); /* Size limit on IBs is 64 kibibytes. */ - priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4); - radeon_cs_set_limit(priv->cs, - RADEON_GEM_DOMAIN_GTT, winsys->gart_size); - radeon_cs_set_limit(priv->cs, - RADEON_GEM_DOMAIN_VRAM, winsys->vram_size); - - winsys->add_buffer = radeon_add_buffer; - winsys->validate = radeon_validate; - - winsys->check_cs = radeon_check_cs; - winsys->begin_cs = radeon_begin_cs; - winsys->write_cs_dword = radeon_write_cs_dword; - winsys->write_cs_reloc = radeon_write_cs_reloc; - winsys->end_cs = radeon_end_cs; - winsys->flush_cs = radeon_flush_cs; - winsys->reset_bos = radeon_reset_bos; - winsys->set_flush_cb = radeon_set_flush_cb; + ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); + radeon_cs_set_limit(ws->cs, + RADEON_GEM_DOMAIN_GTT, ws->gart_size); + radeon_cs_set_limit(ws->cs, + RADEON_GEM_DOMAIN_VRAM, ws->vram_size); + + ws->base.add_buffer = radeon_add_buffer; + ws->base.validate = radeon_validate; + ws->base.destroy = radeon_winsys_destroy; + ws->base.check_cs = radeon_check_cs; + ws->base.begin_cs = radeon_begin_cs; + ws->base.write_cs_dword = radeon_write_cs_dword; + ws->base.write_cs_reloc = radeon_write_cs_reloc; + ws->base.end_cs = radeon_end_cs; + ws->base.flush_cs = radeon_flush_cs; + ws->base.reset_bos = radeon_reset_bos; + ws->base.set_flush_cb = radeon_set_flush_cb; + ws->base.get_value = radeon_get_value; + + ws->base.buffer_create = radeon_r300_winsys_buffer_create; + ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy; + ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling; + ws->base.buffer_map = radeon_r300_winsys_buffer_map; + ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; + ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index cfbdb30266..82a8aad715 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -28,12 +28,12 @@ #include #include "drm.h" #include "radeon_drm.h" +#include "radeon_bo_gem.h" #include "radeon_cs_gem.h" -#include "r300_winsys.h" - +#include "radeon_winsys.h" #include "radeon_buffer.h" -void radeon_setup_winsys(int fd, struct radeon_winsys* winsys); +void radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys); #endif /* RADEON_R300_H */ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index 4901080ca7..c8e725cff0 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -30,16 +30,17 @@ #ifndef RADEON_WINSYS_H #define RADEON_WINSYS_H -#include "util/u_simple_screen.h" +#include "r300_winsys.h" -struct radeon_winsys_priv; - -struct radeon_winsys { +struct radeon_libdrm_winsys { /* Parent class. */ - struct pipe_winsys base; + struct r300_winsys_screen base; + + struct pb_manager *kman; - /* Winsys private */ - struct radeon_winsys_priv* priv; + struct pb_manager *mman; + + struct pb_manager *cman; /* PCI ID */ uint32_t pci_id; @@ -56,56 +57,27 @@ struct radeon_winsys { /* VRAM size. */ uint32_t vram_size; - /* Add a pipe_buffer to the list of buffer objects to validate. */ - boolean (*add_buffer)(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, - uint32_t rd, - uint32_t wd); - - /* Revalidate all currently setup pipe_buffers. - * Returns TRUE if a flush is required. */ - boolean (*validate)(struct radeon_winsys* winsys); - - /* Check to see if there's room for commands. */ - boolean (*check_cs)(struct radeon_winsys* winsys, int size); - - /* Start a command emit. */ - void (*begin_cs)(struct radeon_winsys* winsys, - int size, - const char* file, - const char* function, - int line); - - /* Write a dword to the command buffer. */ - void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword); - - /* Write a relocated dword to the command buffer. */ - void (*write_cs_reloc)(struct radeon_winsys* winsys, - struct pipe_buffer* bo, - uint32_t rd, - uint32_t wd, - uint32_t flags); - - /* Finish a command emit. */ - void (*end_cs)(struct radeon_winsys* winsys, - const char* file, - const char* function, - int line); - - /* Flush the CS. */ - void (*flush_cs)(struct radeon_winsys* winsys); - - /* winsys flush - callback from winsys when flush required */ - void (*set_flush_cb)(struct radeon_winsys *winsys, - void (*flush_cb)(void *), void *data); - - void (*reset_bos)(struct radeon_winsys *winsys); - - void (*buffer_set_tiling)(struct radeon_winsys* winsys, - struct pipe_buffer* buffer, - uint32_t pitch, - boolean microtiled, - boolean macrotiled); + /* DRM FD */ + int fd; + + /* Radeon BO manager. */ + struct radeon_bo_manager *bom; + + /* Radeon CS manager. */ + struct radeon_cs_manager *csm; + + /* Current CS. */ + struct radeon_cs *cs; + + /* Flush CB */ + void (*flush_cb)(void *); + void *flush_data; }; +static INLINE struct radeon_libdrm_winsys * +radeon_winsys_screen(struct r300_winsys_screen *base) +{ + return (struct radeon_libdrm_winsys *)base; +} + #endif -- cgit v1.2.3 From b14548ea32000459f4f0c4b49f3fa11d1ee9c003 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 22 Feb 2010 17:26:30 +1000 Subject: Revert "r300g: rebuild winsys/pipe buffer handling and add buffer map" This reverts commit fff5be8e7b4557c221f2425dcafc2e7cbbba76ba. Probably went too soon with this, dileX reported OA not working for him it works here fine, but the optimisations I wanted aren't working properly yet so I'll fix that now. Signed-off-by: Dave Airlie --- src/gallium/drivers/r300/Makefile | 1 - src/gallium/drivers/r300/r300_context.c | 38 +-- src/gallium/drivers/r300/r300_context.h | 9 +- src/gallium/drivers/r300/r300_cs.h | 22 +- src/gallium/drivers/r300/r300_emit.c | 54 ++- src/gallium/drivers/r300/r300_render.c | 33 +- src/gallium/drivers/r300/r300_screen.c | 38 +-- src/gallium/drivers/r300/r300_screen.h | 2 +- src/gallium/drivers/r300/r300_screen_buffer.c | 222 ------------- src/gallium/drivers/r300/r300_screen_buffer.h | 85 ----- src/gallium/drivers/r300/r300_state.c | 25 +- src/gallium/drivers/r300/r300_texture.c | 41 ++- src/gallium/drivers/r300/r300_texture.h | 4 +- src/gallium/drivers/r300/r300_winsys.h | 127 +------- src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h | 2 + src/gallium/winsys/drm/radeon/core/Makefile | 2 +- src/gallium/winsys/drm/radeon/core/radeon_buffer.h | 60 ++-- src/gallium/winsys/drm/radeon/core/radeon_drm.c | 134 +++++--- src/gallium/winsys/drm/radeon/core/radeon_drm.h | 5 + .../winsys/drm/radeon/core/radeon_drm_buffer.c | 361 --------------------- src/gallium/winsys/drm/radeon/core/radeon_r300.c | 237 ++++---------- src/gallium/winsys/drm/radeon/core/radeon_r300.h | 6 +- src/gallium/winsys/drm/radeon/core/radeon_winsys.h | 86 +++-- 23 files changed, 347 insertions(+), 1247 deletions(-) delete mode 100644 src/gallium/drivers/r300/r300_screen_buffer.c delete mode 100644 src/gallium/drivers/r300/r300_screen_buffer.h delete mode 100644 src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 5707309bdf..afddcb161f 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -14,7 +14,6 @@ C_SOURCES = \ r300_query.c \ r300_render.c \ r300_screen.c \ - r300_screen_buffer.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index a8a6a07a84..f631b4ed27 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -24,7 +24,6 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" -#include "util/u_upload_mgr.h" #include "r300_blit.h" #include "r300_context.h" @@ -55,9 +54,6 @@ static void r300_destroy_context(struct pipe_context* context) FREE(query); } - u_upload_destroy(r300->upload_vb); - u_upload_destroy(r300->upload_ib); - FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); FREE(r300->fb_state.state); @@ -74,7 +70,11 @@ r300_is_texture_referenced(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level) { - return 0; + struct pipe_buffer* buf = 0; + + r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); + + return pipe->is_buffer_referenced(pipe, buf); } static unsigned int @@ -136,14 +136,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, { struct r300_context* r300 = CALLOC_STRUCT(r300_context); struct r300_screen* r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; + struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys; if (!r300) return NULL; - r300->rws = rws; + r300->winsys = radeon_winsys; - r300->context.winsys = (struct pipe_winsys*)rws; + r300->context.winsys = (struct pipe_winsys*)radeon_winsys; r300->context.screen = screen; r300->context.priv = priv; @@ -201,31 +201,11 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->invariant_state.dirty = TRUE; - rws->set_flush_cb(r300->rws, r300_flush_cb, r300); + r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw++; r300->blitter = util_blitter_create(&r300->context); - r300->upload_ib = u_upload_create(screen, - 32 * 1024, 16, - PIPE_BUFFER_USAGE_INDEX); - - if (r300->upload_ib == NULL) - goto no_upload_ib; - - r300->upload_vb = u_upload_create(screen, - 128 * 1024, 16, - PIPE_BUFFER_USAGE_VERTEX); - if (r300->upload_vb == NULL) - goto no_upload_vb; - return &r300->context; - - // u_upload_destroy(r300->upload_vb); - no_upload_ib: - u_upload_destroy(r300->upload_ib); - no_upload_vb: - FREE(r300); - return NULL; } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 749bac0498..443af4ec2e 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -32,7 +32,6 @@ #include "r300_screen.h" -struct u_upload_mgr; struct r300_context; struct r300_fragment_shader; @@ -239,7 +238,7 @@ struct r300_texture { boolean is_npot; /* Pipe buffer backing this texture. */ - struct r300_winsys_buffer *buffer; + struct pipe_buffer* buffer; /* Registers carrying texture format data. */ struct r300_texture_state state; @@ -266,7 +265,7 @@ struct r300_context { struct pipe_context context; /* The interface to the windowing system, etc. */ - struct r300_winsys_screen *rws; + struct radeon_winsys* winsys; /* Draw module. Used mostly for SW TCL. */ struct draw_context* draw; /* Accelerated blit support. */ @@ -331,7 +330,6 @@ struct r300_context { /* Vertex elements for Gallium. */ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; - bool any_user_vbs; struct pipe_stencil_ref stencil_ref; @@ -345,9 +343,6 @@ struct r300_context { boolean polygon_offset_enabled; /* Z buffer bit depth. */ uint32_t zbuffer_bpp; - - struct u_upload_mgr *upload_vb; - struct u_upload_mgr *upload_ib; }; /* Convenience cast wrapper. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index ad07efbffd..151f72b0fe 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -51,7 +51,7 @@ #define CS_LOCALS(context) \ struct r300_context* const cs_context_copy = (context); \ - struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \ + struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \ int cs_count = 0; (void) cs_count; #define CHECK_CS(size) \ @@ -105,34 +105,22 @@ cs_count--; \ } while (0) -#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \ +#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \ "domains (%d, %d, %d)\n", \ bo, offset, rd, wd, flags); \ assert(bo); \ cs_winsys->write_cs_dword(cs_winsys, offset); \ - r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ - cs_count -= 3; \ -} while (0) - - -#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \ - DBG(cs_context_copy, DBG_CS, "r300: writing relocation for texture %p, offset %d, " \ - "domains (%d, %d, %d)\n", \ - tex, offset, rd, wd, flags); \ - assert(tex); \ - cs_winsys->write_cs_dword(cs_winsys, offset); \ - r300_texture_write_reloc(cs_winsys, tex, rd, wd, flags); \ + cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ cs_count -= 3; \ } while (0) - -#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ +#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \ "domains (%d, %d, %d)\n", \ bo, rd, wd, flags); \ assert(bo); \ - r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ + cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ cs_count -= 2; \ } while (0) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 6fb1d7bd92..f7dcd8dc52 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,8 +32,6 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" -#include "r300_screen_buffer.h" -#include "r300_state_inlines.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) @@ -420,10 +418,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "cbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); - OUT_CS_TEX_RELOC(tex, surf->offset, 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_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level], + OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); @@ -436,12 +434,12 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_TEX_RELOC(tex, surf->offset, 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, tex->fb_state.zb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level], + OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); } @@ -491,13 +489,13 @@ static void r300_emit_query_finish(struct r300_context *r300, /* pipe 3 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), 0, RADEON_GEM_DOMAIN_GTT, 0); case 3: /* pipe 2 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), 0, RADEON_GEM_DOMAIN_GTT, 0); case 2: /* pipe 1 only */ @@ -505,13 +503,13 @@ static void r300_emit_query_finish(struct r300_context *r300, OUT_CS_REG(R300_SU_REG_DEST, 1 << (caps->high_second_pipe ? 3 : 1)); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), 0, RADEON_GEM_DOMAIN_GTT, 0); case 1: /* pipe 0 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), 0, RADEON_GEM_DOMAIN_GTT, 0); break; default: @@ -533,7 +531,7 @@ static void rv530_emit_query_single(struct r300_context *r300, BEGIN_CS(8); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -546,10 +544,10 @@ static void rv530_emit_query_double(struct r300_context *r300, BEGIN_CS(14); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -761,7 +759,7 @@ void r300_emit_texture(struct r300_context* r300, 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); - OUT_CS_TEX_RELOC(tex, + OUT_CS_RELOC(tex->buffer, R300_TXO_MACRO_TILE(tex->macrotile) | R300_TXO_MICRO_TILE(tex->microtile), RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); @@ -802,7 +800,7 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) } for (i = 0; i < aos_count; i++) { - OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, + OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, RADEON_GEM_DOMAIN_GTT, 0, 0); } END_CS; @@ -1014,15 +1012,15 @@ void r300_emit_buffer_validate(struct r300_context *r300) boolean invalid = FALSE; /* Clean out BOs. */ - r300->rws->reset_bos(r300->rws); + r300->winsys->reset_bos(r300->winsys); validate: /* Color buffers... */ for (i = 0; i < fb->nr_cbufs; i++) { tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); - if (!r300_add_texture(r300->rws, tex, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1031,8 +1029,8 @@ validate: if (fb->zsbuf) { tex = (struct r300_texture*)fb->zsbuf->texture; assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); - if (!r300_add_texture(r300->rws, tex, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1042,31 +1040,31 @@ validate: tex = r300->textures[i]; if (!tex) continue; - if (!r300_add_texture(r300->rws, tex, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { + 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); goto validate; } } /* ...occlusion query buffer... */ if (r300->dirty_state & R300_NEW_QUERY) { - if (!r300_add_buffer(r300->rws, r300->oqbo, - 0, RADEON_GEM_DOMAIN_GTT)) { + if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, + 0, RADEON_GEM_DOMAIN_GTT)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...and vertex buffer. */ if (r300->vbo) { - if (!r300_add_buffer(r300->rws, r300->vbo, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } else { /* debug_printf("No VBO while emitting dirty state!\n"); */ } - if (!r300->rws->validate(r300->rws)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { /* Well, hell. */ @@ -1098,7 +1096,7 @@ void r300_emit_dirty_state(struct r300_context* r300) /* Make sure we have at least 2*1024 spare dwords. */ /* XXX It would be nice to know the number of dwords we really need to * XXX emit. */ - while (!r300->rws->check_cs(r300->rws, dwords)) { + while (!r300->winsys->check_cs(r300->winsys, dwords)) { r300->context.flush(&r300->context, 0, NULL); } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 47f5d6f7f1..754eb4dc76 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -30,12 +30,10 @@ #include "util/u_format.h" #include "util/u_memory.h" -#include "util/u_upload_mgr.h" #include "util/u_prim.h" #include "r300_cs.h" #include "r300_context.h" -#include "r300_screen_buffer.h" #include "r300_emit.h" #include "r300_reg.h" #include "r300_render.h" @@ -299,7 +297,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | (0 << R300_INDX_BUFFER_SKIP_SHIFT)); OUT_CS(offset_dwords << 2); - OUT_CS_BUF_RELOC(indexBuffer, count_dwords, + OUT_CS_RELOC(indexBuffer, count_dwords, RADEON_GEM_DOMAIN_GTT, 0, 0); END_CS; @@ -310,28 +308,21 @@ static boolean r300_setup_vertex_buffers(struct r300_context *r300) struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_buffer *pbuf; - int ret; - - /* upload buffers first */ - if (r300->any_user_vbs) { - ret = r300_upload_user_buffers(r300); - r300->any_user_vbs = false; - } validate: for (int i = 0; i < r300->vertex_element_count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - if (!r300_add_buffer(r300->rws, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } - if (!r300->rws->validate(r300->rws)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); - return r300->rws->validate(r300->rws); + return r300->winsys->validate(r300->winsys); } return TRUE; @@ -405,20 +396,15 @@ void r300_draw_range_elements(struct pipe_context* pipe, indexSize = 2; } - r300_upload_index_buffer(r300, &indexBuffer, - indexSize, start, count); - - if (!r300_add_buffer(r300->rws, indexBuffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, + RADEON_GEM_DOMAIN_GTT, 0)) { goto cleanup; } - if (!r300->rws->validate(r300->rws)) { + if (!r300->winsys->validate(r300->winsys)) { goto cleanup; } - u_upload_flush(r300->upload_vb); - u_upload_flush(r300->upload_ib); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); @@ -439,7 +425,7 @@ void r300_draw_range_elements(struct pipe_context* pipe, cleanup: if (indexBuffer != orgIndexBuffer) { - pipe_buffer_reference( &indexBuffer, NULL ); + pipe->screen->buffer_destroy(indexBuffer); } } @@ -480,7 +466,6 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return; } - u_upload_flush(r300->upload_vb); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 3b70312c82..6a55570571 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -23,6 +23,7 @@ #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" +#include "util/u_simple_screen.h" #include "r300_context.h" #include "r300_screen.h" @@ -31,8 +32,6 @@ #include "radeon_winsys.h" #include "r300_winsys.h" -#include "r300_screen_buffer.h" - /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. * @@ -293,11 +292,10 @@ static void* r300_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; - struct r300_winsys_screen *rws = r300_winsys_screen(screen); char* map; enum pipe_format format = tex->tex.format; - map = rws->buffer_map(rws, tex->buffer, + map = pipe_buffer_map(screen, tex->buffer, pipe_transfer_buffer_flags(transfer)); if (!map) { @@ -313,26 +311,21 @@ static void r300_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; - struct r300_winsys_screen *rws = r300_winsys_screen(screen); - rws->buffer_unmap(rws, tex->buffer); + pipe_buffer_unmap(screen, tex->buffer); } static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); - struct r300_winsys_screen *rws = r300_winsys_screen(pscreen); - - if (rws) - rws->destroy(rws); FREE(r300screen->caps); FREE(r300screen); } -struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) +struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) { - struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen); - struct r300_capabilities *caps = CALLOC_STRUCT(r300_capabilities); + struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); + struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); if (!r300screen || !caps) { FREE(r300screen); @@ -340,16 +333,16 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) return NULL; } - caps->pci_id = rws->get_value(rws, R300_VID_PCI_ID); - caps->num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES); - caps->num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES); + caps->pci_id = radeon_winsys->pci_id; + caps->num_frag_pipes = radeon_winsys->gb_pipes; + caps->num_z_pipes = radeon_winsys->z_pipes; r300_init_debug(r300screen); r300_parse_chipset(caps); r300screen->caps = caps; - r300screen->rws = rws; - r300screen->screen.winsys = (struct pipe_winsys*)rws; + r300screen->radeon_winsys = radeon_winsys; + r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys; r300screen->screen.destroy = r300_destroy_screen; r300screen->screen.get_name = r300_get_name; r300screen->screen.get_vendor = r300_get_vendor; @@ -363,12 +356,7 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) r300screen->screen.transfer_unmap = r300_transfer_unmap; r300_init_screen_texture_functions(&r300screen->screen); - r300_screen_init_buffer_functions(r300screen); - return &r300screen->screen; -} + u_simple_screen_init(&r300screen->screen); -struct r300_winsys_screen * -r300_winsys_screen(struct pipe_screen *screen) -{ - return r300_screen(screen)->rws; + return &r300screen->screen; } diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 87fc6190ce..502fbfa5a2 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -33,7 +33,7 @@ struct r300_screen { /* Parent class */ struct pipe_screen screen; - struct r300_winsys_screen *rws; + struct radeon_winsys* radeon_winsys; /* Chipset capabilities */ struct r300_capabilities* caps; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c deleted file mode 100644 index 358582ea21..0000000000 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ /dev/null @@ -1,222 +0,0 @@ -#include - -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_memory.h" -#include "util/u_upload_mgr.h" - -#include "r300_screen_buffer.h" - -#include "r300_winsys.h" - -int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_buffer **index_buffer, - unsigned index_size, - unsigned start, - unsigned count) -{ - struct pipe_buffer *upload_buffer = NULL; - unsigned index_offset = start * index_size; - int ret = 0; - - if (r300_buffer_is_user_buffer(*index_buffer)) { - ret = u_upload_buffer(r300->upload_ib, - index_offset, - count * index_size, - *index_buffer, - &index_offset, - &upload_buffer); - if (ret) { - goto done; - } - *index_buffer = upload_buffer; - } - done: - // if (upload_buffer) - // pipe_buffer_reference(&upload_buffer, NULL); - return ret; -} - -int r300_upload_user_buffers(struct r300_context *r300) -{ - enum pipe_error ret = PIPE_OK; - int i, nr; - - nr = r300->vertex_buffer_count; - - for (i = 0; i < nr; i++) { - - if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) { - struct pipe_buffer *upload_buffer = NULL; - unsigned offset = 0; - unsigned size = r300->vertex_buffer[i].buffer->size; - unsigned upload_offset; - - ret = u_upload_buffer(r300->upload_vb, - offset, size, - r300->vertex_buffer[i].buffer, - &upload_offset, &upload_buffer); - if (ret) - return ret; - - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); - r300->vertex_buffer[i].buffer = upload_buffer; - r300->vertex_buffer[i].buffer_offset = upload_offset; - } - } - return ret; -} - -static struct r300_winsys_buffer * -r300_winsys_buffer_create(struct r300_screen *r300screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_winsys_buffer *buf; - - buf = rws->buffer_create(rws, alignment, usage, size); - return buf; -} - -static void r300_winsys_buffer_destroy(struct r300_screen *r300screen, - struct r300_buffer *rbuf) -{ - struct r300_winsys_screen *rws = r300screen->rws; - - if (rbuf->buf) { - rws->buffer_destroy(rbuf->buf); - rbuf->buf = NULL; - } -} - -static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_buffer *rbuf; - - rbuf = CALLOC_STRUCT(r300_buffer); - if (!rbuf) - goto error1; - - rbuf->magic = R300_BUFFER_MAGIC; - - pipe_reference_init(&rbuf->base.reference, 1); - rbuf->base.screen = screen; - rbuf->base.alignment = alignment; - rbuf->base.usage = usage; - rbuf->base.size = size; - - rbuf->buf = r300_winsys_buffer_create(r300screen, - alignment, - usage, - size); - - if (!rbuf->buf) - goto error2; - - return &rbuf->base; -error2: - FREE(rbuf); -error1: - return NULL; -} - - -static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct r300_buffer *rbuf; - - rbuf = CALLOC_STRUCT(r300_buffer); - if (!rbuf) - goto no_rbuf; - - rbuf->magic = R300_BUFFER_MAGIC; - - pipe_reference_init(&rbuf->base.reference, 1); - rbuf->base.screen = screen; - rbuf->base.alignment = 1; - rbuf->base.usage = 0; - rbuf->base.size = bytes; - - rbuf->user_buffer = ptr; - return &rbuf->base; - -no_rbuf: - return NULL; -} - -static void r300_buffer_destroy(struct pipe_buffer *buf) -{ - struct r300_screen *r300screen = r300_screen(buf->screen); - struct r300_buffer *rbuf = r300_buffer(buf); - - r300_winsys_buffer_destroy(r300screen, rbuf); - FREE(rbuf); -} - -static void * -r300_buffer_map_range(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned offset, unsigned length, - unsigned usage ) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); - void *map; - - if (rbuf->user_buffer) - return rbuf->user_buffer; - - map = rws->buffer_map(rws, rbuf->buf, usage); - - return map; -} - -static void * -r300_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned usage) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); - void *map; - - if (rbuf->user_buffer) - return rbuf->user_buffer; - - map = rws->buffer_map(rws, rbuf->buf, usage); - - return map; -} - -static void -r300_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); - - if (rbuf->buf) - rws->buffer_unmap(rws, rbuf->buf); -} - -void r300_screen_init_buffer_functions(struct r300_screen *r300screen) -{ - r300screen->screen.buffer_create = r300_buffer_create; - r300screen->screen.user_buffer_create = r300_user_buffer_create; - r300screen->screen.buffer_map = r300_buffer_map; - r300screen->screen.buffer_map_range = r300_buffer_map_range; -// r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range; - r300screen->screen.buffer_unmap = r300_buffer_unmap; - r300screen->screen.buffer_destroy = r300_buffer_destroy; -} diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h deleted file mode 100644 index 7c026508b5..0000000000 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef R300_SCREEN_BUFFER_H -#define R300_SCREEN_BUFFER_H -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" -#include "r300_screen.h" - -#include "r300_winsys.h" -#include "r300_context.h" - -#define R300_BUFFER_MAGIC 0xabcd1234 - -struct r300_buffer -{ - struct pipe_buffer base; - - uint32_t magic; - - struct r300_winsys_buffer *buf; - - void *user_buffer; -}; - -static INLINE struct r300_buffer * -r300_buffer(struct pipe_buffer *buffer) -{ - if (buffer) { - assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC); - return (struct r300_buffer *)buffer; - } - return NULL; -} - -static INLINE boolean -r300_buffer_is_user_buffer(struct pipe_buffer *buffer) -{ - return r300_buffer(buffer)->user_buffer ? true : false; -} - -static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws, - struct pipe_buffer *buffer, - int rd, int wr) -{ - struct r300_buffer *buf = r300_buffer(buffer); - - if (!buf->buf) - return true; - - return rws->add_buffer(rws, buf->buf, rd, wr); -} - - -static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws, - struct r300_texture *tex, - int rd, int wr) -{ - return rws->add_buffer(rws, tex->buffer, rd, wr); -} - -void r300_screen_init_buffer_functions(struct r300_screen *r300screen); - -static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws, - struct r300_buffer *buf, - uint32_t rd, uint32_t wd, uint32_t flags) -{ - if (!buf->buf) - return; - - rws->write_cs_reloc(rws, buf->buf, rd, wd, flags); -} - -static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws, - struct r300_texture *texture, - uint32_t rd, uint32_t wd, uint32_t flags) -{ - rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags); -} - -int r300_upload_user_buffers(struct r300_context *r300); - -int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_buffer **index_buffer, - unsigned index_size, - unsigned start, - unsigned count); -#endif diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index d8a87dec15..34bf81c193 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -34,7 +34,6 @@ #include "r300_context.h" #include "r300_reg.h" #include "r300_screen.h" -#include "r300_screen_buffer.h" #include "r300_state_inlines.h" #include "r300_fs.h" #include "r300_vs.h" @@ -522,7 +521,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->cbufs[i]->texture; if (tex) { - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -534,7 +533,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->zsbuf->texture; if (tex) { - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -546,7 +545,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->cbufs[i]->texture; level = new_state->cbufs[i]->level; - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -555,7 +554,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->zsbuf->texture; level = new_state->zsbuf->level; - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -1029,26 +1028,10 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); - boolean any_user_buffer = false; - int i; - - if (count == r300->vertex_buffer_count && - memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0) - return; - - 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; - } - - for ( ; i < r300->vertex_buffer_count; i++) - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); memcpy(r300->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); r300->vertex_buffer_count = count; - r300->any_user_vbs = any_user_buffer; if (r300->draw) { draw_flush(r300->draw); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 9016e86ccd..ed2be06254 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -731,7 +731,7 @@ static struct pipe_texture* { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); struct r300_screen* rscreen = r300_screen(screen); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; + struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; if (!tex) { return NULL; @@ -745,13 +745,13 @@ static struct pipe_texture* r300_setup_miptree(rscreen, tex); r300_setup_texture_state(rscreen, tex); - tex->buffer = rws->buffer_create(rws, 2048, - PIPE_BUFFER_USAGE_PIXEL, - tex->size); - rws->buffer_set_tiling(rws, tex->buffer, - tex->pitch[0], - tex->microtile != R300_BUFFER_LINEAR, - tex->macrotile != R300_BUFFER_LINEAR); + tex->buffer = screen->buffer_create(screen, 2048, + PIPE_BUFFER_USAGE_PIXEL, + tex->size); + winsys->buffer_set_tiling(winsys, tex->buffer, + tex->pitch[0], + tex->microtile != R300_BUFFER_LINEAR, + tex->macrotile != R300_BUFFER_LINEAR); if (!tex->buffer) { FREE(tex); @@ -764,9 +764,9 @@ static struct pipe_texture* static void r300_texture_destroy(struct pipe_texture* texture) { struct r300_texture* tex = (struct r300_texture*)texture; - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; - rws->buffer_reference(rws, &tex->buffer, NULL); + pipe_buffer_reference(&tex->buffer, NULL); + FREE(tex); } @@ -806,14 +806,14 @@ static void r300_tex_surface_destroy(struct pipe_surface* s) FREE(s); } -struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, - const struct pipe_texture *base, - const unsigned *stride, - struct r300_winsys_buffer *buffer) +static struct pipe_texture* + r300_texture_blanket(struct pipe_screen* screen, + const struct pipe_texture* base, + const unsigned* stride, + struct pipe_buffer* buffer) { struct r300_texture* tex; struct r300_screen* rscreen = r300_screen(screen); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || @@ -837,7 +837,7 @@ struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *scre r300_setup_flags(tex); r300_setup_texture_state(rscreen, tex); - rws->buffer_reference(rws, &tex->buffer, buffer); + pipe_buffer_reference(&tex->buffer, buffer); return (struct pipe_texture*)tex; } @@ -896,6 +896,7 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; screen->tex_surface_destroy = r300_tex_surface_destroy; + screen->texture_blanket = r300_texture_blanket; screen->video_surface_create = r300_video_surface_create; screen->video_surface_destroy= r300_video_surface_destroy; @@ -903,23 +904,19 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct r300_winsys_buffer** buffer, + struct pipe_buffer** buffer, unsigned* stride) { struct r300_texture* tex = (struct r300_texture*)texture; - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - struct r300_winsys_buffer *buf; - if (!tex) { return FALSE; } - rws->buffer_reference(rws, &buf, tex->buffer); + pipe_buffer_reference(buffer, tex->buffer); if (stride) { *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); } - *buffer = buf; return TRUE; } diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 97724f790c..46a5fb6188 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -63,8 +63,8 @@ r300_video_surface(struct pipe_video_surface *pvs) #ifndef R300_WINSYS_H boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture *texture, - struct r300_winsys_buffer** buffer, + struct pipe_texture* texture, + struct pipe_buffer** buffer, unsigned* stride); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index c6f9174496..40fb8a95ca 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -23,6 +23,10 @@ #ifndef R300_WINSYS_H #define R300_WINSYS_H +#ifdef __cplusplus +extern "C" { +#endif + /* The public interface header for the r300 pipe driver. * Any winsys hosting this pipe needs to implement r300_winsys and then * call r300_create_screen to start things. */ @@ -30,128 +34,19 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" -struct r300_winsys_screen; +struct radeon_winsys; /* Creates a new r300 screen. */ -struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws); - -struct r300_winsys_buffer; +struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct r300_winsys_buffer** buffer, - unsigned *stride); - -enum r300_value_id { - R300_VID_PCI_ID, - R300_VID_GB_PIPES, - R300_VID_Z_PIPES, -}; - -struct r300_winsys_screen { - void (*destroy)(struct r300_winsys_screen *ws); - - /** - * Buffer management. Buffer attributes are mostly fixed over its lifetime. - * - * Remember that gallium gets to choose the interface it needs, and the - * window systems must then implement that interface (rather than the - * other way around...). - * - * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This - * usage argument is only an optimization hint, not a guarantee, therefore - * proper behavior must be observed in all circumstances. - * - * alignment indicates the client's alignment requirements, eg for - * SSE instructions. - */ - struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws, - unsigned alignment, - unsigned usage, - unsigned size); - - /** - * Map the entire data store of a buffer object into the client's address. - * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags. - */ - void *(*buffer_map)( struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf, - unsigned usage ); - - void (*buffer_unmap)( struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf ); - - void (*buffer_destroy)( struct r300_winsys_buffer *buf ); - - - void (*buffer_reference)(struct r300_winsys_screen *rws, - struct r300_winsys_buffer **pdst, - struct r300_winsys_buffer *src); - - boolean (*buffer_references)(struct r300_winsys_buffer *a, - struct r300_winsys_buffer *b); - - /* Add a pipe_buffer to the list of buffer objects to validate. */ - boolean (*add_buffer)(struct r300_winsys_screen *winsys, - struct r300_winsys_buffer *buf, - uint32_t rd, - uint32_t wd); - - /* Revalidate all currently setup pipe_buffers. - * Returns TRUE if a flush is required. */ - boolean (*validate)(struct r300_winsys_screen* winsys); - - /* Check to see if there's room for commands. */ - boolean (*check_cs)(struct r300_winsys_screen* winsys, int size); - - /* Start a command emit. */ - void (*begin_cs)(struct r300_winsys_screen* winsys, - int size, - const char* file, - const char* function, - int line); - - /* Write a dword to the command buffer. */ - void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword); - - /* Write a relocated dword to the command buffer. */ - void (*write_cs_reloc)(struct r300_winsys_screen *winsys, - struct r300_winsys_buffer *buf, - uint32_t rd, - uint32_t wd, - uint32_t flags); - - /* Finish a command emit. */ - void (*end_cs)(struct r300_winsys_screen* winsys, - const char* file, - const char* function, - int line); - - /* Flush the CS. */ - void (*flush_cs)(struct r300_winsys_screen* winsys); - - /* winsys flush - callback from winsys when flush required */ - void (*set_flush_cb)(struct r300_winsys_screen *winsys, - void (*flush_cb)(void *), void *data); - - void (*reset_bos)(struct r300_winsys_screen *winsys); - - void (*buffer_set_tiling)(struct r300_winsys_screen *winsys, - struct r300_winsys_buffer *buffer, - uint32_t pitch, - boolean microtiled, - boolean macrotiled); - - uint32_t (*get_value)(struct r300_winsys_screen *winsys, - enum r300_value_id vid); -}; + struct pipe_buffer** buffer, + unsigned* stride); -struct r300_winsys_screen * -r300_winsys_screen(struct pipe_screen *screen); +#ifdef __cplusplus +} +#endif -struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, - const struct pipe_texture *base, - const unsigned *stride, - struct r300_winsys_buffer *buffer); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h index b36680eb66..c6a7d4a8c5 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h @@ -32,6 +32,8 @@ i965_libdrm_winsys(struct brw_winsys_screen *iws) return (struct i965_libdrm_winsys *)iws; } +struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id); + void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws); diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/drm/radeon/core/Makefile index 13bbbf730d..860cbb6dbf 100644 --- a/src/gallium/winsys/drm/radeon/core/Makefile +++ b/src/gallium/winsys/drm/radeon/core/Makefile @@ -5,7 +5,7 @@ include $(TOP)/configs/current LIBNAME = radeonwinsys C_SOURCES = \ - radeon_drm_buffer.c \ + radeon_buffer.c \ radeon_drm.c \ radeon_r300.c diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index 8e0274e33d..f1c8fc2a3b 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -32,11 +32,11 @@ #include +#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "pipebuffer/pb_buffer.h" -#include "pipebuffer/pb_bufmgr.h" #include "util/u_memory.h" @@ -47,41 +47,41 @@ #include "radeon_winsys.h" +struct radeon_pipe_buffer { + struct pipe_buffer base; + /* Pointer to GPU-backed BO. */ + struct radeon_bo *bo; + /* Pointer to fallback PB buffer. */ + struct pb_buffer *pb; + boolean flinked; + uint32_t flink; +}; #define RADEON_MAX_BOS 24 -static INLINE struct pb_buffer * -radeon_pb_buffer(struct r300_winsys_buffer *buffer) -{ - return (struct pb_buffer *)buffer; -} +struct radeon_winsys_priv { + /* DRM FD */ + int fd; -static INLINE struct r300_winsys_buffer * -radeon_libdrm_winsys_buffer(struct pb_buffer *buffer) -{ - return (struct r300_winsys_buffer *)buffer; -} + /* Radeon BO manager. */ + struct radeon_bo_manager* bom; -struct pb_manager * -radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws); + /* Radeon CS manager. */ + struct radeon_cs_manager* csm; -boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd); + /* Current CS. */ + struct radeon_cs* cs; + /* Flush CB */ + void (*flush_cb)(void *); + void *flush_data; +}; -void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd, - uint32_t flags); - -struct radeon_libdrm_winsys* radeon_pipe_winsys(int fd); - -boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, - uint32_t *handle); -uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf); -struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, - uint32_t handle); - -void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch); - -void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr); +struct radeon_winsys* radeon_pipe_winsys(int fb); +#if 0 +struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch); +#endif #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index f886fda2f2..0c0e118ba3 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -31,22 +31,8 @@ #include "radeon_drm.h" -static struct radeon_libdrm_winsys * -radeon_winsys_create(int fd) -{ - struct radeon_libdrm_winsys *rws; - - rws = CALLOC_STRUCT(radeon_libdrm_winsys); - if (rws == NULL) { - return NULL; - } - - rws->fd = fd; - return rws; -} - /* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) +static void do_ioctls(int fd, struct radeon_winsys* winsys) { struct drm_radeon_gem_info gem_info = {0}; struct drm_radeon_info info = {0}; @@ -137,26 +123,62 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg) { - struct radeon_libdrm_winsys* rws; - - rws = radeon_winsys_create(drmFB); - if (!rws) - return NULL; - - do_ioctls(drmFB, rws); + struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB); + do_ioctls(drmFB, rwinsys); /* The state tracker can organize a softpipe fallback if no hw * driver is found. */ - if (is_r3xx(rws->pci_id)) { - radeon_setup_winsys(drmFB, rws); - return r300_create_screen(&rws->base); + if (is_r3xx(rwinsys->pci_id)) { + radeon_setup_winsys(drmFB, rwinsys); + return r300_create_screen(rwinsys); } else { - FREE(rws); + FREE(rwinsys); return NULL; } } + +boolean radeon_buffer_from_texture(struct drm_api* api, + struct pipe_screen* screen, + struct pipe_texture* texture, + struct pipe_buffer** buffer, + unsigned* stride) +{ + /* XXX fix this */ + return r300_get_texture_buffer(screen, texture, buffer, stride); +} + +/* Create a buffer from a handle. */ +/* XXX what's up with name? */ +struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, + struct pipe_screen* screen, + const char* name, + unsigned handle) +{ + struct radeon_bo_manager* bom = + ((struct radeon_winsys*)screen->winsys)->priv->bom; + struct radeon_pipe_buffer* radeon_buffer; + struct radeon_bo* bo = NULL; + + bo = radeon_bo_open(bom, handle, 0, 0, 0, 0); + if (bo == NULL) { + return NULL; + } + + radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); + if (radeon_buffer == NULL) { + radeon_bo_unref(bo); + return NULL; + } + + pipe_reference_init(&radeon_buffer->base.reference, 1); + radeon_buffer->base.screen = screen; + radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; + radeon_buffer->bo = bo; + return &radeon_buffer->base; +} + static struct pipe_texture* radeon_texture_from_shared_handle(struct drm_api *api, struct pipe_screen *screen, @@ -165,20 +187,18 @@ radeon_texture_from_shared_handle(struct drm_api *api, unsigned stride, unsigned handle) { - struct pb_buffer *_buf; - struct r300_winsys_buffer *buf; + struct pipe_buffer *buffer; struct pipe_texture *blanket; - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(r300_winsys_screen(screen)); - _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle); - if (!_buf) { - return NULL; + buffer = radeon_buffer_from_handle(api, screen, name, handle); + if (!buffer) { + return NULL; } - buf = radeon_libdrm_winsys_buffer(_buf); - blanket = r300_texture_blanket_winsys_buffer(screen, templ, &stride, buf); + blanket = screen->texture_blanket(screen, templ, &stride, buffer); + + pipe_buffer_reference(&buffer, NULL); - pb_reference(&_buf, NULL); return blanket; } @@ -188,14 +208,34 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - struct r300_winsys_buffer *radeon_buffer; - struct pb_buffer *_buf; - if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { + int retval, fd; + struct drm_gem_flink flink; + struct radeon_pipe_buffer* radeon_buffer; + struct pipe_buffer *buffer = NULL; + + if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { return FALSE; } - _buf = radeon_pb_buffer(radeon_buffer); - return radeon_drm_bufmgr_shared_handle_from_buffer(_buf, handle); + radeon_buffer = (struct radeon_pipe_buffer*)buffer; + if (!radeon_buffer->flinked) { + fd = ((struct radeon_winsys*)screen->winsys)->priv->fd; + + flink.handle = radeon_buffer->bo->handle; + + retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (retval) { + debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", + retval); + return FALSE; + } + + radeon_buffer->flink = flink.name; + radeon_buffer->flinked = TRUE; + } + + *handle = radeon_buffer->flink; + return TRUE; } static boolean radeon_local_handle_from_texture(struct drm_api *api, @@ -204,18 +244,16 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - struct r300_winsys_buffer *radeon_buffer; - struct pb_buffer *_buf; - - if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { + struct pipe_buffer *buffer = NULL; + if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { return FALSE; } - _buf = radeon_pb_buffer(radeon_buffer); - *handle = radeon_drm_bufmgr_handle_from_buffer(_buf); + *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle; + + pipe_buffer_reference(&buffer, NULL); - pb_reference(&_buf, NULL); - return true; + return TRUE; } static void radeon_drm_api_destroy(struct drm_api *api) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 2f55061330..8d74cbafc2 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -59,6 +59,11 @@ boolean radeon_buffer_from_texture(struct drm_api* api, struct pipe_buffer** buffer, unsigned* stride); +struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, + struct pipe_screen* screen, + const char* name, + unsigned handle); + boolean radeon_handle_from_buffer(struct drm_api* api, struct pipe_screen* screen, struct pipe_buffer* buffer, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c deleted file mode 100644 index 5f2fd2d7fc..0000000000 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c +++ /dev/null @@ -1,361 +0,0 @@ - -#include "radeon_drm.h" -#include "radeon_bo_gem.h" -#include "radeon_cs_gem.h" - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_simple_list.h" -#include "pipebuffer/pb_buffer.h" -#include "pipebuffer/pb_bufmgr.h" - -#include "radeon_winsys.h" -struct radeon_drm_bufmgr; - -struct radeon_drm_buffer { - struct pb_buffer base; - struct radeon_drm_bufmgr *mgr; - - struct radeon_bo *bo; - - boolean flinked; - uint32_t flink; - - boolean mapped; - struct radeon_drm_buffer *next, *prev; -}; - -extern const struct pb_vtbl radeon_drm_buffer_vtbl; - - -static INLINE struct radeon_drm_buffer * -radeon_drm_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &radeon_drm_buffer_vtbl); - return (struct radeon_drm_buffer *)buf; -} - -struct radeon_drm_bufmgr { - struct pb_manager base; - struct radeon_libdrm_winsys *rws; - struct radeon_drm_buffer buffer_map_list; -}; - -static INLINE struct radeon_drm_bufmgr * -radeon_drm_bufmgr(struct pb_manager *mgr) -{ - assert(mgr); - return (struct radeon_drm_bufmgr *)mgr; -} - -static void -radeon_drm_buffer_destroy(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - - if (buf->mapped) { - remove_from_list(buf); - radeon_bo_unmap(buf->bo); - buf->mapped = false; - } - radeon_bo_unref(buf->bo); - - FREE(buf); -} - -static void * -radeon_drm_buffer_map(struct pb_buffer *_buf, - unsigned flags) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - int write; - - if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { - uint32_t domain; - - if (radeon_bo_is_busy(buf->bo, &domain)) - return NULL; - } - - if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) { - buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data); - } - - if (buf->mapped) - return buf->bo->ptr; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { - write = 1; - } - - if (radeon_bo_map(buf->bo, write)) { - return NULL; - } - buf->mapped = true; - insert_at_tail(&buf->mgr->buffer_map_list, buf); - return buf->bo->ptr; -} - -static void -radeon_drm_buffer_unmap(struct pb_buffer *_buf) -{ - (void)_buf; -} - -static void -radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - *base_buf = buf; - *offset = 0; -} - - -static enum pipe_error -radeon_drm_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - /* Always pinned */ - return PIPE_OK; -} - -static void -radeon_drm_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ -} - -const struct pb_vtbl radeon_drm_buffer_vtbl = { - radeon_drm_buffer_destroy, - radeon_drm_buffer_map, - radeon_drm_buffer_unmap, - radeon_drm_buffer_validate, - radeon_drm_buffer_fence, - radeon_drm_buffer_get_base_buffer, -}; - - -static uint32_t radeon_domain_from_usage(unsigned usage) -{ - uint32_t domain = 0; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BUFFER_USAGE_INDEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - - return domain; -} - -struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, - uint32_t handle) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_libdrm_winsys *rws = mgr->rws; - struct radeon_drm_buffer *buf; - struct radeon_bo *bo; - - bo = radeon_bo_open(rws->bom, handle, 0, - 0, 0, 0); - if (bo == NULL) - return NULL; - - buf = CALLOC_STRUCT(radeon_drm_buffer); - if (!buf) { - radeon_bo_unref(bo); - return NULL; - } - - make_empty_list(buf); - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = 0; - buf->base.base.usage = PIPE_BUFFER_USAGE_PIXEL; - buf->base.base.size = 0; - buf->base.vtbl = &radeon_drm_buffer_vtbl; - buf->mgr = mgr; - - buf->bo = bo; - - // fprintf(stderr,"hand %p : %d\n", &buf->base, handle); - return &buf->base; - -} - -static struct pb_buffer * -radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr, - pb_size size, - const struct pb_desc *desc) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_libdrm_winsys *rws = mgr->rws; - struct radeon_drm_buffer *buf; - uint32_t domain; - - buf = CALLOC_STRUCT(radeon_drm_buffer); - if (!buf) - goto error1; - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = desc->alignment; - buf->base.base.usage = desc->usage; - buf->base.base.size = size; - buf->base.vtbl = &radeon_drm_buffer_vtbl; - buf->mgr = mgr; - - make_empty_list(buf); - domain = radeon_domain_from_usage(desc->usage); - buf->bo = radeon_bo_open(rws->bom, 0, size, - desc->alignment, domain, 0); - if (buf->bo == NULL) - goto error2; - - // fprintf(stderr,"%p : %d\n", &buf->base, size); - return &buf->base; - - error2: - FREE(buf); - error1: - return NULL; -} - -static void -radeon_drm_bufmgr_flush(struct pb_manager *mgr) -{ - /* NOP */ -} - -static void -radeon_drm_bufmgr_destroy(struct pb_manager *_mgr) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - FREE(mgr); -} - -struct pb_manager * -radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws) -{ - struct radeon_drm_bufmgr *mgr; - - mgr = CALLOC_STRUCT(radeon_drm_bufmgr); - if (!mgr) - return NULL; - - mgr->base.destroy = radeon_drm_bufmgr_destroy; - mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer; - mgr->base.flush = radeon_drm_bufmgr_flush; - - mgr->rws = rws; - make_empty_list(&mgr->buffer_map_list); - return &mgr->base; -} - -uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - - return buf->bo->handle; -} - -boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, - uint32_t *handle) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - struct drm_gem_flink flink; - int retval, fd; - if (!buf->flinked) { - fd = buf->mgr->rws->fd; - flink.handle = buf->bo->handle; - - retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - if (retval) { - return false; - } - - buf->flinked = TRUE; - buf->flink = flink.name; - } - *handle = buf->flink; - return TRUE; -} - -static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf; - if (_buf->vtbl == &radeon_drm_buffer_vtbl) { - buf = radeon_drm_buffer(_buf); - } else { - struct pb_buffer *base_buf; - pb_size offset; - pb_get_base_buffer(_buf, &base_buf, &offset); - - buf = radeon_drm_buffer(base_buf); - } - return buf; -} - -void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - uint32_t flags = 0; - - if (microtiled) - flags |= RADEON_BO_FLAGS_MICRO_TILE; - if (macrotiled) - flags |= RADEON_BO_FLAGS_MACRO_TILE; - - radeon_bo_set_tiling(buf->bo, flags, pitch); - -} - -boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo, - rd, wd); - - return true; -} - -void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd, - uint32_t flags) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - int retval; - - retval = radeon_cs_write_reloc(buf->mgr->rws->cs, - buf->bo, rd, wd, flags); - if (retval) { - debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", - buf, rd, wd, flags); - } -} - -void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_drm_buffer *rpb, *t_rpb; - - foreach_s(rpb, t_rpb, &mgr->buffer_map_list) { - rpb->mapped = 0; - radeon_bo_unmap(rpb->bo); - remove_from_list(rpb); - } - - make_empty_list(&mgr->buffer_map_list); - - -} diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index 997abb8f5c..d759beaba1 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,104 +22,29 @@ #include "radeon_r300.h" -static struct r300_winsys_buffer * -radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - struct pb_desc desc; - struct pb_manager *provider; - struct pb_buffer *buffer; - - memset(&desc, 0, sizeof(desc)); - desc.alignment = alignment; - desc.usage = usage; - - if (usage == PIPE_BUFFER_USAGE_CONSTANT) - provider = ws->mman; - else if (usage == PIPE_BUFFER_USAGE_VERTEX || - usage == PIPE_BUFFER_USAGE_INDEX) - provider = ws->cman; - else - provider = ws->kman; - buffer = provider->create_buffer(provider, size, &desc); - if (!buffer) - return NULL; - - return radeon_libdrm_winsys_buffer(buffer); -} - -static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_destroy(_buf); -} -static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - uint32_t pitch, - boolean microtiled, - boolean macrotiled) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch); -} - -static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf, - unsigned usage) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - return pb_map(_buf, 0); -} - -static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_unmap(_buf); -} - -static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, - struct r300_winsys_buffer **pdst, - struct r300_winsys_buffer *src) -{ - struct pb_buffer *_src = radeon_pb_buffer(src); - struct pb_buffer *_dst = radeon_pb_buffer(*pdst); - - pb_reference(&_dst, _src); - - *pdst = radeon_libdrm_winsys_buffer(_dst); -} - -static void radeon_set_flush_cb(struct r300_winsys_screen *rws, +static void radeon_set_flush_cb(struct radeon_winsys *winsys, void (*flush_cb)(void *), void *data) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - ws->flush_cb = flush_cb; - ws->flush_data = data; - radeon_cs_space_set_flush(ws->cs, flush_cb, data); + winsys->priv->flush_cb = flush_cb; + winsys->priv->flush_data = data; + radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data); } -static boolean radeon_add_buffer(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, +static boolean radeon_add_buffer(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, uint32_t rd, uint32_t wd) { - struct pb_buffer *_buf = radeon_pb_buffer(buf); + struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; - return radeon_drm_bufmgr_add_buffer(_buf, rd, wd); + radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd); + return TRUE; } -static boolean radeon_validate(struct r300_winsys_screen *rws) +static boolean radeon_validate(struct radeon_winsys* winsys) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - if (radeon_cs_space_check(ws->cs) < 0) { + if (radeon_cs_space_check(winsys->priv->cs) < 0) { return FALSE; } @@ -127,146 +52,108 @@ static boolean radeon_validate(struct r300_winsys_screen *rws) return TRUE; } -static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size) +static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - struct radeon_cs *cs = ws->cs; + struct radeon_cs* cs = winsys->priv->cs; - return radeon_validate(rws) && cs->cdw + size <= cs->ndw; + return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; } -static void radeon_begin_cs(struct r300_winsys_screen *rws, +static void radeon_begin_cs(struct radeon_winsys* winsys, int size, const char* file, const char* function, int line) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_begin(ws->cs, size, file, function, line); + radeon_cs_begin(winsys->priv->cs, size, file, function, line); } -static void radeon_write_cs_dword(struct r300_winsys_screen *rws, +static void radeon_write_cs_dword(struct radeon_winsys* winsys, uint32_t dword) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_write_dword(ws->cs, dword); + radeon_cs_write_dword(winsys->priv->cs, dword); } -static void radeon_write_cs_reloc(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, +static void radeon_write_cs_reloc(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, uint32_t rd, uint32_t wd, uint32_t flags) { - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags); + int retval = 0; + struct radeon_pipe_buffer* radeon_buffer = + (struct radeon_pipe_buffer*)pbuffer; + + assert(!radeon_buffer->pb); + + retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, + rd, wd, flags); + + if (retval) { + debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", + pbuffer, rd, wd, flags); + } } -static void radeon_reset_bos(struct r300_winsys_screen *rws) +static void radeon_reset_bos(struct radeon_winsys *winsys) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_space_reset_bos(ws->cs); + radeon_cs_space_reset_bos(winsys->priv->cs); } -static void radeon_end_cs(struct r300_winsys_screen *rws, +static void radeon_end_cs(struct radeon_winsys* winsys, const char* file, const char* function, int line) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_end(ws->cs, file, function, line); + radeon_cs_end(winsys->priv->cs, file, function, line); } -static void radeon_flush_cs(struct r300_winsys_screen *rws) +static void radeon_flush_cs(struct radeon_winsys* winsys) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); int retval; /* Don't flush a zero-sized CS. */ - if (!ws->cs->cdw) { + if (!winsys->priv->cs->cdw) { return; } - radeon_drm_bufmgr_flush_maps(ws->kman); /* Emit the CS. */ - retval = radeon_cs_emit(ws->cs); + retval = radeon_cs_emit(winsys->priv->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); - radeon_cs_print(ws->cs, stderr); + radeon_cs_print(winsys->priv->cs, stderr); } /* Reset CS. * Someday, when we care about performance, we should really find a way * to rotate between two or three CS objects so that the GPU can be * spinning through one CS while another one is being filled. */ - radeon_cs_erase(ws->cs); -} - -static uint32_t radeon_get_value(struct r300_winsys_screen *rws, - enum r300_value_id id) -{ - struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; - - switch(id) { - case R300_VID_PCI_ID: - return ws->pci_id; - case R300_VID_GB_PIPES: - return ws->gb_pipes; - case R300_VID_Z_PIPES: - return ws->z_pipes; - } - return 0; -} - -static void -radeon_winsys_destroy(struct r300_winsys_screen *rws) -{ - struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; - radeon_cs_destroy(ws->cs); - - ws->cman->destroy(ws->cman); - ws->kman->destroy(ws->kman); - ws->mman->destroy(ws->mman); - - radeon_bo_manager_gem_dtor(ws->bom); - radeon_cs_manager_gem_dtor(ws->csm); + radeon_cs_erase(winsys->priv->cs); } void -radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) +radeon_setup_winsys(int fd, struct radeon_winsys* winsys) { - ws->csm = radeon_cs_manager_gem_ctor(fd); - - ws->bom = radeon_bo_manager_gem_ctor(fd); - ws->kman = radeon_drm_bufmgr_create(ws); + struct radeon_winsys_priv* priv = winsys->priv; - ws->cman = pb_cache_manager_create(ws->kman, 100000); - ws->mman = pb_malloc_bufmgr_create(); + priv->csm = radeon_cs_manager_gem_ctor(fd); /* Size limit on IBs is 64 kibibytes. */ - ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); - radeon_cs_set_limit(ws->cs, - RADEON_GEM_DOMAIN_GTT, ws->gart_size); - radeon_cs_set_limit(ws->cs, - RADEON_GEM_DOMAIN_VRAM, ws->vram_size); - - ws->base.add_buffer = radeon_add_buffer; - ws->base.validate = radeon_validate; - ws->base.destroy = radeon_winsys_destroy; - ws->base.check_cs = radeon_check_cs; - ws->base.begin_cs = radeon_begin_cs; - ws->base.write_cs_dword = radeon_write_cs_dword; - ws->base.write_cs_reloc = radeon_write_cs_reloc; - ws->base.end_cs = radeon_end_cs; - ws->base.flush_cs = radeon_flush_cs; - ws->base.reset_bos = radeon_reset_bos; - ws->base.set_flush_cb = radeon_set_flush_cb; - ws->base.get_value = radeon_get_value; - - ws->base.buffer_create = radeon_r300_winsys_buffer_create; - ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy; - ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling; - ws->base.buffer_map = radeon_r300_winsys_buffer_map; - ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; - ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; + priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4); + radeon_cs_set_limit(priv->cs, + RADEON_GEM_DOMAIN_GTT, winsys->gart_size); + radeon_cs_set_limit(priv->cs, + RADEON_GEM_DOMAIN_VRAM, winsys->vram_size); + + winsys->add_buffer = radeon_add_buffer; + winsys->validate = radeon_validate; + + winsys->check_cs = radeon_check_cs; + winsys->begin_cs = radeon_begin_cs; + winsys->write_cs_dword = radeon_write_cs_dword; + winsys->write_cs_reloc = radeon_write_cs_reloc; + winsys->end_cs = radeon_end_cs; + winsys->flush_cs = radeon_flush_cs; + winsys->reset_bos = radeon_reset_bos; + winsys->set_flush_cb = radeon_set_flush_cb; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index 82a8aad715..cfbdb30266 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -28,12 +28,12 @@ #include #include "drm.h" #include "radeon_drm.h" -#include "radeon_bo_gem.h" #include "radeon_cs_gem.h" -#include "radeon_winsys.h" +#include "r300_winsys.h" + #include "radeon_buffer.h" -void radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys); +void radeon_setup_winsys(int fd, struct radeon_winsys* winsys); #endif /* RADEON_R300_H */ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index c8e725cff0..4901080ca7 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -30,17 +30,16 @@ #ifndef RADEON_WINSYS_H #define RADEON_WINSYS_H -#include "r300_winsys.h" +#include "util/u_simple_screen.h" -struct radeon_libdrm_winsys { - /* Parent class. */ - struct r300_winsys_screen base; - - struct pb_manager *kman; +struct radeon_winsys_priv; - struct pb_manager *mman; +struct radeon_winsys { + /* Parent class. */ + struct pipe_winsys base; - struct pb_manager *cman; + /* Winsys private */ + struct radeon_winsys_priv* priv; /* PCI ID */ uint32_t pci_id; @@ -57,27 +56,56 @@ struct radeon_libdrm_winsys { /* VRAM size. */ uint32_t vram_size; - /* DRM FD */ - int fd; - - /* Radeon BO manager. */ - struct radeon_bo_manager *bom; - - /* Radeon CS manager. */ - struct radeon_cs_manager *csm; - - /* Current CS. */ - struct radeon_cs *cs; - - /* Flush CB */ - void (*flush_cb)(void *); - void *flush_data; + /* Add a pipe_buffer to the list of buffer objects to validate. */ + boolean (*add_buffer)(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd); + + /* Revalidate all currently setup pipe_buffers. + * Returns TRUE if a flush is required. */ + boolean (*validate)(struct radeon_winsys* winsys); + + /* Check to see if there's room for commands. */ + boolean (*check_cs)(struct radeon_winsys* winsys, int size); + + /* Start a command emit. */ + void (*begin_cs)(struct radeon_winsys* winsys, + int size, + const char* file, + const char* function, + int line); + + /* Write a dword to the command buffer. */ + void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword); + + /* Write a relocated dword to the command buffer. */ + void (*write_cs_reloc)(struct radeon_winsys* winsys, + struct pipe_buffer* bo, + uint32_t rd, + uint32_t wd, + uint32_t flags); + + /* Finish a command emit. */ + void (*end_cs)(struct radeon_winsys* winsys, + const char* file, + const char* function, + int line); + + /* Flush the CS. */ + void (*flush_cs)(struct radeon_winsys* winsys); + + /* winsys flush - callback from winsys when flush required */ + void (*set_flush_cb)(struct radeon_winsys *winsys, + void (*flush_cb)(void *), void *data); + + void (*reset_bos)(struct radeon_winsys *winsys); + + void (*buffer_set_tiling)(struct radeon_winsys* winsys, + struct pipe_buffer* buffer, + uint32_t pitch, + boolean microtiled, + boolean macrotiled); }; -static INLINE struct radeon_libdrm_winsys * -radeon_winsys_screen(struct r300_winsys_screen *base) -{ - return (struct radeon_libdrm_winsys *)base; -} - #endif -- cgit v1.2.3 From 902ccfcb40f21e1a5fca2f1bec1cbbabb053d8cf Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 22 Feb 2010 13:51:38 +0100 Subject: r300g: fix draw_elements for "start" != 0 Reported-by: Andre Maasikas --- src/gallium/drivers/r300/r300_render.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 754eb4dc76..648d884654 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -258,11 +258,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, assert((start * indexSize) % 4 == 0); - /* XXX Non-zero offset locks up. */ - if (offset_dwords != 0) { - return; - } - if (alt_num_verts) { assert(count < (1 << 24)); BEGIN_CS(16); @@ -276,13 +271,13 @@ static void r300_emit_draw_elements(struct r300_context *r300, OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); if (indexSize == 4) { - count_dwords = count + start; + count_dwords = count; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | R300_VAP_VF_CNTL__INDEX_SIZE_32bit | r300_translate_primitive(mode) | (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); } else { - count_dwords = (count + start + 1) / 2; + count_dwords = (count + 1) / 2; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | r300_translate_primitive(mode) | (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); -- cgit v1.2.3 From e6632b4bf7cba5fe8a77d54635a3b617fa67185f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 22 Feb 2010 15:11:29 +0100 Subject: r300g: prevent CS overflow when emitting the draw packets Signed-off-by: Corbin Simpson --- src/gallium/drivers/r300/r300_emit.c | 29 +++++++++++------------ src/gallium/drivers/r300/r300_emit.h | 2 ++ src/gallium/drivers/r300/r300_render.c | 42 ++++++++++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f7dcd8dc52..2d8801c08a 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1076,16 +1076,10 @@ validate: } } -/* Emit all dirty state. */ -void r300_emit_dirty_state(struct r300_context* r300) +unsigned r300_get_num_dirty_dwords(struct r300_context *r300) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_atom* atom; - unsigned i, dwords = 1024; - int dirty_tex = 0; - - /* Check the required number of dwords against the space remaining in the - * current CS object. If we need more, then flush. */ + unsigned dwords = 0; foreach(atom, &r300->atom_list) { if (atom->dirty || atom->always_dirty) { @@ -1093,12 +1087,19 @@ void r300_emit_dirty_state(struct r300_context* r300) } } - /* Make sure we have at least 2*1024 spare dwords. */ - /* XXX It would be nice to know the number of dwords we really need to - * XXX emit. */ - while (!r300->winsys->check_cs(r300->winsys, dwords)) { - r300->context.flush(&r300->context, 0, NULL); - } + /* XXX This is the compensation for the non-atomized states. */ + dwords += 2048; + + return dwords; +} + +/* Emit all dirty state. */ +void r300_emit_dirty_state(struct r300_context* r300) +{ + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_atom* atom; + unsigned i; + int dirty_tex = 0; if (r300->dirty_state & R300_NEW_QUERY) { r300_emit_query_start(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 6b96d9b57c..ff709a0595 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -90,6 +90,8 @@ void r300_emit_ztop_state(struct r300_context* r300, void* state); void r300_flush_textures(struct r300_context* r300); +unsigned r300_get_num_dirty_dwords(struct r300_context *r300); + /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 648d884654..ec72d6c3b5 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -118,6 +118,18 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, return color_control; } +/* Check if the requested number of dwords is available in the CS and + * if not, flush. Return TRUE if the flush occured. */ +static boolean r300_reserve_cs_space(struct r300_context *r300, + unsigned dwords) +{ + while (!r300->winsys->check_cs(r300->winsys, dwords)) { + r300->context.flush(&r300->context, 0, NULL); + return TRUE; + } + return FALSE; +} + static boolean immd_is_good_idea(struct r300_context *r300, unsigned count) { @@ -132,7 +144,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; unsigned vertex_element_count = r300->vertex_element_count; - unsigned i, v, vbi, dw, elem_offset; + unsigned i, v, vbi, dw, elem_offset, dwords; /* Size of the vertex, in dwords. */ unsigned vertex_size = 0; @@ -171,9 +183,12 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, } } + dwords = 10 + count * vertex_size; + + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_emit_dirty_state(r300); - BEGIN_CS(10 + count * vertex_size); + BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); @@ -400,8 +415,9 @@ void r300_draw_range_elements(struct pipe_context* pipe, goto cleanup; } + /* 128 dwords for emit_aos and emit_draw_elements */ + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); r300_emit_dirty_state(r300); - r300_emit_aos(r300, 0); if (alt_num_verts || count <= 65535) { @@ -415,6 +431,12 @@ void r300_draw_range_elements(struct pipe_context* pipe, start += short_count; count -= short_count; + + /* 16 spare dwords are enough for emit_draw_elements. */ + if (count && r300_reserve_cs_space(r300, 16)) { + r300_emit_dirty_state(r300); + r300_emit_aos(r300, 0); + } } while (count); } @@ -461,6 +483,9 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return; } + /* Make sure there are at least 128 spare dwords in the command buffer. + * (most of it being consumed by emit_aos) */ + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { @@ -474,6 +499,12 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, start += short_count; count -= short_count; + + /* Again, we emit both AOS and draw_arrays so there should be + * at least 128 spare dwords. */ + if (count && r300_reserve_cs_space(r300, 128)) { + r300_emit_dirty_state(r300); + } } while (count); } } @@ -690,6 +721,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render, CS_LOCALS(r300); + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2); r300_emit_dirty_state(r300); DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); @@ -708,12 +740,14 @@ static void r300_render_draw(struct vbuf_render* render, struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; int i; + unsigned dwords = 2 + (count+1)/2; CS_LOCALS(r300); + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_emit_dirty_state(r300); - BEGIN_CS(2 + (count+1)/2); + BEGIN_CS(dwords); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | r300render->hwprim); -- cgit v1.2.3 From dba7ad895333b9b0988239266a217edeebe6a3b3 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 26 Feb 2010 22:34:09 +0100 Subject: r300g: remove pointless "while" --- src/gallium/drivers/r300/r300_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index ec72d6c3b5..d604bfb7d7 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -123,7 +123,7 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, static boolean r300_reserve_cs_space(struct r300_context *r300, unsigned dwords) { - while (!r300->winsys->check_cs(r300->winsys, dwords)) { + if (!r300->winsys->check_cs(r300->winsys, dwords)) { r300->context.flush(&r300->context, 0, NULL); return TRUE; } -- cgit v1.2.3 From 93da1522098145f0e7ff9d4188050728b075b4a1 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 00:37:01 +0100 Subject: r300g: always emit the correct max vertex index to avoid DRM errors Fixing bizarre reports that a vertex buffer is not large enough. --- src/gallium/drivers/r300/r300_context.h | 1 + src/gallium/drivers/r300/r300_render.c | 7 +++++-- src/gallium/drivers/r300/r300_state.c | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 3d4f6524e5..8704f18529 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -326,6 +326,7 @@ struct r300_context { /* Vertex buffers for Gallium. */ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; + int vertex_buffer_max_index; /* Vertex elements for Gallium. */ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index d604bfb7d7..e4f7615368 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -452,8 +452,11 @@ void r300_draw_elements(struct pipe_context* pipe, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { - pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0, ~0, - mode, start, count); + struct r300_context *r300 = r300_context(pipe); + + pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0, + r300->vertex_buffer_max_index, + mode, start, count); } void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 0f14ccc53e..ee4409c889 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1026,10 +1026,17 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); + unsigned i, max_index = ~0; memcpy(r300->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); + + for (i = 0; i < count; i++) { + max_index = MIN2(buffers[i].max_index, max_index); + } + r300->vertex_buffer_count = count; + r300->vertex_buffer_max_index = max_index; if (r300->draw) { draw_flush(r300->draw); -- cgit v1.2.3 From d36e3952c21240cde19dac7f16cc37aac7174673 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 17:00:03 +0100 Subject: r300g: put validating buffers after flushing Also cleaning up the nasty validation process. --- src/gallium/drivers/r300/r300_emit.c | 32 +++++++++++++++++--- src/gallium/drivers/r300/r300_emit.h | 4 ++- src/gallium/drivers/r300/r300_render.c | 54 ++++------------------------------ 3 files changed, 37 insertions(+), 53 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 013611018b..d66fa0dbdb 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1010,11 +1010,16 @@ void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, voi END_CS; } -void r300_emit_buffer_validate(struct r300_context *r300) +void r300_emit_buffer_validate(struct r300_context *r300, + boolean do_validate_vertex_buffers, + struct pipe_buffer *index_buffer) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; struct r300_texture* tex; + struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; + struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_buffer *pbuf; unsigned i; boolean invalid = FALSE; @@ -1061,16 +1066,35 @@ validate: goto validate; } } - /* ...and vertex buffer. */ + /* ...vertex buffer for SWTCL path... */ if (r300->vbo) { if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } - } else { - /* debug_printf("No VBO while emitting dirty state!\n"); */ } + /* ...vertex buffers for HWTCL path... */ + if (do_validate_vertex_buffers) { + for (i = 0; i < r300->vertex_element_count; i++) { + pbuf = vbuf[velem[i].vertex_buffer_index].buffer; + + if (!r300->winsys->add_buffer(r300->winsys, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { + r300->context.flush(&r300->context, 0, NULL); + goto validate; + } + } + } + /* ...and index buffer for HWTCL path. */ + if (index_buffer) { + if (!r300->winsys->add_buffer(r300->winsys, index_buffer, + RADEON_GEM_DOMAIN_GTT, 0)) { + r300->context.flush(&r300->context, 0, NULL); + goto validate; + } + } + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index c73b016b76..4a3f94087b 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -105,6 +105,8 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300); /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); -void r300_emit_buffer_validate(struct r300_context *r300); +void r300_emit_buffer_validate(struct r300_context *r300, + boolean do_validate_vertex_buffers, + struct pipe_buffer *index_buffer); #endif /* R300_EMIT_H */ diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index e4f7615368..c5baf5508e 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -186,6 +186,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, dwords = 10 + count * vertex_size; r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); + r300_emit_buffer_validate(r300, FALSE, 0); r300_emit_dirty_state(r300); BEGIN_CS(dwords); @@ -313,31 +314,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } -static boolean r300_setup_vertex_buffers(struct r300_context *r300) -{ - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; - struct pipe_buffer *pbuf; - -validate: - for (int i = 0; i < r300->vertex_element_count; i++) { - pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { - r300->context.flush(&r300->context, 0, NULL); - goto validate; - } - } - - if (!r300->winsys->validate(r300->winsys)) { - r300->context.flush(&r300->context, 0, NULL); - return r300->winsys->validate(r300->winsys); - } - - return TRUE; -} - static void r300_shorten_ubyte_elts(struct r300_context* r300, struct pipe_buffer** elts, unsigned count) @@ -393,30 +369,16 @@ void r300_draw_range_elements(struct pipe_context* pipe, return; } - r300_update_derived_state(r300); - - r300_emit_buffer_validate(r300); - - if (!r300_setup_vertex_buffers(r300)) { - return; - } - if (indexSize == 1) { r300_shorten_ubyte_elts(r300, &indexBuffer, count); indexSize = 2; } - if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, - RADEON_GEM_DOMAIN_GTT, 0)) { - goto cleanup; - } - - if (!r300->winsys->validate(r300->winsys)) { - goto cleanup; - } + r300_update_derived_state(r300); /* 128 dwords for emit_aos and emit_draw_elements */ r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); + r300_emit_buffer_validate(r300, TRUE, indexBuffer); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); @@ -434,13 +396,13 @@ void r300_draw_range_elements(struct pipe_context* pipe, /* 16 spare dwords are enough for emit_draw_elements. */ if (count && r300_reserve_cs_space(r300, 16)) { + r300_emit_buffer_validate(r300, TRUE, indexBuffer); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); } } while (count); } -cleanup: if (indexBuffer != orgIndexBuffer) { pipe->screen->buffer_destroy(indexBuffer); } @@ -477,18 +439,13 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, r300_update_derived_state(r300); - r300_emit_buffer_validate(r300); - if (immd_is_good_idea(r300, count)) { r300_emit_draw_arrays_immediate(r300, mode, start, count); } else { - if (!r300_setup_vertex_buffers(r300)) { - return; - } - /* Make sure there are at least 128 spare dwords in the command buffer. * (most of it being consumed by emit_aos) */ r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); + r300_emit_buffer_validate(r300, TRUE, 0); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { @@ -506,6 +463,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, /* Again, we emit both AOS and draw_arrays so there should be * at least 128 spare dwords. */ if (count && r300_reserve_cs_space(r300, 128)) { + r300_emit_buffer_validate(r300, TRUE, 0); r300_emit_dirty_state(r300); } } while (count); -- cgit v1.2.3 From 942762cd973af0df75040de21d3321cd19829e70 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 28 Feb 2010 07:45:56 +0100 Subject: r300g: decouple vertex stream setup (PSC) and VS output mapping (VAP_OUT) Formerly known as vertex_format_state. These two are completely unrelated when using HWTCL and decoupling them makes the design less SWTCL-centric. When bypass_vs_clip_and_viewport gets removed, the PSC setup will no longer be a derived state. This change shouldn't make unbreaking SWTCL harder. --- src/gallium/drivers/r300/r300_context.c | 9 +++-- src/gallium/drivers/r300/r300_context.h | 35 ++++++++++------- src/gallium/drivers/r300/r300_emit.c | 55 +++++++++++++++------------ src/gallium/drivers/r300/r300_emit.h | 5 ++- src/gallium/drivers/r300/r300_render.c | 2 +- src/gallium/drivers/r300/r300_state.c | 14 +++++-- src/gallium/drivers/r300/r300_state_derived.c | 47 +++++++++++++---------- 7 files changed, 101 insertions(+), 66 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 3a84fc564d..1d7d598b24 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -59,7 +59,8 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->fb_state.state); FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); - FREE(r300->vertex_format_state.state); + FREE(r300->vertex_stream_state.state); + FREE(r300->vap_output_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); FREE(r300); @@ -127,7 +128,8 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(scissor_state, 3); R300_INIT_ATOM(viewport_state, 9); R300_INIT_ATOM(rs_block_state, 0); - R300_INIT_ATOM(vertex_format_state, 26); + 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(texture_cache_inval, 2); @@ -138,7 +140,8 @@ static void r300_setup_atoms(struct r300_context* r300) r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); - r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info); + r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_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); } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 47f2aa5154..3eb884a0cf 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -134,6 +134,21 @@ struct r300_texture_fb_state { uint32_t zb_format; /* R300_ZB_FORMAT */ }; +struct r300_vertex_stream_state { + /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ + uint32_t vap_prog_stream_cntl[8]; + /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ + uint32_t vap_prog_stream_cntl_ext[8]; + + 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 */ @@ -246,16 +261,6 @@ struct r300_texture { enum r300_buffer_tiling microtile, macrotile; }; -struct r300_vertex_info { - /* Parent class */ - struct vertex_info vinfo; - - /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ - uint32_t vap_prog_stream_cntl[8]; - /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ - uint32_t vap_prog_stream_cntl_ext[8]; -}; - extern struct pipe_viewport_state r300_viewport_identity; struct r300_context { @@ -280,9 +285,6 @@ struct r300_context { struct r300_query *query_current; struct r300_query query_list; - /* Vertex formatting information. */ - struct r300_atom vertex_format_state; - /* Various CSO state objects. */ /* Beginning of atom list. */ struct r300_atom atom_list; @@ -312,6 +314,10 @@ struct r300_context { /* Texture states. */ struct r300_texture* textures[8]; int texture_count; + /* 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; /* Viewport state. */ @@ -334,6 +340,9 @@ struct r300_context { struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; + /* Vertex info for Draw. */ + struct vertex_info vertex_info; + struct pipe_stencil_ref stencil_ref; /* Bitmask of dirty state objects. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index d66fa0dbdb..6a6771399a 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -814,44 +814,51 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) END_CS; } -void r300_emit_vertex_format_state(struct r300_context* r300, +void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state) { - struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state; + struct r300_vertex_stream_state *streams = + (struct r300_vertex_stream_state*)state; unsigned i; CS_LOCALS(r300); - DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n"); + DBG(r300, DBG_DRAW, "r300: PSC emit:\n"); BEGIN_CS(size); - OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size); - - OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); - OUT_CS(vertex_info->vinfo.hwfmt[0]); - OUT_CS(vertex_info->vinfo.hwfmt[1]); - OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); - OUT_CS(vertex_info->vinfo.hwfmt[2]); - OUT_CS(vertex_info->vinfo.hwfmt[3]); - for (i = 0; i < 4; i++) { - DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i, - vertex_info->vinfo.hwfmt[i]); - } - - OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8); - for (i = 0; i < 8; i++) { - OUT_CS(vertex_info->vap_prog_stream_cntl[i]); + OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count); + for (i = 0; i < streams->count; i++) { + OUT_CS(streams->vap_prog_stream_cntl[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i, - vertex_info->vap_prog_stream_cntl[i]); + streams->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(vertex_info->vap_prog_stream_cntl_ext[i]); + OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count); + for (i = 0; i < streams->count; i++) { + OUT_CS(streams->vap_prog_stream_cntl_ext[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i, - vertex_info->vap_prog_stream_cntl_ext[i]); + streams->vap_prog_stream_cntl_ext[i]); } 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 4a3f94087b..a2c2a91b88 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -77,9 +77,12 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_buffer(struct r300_context* r300); -void r300_emit_vertex_format_state(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_vertex_program_code(struct r300_context* r300, struct r300_vertex_program_code* code); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index c5baf5508e..770a92be74 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -597,7 +597,7 @@ r300_render_get_vertex_info(struct vbuf_render* render) r300_update_derived_state(r300); - return (struct vertex_info*)r300->vertex_format_state.state; + return &r300->vertex_info; } static boolean r300_render_allocate_vertices(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 97a0897a5e..5a47158400 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -659,7 +659,11 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300->fs = fs; r300_pick_fragment_shader(r300); - r300->vertex_format_state.dirty = TRUE; + 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; + } r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -1033,9 +1037,9 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, if (r300->draw) { draw_flush(r300->draw); draw_set_vertex_buffers(r300->draw, count, buffers); + } else { + r300->vertex_stream_state.dirty = TRUE; } - - r300->vertex_format_state.dirty = TRUE; } static boolean r300_validate_aos(struct r300_context *r300) @@ -1114,7 +1118,9 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->vs_state.size = vs->code.length + 9; r300->vs_state.dirty = TRUE; - r300->vertex_format_state.dirty = TRUE; + r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ + r300->vap_output_state.dirty = TRUE; + r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */ r300->pvs_flush.dirty = TRUE; if (r300->fs) { diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 86301e23d7..0574d98e07 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -49,9 +49,7 @@ static void r300_draw_emit_attrib(struct r300_context* r300, output = draw_find_shader_output(r300->draw, info->output_semantic_name[index], info->output_semantic_index[index]); - draw_emit_vertex_attr( - (struct vertex_info*)r300->vertex_format_state.state, - emit, interp, output); + draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output); } static void r300_draw_emit_all_attribs(struct r300_context* r300) @@ -106,17 +104,21 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) } /* Update the PSC tables. */ +/* XXX move this function into r300_state.c after TCL-bypass gets removed + * XXX because this one is dependent only on vertex elements. */ static void r300_vertex_psc(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_info *vformat = - (struct r300_vertex_info*)r300->vertex_format_state.state; + struct r300_vertex_stream_state *vformat = + (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; uint16_t type, swizzle; enum pipe_format format; unsigned i; int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; int* stream_tab; + memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); + /* If TCL is bypassed, map vertex streams to equivalent VS output * locations. */ if (r300->tcl_bypass) { @@ -157,20 +159,25 @@ static void r300_vertex_psc(struct r300_context* r300) } vformat->vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC << (i & 1 ? 16 : 0)); + + vformat->count = (i >> 1) + 1; + r300->vertex_stream_state.size = (1 + vformat->count) * 2; } /* Update the PSC tables for SW TCL, using Draw. */ static void r300_swtcl_vertex_psc(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_info *vformat = - (struct r300_vertex_info*)r300->vertex_format_state.state; - struct vertex_info* vinfo = &vformat->vinfo; + struct r300_vertex_stream_state *vformat = + (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; + 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; + memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); + /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ attrib_count = vinfo->num_attribs; @@ -212,6 +219,9 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) } vformat->vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC << (i & 1 ? 16 : 0)); + + vformat->count = (i >> 1) + 1; + r300->vertex_stream_state.size = (1 + vformat->count) * 2; } static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, @@ -430,13 +440,12 @@ static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_screen* r300screen = r300_screen(r300->context.screen); - struct r300_vertex_info *vformat = - (struct r300_vertex_info*)r300->vertex_format_state.state; - struct vertex_info* vinfo = &vformat->vinfo; + struct r300_vap_output_state *vap_out = + (struct r300_vap_output_state*)r300->vap_output_state.state; - /* Mmm, delicious hax */ - memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info)); - memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4); + /* XXX Mmm, delicious hax */ + memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); + memcpy(vap_out, vs->hwfmt, sizeof(uint)*4); r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); @@ -444,8 +453,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300) r300_vertex_psc(r300); } else { r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size( - (struct vertex_info*)r300->vertex_format_state.state); + draw_compute_vertex_size(&r300->vertex_info); r300_swtcl_vertex_psc(r300); } } @@ -523,10 +531,9 @@ static void r300_update_ztop(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - /* XXX */ - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER || - r300->vs_state.dirty || r300->vertex_format_state.dirty || - r300->rs_state.dirty) { + if (r300->rs_block_state.dirty || + r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */ + r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */ r300_update_derived_shader_state(r300); } -- cgit v1.2.3 From e9441e1f88cc07365f4d7d9149ccefe128809645 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 1 Mar 2010 18:46:49 +0100 Subject: r300g: adapt to new vertex element cso --- src/gallium/drivers/r300/r300_blit.c | 1 + src/gallium/drivers/r300/r300_context.h | 8 +++-- src/gallium/drivers/r300/r300_emit.c | 4 +-- src/gallium/drivers/r300/r300_render.c | 12 ++++---- src/gallium/drivers/r300/r300_state.c | 44 +++++++++++++++++++-------- src/gallium/drivers/r300/r300_state_derived.c | 6 ++-- 6 files changed, 50 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index eb9b0beeb5..2f9650df1b 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -34,6 +34,7 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); util_blitter_save_vertex_shader(r300->blitter, r300->vs); + util_blitter_save_vertex_elements(r300->blitter, r300->vs); } /* Clear currently bound buffers. */ diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 1eba8a8ed1..0ee0ab47a6 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -247,6 +247,11 @@ struct r300_vertex_info { uint32_t vap_prog_stream_cntl_ext[8]; }; +struct r300_velems_state { + unsigned count; + struct pipe_vertex_element velem[]; +}; + extern struct pipe_viewport_state r300_viewport_identity; struct r300_context { @@ -317,8 +322,7 @@ struct r300_context { struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; /* Vertex elements for Gallium. */ - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; - int vertex_element_count; + struct r300_velems_state *velems; struct pipe_stencil_ref stencil_ref; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 88fe166359..fa3df9a23b 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -776,9 +776,9 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_aos(struct r300_context* r300, unsigned offset) { struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; int i; - unsigned size1, size2, aos_count = r300->vertex_element_count; + unsigned size1, size2, aos_count = r300->velems->count; unsigned packet_size = (aos_count * 3 + 1) / 2; CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cd4971ae13..1850a6f247 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -128,7 +128,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, { struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; - unsigned vertex_element_count = r300->vertex_element_count; + unsigned vertex_element_count = r300->velems->count; unsigned i, v, vbi, dw, elem_offset; /* Size of the vertex, in dwords. */ @@ -151,7 +151,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ for (i = 0; i < vertex_element_count; i++) { - velem = &r300->vertex_element[i]; + velem = &r300->velems->velem[i]; offset[i] = velem->src_offset / 4; size[i] = util_format_get_blocksize(velem->src_format) / 4; vertex_size += size[i]; @@ -183,7 +183,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Emit vertices. */ for (v = 0; v < count; v++) { for (i = 0; i < vertex_element_count; i++) { - velem = &r300->vertex_element[i]; + velem = &r300->velems->velem[i]; vbi = velem->vertex_buffer_index; elem_offset = offset[i] + stride[vbi] * (v + start); @@ -196,7 +196,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Unmap buffers. */ for (i = 0; i < vertex_element_count; i++) { - vbi = r300->vertex_element[i].vertex_buffer_index; + vbi = r300->velems->velem[i].vertex_buffer_index; if (map[vbi]) { vbuf = &r300->vertex_buffer[vbi]; @@ -278,11 +278,11 @@ static void r300_emit_draw_elements(struct r300_context *r300, static boolean r300_setup_vertex_buffers(struct r300_context *r300) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; struct pipe_buffer *pbuf; validate: - for (int i = 0; i < r300->vertex_element_count; i++) { + for (int i = 0; i < r300->velems->count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; if (!r300->winsys->add_buffer(r300->winsys, pbuf, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c193..ceac690fc4 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1044,11 +1044,11 @@ 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->vertex_element; + 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->vertex_element_count; i++) { + 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; @@ -1057,20 +1057,32 @@ static boolean r300_validate_aos(struct r300_context *r300) return TRUE; } -static void r300_set_vertex_elements(struct pipe_context* pipe, - unsigned count, - const struct pipe_vertex_element* elements) +static void* r300_create_vertex_elements_state(struct pipe_context* pipe, + unsigned count, + const struct pipe_vertex_element* attribs) { - struct r300_context* r300 = r300_context(pipe); + /*XXX could precalculate state here instead of later */ + struct r300_velems_state *velems; + assert(count <= PIPE_MAX_ATTRIBS); + velems = (struct r300_velems_state *) MALLOC(sizeof(struct r300_velems_state) + count * sizeof(*attribs)); + if (velems) { + velems->count = count; + memcpy(velems->velem, attribs, sizeof(*attribs) * count); + } + return velems; +} + +static void r300_bind_vertex_elements_state(struct pipe_context *pipe, + void *velems) +{ + struct r300_context *r300 = r300_context(pipe); + struct r300_velems_state *r300_velems = (struct r300_velems_state *) velems; - memcpy(r300->vertex_element, - elements, - sizeof(struct pipe_vertex_element) * count); - r300->vertex_element_count = count; + r300->velems = r300_velems; if (r300->draw) { draw_flush(r300->draw); - draw_set_vertex_elements(r300->draw, count, elements); + draw_set_vertex_elements(r300->draw, r300_velems->count, r300_velems->velem); } if (!r300_validate_aos(r300)) { @@ -1080,6 +1092,11 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, } } +static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) +{ + FREE( velems ); +} + static void* r300_create_vs_state(struct pipe_context* pipe, const struct pipe_shader_state* shader) { @@ -1241,7 +1258,10 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.set_viewport_state = r300_set_viewport_state; r300->context.set_vertex_buffers = r300_set_vertex_buffers; - r300->context.set_vertex_elements = r300_set_vertex_elements; + + r300->context.create_vertex_elements_state = r300_create_vertex_elements_state; + r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state; + r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state; r300->context.create_vs_state = r300_create_vs_state; r300->context.bind_vs_state = r300_bind_vs_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2cbce9210a..c43a93601c 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -128,10 +128,10 @@ static void r300_vertex_psc(struct r300_context* r300) DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" " in psc\n", r300->vs->info.num_inputs, - r300->vertex_element_count); + r300->velems->count); - for (i = 0; i < r300->vertex_element_count; i++) { - format = r300->vertex_element[i].src_format; + for (i = 0; i < r300->velems->count; i++) { + format = r300->velems->velem[i].src_format; type = r300_translate_vertex_data_type(format) | (stream_tab[i] << R300_DST_VEC_LOC_SHIFT); -- cgit v1.2.3 From 566390bedf4e5f24b5234e9dc08ecb1a6fd4d13b Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Thu, 4 Mar 2010 12:46:20 -0800 Subject: r300g: Fix indexbuf upper limits. Wine tends to pessimistically use ~0 for its max index, but r300s only can go up to 2^24-1, causing the kernel checker to freak out. Civ4 is marginally improved now. Still crashes, but not as bad. --- src/gallium/drivers/r300/r300_render.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 770a92be74..6c891029a5 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -273,9 +273,14 @@ static void r300_emit_draw_elements(struct r300_context *r300, CS_LOCALS(r300); assert((start * indexSize) % 4 == 0); + assert(count < (1 << 24)); + + DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", + count, minIndex, maxIndex); + + maxIndex = MIN2(maxIndex, ((1 << 24) - 1)); if (alt_num_verts) { - assert(count < (1 << 24)); BEGIN_CS(16); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); } else { -- cgit v1.2.3 From c37a20416d681a3fea42a1a2ce907eb8e11ba795 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 6 Mar 2010 19:35:10 +0100 Subject: r300g: clamp vertex max index according to currently bound buffers --- src/gallium/drivers/r300/r300_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 6c891029a5..073664fa45 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -278,7 +278,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", count, minIndex, maxIndex); - maxIndex = MIN2(maxIndex, ((1 << 24) - 1)); + maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); if (alt_num_verts) { BEGIN_CS(16); -- cgit v1.2.3 From b03b70f6586baf3ff419be28817f61e6c4bacfb5 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 7 Mar 2010 02:40:57 +0100 Subject: r300g: validate buffers when using SWTCL --- src/gallium/drivers/r300/r300_render.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 073664fa45..c8420bcdd5 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -186,7 +186,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, dwords = 10 + count * vertex_size; r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); - r300_emit_buffer_validate(r300, FALSE, 0); + r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_dirty_state(r300); BEGIN_CS(dwords); @@ -450,7 +450,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, /* Make sure there are at least 128 spare dwords in the command buffer. * (most of it being consumed by emit_aos) */ r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); - r300_emit_buffer_validate(r300, TRUE, 0); + r300_emit_buffer_validate(r300, TRUE, NULL); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { @@ -468,7 +468,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, /* Again, we emit both AOS and draw_arrays so there should be * at least 128 spare dwords. */ if (count && r300_reserve_cs_space(r300, 128)) { - r300_emit_buffer_validate(r300, TRUE, 0); + r300_emit_buffer_validate(r300, TRUE, NULL); r300_emit_dirty_state(r300); } } while (count); @@ -688,6 +688,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render, CS_LOCALS(r300); r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2); + r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_dirty_state(r300); DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); @@ -711,6 +712,7 @@ static void r300_render_draw(struct vbuf_render* render, CS_LOCALS(r300); r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); + r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_dirty_state(r300); BEGIN_CS(dwords); -- cgit v1.2.3 From 22812421b5f394af741022f2f65ba19bc7b0aa73 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 9 Mar 2010 16:24:47 +0100 Subject: r300g: fix gallium-vertexlementcso merge damage --- src/gallium/drivers/r300/r300_emit.c | 4 ++-- src/gallium/drivers/r300/r300_render.c | 25 ------------------------- src/gallium/drivers/r300/r300_state_derived.c | 1 - 3 files changed, 2 insertions(+), 28 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 65377b3865..55e9217fd3 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1004,7 +1004,7 @@ void r300_emit_buffer_validate(struct r300_context *r300, (struct r300_textures_state*)r300->textures_state.state; struct r300_texture* tex; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; struct pipe_buffer *pbuf; unsigned i; boolean invalid = FALSE; @@ -1062,7 +1062,7 @@ validate: } /* ...vertex buffers for HWTCL path... */ if (do_validate_vertex_buffers) { - for (i = 0; i < r300->vertex_element_count; i++) { + for (i = 0; i < r300->velems->count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; if (!r300->winsys->add_buffer(r300->winsys, pbuf, diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index d0e06ade40..2605628c02 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -319,31 +319,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } -static boolean r300_setup_vertex_buffers(struct r300_context *r300) -{ - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->velems->velem; - struct pipe_buffer *pbuf; - -validate: - for (int i = 0; i < r300->velems->count; i++) { - pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { - r300->context.flush(&r300->context, 0, NULL); - goto validate; - } - } - - if (!r300->winsys->validate(r300->winsys)) { - r300->context.flush(&r300->context, 0, NULL); - return r300->winsys->validate(r300->winsys); - } - - return TRUE; -} - static void r300_shorten_ubyte_elts(struct r300_context* r300, struct pipe_buffer** elts, unsigned count) diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 4422581b51..81a373abad 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -128,7 +128,6 @@ static void r300_vertex_psc(struct r300_context* r300) " in psc\n", vs->info.num_inputs, r300->velems->count); - r300->vertex_element_count); for (i = 0; i < r300->velems->count; i++) { format = r300->velems->velem[i].src_format; -- cgit v1.2.3 From 007f25b3bde88de550d6ddba6a96769e4f3d5ce7 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Tue, 9 Mar 2010 20:03:35 -0800 Subject: r300g: Reorder regs, save one dword. Or, put another way, save 10% on rendering calls. --- src/gallium/drivers/r300/r300_render.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/gallium/drivers/r300/r300_render.c') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 2605628c02..9c001ae186 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -183,7 +183,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, } } - dwords = 10 + count * vertex_size; + dwords = 9 + count * vertex_size; r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_emit_buffer_validate(r300, FALSE, NULL); @@ -193,8 +193,9 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); + OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); + OUT_CS(count - 1); + OUT_CS(0); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | r300_translate_primitive(mode)); @@ -238,15 +239,16 @@ static void r300_emit_draw_arrays(struct r300_context *r300, if (alt_num_verts) { assert(count < (1 << 24)); - BEGIN_CS(10); + BEGIN_CS(9); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); } else { - BEGIN_CS(8); + BEGIN_CS(7); } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); + OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); + OUT_CS(count - 1); + OUT_CS(0); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300_translate_primitive(mode) | @@ -281,15 +283,16 @@ static void r300_emit_draw_elements(struct r300_context *r300, maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); if (alt_num_verts) { - BEGIN_CS(16); + BEGIN_CS(15); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); } else { - BEGIN_CS(14); + BEGIN_CS(13); } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); + OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); + OUT_CS(maxIndex); + OUT_CS(minIndex); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); if (indexSize == 4) { count_dwords = count; -- cgit v1.2.3