From 074606a806df755ecbb84e0a1182c66fd0b2a8dd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 24 Oct 2009 13:18:34 +0100 Subject: i965g: more files compiling --- src/gallium/drivers/i965/brw_batchbuffer.h | 124 +++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/gallium/drivers/i965/brw_batchbuffer.h (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h new file mode 100644 index 0000000000..76b3c1bf69 --- /dev/null +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -0,0 +1,124 @@ +#ifndef BRW_BATCHBUFFER_H +#define BRW_BATCHBUFFER_H + +#include "brw_types.h" +#include "brw_winsys.h" +#include "brw_reg.h" + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +/* All ignored: + */ +enum cliprect_mode { + IGNORE_CLIPRECTS, + LOOP_CLIPRECTS, + NO_LOOP_CLIPRECTS, + REFERENCES_CLIPRECTS +}; + +void brw_batchbuffer_free(struct brw_batchbuffer *batch); + +void _brw_batchbuffer_flush(struct brw_batchbuffer *batch, + const char *file, int line); + +#define brw_batchbuffer_flush(batch) \ + _brw_batchbuffer_flush(batch, __FILE__, __LINE__) + +void brw_batchbuffer_reset(struct brw_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void brw_batchbuffer_data(struct brw_batchbuffer *batch, + const void *data, GLuint bytes, + enum cliprect_mode cliprect_mode); + +void brw_batchbuffer_release_space(struct brw_batchbuffer *batch, + GLuint bytes); + +GLboolean brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, + struct brw_winsys_buffer *buffer, + uint32_t read_domains, + uint32_t write_domain, + uint32_t offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLint +brw_batchbuffer_space(struct brw_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +brw_batchbuffer_emit_dword(struct brw_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(brw_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE boolean +brw_batchbuffer_require_space(struct brw_batchbuffer *batch, + GLuint sz, + enum cliprect_mode cliprect_mode) +{ + assert(sz < batch->size - 8); + if (brw_batchbuffer_space(batch) < sz) { + assert(0); + return FALSE; + } + + /* All commands should be executed once regardless of cliprect + * mode. + */ + (void)cliprect_mode; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, cliprect_mode) do { \ + brw_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \ + assert(intel->batch->emit.start_ptr == NULL); \ + intel->batch->emit.total = (n) * 4; \ + intel->batch->emit.start_ptr = intel->batch->ptr; \ +} while (0) + +#define OUT_BATCH(d) brw_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \ + assert((unsigned) (delta) < buf->size); \ + brw_batchbuffer_emit_reloc(intel->batch, buf, \ + read_domains, write_domain, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { \ + unsigned int _n = intel->batch->ptr - intel->batch->emit.start_ptr; \ + assert(intel->batch->emit.start_ptr != NULL); \ + if (_n != intel->batch->emit.total) { \ + fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n", \ + _n, intel->batch->emit.total); \ + abort(); \ + } \ + intel->batch->emit.start_ptr = NULL; \ +} while(0) + + +static INLINE void +brw_batchbuffer_emit_mi_flush(struct brw_batchbuffer *batch) +{ + brw_batchbuffer_require_space(batch, 4, IGNORE_CLIPRECTS); + brw_batchbuffer_emit_dword(batch, MI_FLUSH); +} + +#endif -- cgit v1.2.3 From 4f7931bb3554cb1839adc2044e3abe6d4af8b0b5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 24 Oct 2009 17:07:01 +0100 Subject: i965g: more work on compiling --- src/gallium/drivers/i965/Makefile | 2 - src/gallium/drivers/i965/brw_batchbuffer.h | 41 ++- src/gallium/drivers/i965/brw_cc.c | 8 +- src/gallium/drivers/i965/brw_clip.c | 7 +- src/gallium/drivers/i965/brw_clip.h | 19 +- src/gallium/drivers/i965/brw_clip_line.c | 21 +- src/gallium/drivers/i965/brw_clip_point.c | 1 - src/gallium/drivers/i965/brw_clip_state.c | 22 +- src/gallium/drivers/i965/brw_clip_tri.c | 5 +- src/gallium/drivers/i965/brw_clip_unfilled.c | 28 +- src/gallium/drivers/i965/brw_clip_util.c | 31 +- src/gallium/drivers/i965/brw_context.c | 87 +++--- src/gallium/drivers/i965/brw_context.h | 47 ++- src/gallium/drivers/i965/brw_curbe.c | 63 ++-- src/gallium/drivers/i965/brw_debug.h | 42 +++ src/gallium/drivers/i965/brw_defines.h | 7 - src/gallium/drivers/i965/brw_draw.c | 134 ++++----- src/gallium/drivers/i965/brw_draw.h | 15 +- src/gallium/drivers/i965/brw_draw_upload.c | 2 - src/gallium/drivers/i965/brw_eu.h | 2 + src/gallium/drivers/i965/brw_misc_state.c | 2 - src/gallium/drivers/i965/brw_pipe_debug.c | 2 - src/gallium/drivers/i965/brw_pipe_query.c | 4 +- src/gallium/drivers/i965/brw_pipe_vertex.c | 26 ++ src/gallium/drivers/i965/brw_reg.h | 36 +++ src/gallium/drivers/i965/brw_screen.c | 365 ++++++++++++++++++++++++ src/gallium/drivers/i965/brw_screen.h | 6 +- src/gallium/drivers/i965/brw_sf.c | 2 +- src/gallium/drivers/i965/brw_sf_state.c | 3 +- src/gallium/drivers/i965/brw_state_cache.c | 4 +- src/gallium/drivers/i965/brw_state_debug.c | 145 ++++++++++ src/gallium/drivers/i965/brw_state_upload.c | 113 +------- src/gallium/drivers/i965/brw_tex.c | 2 - src/gallium/drivers/i965/brw_tex_layout.c | 4 +- src/gallium/drivers/i965/brw_types.h | 3 + src/gallium/drivers/i965/brw_vs_surface_state.c | 3 +- src/gallium/drivers/i965/brw_winsys.h | 54 ++-- src/gallium/drivers/i965/brw_wm.c | 2 +- src/gallium/drivers/i965/brw_wm_state.c | 8 +- src/gallium/drivers/i965/brw_wm_surface_state.c | 9 +- src/gallium/drivers/i965/intel_chipset.h | 116 -------- src/gallium/drivers/i965/intel_tex_format.c | 28 -- src/gallium/drivers/i965/intel_tex_layout.c | 2 - 43 files changed, 920 insertions(+), 603 deletions(-) create mode 100644 src/gallium/drivers/i965/brw_debug.h delete mode 100644 src/gallium/drivers/i965/brw_pipe_debug.c create mode 100644 src/gallium/drivers/i965/brw_pipe_vertex.c create mode 100644 src/gallium/drivers/i965/brw_screen.c create mode 100644 src/gallium/drivers/i965/brw_state_debug.c delete mode 100644 src/gallium/drivers/i965/intel_chipset.h delete mode 100644 src/gallium/drivers/i965/intel_tex_format.c (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index 480d2efbc5..40c8364824 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -26,7 +26,6 @@ C_SOURCES = \ brw_gs_state.c \ brw_misc_state.c \ brw_pipe_blend.c \ - brw_pipe_debug.c \ brw_pipe_depth.c \ brw_pipe_fb.c \ brw_pipe_flush.c \ @@ -63,7 +62,6 @@ C_SOURCES = \ brw_wm_surface_state.c \ brw_bo.c \ intel_batchbuffer.c \ - intel_tex_format.c \ intel_tex_layout.c include ../../Makefile.template diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 76b3c1bf69..b8492882e1 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -4,6 +4,7 @@ #include "brw_types.h" #include "brw_winsys.h" #include "brw_reg.h" +#include "util/u_debug.h" #define BATCH_SZ 16384 #define BATCH_RESERVED 16 @@ -68,56 +69,50 @@ brw_batchbuffer_emit_dword(struct brw_batchbuffer *batch, GLuint dword) static INLINE boolean brw_batchbuffer_require_space(struct brw_batchbuffer *batch, - GLuint sz, - enum cliprect_mode cliprect_mode) + GLuint sz) { assert(sz < batch->size - 8); if (brw_batchbuffer_space(batch) < sz) { assert(0); return FALSE; } - - /* All commands should be executed once regardless of cliprect - * mode. - */ - (void)cliprect_mode; +#ifdef DEBUG + batch->emit.end_ptr = batch->ptr + sz; +#endif + return TRUE; } /* Here are the crusty old macros, to be removed: */ -#define BATCH_LOCALS - #define BEGIN_BATCH(n, cliprect_mode) do { \ - brw_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \ - assert(intel->batch->emit.start_ptr == NULL); \ - intel->batch->emit.total = (n) * 4; \ - intel->batch->emit.start_ptr = intel->batch->ptr; \ + brw_batchbuffer_require_space(brw->batch, (n)*4); \ } while (0) -#define OUT_BATCH(d) brw_batchbuffer_emit_dword(intel->batch, d) +#define OUT_BATCH(d) brw_batchbuffer_emit_dword(brw->batch, d) #define OUT_RELOC(buf, read_domains, write_domain, delta) do { \ assert((unsigned) (delta) < buf->size); \ - brw_batchbuffer_emit_reloc(intel->batch, buf, \ + brw_batchbuffer_emit_reloc(brw->batch, buf, \ read_domains, write_domain, delta); \ } while (0) +#ifdef DEBUG #define ADVANCE_BATCH() do { \ - unsigned int _n = intel->batch->ptr - intel->batch->emit.start_ptr; \ - assert(intel->batch->emit.start_ptr != NULL); \ - if (_n != intel->batch->emit.total) { \ - fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n", \ - _n, intel->batch->emit.total); \ + unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr; \ + if (_n != 0) { \ + debug_printf("%s: %d too many bytes emitted to batch\n", __FUNCTION__, _n); \ abort(); \ } \ - intel->batch->emit.start_ptr = NULL; \ + brw->batch->emit.end_ptr = NULL; \ } while(0) - +#else +#define ADVANCE_BATCH() +#endif static INLINE void brw_batchbuffer_emit_mi_flush(struct brw_batchbuffer *batch) { - brw_batchbuffer_require_space(batch, 4, IGNORE_CLIPRECTS); + brw_batchbuffer_require_space(batch, 4); brw_batchbuffer_emit_dword(batch, MI_FLUSH); } diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index c8e7851d75..76759304eb 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -109,10 +109,10 @@ static void cc_unit_populate_key(const struct brw_context *brw, struct brw_cc_unit_key *key) { - key->cc0 = brw->curr.dsa->cc0; - key->cc1 = brw->curr.dsa->cc1; - key->cc2 = brw->curr.dsa->cc2; - key->cc3 = combine_cc3( brw->curr.dsa->cc3, brw->curr.blend->cc3 ); + key->cc0 = brw->curr.zstencil->cc0; + key->cc1 = brw->curr.zstencil->cc1; + key->cc2 = brw->curr.zstencil->cc2; + key->cc3 = combine_cc3( brw->curr.zstencil->cc3, brw->curr.blend->cc3 ); key->cc5 = brw->curr.blend->cc5; key->cc6 = brw->curr.blend->cc6; key->cc7 = brw->curr.blend->cc7; diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c index 591e904705..622d9dba96 100644 --- a/src/gallium/drivers/i965/brw_clip.c +++ b/src/gallium/drivers/i965/brw_clip.c @@ -65,15 +65,16 @@ static void compile_clip_prog( struct brw_context *brw, c.func.single_program_flow = 1; + c.chipset = brw->chipset; c.key = *key; - c.need_ff_sync = BRW_IS_IGDNG(brw); + c.need_ff_sync = c.chipset.is_igdng; /* Need to locate the two positions present in vertex + header. * These are currently hardcoded: */ c.header_position_offset = ATTR_SIZE; - if (BRW_IS_IGDNG(brw)) + if (c.chipset.is_igdng) delta = 3 * REG_SIZE; else delta = REG_SIZE; @@ -160,7 +161,7 @@ static void upload_clip_prog(struct brw_context *brw) key.primitive = brw->reduced_primitive; /* PIPE_NEW_VS */ - key.nr_attrs = brw->curr.vs->info.file_max[TGSI_FILE_OUTPUT] + 1; + key.nr_attrs = brw->curr.vertex_shader->info.file_max[TGSI_FILE_OUTPUT] + 1; /* PIPE_NEW_CLIP */ key.nr_userclip = brw->curr.ucp.nr; diff --git a/src/gallium/drivers/i965/brw_clip.h b/src/gallium/drivers/i965/brw_clip.h index cfe51bf292..772c34be88 100644 --- a/src/gallium/drivers/i965/brw_clip.h +++ b/src/gallium/drivers/i965/brw_clip.h @@ -32,8 +32,8 @@ #ifndef BRW_CLIP_H #define BRW_CLIP_H - -#include "brw_context.h" +#include "pipe/p_state.h" +#include "brw_reg.h" #include "brw_eu.h" #define MAX_VERTS (3+6+6) @@ -60,6 +60,12 @@ struct brw_clip_prog_key { GLfloat offset_units; }; +struct brw_clip_prog_data { + GLuint curb_read_length; /* user planes? */ + GLuint clip_mode; + GLuint urb_read_length; + GLuint total_grf; +}; #define CLIP_LINE 0 #define CLIP_POINT 1 @@ -112,12 +118,21 @@ struct brw_clip_compile { GLuint last_tmp; GLboolean need_direction; + struct brw_chipset chipset; GLuint last_mrf; GLuint header_position_offset; GLuint offset[PIPE_MAX_SHADER_OUTPUTS]; GLboolean need_ff_sync; + + GLuint nr_color_attrs; + GLuint offset_color0; + GLuint offset_color1; + GLuint offset_bfc0; + GLuint offset_bfc1; + + GLuint offset_edge; }; #define ATTR_SIZE (4*4) diff --git a/src/gallium/drivers/i965/brw_clip_line.c b/src/gallium/drivers/i965/brw_clip_line.c index 6b4da25644..a4790bda95 100644 --- a/src/gallium/drivers/i965/brw_clip_line.c +++ b/src/gallium/drivers/i965/brw_clip_line.c @@ -29,14 +29,16 @@ * Keith Whitwell */ +#include "util/u_debug.h" + #include "brw_defines.h" -#include "brw_context.h" #include "brw_eu.h" #include "brw_util.h" #include "brw_clip.h" + static void brw_clip_line_alloc_regs( struct brw_clip_compile *c ) { GLuint i = 0,j; @@ -130,6 +132,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) struct brw_instruction *is_neg2 = NULL; struct brw_instruction *not_culled; struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); + const int hpos = 0; /* XXX: position not always first element */ brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0])); brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1])); @@ -145,7 +148,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_clip_init_clipmask(c); /* -ve rhw workaround */ - if (BRW_IS_965(p->brw)) { + if (c->chipset.is_965) { brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); @@ -170,19 +173,19 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) /* dp = DP4(vtx->position, plane) */ - brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); + brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset[hpos]), c->reg.plane_equation); /* if (IS_NEGATIVE(dp1)) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_L); - brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); + brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[hpos]), c->reg.plane_equation); is_negative = brw_IF(p, BRW_EXECUTE_1); { /* * Both can be negative on GM965/G965 due to RHW workaround * if so, this object should be rejected. */ - if (BRW_IS_965(p->brw)) { + if (c->chipset.is_965) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0)); is_neg2 = brw_IF(p, BRW_EXECUTE_1); { @@ -207,7 +210,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) /* If both are positive, do nothing */ /* Only on GM965/G965 */ - if (BRW_IS_965(p->brw)) { + if (c->chipset.is_965) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); is_neg2 = brw_IF(p, BRW_EXECUTE_1); } @@ -222,7 +225,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_set_predicate_control(p, BRW_PREDICATE_NONE); } - if (BRW_IS_965(p->brw)) { + if (c->chipset.is_965) { brw_ENDIF(p, is_neg2); } } @@ -245,8 +248,8 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0)); not_culled = brw_IF(p, BRW_EXECUTE_1); { - brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, GL_FALSE); - brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, GL_FALSE); + brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, FALSE); + brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, FALSE); brw_clip_emit_vue(c, newvtx0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START); brw_clip_emit_vue(c, newvtx1, 0, 1, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END); diff --git a/src/gallium/drivers/i965/brw_clip_point.c b/src/gallium/drivers/i965/brw_clip_point.c index b2cf7b2011..e0a5330556 100644 --- a/src/gallium/drivers/i965/brw_clip_point.c +++ b/src/gallium/drivers/i965/brw_clip_point.c @@ -30,7 +30,6 @@ */ #include "brw_defines.h" -#include "brw_context.h" #include "brw_eu.h" #include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c index 0ea7ce5734..25b8c6372f 100644 --- a/src/gallium/drivers/i965/brw_clip_state.c +++ b/src/gallium/drivers/i965/brw_clip_state.c @@ -29,9 +29,13 @@ * Keith Whitwell */ +#include "util/u_math.h" + #include "brw_context.h" +#include "brw_clip.h" #include "brw_state.h" #include "brw_defines.h" +#include "brw_debug.h" struct brw_clip_unit_key { unsigned int total_grf; @@ -77,7 +81,7 @@ clip_unit_create_from_key(struct brw_context *brw, memset(&clip, 0, sizeof(clip)); - clip.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1; + clip.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1; /* reloc */ clip.thread0.kernel_start_pointer = brw->clip.prog_bo->offset >> 6; @@ -112,10 +116,10 @@ clip_unit_create_from_key(struct brw_context *brw, clip.thread4.max_threads = 1 - 1; } - if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) + if (BRW_DEBUG & DEBUG_SINGLE_THREAD) clip.thread4.max_threads = 0; - if (INTEL_DEBUG & DEBUG_STATS) + if (BRW_DEBUG & DEBUG_STATS) clip.thread4.stats_enable = 1; clip.clip5.userclip_enable_flags = 0x7f; @@ -145,12 +149,12 @@ clip_unit_create_from_key(struct brw_context *brw, /* Emit clip program relocation */ assert(brw->clip.prog_bo); - dri_bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, - 0, - clip.thread0.grf_reg_count << 1, - offsetof(struct brw_clip_unit_state, thread0), - brw->clip.prog_bo); + brw->sws->bo_emit_reloc(bo, + I915_GEM_DOMAIN_INSTRUCTION, + 0, + clip.thread0.grf_reg_count << 1, + offsetof(struct brw_clip_unit_state, thread0), + brw->clip.prog_bo); return bo; } diff --git a/src/gallium/drivers/i965/brw_clip_tri.c b/src/gallium/drivers/i965/brw_clip_tri.c index d8feca6a87..5486f4fa89 100644 --- a/src/gallium/drivers/i965/brw_clip_tri.c +++ b/src/gallium/drivers/i965/brw_clip_tri.c @@ -30,7 +30,6 @@ */ #include "brw_defines.h" -#include "brw_context.h" #include "brw_eu.h" #include "brw_util.h" #include "brw_clip.h" @@ -71,7 +70,7 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, for (j = 0; j < 3; j++) { GLuint delta = c->nr_attrs*16 + 32; - if (BRW_IS_IGDNG(c->func.brw)) + if (c->chipset.is_igdng) delta = c->nr_attrs * 16 + 32 * 3; brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0)); @@ -565,7 +564,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) /* if -ve rhw workaround bit is set, do cliptest */ - if (BRW_IS_965(p->brw)) { + if (c->chipset.is_965) { brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); diff --git a/src/gallium/drivers/i965/brw_clip_unfilled.c b/src/gallium/drivers/i965/brw_clip_unfilled.c index 8501599aef..1cb86dd25b 100644 --- a/src/gallium/drivers/i965/brw_clip_unfilled.c +++ b/src/gallium/drivers/i965/brw_clip_unfilled.c @@ -29,10 +29,7 @@ * Keith Whitwell */ -#include "brw_batchbuffer.h" - #include "brw_defines.h" -#include "brw_context.h" #include "brw_eu.h" #include "brw_util.h" #include "brw_clip.h" @@ -126,8 +123,7 @@ static void copy_bfc( struct brw_clip_compile *c ) /* Do we have any colors to copy? */ - if (!(c->offset[VERT_RESULT_COL0] && c->offset[VERT_RESULT_BFC0]) && - !(c->offset[VERT_RESULT_COL1] && c->offset[VERT_RESULT_BFC1])) + if (c->nr_color_attrs == 0) return; /* In some wierd degnerate cases we can end up testing the @@ -150,15 +146,15 @@ static void copy_bfc( struct brw_clip_compile *c ) GLuint i; for (i = 0; i < 3; i++) { - if (c->offset[VERT_RESULT_COL0] && c->offset[VERT_RESULT_BFC0]) + if (c->offset_color0 && c->offset_bfc0) brw_MOV(p, - byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_COL0]), - byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC0])); + byte_offset(c->reg.vertex[i], c->offset_color0), + byte_offset(c->reg.vertex[i], c->offset_bfc0)); - if (c->offset[VERT_RESULT_COL1] && c->offset[VERT_RESULT_BFC1]) + if (c->offset_color1 && c->offset_bfc1) brw_MOV(p, - byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_COL1]), - byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC1])); + byte_offset(c->reg.vertex[i], c->offset_color0), + byte_offset(c->reg.vertex[i], c->offset_bfc0)); } } brw_ENDIF(p, ccw); @@ -218,12 +214,12 @@ static void merge_edgeflags( struct brw_clip_compile *c ) { brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ); brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8)); - brw_MOV(p, byte_offset(c->reg.vertex[0], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0)); + brw_MOV(p, byte_offset(c->reg.vertex[0], c->offset_edge), brw_imm_f(0)); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ); brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9)); - brw_MOV(p, byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0)); + brw_MOV(p, byte_offset(c->reg.vertex[2], c->offset_edge), brw_imm_f(0)); brw_set_predicate_control(p, BRW_PREDICATE_NONE); } brw_ENDIF(p, is_poly); @@ -294,7 +290,7 @@ static void emit_lines(struct brw_clip_compile *c, /* draw edge if edgeflag != 0 */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, - deref_1f(v0, c->offset[VERT_RESULT_EDGE]), + deref_1f(v0, c->offset_edge), brw_imm_f(0)); draw_edge = brw_IF(p, BRW_EXECUTE_1); { @@ -333,7 +329,7 @@ static void emit_points(struct brw_clip_compile *c, */ brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, - deref_1f(v0, c->offset[VERT_RESULT_EDGE]), + deref_1f(v0, c->offset_edge), brw_imm_f(0)); draw_point = brw_IF(p, BRW_EXECUTE_1); { @@ -450,7 +446,7 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c ) brw_clip_tri_init_vertices(c); brw_clip_init_ff_sync(c); - assert(c->offset[VERT_RESULT_EDGE]); + assert(c->offset_edge); if (c->key.fill_ccw == CLIP_CULL && c->key.fill_cw == CLIP_CULL) { diff --git a/src/gallium/drivers/i965/brw_clip_util.c b/src/gallium/drivers/i965/brw_clip_util.c index 60bfd3538e..f8f98c8037 100644 --- a/src/gallium/drivers/i965/brw_clip_util.c +++ b/src/gallium/drivers/i965/brw_clip_util.c @@ -31,7 +31,6 @@ #include "brw_defines.h" -#include "brw_context.h" #include "brw_eu.h" #include "brw_util.h" #include "brw_clip.h" @@ -144,10 +143,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, for (i = 0; i < c->nr_attrs; i++) { GLuint delta = i*16 + 32; - if (BRW_IS_IGDNG(p->brw)) + if (c->chipset.is_igdng) delta = i * 16 + 32 * 3; - if (delta == c->offset[VERT_RESULT_EDGE]) { + if (delta == c->offset_edge) { if (force_edgeflag) brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1)); else @@ -178,7 +177,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, if (i & 1) { GLuint delta = i*16 + 32; - if (BRW_IS_IGDNG(p->brw)) + if (c->chipset.is_igdng) delta = i * 16 + 32 * 3; brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); @@ -304,25 +303,25 @@ void brw_clip_copy_colors( struct brw_clip_compile *c, { struct brw_compile *p = &c->func; - if (c->offset[VERT_RESULT_COL0]) + if (c->offset_color0) brw_MOV(p, - byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL0]), - byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL0])); + byte_offset(c->reg.vertex[to], c->offset_color0), + byte_offset(c->reg.vertex[from], c->offset_color0)); - if (c->offset[VERT_RESULT_COL1]) + if (c->offset_color1) brw_MOV(p, - byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL1]), - byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL1])); + byte_offset(c->reg.vertex[to], c->offset_color1), + byte_offset(c->reg.vertex[from], c->offset_color1)); - if (c->offset[VERT_RESULT_BFC0]) + if (c->offset_bfc0) brw_MOV(p, - byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC0]), - byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC0])); + byte_offset(c->reg.vertex[to], c->offset_bfc0), + byte_offset(c->reg.vertex[from], c->offset_bfc0)); - if (c->offset[VERT_RESULT_BFC1]) + if (c->offset_bfc1) brw_MOV(p, - byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC1]), - byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC1])); + byte_offset(c->reg.vertex[to], c->offset_bfc1), + byte_offset(c->reg.vertex[from], c->offset_bfc1)); } diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index 07a5420d6e..e9605bafe6 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -31,64 +31,31 @@ #include "pipe/p_context.h" +#include "util/u_simple_list.h" #include "brw_context.h" #include "brw_defines.h" #include "brw_draw.h" #include "brw_state.h" -#include "brw_vs.h" -#include "brw_screen_tex.h" #include "brw_batchbuffer.h" +#include "brw_winsys.h" - - -struct pipe_context *brw_create_context( struct pipe_screen *screen, - void *priv ) -{ - struct brw_context *brw = (struct brw_context *) CALLOC_STRUCT(brw_context); - - if (!brw) { - debug_printf("%s: failed to alloc context\n", __FUNCTION__); - return GL_FALSE; - } - - /* We want the GLSL compiler to emit code that uses condition codes */ - ctx->Shader.EmitCondCodes = GL_TRUE; - ctx->Shader.EmitNVTempInitialization = GL_TRUE; - - - brw_init_query( brw ); - brw_init_state( brw ); - brw_draw_init( brw ); - - brw->state.dirty.mesa = ~0; - brw->state.dirty.brw = ~0; - - brw->emit_state_always = 0; - - make_empty_list(&brw->query.active_head); - - - return GL_TRUE; -} - -/** - * called from intelDestroyContext() - */ -static void brw_destroy_context( struct brw_context *brw ) +static void brw_destroy_context( struct pipe_context *pipe ) { + struct brw_context *brw = brw_context(pipe); int i; brw_destroy_state(brw); - brw_draw_destroy( brw ); - _mesa_free(brw->wm.compile_data); + brw_draw_cleanup( brw ); + + FREE(brw->wm.compile_data); - for (i = 0; i < brw->state.nr_color_regions; i++) - intel_region_release(&brw->state.color_regions[i]); - brw->state.nr_color_regions = 0; - intel_region_release(&brw->state.depth_region); + for (i = 0; i < brw->curr.fb.nr_cbufs; i++) + pipe_surface_reference(&brw->curr.fb.cbufs[i], NULL); + brw->curr.fb.nr_cbufs = 0; + pipe_surface_reference(&brw->curr.fb.zsbuf, NULL); brw->sws->bo_unreference(brw->curbe.curbe_bo); brw->sws->bo_unreference(brw->vs.prog_bo); @@ -114,3 +81,35 @@ static void brw_destroy_context( struct brw_context *brw ) brw->sws->bo_unreference(brw->cc.state_bo); brw->sws->bo_unreference(brw->cc.vp_bo); } + + +struct pipe_context *brw_create_context(struct pipe_screen *screen) +{ + struct brw_context *brw = (struct brw_context *) CALLOC_STRUCT(brw_context); + + if (!brw) { + debug_printf("%s: failed to alloc context\n", __FUNCTION__); + return GL_FALSE; + } + + /* We want the GLSL compiler to emit code that uses condition codes */ + //ctx->Shader.EmitCondCodes = GL_TRUE; + //ctx->Shader.EmitNVTempInitialization = GL_TRUE; + + brw->base.destroy = brw_destroy_context; + + brw_init_query( brw ); + brw_init_state( brw ); + brw_draw_init( brw ); + + brw->state.dirty.mesa = ~0; + brw->state.dirty.brw = ~0; + + brw->emit_state_always = 0; + + make_empty_list(&brw->query.active_head); + + + return &brw->base; +} + diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 3a2fece45c..dd782fdba9 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -35,6 +35,7 @@ #include "brw_structs.h" #include "brw_winsys.h" +#include "brw_reg.h" #include "pipe/p_state.h" #include "pipe/p_context.h" #include "tgsi/tgsi_scan.h" @@ -178,8 +179,8 @@ struct brw_fragment_shader { #define PIPE_NEW_VERTEX_ELEMENT 0x2 #define PIPE_NEW_FRAGMENT_SHADER 0x2 #define PIPE_NEW_VERTEX_SHADER 0x2 -#define PIPE_NEW_FRAGMENT_CONSTS 0x2 -#define PIPE_NEW_VERTEX_CONSTS 0x2 +#define PIPE_NEW_FRAGMENT_CONSTANTS 0x2 +#define PIPE_NEW_VERTEX_CONSTANTS 0x2 #define PIPE_NEW_CLIP 0x2 @@ -256,12 +257,8 @@ struct brw_sf_prog_data { GLuint urb_entry_size; }; -struct brw_clip_prog_data { - GLuint curb_read_length; /* user planes? */ - GLuint clip_mode; - GLuint urb_read_length; - GLuint total_grf; -}; + +struct brw_clip_prog_data; struct brw_gs_prog_data { GLuint urb_read_length; @@ -298,15 +295,15 @@ struct brw_vs_ouput_sizes { * This contains pointers to the drawing surfaces and current texture * objects and shader constant buffers (+2). */ -#define BRW_WM_MAX_SURF (MAX_DRAW_BUFFERS + BRW_MAX_TEX_UNIT + 1) +#define BRW_WM_MAX_SURF (PIPE_MAX_COLOR_BUFS + BRW_MAX_TEX_UNIT + 1) /** * Helpers to convert drawing buffers, textures and constant buffers * to surface binding table indexes, for WM. */ #define SURF_INDEX_DRAW(d) (d) -#define SURF_INDEX_FRAG_CONST_BUFFER (MAX_DRAW_BUFFERS) -#define SURF_INDEX_TEXTURE(t) (MAX_DRAW_BUFFERS + 1 + (t)) +#define SURF_INDEX_FRAG_CONST_BUFFER (PIPE_MAX_COLOR_BUFS) +#define SURF_INDEX_TEXTURE(t) (PIPE_MAX_COLOR_BUFS + 1 + (t)) /** * Size of surface binding table for the VS. @@ -457,28 +454,32 @@ struct brw_query_object { */ struct brw_context { - struct pipe_context pipe; + struct pipe_context base; + struct brw_chipset chipset; struct brw_screen *brw_screen; struct brw_winsys_screen *sws; + struct brw_batchbuffer *batch; + GLuint primitive; GLuint reduced_primitive; GLboolean emit_state_always; - GLboolean no_batch_wrap; /* Active vertex program: */ struct { - const struct brw_vertex_shader *vs; - const struct brw_fragment_shader *fs; + const struct brw_vertex_shader *vertex_shader; + const struct brw_fragment_shader *fragment_shader; const struct brw_blend_state *blend; const struct brw_rasterizer_state *rast; - const struct brw_depth_stencil_alpha_state *dsa; + const struct brw_depth_stencil_alpha_state *zstencil; struct pipe_framebuffer_state fb; struct pipe_viewport_state vp; struct pipe_clip_state ucp; + struct pipe_buffer *vertex_constants; + struct pipe_buffer *fragment_constants; } curr; struct { @@ -673,15 +674,6 @@ struct brw_context }; -#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) - - - -/*====================================================================== - * brw_vtbl.c - */ -void brwInitVtbl( struct brw_context *brw ); - /*====================================================================== * brw_queryobj.c @@ -730,9 +722,10 @@ brw_context( struct pipe_context *ctx ) } +#define BRW_IS_965(brw) ((brw)->chipset.is_965) +#define BRW_IS_IGDNG(brw) ((brw)->chipset.is_igdng) +#define BRW_IS_G4X(brw) ((brw)->chipset.is_g4x) -#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX)) - 1) - #endif diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index f2524d75e2..edc39ff223 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -29,13 +29,16 @@ * Keith Whitwell */ +#include "util/u_memory.h" +#include "util/u_math.h" #include "brw_batchbuffer.h" -#include "intel_regions.h" #include "brw_context.h" #include "brw_defines.h" #include "brw_state.h" #include "brw_util.h" +#include "brw_debug.h" +#include "brw_screen.h" /** @@ -57,7 +60,7 @@ static void calculate_curbe_offsets( struct brw_context *brw ) /* PIPE_NEW_CLIP */ if (brw->curr.ucp.nr) { - GLuint nr_planes = 6 + brw->nr_ucp; + GLuint nr_planes = 6 + brw->curr.ucp.nr; nr_clip_regs = (nr_planes * 4 + 15) / 16; } @@ -156,10 +159,6 @@ static GLfloat fixed_plane[6][4] = { */ static void prepare_constant_buffer(struct brw_context *brw) { - const struct brw_vertex_program *vp = - brw_vertex_program_const(brw->vertex_program); - const struct brw_fragment_program *fp = - brw_fragment_program_const(brw->fragment_program); const GLuint sz = brw->curbe.total_size; const GLuint bufsz = sz * 16 * sizeof(GLfloat); GLfloat *buf; @@ -174,7 +173,7 @@ static void prepare_constant_buffer(struct brw_context *brw) return; } - buf = (GLfloat *) _mesa_calloc(bufsz); + buf = (GLfloat *) CALLOC(bufsz, 1); /* fragment shader constants */ if (brw->curbe.wm_size) { @@ -208,12 +207,12 @@ static void prepare_constant_buffer(struct brw_context *brw) /* Clip planes: */ - assert(brw->nr_ucp <= 6); - for (j = 0; j < brw->nr_ucp; j++) { - buf[offset + i * 4 + 0] = brw->ucp[j][0]; - buf[offset + i * 4 + 1] = brw->ucp[j][1]; - buf[offset + i * 4 + 2] = brw->ucp[j][2]; - buf[offset + i * 4 + 3] = brw->ucp[j][3]; + assert(brw->curr.ucp.nr <= 6); + for (j = 0; j < brw->curr.ucp.nr; j++) { + buf[offset + i * 4 + 0] = brw->curr.ucp.ucp[j][0]; + buf[offset + i * 4 + 1] = brw->curr.ucp.ucp[j][1]; + buf[offset + i * 4 + 2] = brw->curr.ucp.ucp[j][2]; + buf[offset + i * 4 + 3] = brw->curr.ucp.ucp[j][3]; i++; } } @@ -221,23 +220,21 @@ static void prepare_constant_buffer(struct brw_context *brw) /* vertex shader constants */ if (brw->curbe.vs_size) { GLuint offset = brw->curbe.vs_start * 16; - GLuint nr = brw->vs.prog_data->nr_params / 4; + GLuint nr = brw->curr.vertex_shader->info.file_max[TGSI_FILE_CONSTANT]; + struct pipe_screen *screen = &brw->brw_screen->base; - /* map vs constant buffer */ + const GLfloat *value = screen->buffer_map( screen, + brw->curr.vertex_constants, + PIPE_BUFFER_USAGE_CPU_READ); - /* XXX just use a memcpy here */ - for (i = 0; i < nr; i++) { - const GLfloat *value = vp->program.Base.Parameters->ParameterValues[i]; - buf[offset + i * 4 + 0] = value[0]; - buf[offset + i * 4 + 1] = value[1]; - buf[offset + i * 4 + 2] = value[2]; - buf[offset + i * 4 + 3] = value[3]; - } + /* XXX: what if user's constant buffer is too small? + */ + memcpy(&buf[offset], value, nr * 4 * sizeof(float)); - /* unmap vs constant buffer */ + screen->buffer_unmap( screen, brw->curr.vertex_constants ); } - if (0) { + if (BRW_DEBUG & DEBUG_CURBE) { for (i = 0; i < sz*16; i+=4) debug_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4, buf[i+0], buf[i+1], buf[i+2], buf[i+3]); @@ -275,18 +272,22 @@ static void prepare_constant_buffer(struct brw_context *brw) /* Allocate a single page for CURBE entries for this batchbuffer. * They're generally around 64b. */ - brw->curbe.curbe_bo = dri_bo_alloc(brw->intel.bufmgr, "CURBE", - 4096, 1 << 6); + brw->curbe.curbe_bo = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_CURBE, + 4096, 1 << 6); brw->curbe.curbe_next_offset = 0; } brw->curbe.curbe_offset = brw->curbe.curbe_next_offset; brw->curbe.curbe_next_offset += bufsz; - brw->curbe.curbe_next_offset = ALIGN(brw->curbe.curbe_next_offset, 64); + brw->curbe.curbe_next_offset = align(brw->curbe.curbe_next_offset, 64); /* Copy data to the buffer: */ - dri_bo_subdata(brw->curbe.curbe_bo, brw->curbe.curbe_offset, bufsz, buf); + brw->sws->bo_subdata(brw->curbe.curbe_bo, + brw->curbe.curbe_offset, + bufsz, + buf); } brw_add_validated_bo(brw, brw->curbe.curbe_bo); @@ -325,8 +326,8 @@ static void emit_constant_buffer(struct brw_context *brw) const struct brw_tracked_state brw_constant_buffer = { .dirty = { - .mesa = (PIPE_NEW_FS_CONSTANTS | - PIPE_NEW_VS_CONSTANTS | + .mesa = (PIPE_NEW_FRAGMENT_CONSTANTS | + PIPE_NEW_VERTEX_CONSTANTS | PIPE_NEW_CLIP), .brw = (BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_VERTEX_PROGRAM | diff --git a/src/gallium/drivers/i965/brw_debug.h b/src/gallium/drivers/i965/brw_debug.h new file mode 100644 index 0000000000..aee62f7a5b --- /dev/null +++ b/src/gallium/drivers/i965/brw_debug.h @@ -0,0 +1,42 @@ +#ifndef BRW_DEBUG_H +#define BRW_DEBUG_H + +/* ================================================================ + * Debugging: + */ + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BLIT 0x8 +#define DEBUG_CURBE 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_BATCH 0x80 +#define DEBUG_PIXEL 0x100 +#define DEBUG_BUFMGR 0x200 +#define DEBUG_unused1 0x400 +#define DEBUG_unused2 0x800 +#define DEBUG_unused3 0x1000 +#define DEBUG_SYNC 0x2000 +#define DEBUG_PRIMS 0x4000 +#define DEBUG_VERTS 0x8000 +#define DEBUG_unused4 0x10000 +#define DEBUG_DMA 0x20000 +#define DEBUG_SANITY 0x40000 +#define DEBUG_SLEEP 0x80000 +#define DEBUG_STATS 0x100000 +#define DEBUG_unused5 0x200000 +#define DEBUG_SINGLE_THREAD 0x400000 +#define DEBUG_WM 0x800000 +#define DEBUG_URB 0x1000000 +#define DEBUG_VS 0x2000000 + +#ifdef DEBUG +extern int BRW_DEBUG; +#else +#define BRW_DEBUG 0 +#endif + + +#endif diff --git a/src/gallium/drivers/i965/brw_defines.h b/src/gallium/drivers/i965/brw_defines.h index 1dc64ddc8f..544d36306c 100644 --- a/src/gallium/drivers/i965/brw_defines.h +++ b/src/gallium/drivers/i965/brw_defines.h @@ -838,13 +838,6 @@ #define R02_PRIM_END 0x1 #define R02_PRIM_START 0x2 -#include "intel_chipset.h" - -#define BRW_IS_G4X(brw) (IS_G4X((brw)->brw_screen->pci_id)) -#define BRW_IS_IGDNG(brw) (IS_IGDNG((brw)->brw_screen->pci_id)) -#define BRW_IS_965(brw) (!(BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))) -#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965) -#define CMD_VF_STATISTICS(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965) #define URB_SIZES(brw) (BRW_IS_IGDNG(brw) ? 1024 : \ (BRW_IS_G4X(brw) ? 384 : 256)) /* 512 bit units */ diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 741537309a..7af490bc5a 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -30,9 +30,9 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" +#include "brw_debug.h" #include "brw_batchbuffer.h" -#include "intel_buffer_objects.h" #define FILE_DEBUG_FLAG DEBUG_BATCH @@ -56,26 +56,18 @@ static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = { * programs be immune to the active primitive (ie. cope with all * possibilities). That may not be realistic however. */ -static GLuint brw_set_prim(struct brw_context *brw, GLenum prim) +static GLuint brw_set_prim(struct brw_context *brw, unsigned prim) { - if (INTEL_DEBUG & DEBUG_PRIMS) - _mesa_printf("PRIM: %s\n", _mesa_lookup_enum_by_nr(prim)); + if (BRW_DEBUG & DEBUG_PRIMS) + debug_printf("PRIM: %s\n", u_prim_name(prim)); - /* Slight optimization to avoid the GS program when not needed: - */ - if (prim == GL_QUAD_STRIP && - ctx->Light.ShadeModel != GL_FLAT && - ctx->Polygon.FrontMode == GL_FILL && - ctx->Polygon.BackMode == GL_FILL) - prim = GL_TRIANGLE_STRIP; - if (prim != brw->primitive) { brw->primitive = prim; brw->state.dirty.brw |= BRW_NEW_PRIMITIVE; - if (reduced_prim[prim] != brw->intel.reduced_primitive) { - brw->intel.reduced_primitive = reduced_prim[prim]; + if (reduced_prim[prim] != brw->reduced_primitive) { + brw->reduced_primitive = reduced_prim[prim]; brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE; } } @@ -84,43 +76,33 @@ static GLuint brw_set_prim(struct brw_context *brw, GLenum prim) } -static GLuint trim(GLenum prim, GLuint length) -{ - if (prim == GL_QUAD_STRIP) - return length > 3 ? (length - length % 2) : 0; - else if (prim == GL_QUADS) - return length - length % 4; - else - return length; -} - -static void brw_emit_prim(struct brw_context *brw, - const struct _mesa_prim *prim, - uint32_t hw_prim) +static enum pipe_error brw_emit_prim(struct brw_context *brw, + unsigned prim, + unsigned start, + unsigned count, + boolean indexed, + uint32_t hw_prim) { struct brw_3d_primitive prim_packet; if (INTEL_DEBUG & DEBUG_PRIMS) - _mesa_printf("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode), - prim->start, prim->count); + debug_printf("PRIM: %s %d %d\n", u_prim_name(prim), start, count); prim_packet.header.opcode = CMD_3D_PRIM; prim_packet.header.length = sizeof(prim_packet)/4 - 2; prim_packet.header.pad = 0; prim_packet.header.topology = hw_prim; - prim_packet.header.indexed = prim->indexed; + prim_packet.header.indexed = indexed; - prim_packet.verts_per_instance = trim(prim->mode, prim->count); - prim_packet.start_vert_location = prim->start; - if (prim->indexed) + prim_packet.verts_per_instance = count; + prim_packet.start_vert_location = start; + if (indexed) prim_packet.start_vert_location += brw->ib.start_vertex_offset; prim_packet.instance_count = 1; prim_packet.start_instance_location = 0; prim_packet.base_vert_location = prim->basevertex; - /* Can't wrap here, since we rely on the validated state. */ - brw->no_batch_wrap = GL_TRUE; /* If we're set to always flush, do it before and after the primitive emit. * We want to catch both missed flushes that hurt instruction/state cache @@ -128,13 +110,15 @@ static void brw_emit_prim(struct brw_context *brw, * the besides the draw code. */ if (intel->always_flush_cache) { - BEGIN_BATCH(1, IGNORE_CLIPRECTS); + BEGIN_BATCH(1, IGNORE_CLIPRECTS) OUT_BATCH(intel->vtbl.flush_cmd()); ADVANCE_BATCH(); } if (prim_packet.verts_per_instance) { - brw_batchbuffer_data( brw->intel.batch, &prim_packet, - sizeof(prim_packet), LOOP_CLIPRECTS); + ret = brw_batchbuffer_data( brw->intel.batch, &prim_packet, + sizeof(prim_packet), LOOP_CLIPRECTS); + if (ret) + return ret; } if (intel->always_flush_cache) { BEGIN_BATCH(1, IGNORE_CLIPRECTS); @@ -142,34 +126,9 @@ static void brw_emit_prim(struct brw_context *brw, ADVANCE_BATCH(); } - brw->no_batch_wrap = GL_FALSE; + return 0; } -static void brw_merge_inputs( struct brw_context *brw, - const struct gl_client_array *arrays[]) -{ - struct brw_vertex_info old = brw->vb.info; - GLuint i; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) - brw->sws->bo_unreference(brw->vb.inputs[i].bo); - - memset(&brw->vb.inputs, 0, sizeof(brw->vb.inputs)); - memset(&brw->vb.info, 0, sizeof(brw->vb.info)); - - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - brw->vb.inputs[i].glarray = arrays[i]; - brw->vb.inputs[i].attrib = (gl_vert_attrib) i; - - if (arrays[i]->StrideB != 0) - brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) << - ((i%16) * 2); - } - - /* Raise statechanges if input sizes have changed. */ - if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0) - brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS; -} /* May fail if out of video memory for texture or vbo upload, or on * fallback conditions. @@ -229,14 +188,14 @@ static GLboolean brw_try_draw_prims( struct brw_context *brw, return 0; } -void brw_draw_prims( struct brw_context *brw, - const struct gl_client_array *arrays[], - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLboolean index_bounds_valid, - GLuint min_index, - GLuint max_index ) + +static boolean +brw_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *index_buffer, + unsigned index_size, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count) { enum pipe_error ret; @@ -256,15 +215,40 @@ void brw_draw_prims( struct brw_context *brw, ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); assert(ret == 0); } + + return TRUE; } -void brw_draw_init( struct brw_context *brw ) +static boolean +brw_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *index_buffer, + unsigned index_size, + unsigned mode, + unsigned start, unsigned count) { - struct vbo_context *vbo = vbo_context(ctx); + return brw_draw_range_elements( pipe, index_buffer, + index_size, + 0, 0xffffffff, + mode, + start, count ); +} +static boolean +brw_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count) +{ + return brw_draw_elements(pipe, NULL, 0, mode, start, count); +} + + + +void brw_draw_init( struct brw_context *brw ) +{ /* Register our drawing function: */ - vbo->draw_prims = brw_draw_prims; + brw->base.draw_arrays = brw_draw_arrays; + brw->base.draw_elements = brw_draw_elements; + brw->base.draw_range_elements = brw_draw_range_elements; } void brw_draw_destroy( struct brw_context *brw ) diff --git a/src/gallium/drivers/i965/brw_draw.h b/src/gallium/drivers/i965/brw_draw.h index dc7ca8731d..13f0443a81 100644 --- a/src/gallium/drivers/i965/brw_draw.h +++ b/src/gallium/drivers/i965/brw_draw.h @@ -33,21 +33,8 @@ struct brw_context; -void brw_draw_prims( struct brw_context *brw, - const struct gl_client_array *arrays[], - const struct _mesa_prim *prims, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLboolean index_bounds_valid, - GLuint min_index, - GLuint max_index ); - void brw_draw_init( struct brw_context *brw ); -void brw_draw_destroy( struct brw_context *brw ); +void brw_draw_cleanup( struct brw_context *brw ); -/* brw_draw_current.c - */ -void brw_init_current_values(struct brw_context *brw, - struct gl_client_array *arrays); #endif diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 1ab65d60c4..7b0860d04c 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -36,8 +36,6 @@ #include "brw_fallback.h" #include "brw_batchbuffer.h" -#include "intel_buffer_objects.h" -#include "intel_tex.h" diff --git a/src/gallium/drivers/i965/brw_eu.h b/src/gallium/drivers/i965/brw_eu.h index 46d52a473b..ac5a623cac 100644 --- a/src/gallium/drivers/i965/brw_eu.h +++ b/src/gallium/drivers/i965/brw_eu.h @@ -33,6 +33,8 @@ #ifndef BRW_EU_H #define BRW_EU_H +#include "util/u_debug.h" + #include "brw_structs.h" #include "brw_defines.h" diff --git a/src/gallium/drivers/i965/brw_misc_state.c b/src/gallium/drivers/i965/brw_misc_state.c index eb39be8545..0f2612c181 100644 --- a/src/gallium/drivers/i965/brw_misc_state.c +++ b/src/gallium/drivers/i965/brw_misc_state.c @@ -32,8 +32,6 @@ #include "brw_batchbuffer.h" -#include "intel_regions.h" - #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" diff --git a/src/gallium/drivers/i965/brw_pipe_debug.c b/src/gallium/drivers/i965/brw_pipe_debug.c deleted file mode 100644 index 34d6d4028a..0000000000 --- a/src/gallium/drivers/i965/brw_pipe_debug.c +++ /dev/null @@ -1,2 +0,0 @@ - if (INTEL_DEBUG & DEBUG_STATS) - cc.cc5.statistics_enable = 1; diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 55242ac6ad..a2da1373bf 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -43,7 +43,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_batchbuffer.h" -#include "intel_reg.h" +#include "brw_reg.h" /** Waits on the query object's BO and totals the results for this query */ static void @@ -165,7 +165,7 @@ brw_prepare_query_begin(struct brw_context *brw) brw->sws->bo_unreference(brw->query.bo); brw->query.bo = NULL; - brw->query.bo = dri_bo_alloc(brw->bufmgr, "query", 4096, 1); + brw->query.bo = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1); brw->query.index = 0; } diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c new file mode 100644 index 0000000000..b0928adbe4 --- /dev/null +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -0,0 +1,26 @@ + +static void brw_merge_inputs( struct brw_context *brw, + const struct gl_client_array *arrays[]) +{ + struct brw_vertex_info old = brw->vb.info; + GLuint i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + brw->sws->bo_unreference(brw->vb.inputs[i].bo); + + memset(&brw->vb.inputs, 0, sizeof(brw->vb.inputs)); + memset(&brw->vb.info, 0, sizeof(brw->vb.info)); + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + brw->vb.inputs[i].glarray = arrays[i]; + brw->vb.inputs[i].attrib = (gl_vert_attrib) i; + + if (arrays[i]->StrideB != 0) + brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) << + ((i%16) * 2); + } + + /* Raise statechanges if input sizes have changed. */ + if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0) + brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS; +} diff --git a/src/gallium/drivers/i965/brw_reg.h b/src/gallium/drivers/i965/brw_reg.h index a640104d71..f428ec9269 100644 --- a/src/gallium/drivers/i965/brw_reg.h +++ b/src/gallium/drivers/i965/brw_reg.h @@ -76,4 +76,40 @@ #define FENCE_YMAJOR 2 + +/* PCI IDs + */ +#define PCI_CHIP_I965_G 0x29A2 +#define PCI_CHIP_I965_Q 0x2992 +#define PCI_CHIP_I965_G_1 0x2982 +#define PCI_CHIP_I946_GZ 0x2972 +#define PCI_CHIP_I965_GM 0x2A02 +#define PCI_CHIP_I965_GME 0x2A12 + +#define PCI_CHIP_GM45_GM 0x2A42 + +#define PCI_CHIP_IGD_E_G 0x2E02 +#define PCI_CHIP_Q45_G 0x2E12 +#define PCI_CHIP_G45_G 0x2E22 +#define PCI_CHIP_G41_G 0x2E32 +#define PCI_CHIP_B43_G 0x2E42 + +#define PCI_CHIP_ILD_G 0x0042 +#define PCI_CHIP_ILM_G 0x0046 + +struct brw_chipset { + int pci_id:16; + int is_965:1; + int is_igdng:1; + int is_g4x:1; + int pad:13; +}; + + +/* XXX: hacks + */ +#define VERT_RESULT_HPOS 0 /* not always true */ +#define VERT_RESULT_PSIZ 10000 /* disabled */ + + #endif diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c new file mode 100644 index 0000000000..671467989d --- /dev/null +++ b/src/gallium/drivers/i965/brw_screen.c @@ -0,0 +1,365 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_inlines.h" +#include "util/u_memory.h" +#include "util/u_string.h" + +#include "brw_reg.h" +#include "brw_context.h" +#include "brw_screen.h" +#include "brw_buffer.h" +#include "brw_texture.h" +#include "brw_winsys.h" + +#ifdef DEBUG +static const struct debug_named_value debug_names[] = { + { "tex", DEBUG_TEXTURE}, + { "state", DEBUG_STATE}, + { "ioctl", DEBUG_IOCTL}, + { "blit", DEBUG_BLIT}, + { "curbe", DEBUG_CURBE}, + { "fall", DEBUG_FALLBACKS}, + { "verb", DEBUG_VERBOSE}, + { "bat", DEBUG_BATCH}, + { "pix", DEBUG_PIXEL}, + { "buf", DEBUG_BUFMGR}, + { "reg", DEBUG_REGION}, + { "fbo", DEBUG_FBO}, + { "lock", DEBUG_LOCK}, + { "sync", DEBUG_SYNC}, + { "prim", DEBUG_PRIMS }, + { "vert", DEBUG_VERTS }, + { "dri", DEBUG_DRI }, + { "dma", DEBUG_DMA }, + { "san", DEBUG_SANITY }, + { "sleep", DEBUG_SLEEP }, + { "stats", DEBUG_STATS }, + { "tile", DEBUG_TILE }, + { "sing", DEBUG_SINGLE_THREAD }, + { "thre", DEBUG_SINGLE_THREAD }, + { "wm", DEBUG_WM }, + { "urb", DEBUG_URB }, + { "vs", DEBUG_VS }, + { NULL, 0 } +}; + +int BRW_DEBUG = 0; +#endif + + +/* + * Probe functions + */ + + +static const char * +brw_get_vendor(struct pipe_screen *screen) +{ + return "VMware, Inc."; +} + +static const char * +brw_get_name(struct pipe_screen *screen) +{ + static char buffer[128]; + const char *chipset; + + switch (brw_screen(screen)->pci_id) { + case PCI_CHIP_I965_G: + chipset = "I965_G"; + break; + case PCI_CHIP_I965_Q: + chipset = "I965_Q"; + break; + case PCI_CHIP_I965_G_1: + chipset = "I965_G_1"; + break; + case PCI_CHIP_I946_GZ: + chipset = "I946_GZ"; + break; + case PCI_CHIP_I965_GM: + chipset = "I965_GM"; + break; + case PCI_CHIP_I965_GME: + chipset = "I965_GME"; + break; + case PCI_CHIP_GM45_GM: + chipset = "GM45_GM"; + break; + case PCI_CHIP_IGD_E_G: + chipset = "IGD_E_G"; + break; + case PCI_CHIP_Q45_G: + chipset = "Q45_G"; + break; + case PCI_CHIP_G45_G: + chipset = "G45_G"; + break; + case PCI_CHIP_G41_G: + chipset = "G41_G"; + break; + case PCI_CHIP_B43_G: + chipset = "B43_G"; + break; + case PCI_CHIP_ILD_G: + chipset = "ILD_G"; + break; + case PCI_CHIP_ILM_G: + chipset = "ILM_G"; + break; + } + + util_snprintf(buffer, sizeof(buffer), "i965 (chipset: %s)", chipset); + return buffer; +} + +static int +brw_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 11; /* max 1024x1024 */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 11; /* max 1024x1024 */ + default: + return 0; + } +} + +static float +brw_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 7.5; + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 4.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; + + default: + return 0; + } +} + +static boolean +brw_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + static const enum pipe_format tex_supported[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, + PIPE_FORMAT_A8L8_UNORM, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_NONE /* list terminator */ + }; + static const enum pipe_format surface_supported[] = { + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_NONE /* list terminator */ + }; + const enum pipe_format *list; + uint i; + + if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) + list = surface_supported; + else + list = tex_supported; + + for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { + if (list[i] == format) + return TRUE; + } + + return FALSE; +} + + +/* + * Fence functions + */ + + +static void +brw_fence_reference(struct pipe_screen *screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct brw_screen *is = brw_screen(screen); + + is->iws->fence_reference(is->iws, ptr, fence); +} + +static int +brw_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct brw_screen *is = brw_screen(screen); + + return is->iws->fence_signalled(is->iws, fence); +} + +static int +brw_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct brw_screen *is = brw_screen(screen); + + return is->iws->fence_finish(is->iws, fence); +} + + +/* + * Generic functions + */ + + +static void +brw_destroy_screen(struct pipe_screen *screen) +{ + struct brw_screen *is = brw_screen(screen); + + if (is->iws) + is->iws->destroy(is->iws); + + FREE(is); +} + +/** + * Create a new brw_screen object + */ +struct pipe_screen * +brw_create_screen(struct intel_winsys *iws, uint pci_id) +{ + struct brw_screen *is; + struct brw_chipset chipset; + +#ifdef DEBUG + BRW_DEBUG = debug_get_flags_option("BRW_DEBUG", debug_names, 0); + BRW_DEBUG |= debug_get_flags_option("INTEL_DEBUG", debug_names, 0); +#endif + + memset(&chipset, 0, sizeof chipset); + + chipset.pci_id = pci_id; + + switch (pci_id) { + case PCI_CHIP_I965_G: + case PCI_CHIP_I965_Q: + case PCI_CHIP_I965_G_1: + case PCI_CHIP_I946_GZ: + case PCI_CHIP_I965_GM: + case PCI_CHIP_I965_GME: + chipset.is_965 = TRUE; + break; + + case PCI_CHIP_GM45_GM: + case PCI_CHIP_IGD_E_G: + case PCI_CHIP_Q45_G: + case PCI_CHIP_G45_G: + case PCI_CHIP_G41_G: + case PCI_CHIP_B43_G: + chipset.is_g4x = TRUE; + break; + + case PCI_CHIP_ILD_G: + case PCI_CHIP_ILM_G: + chipset.is_igdng = TRUE; + break; + + default: + debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", + __FUNCTION__, pci_id); + return NULL; + } + + + is = CALLOC_STRUCT(brw_screen); + if (!is) + return NULL; + + is->chipset = chipset; + is->iws = iws; + is->base.winsys = NULL; + is->base.destroy = brw_destroy_screen; + is->base.get_name = brw_get_name; + is->base.get_vendor = brw_get_vendor; + is->base.get_param = brw_get_param; + is->base.get_paramf = brw_get_paramf; + is->base.is_format_supported = brw_is_format_supported; + is->base.fence_reference = brw_fence_reference; + is->base.fence_signalled = brw_fence_signalled; + is->base.fence_finish = brw_fence_finish; + + brw_screen_init_texture_functions(is); + brw_screen_init_buffer_functions(is); + + return &is->base; +} diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h index 716b55c52b..79d595d0ad 100644 --- a/src/gallium/drivers/i965/brw_screen.h +++ b/src/gallium/drivers/i965/brw_screen.h @@ -31,6 +31,7 @@ #include "pipe/p_state.h" #include "pipe/p_screen.h" +#include "brw_reg.h" struct brw_winsys_screen; @@ -41,11 +42,8 @@ struct brw_winsys_screen; struct brw_screen { struct pipe_screen base; - + struct brw_chipset chipset; struct brw_winsys_screen *sws; - - boolean is_i945; - uint pci_id; }; /** diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index 54202cbd12..53e8f09e37 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -56,7 +56,7 @@ static void compile_sf_prog( struct brw_context *brw, c.key = *key; c.nr_attrs = util_count_bits(c.key.attrs); c.nr_attr_regs = (c.nr_attrs+1)/2; - c.nr_setup_attrs = util_count_bits(c.key.attrs & DO_SETUP_BITS); + c.nr_setup_attrs = c.key.nr_attrs; c.nr_setup_regs = (c.nr_setup_attrs+1)/2; c.prog_data.urb_read_length = c.nr_attr_regs; diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c index 5e1229d22f..0e406f12e1 100644 --- a/src/gallium/drivers/i965/brw_sf_state.c +++ b/src/gallium/drivers/i965/brw_sf_state.c @@ -68,8 +68,7 @@ static void upload_sf_vp(struct brw_context *brw) */ /* The scissor only needs to handle the intersection of drawable and - * scissor rect. Clipping to the boundaries of static shared buffers - * for front/back/depth is covered by looping over cliprects in brw_draw.c. + * scissor rect. * * Note that the hardware's coordinates are inclusive, while Mesa's min is * inclusive but max is exclusive. diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c index 1b5f27cc16..97f88b3ab3 100644 --- a/src/gallium/drivers/i965/brw_state_cache.c +++ b/src/gallium/drivers/i965/brw_state_cache.c @@ -220,8 +220,8 @@ brw_upload_cache( struct brw_cache *cache, int i; /* Create the buffer object to contain the data */ - bo = dri_bo_alloc(cache->brw->intel.bufmgr, - cache->name[cache_id], data_size, 1 << 6); + bo = brw->sws->bo_alloc(cache->sws, + cache->buffer_type[cache_id], data_size, 1 << 6); /* Set up the memory containing the key, aux_data, and reloc_bufs */ diff --git a/src/gallium/drivers/i965/brw_state_debug.c b/src/gallium/drivers/i965/brw_state_debug.c new file mode 100644 index 0000000000..812b761d40 --- /dev/null +++ b/src/gallium/drivers/i965/brw_state_debug.c @@ -0,0 +1,145 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + + + +#include "brw_context.h" +#include "brw_state.h" + + +struct dirty_bit_map { + uint32_t bit; + char *name; + uint32_t count; +}; + +#define DEFINE_BIT(name) {name, #name, 0} + +static struct dirty_bit_map mesa_bits[] = { + DEFINE_BIT(_NEW_MODELVIEW), + DEFINE_BIT(_NEW_PROJECTION), + DEFINE_BIT(_NEW_TEXTURE_MATRIX), + DEFINE_BIT(_NEW_COLOR_MATRIX), + DEFINE_BIT(_NEW_ACCUM), + DEFINE_BIT(_NEW_COLOR), + DEFINE_BIT(_NEW_DEPTH), + DEFINE_BIT(_NEW_EVAL), + DEFINE_BIT(_NEW_FOG), + DEFINE_BIT(_NEW_HINT), + DEFINE_BIT(_NEW_LIGHT), + DEFINE_BIT(_NEW_LINE), + DEFINE_BIT(_NEW_PIXEL), + DEFINE_BIT(_NEW_POINT), + DEFINE_BIT(_NEW_POLYGON), + DEFINE_BIT(_NEW_POLYGONSTIPPLE), + DEFINE_BIT(_NEW_SCISSOR), + DEFINE_BIT(_NEW_STENCIL), + DEFINE_BIT(_NEW_TEXTURE), + DEFINE_BIT(_NEW_TRANSFORM), + DEFINE_BIT(_NEW_VIEWPORT), + DEFINE_BIT(_NEW_PACKUNPACK), + DEFINE_BIT(_NEW_ARRAY), + DEFINE_BIT(_NEW_RENDERMODE), + DEFINE_BIT(_NEW_BUFFERS), + DEFINE_BIT(_NEW_MULTISAMPLE), + DEFINE_BIT(_NEW_TRACK_MATRIX), + DEFINE_BIT(_NEW_PROGRAM), + DEFINE_BIT(_NEW_PROGRAM_CONSTANTS), + {0, 0, 0} +}; + +static struct dirty_bit_map brw_bits[] = { + DEFINE_BIT(BRW_NEW_URB_FENCE), + DEFINE_BIT(BRW_NEW_FRAGMENT_PROGRAM), + DEFINE_BIT(BRW_NEW_VERTEX_PROGRAM), + DEFINE_BIT(BRW_NEW_INPUT_DIMENSIONS), + DEFINE_BIT(BRW_NEW_CURBE_OFFSETS), + DEFINE_BIT(BRW_NEW_REDUCED_PRIMITIVE), + DEFINE_BIT(BRW_NEW_PRIMITIVE), + DEFINE_BIT(BRW_NEW_CONTEXT), + DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), + DEFINE_BIT(BRW_NEW_PSP), + DEFINE_BIT(BRW_NEW_FENCE), + DEFINE_BIT(BRW_NEW_INDICES), + DEFINE_BIT(BRW_NEW_INDEX_BUFFER), + DEFINE_BIT(BRW_NEW_VERTICES), + DEFINE_BIT(BRW_NEW_BATCH), + DEFINE_BIT(BRW_NEW_DEPTH_BUFFER), + {0, 0, 0} +}; + +static struct dirty_bit_map cache_bits[] = { + DEFINE_BIT(CACHE_NEW_CC_VP), + DEFINE_BIT(CACHE_NEW_CC_UNIT), + DEFINE_BIT(CACHE_NEW_WM_PROG), + DEFINE_BIT(CACHE_NEW_SAMPLER_DEFAULT_COLOR), + DEFINE_BIT(CACHE_NEW_SAMPLER), + DEFINE_BIT(CACHE_NEW_WM_UNIT), + DEFINE_BIT(CACHE_NEW_SF_PROG), + DEFINE_BIT(CACHE_NEW_SF_VP), + DEFINE_BIT(CACHE_NEW_SF_UNIT), + DEFINE_BIT(CACHE_NEW_VS_UNIT), + DEFINE_BIT(CACHE_NEW_VS_PROG), + DEFINE_BIT(CACHE_NEW_GS_UNIT), + DEFINE_BIT(CACHE_NEW_GS_PROG), + DEFINE_BIT(CACHE_NEW_CLIP_VP), + DEFINE_BIT(CACHE_NEW_CLIP_UNIT), + DEFINE_BIT(CACHE_NEW_CLIP_PROG), + DEFINE_BIT(CACHE_NEW_SURFACE), + DEFINE_BIT(CACHE_NEW_SURF_BIND), + {0, 0, 0} +}; + + +static void +brw_update_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) +{ + int i; + + for (i = 0; i < 32; i++) { + if (bit_map[i].bit == 0) + return; + + if (bit_map[i].bit & bits) + bit_map[i].count++; + } +} + +static void +brw_print_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) +{ + int i; + + for (i = 0; i < 32; i++) { + if (bit_map[i].bit == 0) + return; + + fprintf(stderr, "0x%08x: %12d (%s)\n", + bit_map[i].bit, bit_map[i].count, bit_map[i].name); + } +} + diff --git a/src/gallium/drivers/i965/brw_state_upload.c b/src/gallium/drivers/i965/brw_state_upload.c index 842380e38f..8659e35289 100644 --- a/src/gallium/drivers/i965/brw_state_upload.c +++ b/src/gallium/drivers/i965/brw_state_upload.c @@ -45,7 +45,7 @@ const struct brw_tracked_state *atoms[] = { &brw_check_fallback, - &brw_wm_input_sizes, +// &brw_wm_input_sizes, &brw_vs_prog, &brw_gs_prog, &brw_clip_prog, @@ -155,117 +155,6 @@ brw_clear_validated_bos(struct brw_context *brw) brw->state.validated_bo_count = 0; } -struct dirty_bit_map { - uint32_t bit; - char *name; - uint32_t count; -}; - -#define DEFINE_BIT(name) {name, #name, 0} - -static struct dirty_bit_map mesa_bits[] = { - DEFINE_BIT(_NEW_MODELVIEW), - DEFINE_BIT(_NEW_PROJECTION), - DEFINE_BIT(_NEW_TEXTURE_MATRIX), - DEFINE_BIT(_NEW_COLOR_MATRIX), - DEFINE_BIT(_NEW_ACCUM), - DEFINE_BIT(_NEW_COLOR), - DEFINE_BIT(_NEW_DEPTH), - DEFINE_BIT(_NEW_EVAL), - DEFINE_BIT(_NEW_FOG), - DEFINE_BIT(_NEW_HINT), - DEFINE_BIT(_NEW_LIGHT), - DEFINE_BIT(_NEW_LINE), - DEFINE_BIT(_NEW_PIXEL), - DEFINE_BIT(_NEW_POINT), - DEFINE_BIT(_NEW_POLYGON), - DEFINE_BIT(_NEW_POLYGONSTIPPLE), - DEFINE_BIT(_NEW_SCISSOR), - DEFINE_BIT(_NEW_STENCIL), - DEFINE_BIT(_NEW_TEXTURE), - DEFINE_BIT(_NEW_TRANSFORM), - DEFINE_BIT(_NEW_VIEWPORT), - DEFINE_BIT(_NEW_PACKUNPACK), - DEFINE_BIT(_NEW_ARRAY), - DEFINE_BIT(_NEW_RENDERMODE), - DEFINE_BIT(_NEW_BUFFERS), - DEFINE_BIT(_NEW_MULTISAMPLE), - DEFINE_BIT(_NEW_TRACK_MATRIX), - DEFINE_BIT(_NEW_PROGRAM), - DEFINE_BIT(_NEW_PROGRAM_CONSTANTS), - {0, 0, 0} -}; - -static struct dirty_bit_map brw_bits[] = { - DEFINE_BIT(BRW_NEW_URB_FENCE), - DEFINE_BIT(BRW_NEW_FRAGMENT_PROGRAM), - DEFINE_BIT(BRW_NEW_VERTEX_PROGRAM), - DEFINE_BIT(BRW_NEW_INPUT_DIMENSIONS), - DEFINE_BIT(BRW_NEW_CURBE_OFFSETS), - DEFINE_BIT(BRW_NEW_REDUCED_PRIMITIVE), - DEFINE_BIT(BRW_NEW_PRIMITIVE), - DEFINE_BIT(BRW_NEW_CONTEXT), - DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), - DEFINE_BIT(BRW_NEW_PSP), - DEFINE_BIT(BRW_NEW_FENCE), - DEFINE_BIT(BRW_NEW_INDICES), - DEFINE_BIT(BRW_NEW_INDEX_BUFFER), - DEFINE_BIT(BRW_NEW_VERTICES), - DEFINE_BIT(BRW_NEW_BATCH), - DEFINE_BIT(BRW_NEW_DEPTH_BUFFER), - {0, 0, 0} -}; - -static struct dirty_bit_map cache_bits[] = { - DEFINE_BIT(CACHE_NEW_CC_VP), - DEFINE_BIT(CACHE_NEW_CC_UNIT), - DEFINE_BIT(CACHE_NEW_WM_PROG), - DEFINE_BIT(CACHE_NEW_SAMPLER_DEFAULT_COLOR), - DEFINE_BIT(CACHE_NEW_SAMPLER), - DEFINE_BIT(CACHE_NEW_WM_UNIT), - DEFINE_BIT(CACHE_NEW_SF_PROG), - DEFINE_BIT(CACHE_NEW_SF_VP), - DEFINE_BIT(CACHE_NEW_SF_UNIT), - DEFINE_BIT(CACHE_NEW_VS_UNIT), - DEFINE_BIT(CACHE_NEW_VS_PROG), - DEFINE_BIT(CACHE_NEW_GS_UNIT), - DEFINE_BIT(CACHE_NEW_GS_PROG), - DEFINE_BIT(CACHE_NEW_CLIP_VP), - DEFINE_BIT(CACHE_NEW_CLIP_UNIT), - DEFINE_BIT(CACHE_NEW_CLIP_PROG), - DEFINE_BIT(CACHE_NEW_SURFACE), - DEFINE_BIT(CACHE_NEW_SURF_BIND), - {0, 0, 0} -}; - - -static void -brw_update_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) -{ - int i; - - for (i = 0; i < 32; i++) { - if (bit_map[i].bit == 0) - return; - - if (bit_map[i].bit & bits) - bit_map[i].count++; - } -} - -static void -brw_print_dirty_count(struct dirty_bit_map *bit_map, int32_t bits) -{ - int i; - - for (i = 0; i < 32; i++) { - if (bit_map[i].bit == 0) - return; - - fprintf(stderr, "0x%08x: %12d (%s)\n", - bit_map[i].bit, bit_map[i].count, bit_map[i].name); - } -} /*********************************************************************** * Emit all state: diff --git a/src/gallium/drivers/i965/brw_tex.c b/src/gallium/drivers/i965/brw_tex.c index c33c19ee51..6f7adb6393 100644 --- a/src/gallium/drivers/i965/brw_tex.c +++ b/src/gallium/drivers/i965/brw_tex.c @@ -30,8 +30,6 @@ */ -#include "intel_regions.h" -#include "intel_tex.h" #include "brw_context.h" /** diff --git a/src/gallium/drivers/i965/brw_tex_layout.c b/src/gallium/drivers/i965/brw_tex_layout.c index 813cd31f49..50c30878c6 100644 --- a/src/gallium/drivers/i965/brw_tex_layout.c +++ b/src/gallium/drivers/i965/brw_tex_layout.c @@ -32,9 +32,7 @@ /* Code to layout images in a mipmap tree for i965. */ -#include "intel_mipmap_tree.h" -#include "intel_tex_layout.h" -#include "intel_chipset.h" +#include "brw_tex_layout.h" #define FILE_DEBUG_FLAG DEBUG_MIPTREE diff --git a/src/gallium/drivers/i965/brw_types.h b/src/gallium/drivers/i965/brw_types.h index 87dae13d94..89e08a5c80 100644 --- a/src/gallium/drivers/i965/brw_types.h +++ b/src/gallium/drivers/i965/brw_types.h @@ -15,4 +15,7 @@ typedef float GLfloat; typedef uint8_t GLboolean; +#define GL_FALSE FALSE +#define GL_TRUE TRUE + #endif diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 6446e8e761..319e29bfcb 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -52,7 +52,8 @@ brw_vs_update_constant_buffer(struct brw_context *brw) if (!vp->use_const_buffer) return NULL; - const_buffer = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", + const_buffer = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_SHADER_CONSTANTS, size, 64); /* _NEW_PROGRAM_CONSTANTS */ diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index 2142db5a4d..82cd8007ac 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -37,6 +37,7 @@ struct brw_winsys_buffer { struct brw_winsys_screen *sws; void *bo; unsigned offset; + unsigned size; }; enum brw_buffer_usage { @@ -63,6 +64,11 @@ enum brw_buffer_type BRW_BUFFER_TYPE_TEXTURE, BRW_BUFFER_TYPE_SCANOUT, /**< a texture used for scanning out from */ BRW_BUFFER_TYPE_VERTEX, + BRW_BUFFER_TYPE_CURBE, + BRW_BUFFER_TYPE_QUERY, + BRW_BUFFER_TYPE_SHADER_CONSTANTS, + BRW_BUFFER_TYPE_WM_SCRATCH, + BRW_BUFFER_TYPE_BATCH, }; @@ -82,6 +88,10 @@ struct brw_batchbuffer { uint8_t *map; uint8_t *ptr; size_t size; + struct { + uint8_t *end_ptr; + } emit; + size_t relocs; size_t max_relocs; @@ -125,15 +135,15 @@ struct brw_winsys_screen { /** * Buffer functions. */ + /*@{*/ /** * Create a buffer. */ - struct brw_winsys_buffer *(*buffer_create)(struct brw_winsys *iws, - unsigned size, - unsigned alignment, - enum brw_buffer_type type); - + struct brw_winsys_buffer *(*bo_alloc)( struct brw_winsys_screen *sws, + enum brw_buffer_type type, + unsigned size, + unsigned alignment ); /* Reference and unreference buffers: */ @@ -146,6 +156,11 @@ struct brw_winsys_screen { unsigned offset, struct brw_winsys_buffer *b2); + void (*bo_subdata)(struct brw_winsys_buffer *dst, + size_t offset, + size_t size, + const void *data); + /** * Map a buffer. */ @@ -159,17 +174,6 @@ struct brw_winsys_screen { void (*buffer_unmap)(struct brw_winsys *iws, struct brw_winsys_buffer *buffer); - /** - * Write to a buffer. - * - * Arguments follows pipe_buffer_write. - */ - int (*buffer_write)(struct brw_winsys *iws, - struct brw_winsys_buffer *dst, - size_t offset, - size_t size, - const void *data); - void (*buffer_destroy)(struct brw_winsys *iws, struct brw_winsys_buffer *buffer); /*@}*/ @@ -208,14 +212,14 @@ struct brw_winsys_screen { /** - * Create i915 pipe_screen. + * Create brw pipe_screen. */ -struct pipe_screen *i915_create_screen(struct brw_winsys *iws, unsigned pci_id); +struct pipe_screen *brw_create_screen(struct brw_winsys *iws, unsigned pci_id); /** - * Create a i915 pipe_context. + * Create a brw pipe_context. */ -struct pipe_context *i915_create_context(struct pipe_screen *screen); +struct pipe_context *brw_create_context(struct pipe_screen *screen); /** * Get the brw_winsys buffer backing the texture. @@ -223,7 +227,7 @@ struct pipe_context *i915_create_context(struct pipe_screen *screen); * TODO UGLY */ struct pipe_texture; -boolean i915_get_texture_buffer_brw(struct pipe_texture *texture, +boolean brw_get_texture_buffer_brw(struct pipe_texture *texture, struct brw_winsys_buffer **buffer, unsigned *stride); @@ -232,10 +236,10 @@ boolean i915_get_texture_buffer_brw(struct pipe_texture *texture, * * TODO UGLY */ -struct pipe_texture * i915_texture_blanket_brw(struct pipe_screen *screen, - struct pipe_texture *tmplt, - unsigned pitch, - struct brw_winsys_buffer *buffer); +struct pipe_texture * brw_texture_blanket(struct pipe_screen *screen, + struct pipe_texture *tmplt, + unsigned pitch, + struct brw_winsys_buffer *buffer); diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 32b8900bac..284cf42f8b 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -310,7 +310,7 @@ static void brw_wm_populate_key( struct brw_context *brw, } /* CACHE_NEW_VS_PROG */ - key->vp_outputs_written = brw->vs.prog_data->outputs_written & DO_SETUP_BITS; + key->vp_outputs_written = brw->vs.prog_data->outputs_written; /* bitmask */ /* The unique fragment program ID */ key->program_string_id = fp->id; diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c index 958c00d3e0..16a2324049 100644 --- a/src/gallium/drivers/i965/brw_wm_state.c +++ b/src/gallium/drivers/i965/brw_wm_state.c @@ -272,10 +272,10 @@ static void upload_wm_unit( struct brw_context *brw ) brw->wm.scratch_bo = NULL; } if (brw->wm.scratch_bo == NULL) { - brw->wm.scratch_bo = dri_bo_alloc(intel->bufmgr, - "wm scratch", - total, - 4096); + brw->wm.scratch_bo = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_WM_SCRATCH, + total, + 4096); } } diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index 5045c9b4a6..e1ed6438dc 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -30,11 +30,7 @@ */ -#include "intel_mipmap_tree.h" #include "brw_batchbuffer.h" -#include "intel_tex.h" -#include "intel_fbo.h" - #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" @@ -365,7 +361,8 @@ brw_wm_update_constant_buffer(struct brw_context *brw) if (!fp->use_const_buffer) return NULL; - const_buffer = drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer", + const_buffer = drm_intel_bo_alloc(intel->bufmgr, + BRW_BUFFER_TYPE_SHADER_CONSTANTS, size, 64); /* _NEW_PROGRAM_CONSTANTS */ @@ -686,7 +683,7 @@ static void prepare_wm_surfaces(struct brw_context *brw ) } old_nr_surfaces = brw->wm.nr_surfaces; - brw->wm.nr_surfaces = MAX_DRAW_BUFFERS; + brw->wm.nr_surfaces = PIPE_MAX_COLOR_BUFS; if (brw->wm.surf_bo[SURF_INDEX_FRAG_CONST_BUFFER] != NULL) brw->wm.nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1; diff --git a/src/gallium/drivers/i965/intel_chipset.h b/src/gallium/drivers/i965/intel_chipset.h deleted file mode 100644 index 3c38f1676c..0000000000 --- a/src/gallium/drivers/i965/intel_chipset.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright © 2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 - -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 - -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_E7221_G 0x258A -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE - -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q33_G 0x29D2 - -#define PCI_CHIP_IGD_GM 0xA011 -#define PCI_CHIP_IGD_G 0xA001 - -#define IS_IGDGM(devid) (devid == PCI_CHIP_IGD_GM) -#define IS_IGDG(devid) (devid == PCI_CHIP_IGD_G) -#define IS_IGD(devid) (IS_IGDG(devid) || IS_IGDGM(devid)) - -#define PCI_CHIP_I965_G 0x29A2 -#define PCI_CHIP_I965_Q 0x2992 -#define PCI_CHIP_I965_G_1 0x2982 -#define PCI_CHIP_I946_GZ 0x2972 -#define PCI_CHIP_I965_GM 0x2A02 -#define PCI_CHIP_I965_GME 0x2A12 - -#define PCI_CHIP_GM45_GM 0x2A42 - -#define PCI_CHIP_IGD_E_G 0x2E02 -#define PCI_CHIP_Q45_G 0x2E12 -#define PCI_CHIP_G45_G 0x2E22 -#define PCI_CHIP_G41_G 0x2E32 - -#define PCI_CHIP_ILD_G 0x0042 -#define PCI_CHIP_ILM_G 0x0046 - -#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \ - devid == PCI_CHIP_I915_GM || \ - devid == PCI_CHIP_I945_GM || \ - devid == PCI_CHIP_I945_GME || \ - devid == PCI_CHIP_I965_GM || \ - devid == PCI_CHIP_I965_GME || \ - devid == PCI_CHIP_GM45_GM || \ - IS_IGD(devid) || \ - devid == PCI_CHIP_ILM_G) - -#define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \ - devid == PCI_CHIP_Q45_G || \ - devid == PCI_CHIP_G45_G || \ - devid == PCI_CHIP_G41_G) -#define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM) -#define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid)) - -#define IS_ILD(devid) (devid == PCI_CHIP_ILD_G) -#define IS_ILM(devid) (devid == PCI_CHIP_ILM_G) -#define IS_IGDNG(devid) (IS_ILD(devid) || IS_ILM(devid)) - -#define IS_915(devid) (devid == PCI_CHIP_I915_G || \ - devid == PCI_CHIP_E7221_G || \ - devid == PCI_CHIP_I915_GM) - -#define IS_945(devid) (devid == PCI_CHIP_I945_G || \ - devid == PCI_CHIP_I945_GM || \ - devid == PCI_CHIP_I945_GME || \ - devid == PCI_CHIP_G33_G || \ - devid == PCI_CHIP_Q33_G || \ - devid == PCI_CHIP_Q35_G || IS_IGD(devid)) - -#define IS_965(devid) (devid == PCI_CHIP_I965_G || \ - devid == PCI_CHIP_I965_Q || \ - devid == PCI_CHIP_I965_G_1 || \ - devid == PCI_CHIP_I965_GM || \ - devid == PCI_CHIP_I965_GME || \ - devid == PCI_CHIP_I946_GZ || \ - IS_G4X(devid) || \ - IS_IGDNG(devid)) - -#define IS_9XX(devid) (IS_915(devid) || \ - IS_945(devid) || \ - IS_965(devid)) diff --git a/src/gallium/drivers/i965/intel_tex_format.c b/src/gallium/drivers/i965/intel_tex_format.c deleted file mode 100644 index c62ecdadf0..0000000000 --- a/src/gallium/drivers/i965/intel_tex_format.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "intel_context.h" -#include "intel_tex.h" -#include "intel_chipset.h" - - - - -int intel_compressed_num_bytes(GLuint mesaFormat) -{ - int bytes = 0; - switch(mesaFormat) { - - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - case MESA_FORMAT_RGB_DXT1: - case MESA_FORMAT_RGBA_DXT1: - bytes = 2; - break; - - case MESA_FORMAT_RGBA_DXT3: - case MESA_FORMAT_RGBA_DXT5: - bytes = 4; - default: - break; - } - - return bytes; -} diff --git a/src/gallium/drivers/i965/intel_tex_layout.c b/src/gallium/drivers/i965/intel_tex_layout.c index 1cdab49e5e..7e0ca553f2 100644 --- a/src/gallium/drivers/i965/intel_tex_layout.c +++ b/src/gallium/drivers/i965/intel_tex_layout.c @@ -30,9 +30,7 @@ * Michel Dänzer */ -#include "intel_mipmap_tree.h" #include "intel_tex_layout.h" -#include "intel_context.h" void intel_get_texture_alignment_unit(GLenum internalFormat, GLuint *w, GLuint *h) { -- cgit v1.2.3 From 4dd2f6640b70e2313f8771f7588aa49a861153aa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 Oct 2009 00:02:16 +0100 Subject: i965g: more work on compiling, particularly the brw_draw files --- src/gallium/auxiliary/util/u_debug.c | 27 +++ src/gallium/auxiliary/util/u_prim.h | 2 + src/gallium/auxiliary/util/u_upload_mgr.h | 2 + src/gallium/drivers/i965/Makefile | 2 +- src/gallium/drivers/i965/brw_batchbuffer.c | 198 +++++++++++++++ src/gallium/drivers/i965/brw_batchbuffer.h | 14 +- src/gallium/drivers/i965/brw_cc.c | 8 +- src/gallium/drivers/i965/brw_clip.c | 4 +- src/gallium/drivers/i965/brw_clip_state.c | 4 +- src/gallium/drivers/i965/brw_context.c | 2 +- src/gallium/drivers/i965/brw_context.h | 68 ++++-- src/gallium/drivers/i965/brw_curbe.c | 13 +- src/gallium/drivers/i965/brw_draw.c | 165 +++++++------ src/gallium/drivers/i965/brw_draw.h | 3 +- src/gallium/drivers/i965/brw_draw_upload.c | 372 +++++++++++++++++------------ src/gallium/drivers/i965/brw_eu.c | 5 +- src/gallium/drivers/i965/brw_eu_debug.c | 13 +- src/gallium/drivers/i965/brw_misc_state.c | 18 +- src/gallium/drivers/i965/brw_pipe_flush.c | 3 + src/gallium/drivers/i965/brw_pipe_shader.c | 19 ++ src/gallium/drivers/i965/brw_pipe_vertex.c | 25 +- src/gallium/drivers/i965/brw_screen.h | 22 ++ src/gallium/drivers/i965/brw_sf.c | 2 +- src/gallium/drivers/i965/brw_sf_state.c | 39 +-- src/gallium/drivers/i965/brw_state.h | 6 +- src/gallium/drivers/i965/brw_state_batch.c | 4 +- src/gallium/drivers/i965/brw_swtnl.c | 6 +- src/gallium/drivers/i965/brw_winsys.h | 7 + src/gallium/drivers/i965/brw_wm.c | 2 +- src/gallium/drivers/i965/brw_wm.h | 8 +- src/gallium/drivers/i965/brw_wm_glsl.c | 28 --- src/gallium/drivers/i965/brw_wm_pass0.c | 32 +-- src/mesa/state_tracker/st_draw.c | 3 +- 33 files changed, 722 insertions(+), 404 deletions(-) create mode 100644 src/gallium/drivers/i965/brw_batchbuffer.c (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 96d400c839..321ac59a7d 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -69,6 +69,7 @@ #include "util/u_stream.h" #include "util/u_math.h" #include "util/u_tile.h" +#include "util/u_prim.h" #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY @@ -600,6 +601,32 @@ const char *pf_name( enum pipe_format format ) } + +static const struct debug_named_value pipe_prim_names[] = { +#ifdef DEBUG + DEBUG_NAMED_VALUE(PIPE_PRIM_POINTS), + DEBUG_NAMED_VALUE(PIPE_PRIM_LINES), + DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_LOOP), + DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP), + DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES), + DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP), + DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_FAN), + DEBUG_NAMED_VALUE(PIPE_PRIM_QUADS), + DEBUG_NAMED_VALUE(PIPE_PRIM_QUAD_STRIP), + DEBUG_NAMED_VALUE(PIPE_PRIM_POLYGON), +#endif + DEBUG_NAMED_VALUE_END +}; + + +const char *u_prim_name( unsigned prim ) +{ + return debug_dump_enum(pipe_prim_names, prim); +} + + + + #ifdef DEBUG void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index a9b533eea7..7434329962 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -135,4 +135,6 @@ static INLINE unsigned u_reduced_prim( unsigned pipe_prim ) } } +const char *u_prim_name( unsigned pipe_prim ); + #endif diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h index 745b5834af..d414a1f2f6 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.h +++ b/src/gallium/auxiliary/util/u_upload_mgr.h @@ -32,6 +32,8 @@ #ifndef U_UPLOAD_MGR_H #define U_UPLOAD_MGR_H +#include "pipe/p_error.h" + struct pipe_screen; struct pipe_buffer; struct u_upload_mgr; diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index 40c8364824..40e8aa8786 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -61,7 +61,7 @@ C_SOURCES = \ brw_wm_state.c \ brw_wm_surface_state.c \ brw_bo.c \ - intel_batchbuffer.c \ + brw_batchbuffer.c \ intel_tex_layout.c include ../../Makefile.template diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c new file mode 100644 index 0000000000..8bcac76ede --- /dev/null +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -0,0 +1,198 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "brw_batchbuffer.h" +#include "brw_decode.h" +#include "brw_reg.h" +#include "brw_winsys.h" + + +void +brw_batchbuffer_reset(struct brw_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + brw->sws->bo_unreference(batch->buf); + batch->buf = NULL; + } + + if (!batch->buffer && intel->ttm == GL_TRUE) + batch->buffer = malloc (intel->maxBatchSize); + + batch->buf = batch->sws->bo_alloc(batch->sws, + BRW_BUFFER_TYPE_BATCH, + intel->maxBatchSize, 4096); + if (batch->buffer) + batch->map = batch->buffer; + else { + batch->sws->bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + } + batch->size = intel->maxBatchSize; + batch->ptr = batch->map; + batch->dirty_state = ~0; + batch->cliprect_mode = IGNORE_CLIPRECTS; +} + +struct brw_batchbuffer * +brw_batchbuffer_alloc(struct brw_winsys_screen *sws) +{ + struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer); + + batch->sws = sws; + brw_batchbuffer_reset(batch); + + return batch; +} + +void +brw_batchbuffer_free(struct brw_batchbuffer *batch) +{ + if (batch->map) { + dri_bo_unmap(batch->buf); + batch->map = NULL; + } + + brw->sws->bo_unreference(batch->buf); + batch->buf = NULL; + FREE(batch); +} + + +void +_brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file, + int line) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + + if (used == 0) + return; + + if (intel->first_post_swapbuffers_batch == NULL) { + intel->first_post_swapbuffers_batch = intel->batch->buf; + batch->sws->bo_reference(intel->first_post_swapbuffers_batch); + } + + if (intel->first_post_swapbuffers_batch == NULL) { + intel->first_post_swapbuffers_batch = intel->batch->buf; + batch->sws->bo_reference(intel->first_post_swapbuffers_batch); + } + + + if (INTEL_DEBUG & DEBUG_BATCH) + fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line, + used); + + /* Emit a flush if the bufmgr doesn't do it for us. */ + if (intel->always_flush_cache || !intel->ttm) { + *(GLuint *) (batch->ptr) = intel->vtbl.flush_cmd(); + batch->ptr += 4; + used = batch->ptr - batch->map; + } + + /* Round batchbuffer usage to 2 DWORDs. */ + + if ((used & 4) == 0) { + *(GLuint *) (batch->ptr) = 0; /* noop */ + batch->ptr += 4; + used = batch->ptr - batch->map; + } + + /* Mark the end of the buffer. */ + *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END; /* noop */ + batch->ptr += 4; + used = batch->ptr - batch->map; + + batch->sws->bo_unmap(batch->buf); + + batch->map = NULL; + batch->ptr = NULL; + + batch->sws->bo_exec(batch->buf, used, NULL, 0, 0 ); + + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + intel_decode(batch->buf->virtual, used / 4, batch->buf->offset, + brw->brw_screen->pci_id); + dri_bo_unmap(batch->buf); + } + + if (INTEL_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "waiting for idle\n"); + dri_bo_map(batch->buf, GL_TRUE); + dri_bo_unmap(batch->buf); + } + + /* Reset the buffer: + */ + brw_batchbuffer_reset(batch); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, + struct brw_winsys_buffer *buffer, + uint32_t read_domains, uint32_t write_domain, + uint32_t delta) +{ + int ret; + + if (batch->ptr - batch->map > batch->buf->size) + _mesa_printf ("bad relocation ptr %p map %p offset %d size %d\n", + batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size); + + ret = batch->sws->bo_emit_reloc(batch->buf, + read_domains, + write_domain, + delta, + batch->ptr - batch->map, + buffer); + + /* + * Using the old buffer offset, write in what the right data would be, in case + * the buffer doesn't move and we can short-circuit the relocation processing + * in the kernel + */ + brw_batchbuffer_emit_dword (batch, buffer->offset + delta); + + return GL_TRUE; +} + +void +brw_batchbuffer_data(struct brw_batchbuffer *batch, + const void *data, GLuint bytes, + enum cliprect_mode cliprect_mode) +{ + assert((bytes & 3) == 0); + brw_batchbuffer_require_space(batch, bytes); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index b8492882e1..25bb9cefca 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -33,18 +33,16 @@ void brw_batchbuffer_reset(struct brw_batchbuffer *batch); * Consider it a convenience function wrapping multple * intel_buffer_dword() calls. */ -void brw_batchbuffer_data(struct brw_batchbuffer *batch, +int brw_batchbuffer_data(struct brw_batchbuffer *batch, const void *data, GLuint bytes, enum cliprect_mode cliprect_mode); -void brw_batchbuffer_release_space(struct brw_batchbuffer *batch, - GLuint bytes); -GLboolean brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, - struct brw_winsys_buffer *buffer, - uint32_t read_domains, - uint32_t write_domain, - uint32_t offset); +int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, + struct brw_winsys_buffer *buffer, + uint32_t read_domains, + uint32_t write_domain, + uint32_t offset); /* Inline functions - might actually be better off with these * non-inlined. Certainly better off switching all command packets to diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index 76759304eb..ca10bc73f6 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -57,7 +57,7 @@ static void calc_sane_viewport( const struct pipe_viewport_state *vp, svp->far = 1; } -static void prepare_cc_vp( struct brw_context *brw ) +static int prepare_cc_vp( struct brw_context *brw ) { struct brw_cc_viewport ccv; struct sane_viewport svp; @@ -72,6 +72,8 @@ static void prepare_cc_vp( struct brw_context *brw ) brw->sws->bo_unreference(brw->cc.vp_bo); brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 ); + + return 0; } const struct brw_tracked_state brw_cc_vp = { @@ -158,7 +160,7 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) return bo; } -static void prepare_cc_unit( struct brw_context *brw ) +static int prepare_cc_unit( struct brw_context *brw ) { struct brw_cc_unit_key key; @@ -172,6 +174,8 @@ static void prepare_cc_unit( struct brw_context *brw ) if (brw->cc.state_bo == NULL) brw->cc.state_bo = cc_unit_create_from_key(brw, &key); + + return 0; } const struct brw_tracked_state brw_cc_unit = { diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c index 622d9dba96..1a52fa771b 100644 --- a/src/gallium/drivers/i965/brw_clip.c +++ b/src/gallium/drivers/i965/brw_clip.c @@ -146,7 +146,7 @@ static void compile_clip_prog( struct brw_context *brw, /* Calculate interpolants for triangle and line rasterization. */ -static void upload_clip_prog(struct brw_context *brw) +static int upload_clip_prog(struct brw_context *brw) { struct brw_clip_prog_key key; @@ -173,6 +173,8 @@ static void upload_clip_prog(struct brw_context *brw) &brw->clip.prog_data); if (brw->clip.prog_bo == NULL) compile_clip_prog( brw, &key ); + + return 0; } diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c index 25b8c6372f..bf4e6f5103 100644 --- a/src/gallium/drivers/i965/brw_clip_state.c +++ b/src/gallium/drivers/i965/brw_clip_state.c @@ -159,7 +159,7 @@ clip_unit_create_from_key(struct brw_context *brw, return bo; } -static void upload_clip_unit( struct brw_context *brw ) +static int upload_clip_unit( struct brw_context *brw ) { struct brw_clip_unit_key key; @@ -173,6 +173,8 @@ static void upload_clip_unit( struct brw_context *brw ) if (brw->clip.state_bo == NULL) { brw->clip.state_bo = clip_unit_create_from_key(brw, &key); } + + return 0; } const struct brw_tracked_state brw_clip_unit = { diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index e9605bafe6..e10b7d8bf5 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -105,7 +105,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen) brw->state.dirty.mesa = ~0; brw->state.dirty.brw = ~0; - brw->emit_state_always = 0; + brw->flags.always_emit_state = 0; make_empty_list(&brw->query.active_head); diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index dd782fdba9..7ead641811 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -182,6 +182,8 @@ struct brw_fragment_shader { #define PIPE_NEW_FRAGMENT_CONSTANTS 0x2 #define PIPE_NEW_VERTEX_CONSTANTS 0x2 #define PIPE_NEW_CLIP 0x2 +#define PIPE_NEW_INDEX_BUFFER 0x2 +#define PIPE_NEW_INDEX_RANGE 0x2 #define BRW_NEW_URB_FENCE 0x1 @@ -387,8 +389,8 @@ struct brw_cache { */ struct brw_tracked_state { struct brw_state_flags dirty; - void (*prepare)( struct brw_context *brw ); - void (*emit)( struct brw_context *brw ); + int (*prepare)( struct brw_context *brw ); + int (*emit)( struct brw_context *brw ); }; /* Flags for brw->state.cache. @@ -465,9 +467,7 @@ struct brw_context GLuint primitive; GLuint reduced_primitive; - GLboolean emit_state_always; - - /* Active vertex program: + /* Active state from the state tracker: */ struct { const struct brw_vertex_shader *vertex_shader; @@ -475,11 +475,31 @@ struct brw_context const struct brw_blend_state *blend; const struct brw_rasterizer_state *rast; const struct brw_depth_stencil_alpha_state *zstencil; + + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; + struct pipe_framebuffer_state fb; struct pipe_viewport_state vp; struct pipe_clip_state ucp; struct pipe_buffer *vertex_constants; struct pipe_buffer *fragment_constants; + + /** + * Index buffer for this draw_prims call. + * + * Updates are signaled by PIPE_NEW_INDEX_BUFFER. + */ + struct pipe_buffer *index_buffer; + unsigned index_size; + + /* Updates are signalled by PIPE_NEW_INDEX_RANGE: + */ + unsigned min_index; + unsigned max_index; + } curr; struct { @@ -504,30 +524,26 @@ struct brw_context struct brw_cached_batch_item *cached_batch_items; struct { - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned num_vertex_element; - unsigned num_vertex_buffer; - struct u_upload_mgr *upload_vertex; struct u_upload_mgr *upload_index; - - /* Summary of size and varying of active arrays, so we can check - * for changes to this state: + /* Information on uploaded vertex buffers: */ - struct brw_vertex_info info; - unsigned int min_index, max_index; + struct { + unsigned stride; /* in bytes between successive vertices */ + unsigned offset; /* in bytes, of first vertex in bo */ + unsigned vertex_count; /* count of valid vertices which may be accessed */ + struct brw_winsys_buffer *bo; + } vb[PIPE_MAX_ATTRIBS]; + + struct { + } ve[PIPE_MAX_ATTRIBS]; + + unsigned nr_vb; /* currently the same as curr.num_vertex_buffers */ + unsigned nr_ve; /* currently the same as curr.num_vertex_elements */ } vb; struct { - /** - * Index buffer for this draw_prims call. - * - * Updates are signaled by BRW_NEW_INDICES. - */ - const struct _mesa_index_buffer *ib; - /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */ struct brw_winsys_buffer *bo; unsigned int offset; @@ -668,6 +684,14 @@ struct brw_context int index; GLboolean active; } query; + + struct { + unsigned always_emit_state:1; + unsigned always_flush_batch:1; + unsigned force_swtnl:1; + unsigned no_swtnl:1; + } flags; + /* Used to give every program string a unique id */ GLuint program_id; diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index edc39ff223..278ffa4ca2 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -48,7 +48,7 @@ * constants. That greatly reduces the demand for space in the CURBE. * Some of the comments within are dated... */ -static void calculate_curbe_offsets( struct brw_context *brw ) +static int calculate_curbe_offsets( struct brw_context *brw ) { /* CACHE_NEW_WM_PROG */ const GLuint nr_fp_regs = (brw->wm.prog_data->nr_params + 15) / 16; @@ -104,6 +104,8 @@ static void calculate_curbe_offsets( struct brw_context *brw ) brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS; } + + return 0; } @@ -157,7 +159,7 @@ static GLfloat fixed_plane[6][4] = { * cache mechanism, but maybe would benefit from a comparison against * the current uploaded set of constants. */ -static void prepare_constant_buffer(struct brw_context *brw) +static int prepare_constant_buffer(struct brw_context *brw) { const GLuint sz = brw->curbe.total_size; const GLuint bufsz = sz * 16 * sizeof(GLfloat); @@ -170,7 +172,7 @@ static void prepare_constant_buffer(struct brw_context *brw) brw->curbe.last_buf = NULL; brw->curbe.last_bufsz = 0; } - return; + return 0; } buf = (GLfloat *) CALLOC(bufsz, 1); @@ -305,9 +307,11 @@ static void prepare_constant_buffer(struct brw_context *brw) * flushes as necessary when doublebuffering of CURBEs isn't * possible. */ + + return 0; } -static void emit_constant_buffer(struct brw_context *brw) +static int emit_constant_buffer(struct brw_context *brw) { GLuint sz = brw->curbe.total_size; @@ -322,6 +326,7 @@ static void emit_constant_buffer(struct brw_context *brw) (sz - 1) + brw->curbe.curbe_offset); } ADVANCE_BATCH(); + return 0; } const struct brw_tracked_state brw_constant_buffer = { diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 7af490bc5a..b5fe7c9601 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -26,15 +26,18 @@ **************************************************************************/ +#include "util/u_prim.h" +#include "util/u_upload_mgr.h" + #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" #include "brw_debug.h" +#include "brw_screen.h" #include "brw_batchbuffer.h" -#define FILE_DEBUG_FLAG DEBUG_BATCH static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = { _3DPRIM_POINTLIST, @@ -56,18 +59,21 @@ static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = { * programs be immune to the active primitive (ie. cope with all * possibilities). That may not be realistic however. */ -static GLuint brw_set_prim(struct brw_context *brw, unsigned prim) +static int brw_set_prim(struct brw_context *brw, unsigned prim ) { if (BRW_DEBUG & DEBUG_PRIMS) debug_printf("PRIM: %s\n", u_prim_name(prim)); if (prim != brw->primitive) { + unsigned reduced_prim; + brw->primitive = prim; brw->state.dirty.brw |= BRW_NEW_PRIMITIVE; - if (reduced_prim[prim] != brw->reduced_primitive) { - brw->reduced_primitive = reduced_prim[prim]; + reduced_prim = u_reduced_prim(prim); + if (reduced_prim != brw->reduced_primitive) { + brw->reduced_primitive = reduced_prim; brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE; } } @@ -77,17 +83,14 @@ static GLuint brw_set_prim(struct brw_context *brw, unsigned prim) -static enum pipe_error brw_emit_prim(struct brw_context *brw, - unsigned prim, - unsigned start, - unsigned count, - boolean indexed, - uint32_t hw_prim) +static int brw_emit_prim(struct brw_context *brw, + unsigned start, + unsigned count, + boolean indexed, + uint32_t hw_prim) { struct brw_3d_primitive prim_packet; - - if (INTEL_DEBUG & DEBUG_PRIMS) - debug_printf("PRIM: %s %d %d\n", u_prim_name(prim), start, count); + int ret; prim_packet.header.opcode = CMD_3D_PRIM; prim_packet.header.length = sizeof(prim_packet)/4 - 2; @@ -101,7 +104,7 @@ static enum pipe_error brw_emit_prim(struct brw_context *brw, prim_packet.start_vert_location += brw->ib.start_vertex_offset; prim_packet.instance_count = 1; prim_packet.start_instance_location = 0; - prim_packet.base_vert_location = prim->basevertex; + prim_packet.base_vert_location = 0; // prim->basevertex; XXX: add this to gallium /* If we're set to always flush, do it before and after the primitive emit. @@ -109,20 +112,20 @@ static enum pipe_error brw_emit_prim(struct brw_context *brw, * and missed flushes of the render cache as it heads to other parts of * the besides the draw code. */ - if (intel->always_flush_cache) { - BEGIN_BATCH(1, IGNORE_CLIPRECTS) - OUT_BATCH(intel->vtbl.flush_cmd()); + if (0) { + BEGIN_BATCH(1, IGNORE_CLIPRECTS); + OUT_BATCH((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE); ADVANCE_BATCH(); } if (prim_packet.verts_per_instance) { - ret = brw_batchbuffer_data( brw->intel.batch, &prim_packet, + ret = brw_batchbuffer_data( brw->batch, &prim_packet, sizeof(prim_packet), LOOP_CLIPRECTS); if (ret) return ret; } - if (intel->always_flush_cache) { + if (0) { BEGIN_BATCH(1, IGNORE_CLIPRECTS); - OUT_BATCH(intel->vtbl.flush_cmd()); + OUT_BATCH((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE); ADVANCE_BATCH(); } @@ -133,44 +136,24 @@ static enum pipe_error brw_emit_prim(struct brw_context *brw, /* May fail if out of video memory for texture or vbo upload, or on * fallback conditions. */ -static GLboolean brw_try_draw_prims( struct brw_context *brw, - const struct gl_client_array *arrays[], - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index ) +static int +try_draw_range_elements(struct brw_context *brw, + struct pipe_buffer *index_buffer, + unsigned hw_prim, + unsigned start, unsigned count) { - struct brw_context *brw = brw_context(ctx); - GLboolean retval = GL_FALSE; - GLboolean warn = GL_FALSE; - GLboolean first_time = GL_TRUE; - uint32_t hw_prim; - GLuint i; - - if (ctx->NewState) - _mesa_update_state( ctx ); - - /* Bind all inputs, derive varying and size information: - */ - brw_merge_inputs( brw, arrays ); - - brw->ib.ib = ib; - brw->state.dirty.brw |= BRW_NEW_INDICES; - - brw->vb.min_index = min_index; - brw->vb.max_index = max_index; - brw->state.dirty.brw |= BRW_NEW_VERTICES; - - hw_prim = brw_set_prim(brw, prim[i].mode); + int ret; - brw_validate_state(brw); + ret = brw_validate_state(brw); + if (ret) + return ret; /* Check that we can fit our state in with our existing batchbuffer, or * flush otherwise. */ - ret = dri_bufmgr_check_aperture_space(brw->state.validated_bos, - brw->state.validated_bo_count); + ret = brw->sws->check_aperture_space(brw->sws, + brw->state.validated_bos, + brw->state.validated_bo_count); if (ret) return ret; @@ -178,12 +161,12 @@ static GLboolean brw_try_draw_prims( struct brw_context *brw, if (ret) return ret; - ret = brw_emit_prim(brw, &prim[i], hw_prim); + ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim); if (ret) return ret; - if (intel->always_flush_batch) - brw_batchbuffer_flush(intel->batch); + if (brw->flags.always_flush_batch) + brw_batchbuffer_flush(brw->batch); return 0; } @@ -197,22 +180,45 @@ brw_draw_range_elements(struct pipe_context *pipe, unsigned max_index, unsigned mode, unsigned start, unsigned count) { - enum pipe_error ret; + struct brw_context *brw = brw_context(pipe); + int ret; + uint32_t hw_prim; + + hw_prim = brw_set_prim(brw, mode); - if (!vbo_all_varyings_in_vbos(arrays)) { - if (!index_bounds_valid) - vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index); + if (BRW_DEBUG & DEBUG_PRIMS) + debug_printf("PRIM: %s %d %d\n", u_prim_name(mode), start, count); + + /* Potentially trigger upload of new index buffer. + * + * XXX: do we need to go through state validation to achieve this? + * Could just call upload code directly. + */ + if (brw->curr.index_buffer != index_buffer) { + pipe_buffer_reference( &brw->curr.index_buffer, index_buffer ); + brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER; + } + + /* XXX: do we really care? + */ + if (brw->curr.min_index != min_index || + brw->curr.max_index != max_index) + { + brw->curr.min_index = min_index; + brw->curr.max_index = max_index; + brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE; } + /* Make a first attempt at drawing: */ - ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); /* Otherwise, flush and retry: */ if (ret != 0) { - brw_batchbuffer_flush(intel->batch); - ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + brw_batchbuffer_flush(brw->batch); + ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); assert(ret == 0); } @@ -242,28 +248,37 @@ brw_draw_arrays(struct pipe_context *pipe, unsigned mode, -void brw_draw_init( struct brw_context *brw ) +boolean brw_draw_init( struct brw_context *brw ) { /* Register our drawing function: */ brw->base.draw_arrays = brw_draw_arrays; brw->base.draw_elements = brw_draw_elements; brw->base.draw_range_elements = brw_draw_range_elements; -} -void brw_draw_destroy( struct brw_context *brw ) -{ - int i; + /* Create helpers for uploading data in user buffers: + */ + brw->vb.upload_vertex = u_upload_create( &brw->brw_screen->base, + 128 * 1024, + 64, + PIPE_BUFFER_USAGE_VERTEX ); + if (brw->vb.upload_vertex == NULL) + return FALSE; + + brw->vb.upload_index = u_upload_create( &brw->brw_screen->base, + 128 * 1024, + 64, + PIPE_BUFFER_USAGE_INDEX ); + if (brw->vb.upload_index == NULL) + return FALSE; - if (brw->vb.upload.bo != NULL) { - brw->sws->bo_unreference(brw->vb.upload.bo); - brw->vb.upload.bo = NULL; - } + return TRUE; +} - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - brw->sws->bo_unreference(brw->vb.inputs[i].bo); - brw->vb.inputs[i].bo = NULL; - } +void brw_draw_cleanup( struct brw_context *brw ) +{ + u_upload_destroy( brw->vb.upload_vertex ); + u_upload_destroy( brw->vb.upload_index ); brw->sws->bo_unreference(brw->ib.bo); brw->ib.bo = NULL; diff --git a/src/gallium/drivers/i965/brw_draw.h b/src/gallium/drivers/i965/brw_draw.h index 13f0443a81..8dc5dbce62 100644 --- a/src/gallium/drivers/i965/brw_draw.h +++ b/src/gallium/drivers/i965/brw_draw.h @@ -32,8 +32,7 @@ struct brw_context; - -void brw_draw_init( struct brw_context *brw ); +boolean brw_draw_init( struct brw_context *brw ); void brw_draw_cleanup( struct brw_context *brw ); diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 7b0860d04c..040d8ca93a 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -26,21 +26,23 @@ **************************************************************************/ #include "pipe/p_context.h" +#include "pipe/p_error.h" #include "util/u_upload_mgr.h" +#include "util/u_math.h" #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_fallback.h" - +#include "brw_screen.h" #include "brw_batchbuffer.h" +#include "brw_debug.h" -unsigned brw_translate_surface_format( unsigned id ) +static unsigned brw_translate_surface_format( unsigned id ) { switch (id) { case PIPE_FORMAT_R64_FLOAT: @@ -186,70 +188,136 @@ static unsigned get_index_type(int type) } - -static boolean brw_prepare_vertices(struct brw_context *brw) +static int brw_prepare_vertices(struct brw_context *brw) { - GLbitfield vs_inputs = brw->vs.prog_data->inputs_read; + unsigned int min_index = brw->curr.min_index; + unsigned int max_index = brw->curr.max_index; GLuint i; - const unsigned char *ptr = NULL; - GLuint interleave = 0; - unsigned int min_index = brw->vb.min_index; - unsigned int max_index = brw->vb.max_index; - - struct brw_vertex_element *upload[VERT_ATTRIB_MAX]; - GLuint nr_uploads = 0; - - /* First build an array of pointers to ve's in vb.inputs_read - */ - if (0) - _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); - + int ret; + if (BRW_DEBUG & DEBUG_VERTS) + debug_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); - for (i = 0; i < brw->vb.num_vertex_buffer; i++) { - struct brw_vertex_buffer *vb = brw->vb.vertex_buffer[i]; - unsigned size = (vb->stride == 0 ? - vb->size : - vb->stride * (max_index + 1 - min_index)); - - if (brw_is_user_buffer(vb)) { - u_upload_buffer( brw->upload_vertex, - min_index * vb->stride, - size, - &offset, - &buffer ); + for (i = 0; i < brw->curr.num_vertex_buffers; i++) { + struct pipe_vertex_buffer *vb = &brw->curr.vertex_buffer[i]; + struct brw_winsys_buffer *bo; + struct pipe_buffer *upload_buf; + unsigned offset; + + if (BRW_DEBUG & DEBUG_VERTS) + debug_printf("%s vb[%d] user:%d offset:0x%x sz:0x%x stride:0x%x\n", + __FUNCTION__, i, + brw_buffer_is_user_buffer(vb->buffer), + vb->buffer_offset, + vb->buffer->size, + vb->stride); + + if (brw_buffer_is_user_buffer(vb->buffer)) { + + /* XXX: simplify this. Stop the state trackers from generating + * zero-stride buffers & have them use additional constants (or + * add support for >1 constant buffer) instead. + */ + unsigned size = (vb->stride == 0 ? + vb->buffer->size - vb->buffer_offset : + MAX2(vb->buffer->size - vb->buffer_offset, + vb->stride * (max_index + 1 - min_index))); + + ret = u_upload_buffer( brw->vb.upload_vertex, + vb->buffer_offset + min_index * vb->stride, + size, + vb->buffer, + &offset, + &upload_buf ); + if (ret) + return ret; + + bo = brw_buffer(upload_buf)->bo; + + assert(offset + size <= bo->size); } else { - offset = 0; - buffer = vb->buffer; + offset = vb->buffer_offset; + bo = brw_buffer(vb->buffer)->bo; } + + assert(offset < bo->size); /* Set up post-upload info about this vertex buffer: */ - input->offset = (unsigned long)offset; - input->stride = vb->stride; - input->count = count; - brw->sws->bo_unreference(input->bo); - input->bo = intel_bufferobj_buffer(intel, intel_buffer, - INTEL_READ); - brw->sws->bo_reference(input->bo); - - assert(input->offset < input->bo->size); - assert(input->offset + size <= input->bo->size); + brw->vb.vb[i].offset = offset; + brw->vb.vb[i].stride = vb->stride; + brw->vb.vb[i].vertex_count = (vb->stride == 0 ? + 1 : + (bo->size - offset) / vb->stride); + brw->sws->bo_unreference(brw->vb.vb[i].bo); + brw->vb.vb[i].bo = bo; + brw->sws->bo_reference(brw->vb.vb[i].bo); + + /* Don't need to retain this reference. We have a reference on + * the underlying winsys buffer: + */ + pipe_buffer_reference( &upload_buf, NULL ); } + brw->vb.nr_vb = i; brw_prepare_query_begin(brw); - for (i = 0; i < brw->vb.nr_enabled; i++) { - struct brw_vertex_element *input = brw->vb.enabled[i]; + for (i = 0; i < brw->vb.nr_vb; i++) { + brw_add_validated_bo(brw, brw->vb.vb[i].bo); + } + + return 0; +} + +static int brw_emit_vertex_buffers( struct brw_context *brw ) +{ + int i; + + /* If the VS doesn't read any inputs (calculating vertex position from + * a state variable for some reason, for example), just bail. + * + * The stale VB state stays in place, but they don't do anything unless + * a VE loads from them. + */ + if (brw->vb.nr_vb == 0) { + if (BRW_DEBUG & DEBUG_VERTS) + debug_printf("%s: no active vertex buffers\n", __FUNCTION__); - brw_add_validated_bo(brw, input->bo); + return 0; + } + + /* Emit VB state packets. + */ + BEGIN_BATCH(1 + brw->vb.nr_vb * 4, IGNORE_CLIPRECTS); + OUT_BATCH((CMD_VERTEX_BUFFER << 16) | + ((1 + brw->vb.nr_vb * 4) - 2)); + + for (i = 0; i < brw->vb.nr_vb; i++) { + OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) | + BRW_VB0_ACCESS_VERTEXDATA | + (brw->vb.vb[i].stride << BRW_VB0_PITCH_SHIFT)); + OUT_RELOC(brw->vb.vb[i].bo, + I915_GEM_DOMAIN_VERTEX, 0, + brw->vb.vb[i].offset); + if (BRW_IS_IGDNG(brw)) { + OUT_RELOC(brw->vb.vb[i].bo, + I915_GEM_DOMAIN_VERTEX, 0, + brw->vb.vb[i].bo->size - 1); + } else + OUT_BATCH(brw->vb.vb[i].stride ? brw->vb.vb[i].vertex_count : 0); + OUT_BATCH(0); /* Instance data step rate */ } + ADVANCE_BATCH(); + return 0; } -static void brw_emit_vertices(struct brw_context *brw) + + + +static int brw_emit_vertex_elements(struct brw_context *brw) { GLuint i; @@ -262,7 +330,7 @@ static void brw_emit_vertices(struct brw_context *brw) * The stale VB state stays in place, but they don't do anything unless * a VE loads from them. */ - if (brw->vb.nr_enabled == 0) { + if (brw->vb.nr_ve == 0) { BEGIN_BATCH(3, IGNORE_CLIPRECTS); OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1); OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) | @@ -274,59 +342,23 @@ static void brw_emit_vertices(struct brw_context *brw) (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) | (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT)); ADVANCE_BATCH(); - return; + return 0; } - /* Now emit VB and VEP state packets. + /* Now emit vertex element (VEP) state packets. * - * This still defines a hardware VB for each input, even if they - * are interleaved or from the same VBO. TBD if this makes a - * performance difference. */ - BEGIN_BATCH(1 + brw->vb.nr_enabled * 4, IGNORE_CLIPRECTS); - OUT_BATCH((CMD_VERTEX_BUFFER << 16) | - ((1 + brw->vb.nr_enabled * 4) - 2)); - - for (i = 0; i < brw->vb.nr_enabled; i++) { - struct brw_vertex_element *input = brw->vb.enabled[i]; - - OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) | - BRW_VB0_ACCESS_VERTEXDATA | - (input->stride << BRW_VB0_PITCH_SHIFT)); - OUT_RELOC(input->bo, - I915_GEM_DOMAIN_VERTEX, 0, - input->offset); - if (BRW_IS_IGDNG(brw)) { - if (input->stride) { - OUT_RELOC(input->bo, - I915_GEM_DOMAIN_VERTEX, 0, - input->offset + input->stride * input->count - 1); - } else { - assert(input->count == 1); - OUT_RELOC(input->bo, - I915_GEM_DOMAIN_VERTEX, 0, - input->offset + input->element_size - 1); - } - } else - OUT_BATCH(input->stride ? input->count : 0); - OUT_BATCH(0); /* Instance data step rate */ - } - ADVANCE_BATCH(); - - BEGIN_BATCH(1 + brw->vb.nr_enabled * 2, IGNORE_CLIPRECTS); - OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2)); - for (i = 0; i < brw->vb.nr_enabled; i++) { - struct brw_vertex_element *input = brw->vb.enabled[i]; - uint32_t format = get_surface_type(input->glarray->Type, - input->glarray->Size, - input->glarray->Format, - input->glarray->Normalized); + BEGIN_BATCH(1 + brw->curr.num_vertex_elements * 2, IGNORE_CLIPRECTS); + OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_ve * 2) - 2)); + for (i = 0; i < brw->vb.nr_ve; i++) { + const struct pipe_vertex_element *input = &brw->curr.vertex_element[i]; + uint32_t format = brw_translate_surface_format( input->src_format ); uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC; uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC; uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC; uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC; - switch (input->glarray->Size) { + switch (input->nr_components) { case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; @@ -352,11 +384,29 @@ static void brw_emit_vertices(struct brw_context *brw) ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT)); } ADVANCE_BATCH(); + return 0; +} + + +static int brw_emit_vertices( struct brw_context *brw ) +{ + int ret; + + ret = brw_emit_vertex_buffers( brw ); + if (ret) + return ret; + + ret = brw_emit_vertex_elements( brw ); + if (ret) + return ret; + + return 0; } + const struct brw_tracked_state brw_vertices = { .dirty = { - .mesa = 0, + .mesa = PIPE_NEW_INDEX_RANGE, .brw = BRW_NEW_BATCH | BRW_NEW_VERTICES, .cache = 0, }, @@ -364,104 +414,106 @@ const struct brw_tracked_state brw_vertices = { .emit = brw_emit_vertices, }; -static void brw_prepare_indices(struct brw_context *brw) + +static int brw_prepare_indices(struct brw_context *brw) { - const struct _mesa_index_buffer *index_buffer = brw->ib.ib; - GLuint ib_size; + struct pipe_buffer *index_buffer = brw->curr.index_buffer; struct brw_winsys_buffer *bo = NULL; - struct gl_buffer_object *bufferobj; GLuint offset; - GLuint ib_type_size; + GLuint index_size; + GLuint ib_size; + int ret; if (index_buffer == NULL) - return; + return 0; - ib_type_size = get_size(index_buffer->type); - ib_size = ib_type_size * index_buffer->count; - bufferobj = index_buffer->obj;; + if (DEBUG & DEBUG_VERTS) + debug_printf("%s: index_size:%d index_buffer->size:%d\n", + __FUNCTION__, + brw->curr.index_size, + brw->curr.index_buffer->size); - /* Turn into a proper VBO: - */ - if (!_mesa_is_bufferobj(bufferobj)) { - brw->ib.start_vertex_offset = 0; + ib_size = index_buffer->size; + index_size = brw->curr.index_size; - /* Get new bufferobj, offset: - */ - get_space(brw, ib_size, &bo, &offset); - - /* Straight upload + /* Turn userbuffer into a proper hardware buffer? + */ + if (brw_buffer_is_user_buffer(index_buffer)) { + struct pipe_buffer *upload_buf; + + ret = u_upload_buffer( brw->vb.upload_index, + 0, + ib_size, + index_buffer, + &offset, + &upload_buf ); + if (ret) + return ret; + + bo = brw_buffer(upload_buf)->bo; + brw->sws->bo_reference(bo); + pipe_buffer_reference( &upload_buf, NULL ); + + /* XXX: annotate the userbuffer with the upload information so + * that successive calls don't get re-uploaded. */ - brw_bo_subdata(bo, offset, ib_size, index_buffer->ptr); - - } else { - offset = (GLuint) (unsigned long) index_buffer->ptr; - brw->ib.start_vertex_offset = 0; + } + else { + bo = brw_buffer(index_buffer)->bo; + brw->sws->bo_reference(bo); + + ib_size = bo->size; + offset = 0; + } - /* If the index buffer isn't aligned to its element size, we have to - * rebase it into a temporary. - */ - if ((get_size(index_buffer->type) - 1) & offset) { - GLubyte *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_DRAW_ARB, - bufferobj); - map += offset; - - get_space(brw, ib_size, &bo, &offset); - - dri_bo_subdata(bo, offset, ib_size, map); - - ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj); - } else { - bo = intel_bufferobj_buffer(intel, intel_buffer_object(bufferobj), - INTEL_READ); - brw->sws->bo_reference(bo); - - /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading - * the index buffer state when we're just moving the start index - * of our drawing. - */ - brw->ib.start_vertex_offset = offset / ib_type_size; - offset = 0; - ib_size = bo->size; - } + /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the + * index buffer state when we're just moving the start index of our + * drawing. + * + * In gallium this will happen in the case where successive draw + * calls are made with (distinct?) userbuffers, but the upload_mgr + * places the data into a single winsys buffer. + * + * This statechange doesn't raise any state flags and is always + * just merged into the final draw packet: + */ + if (1) { + assert((offset & (index_size - 1)) == 0); + brw->ib.start_vertex_offset = offset / index_size; } + /* These statechanges trigger a new CMD_INDEX_BUFFER packet: + */ if (brw->ib.bo != bo || - brw->ib.offset != offset || brw->ib.size != ib_size) { - drm_intel_bo_unreference(brw->ib.bo); + brw->sws->bo_unreference(brw->ib.bo); brw->ib.bo = bo; - brw->ib.offset = offset; brw->ib.size = ib_size; - brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; - } else { - drm_intel_bo_unreference(bo); + } + else { + brw->sws->bo_unreference(bo); } brw_add_validated_bo(brw, brw->ib.bo); + return 0; } const struct brw_tracked_state brw_indices = { .dirty = { - .mesa = 0, - .brw = BRW_NEW_INDICES, + .mesa = PIPE_NEW_INDEX_BUFFER, + .brw = 0, .cache = 0, }, .prepare = brw_prepare_indices, }; -static void brw_emit_index_buffer(struct brw_context *brw) +static int brw_emit_index_buffer(struct brw_context *brw) { - const struct _mesa_index_buffer *index_buffer = brw->ib.ib; - - if (index_buffer == NULL) - return; - /* Emit the indexbuffer packet: */ + if (brw->ib.bo) { struct brw_indexbuffer ib; @@ -469,7 +521,7 @@ static void brw_emit_index_buffer(struct brw_context *brw) ib.header.bits.opcode = CMD_INDEX_BUFFER; ib.header.bits.length = sizeof(ib)/4 - 2; - ib.header.bits.index_format = get_index_type(index_buffer->type); + ib.header.bits.index_format = get_index_type(brw->ib.size); ib.header.bits.cut_index_enable = 0; BEGIN_BATCH(4, IGNORE_CLIPRECTS); @@ -483,6 +535,8 @@ static void brw_emit_index_buffer(struct brw_context *brw) OUT_BATCH( 0 ); ADVANCE_BATCH(); } + + return 0; } const struct brw_tracked_state brw_index_buffer = { diff --git a/src/gallium/drivers/i965/brw_eu.c b/src/gallium/drivers/i965/brw_eu.c index 1df561386e..df49d4b72f 100644 --- a/src/gallium/drivers/i965/brw_eu.c +++ b/src/gallium/drivers/i965/brw_eu.c @@ -29,6 +29,7 @@ * Keith Whitwell */ +#include "util/u_memory.h" #include "brw_context.h" #include "brw_defines.h" @@ -237,7 +238,7 @@ brw_resolve_cals(struct brw_compile *c) struct brw_glsl_call *call, *next; for (call = c->first_call; call; call = next) { next = call->next; - _mesa_free(call); + FREE(call); } c->first_call = NULL; } @@ -247,7 +248,7 @@ brw_resolve_cals(struct brw_compile *c) struct brw_glsl_label *label, *next; for (label = c->first_label; label; label = next) { next = label->next; - _mesa_free(label); + FREE(label); } c->first_label = NULL; } diff --git a/src/gallium/drivers/i965/brw_eu_debug.c b/src/gallium/drivers/i965/brw_eu_debug.c index ad7ec36e86..5989f5a04e 100644 --- a/src/gallium/drivers/i965/brw_eu_debug.c +++ b/src/gallium/drivers/i965/brw_eu_debug.c @@ -28,7 +28,8 @@ * Authors: * Keith Whitwell */ - + +#include "util/u_debug.h" #include "brw_eu.h" @@ -52,7 +53,7 @@ void brw_print_reg( struct brw_reg hwreg ) "f" }; - _mesa_printf("%s%s", + debug_printf("%s%s", hwreg.abs ? "abs/" : "", hwreg.negate ? "-" : ""); @@ -64,7 +65,7 @@ void brw_print_reg( struct brw_reg hwreg ) hwreg.hstride == BRW_HORIZONTAL_STRIDE_1 && hwreg.type == BRW_REGISTER_TYPE_F) { /* vector register */ - _mesa_printf("vec%d", hwreg.nr); + debug_printf("vec%d", hwreg.nr); } else if (hwreg.file == BRW_GENERAL_REGISTER_FILE && hwreg.vstride == BRW_VERTICAL_STRIDE_0 && @@ -72,13 +73,13 @@ void brw_print_reg( struct brw_reg hwreg ) hwreg.hstride == BRW_HORIZONTAL_STRIDE_0 && hwreg.type == BRW_REGISTER_TYPE_F) { /* "scalar" register */ - _mesa_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4); + debug_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4); } else if (hwreg.file == BRW_IMMEDIATE_VALUE) { - _mesa_printf("imm %f", hwreg.dw1.f); + debug_printf("imm %f", hwreg.dw1.f); } else { - _mesa_printf("%s%d.%d<%d;%d,%d>:%s", + debug_printf("%s%d.%d<%d;%d,%d>:%s", file[hwreg.file], hwreg.nr, hwreg.subnr / type_sz(hwreg.type), diff --git a/src/gallium/drivers/i965/brw_misc_state.c b/src/gallium/drivers/i965/brw_misc_state.c index 0f2612c181..98fec85c1d 100644 --- a/src/gallium/drivers/i965/brw_misc_state.c +++ b/src/gallium/drivers/i965/brw_misc_state.c @@ -315,24 +315,20 @@ const struct brw_tracked_state brw_polygon_stipple = { static void upload_polygon_stipple_offset(struct brw_context *brw) { - __DRIdrawablePrivate *dPriv = brw->intel.driDrawable; struct brw_polygon_stipple_offset bpso; memset(&bpso, 0, sizeof(bpso)); bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET; bpso.header.length = sizeof(bpso)/4-2; - /* If we're drawing to a system window (ctx->DrawBuffer->Name == 0), - * we have to invert the Y axis in order to match the OpenGL - * pixel coordinate system, and our offset must be matched - * to the window position. If we're drawing to a FBO - * (ctx->DrawBuffer->Name != 0), then our native pixel coordinate - * system works just fine, and there's no window system to - * worry about. + /* Never need to offset stipple coordinates. + * + * XXX: is it ever necessary to invert Y values? */ - if (brw->intel.ctx.DrawBuffer->Name == 0) { - bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31; - bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31; + if (0) { + int x = 0, y = 0, h = 0; + bpso.bits0.x_offset = (32 - (x & 31)) & 31; + bpso.bits0.y_offset = (32 - ((y + h) & 31)) & 31; } else { bpso.bits0.y_offset = 0; diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c index e85a1a9c1b..65e7151517 100644 --- a/src/gallium/drivers/i965/brw_pipe_flush.c +++ b/src/gallium/drivers/i965/brw_pipe_flush.c @@ -53,6 +53,9 @@ static void brw_note_fence( struct brw_context *brw, GLuint fence ) static GLuint brw_flush_cmd( void ) { struct brw_mi_flush flush; + + return ; + flush.opcode = CMD_MI_FLUSH; flush.pad = 0; flush.flags = BRW_FLUSH_STATE_CACHE; diff --git a/src/gallium/drivers/i965/brw_pipe_shader.c b/src/gallium/drivers/i965/brw_pipe_shader.c index fbb772d18c..8b61da763c 100644 --- a/src/gallium/drivers/i965/brw_pipe_shader.c +++ b/src/gallium/drivers/i965/brw_pipe_shader.c @@ -33,6 +33,25 @@ #include "brw_util.h" #include "brw_wm.h" + +/** + * Determine if the given fragment program uses GLSL features such + * as flow conditionals, loops, subroutines. + * Some GLSL shaders may use these features, others might not. + */ +GLboolean brw_wm_is_glsl(const struct brw_fragment_shader *fp) +{ + return (fp->info.insn_count[TGSI_OPCODE_ARL] > 0 || + fp->info.insn_count[TGSI_OPCODE_IF] > 0 || + fp->info.insn_count[TGSI_OPCODE_ENDIF] > 0 || /* redundant - IF */ + fp->info.insn_count[TGSI_OPCODE_CAL] > 0 || + fp->info.insn_count[TGSI_OPCODE_BRK] > 0 || /* redundant - BGNLOOP */ + fp->info.insn_count[TGSI_OPCODE_RET] > 0 || /* redundant - CAL */ + fp->info.insn_count[TGSI_OPCODE_BGNLOOP] > 0); +} + + + static void brwBindProgram( struct brw_context *brw, GLenum target, struct gl_program *prog ) diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c index b0928adbe4..d1d0d7cd43 100644 --- a/src/gallium/drivers/i965/brw_pipe_vertex.c +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -1,26 +1,11 @@ -static void brw_merge_inputs( struct brw_context *brw, - const struct gl_client_array *arrays[]) -{ - struct brw_vertex_info old = brw->vb.info; - GLuint i; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) - brw->sws->bo_unreference(brw->vb.inputs[i].bo); - memset(&brw->vb.inputs, 0, sizeof(brw->vb.inputs)); - memset(&brw->vb.info, 0, sizeof(brw->vb.info)); +void +brw_pipe_vertex_cleanup( struct brw_context *brw ) +{ for (i = 0; i < VERT_ATTRIB_MAX; i++) { - brw->vb.inputs[i].glarray = arrays[i]; - brw->vb.inputs[i].attrib = (gl_vert_attrib) i; - - if (arrays[i]->StrideB != 0) - brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) << - ((i%16) * 2); + brw->sws->bo_unreference(brw->vb.inputs[i].bo); + brw->vb.inputs[i].bo = NULL; } - - /* Raise statechanges if input sizes have changed. */ - if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0) - brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS; } diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h index 79d595d0ad..b0be0e1f8a 100644 --- a/src/gallium/drivers/i965/brw_screen.h +++ b/src/gallium/drivers/i965/brw_screen.h @@ -56,6 +56,14 @@ struct brw_transfer unsigned offset; }; +struct brw_buffer +{ + struct pipe_buffer base; + struct brw_winsys_buffer *bo; + void *ptr; + boolean is_user_buffer; +}; + /* * Cast wrappers @@ -72,5 +80,19 @@ brw_transfer(struct pipe_transfer *transfer) return (struct brw_transfer *)transfer; } +static INLINE struct brw_buffer * +brw_buffer(struct pipe_buffer *buffer) +{ + return (struct brw_buffer *)buffer; +} + + +/* Pipe buffer helpers + */ +static INLINE boolean +brw_buffer_is_user_buffer( const struct pipe_buffer *buf ) +{ + return ((const struct brw_buffer *)buf)->is_user_buffer; +} #endif /* BRW_SCREEN_H */ diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index 53e8f09e37..e2db2e76e6 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -134,7 +134,7 @@ static void upload_sf_prog(struct brw_context *brw) key.attrs = brw->vs.prog_data->outputs_written; /* BRW_NEW_REDUCED_PRIMITIVE */ - switch (brw->intel.reduced_primitive) { + switch (brw->reduced_primitive) { case GL_TRIANGLES: /* NOTE: We just use the edgeflag attribute as an indicator that * unfilled triangles are active. We don't actually do the diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c index 0e406f12e1..648a16a038 100644 --- a/src/gallium/drivers/i965/brw_sf_state.c +++ b/src/gallium/drivers/i965/brw_sf_state.c @@ -40,19 +40,12 @@ static void upload_sf_vp(struct brw_context *brw) const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF; struct brw_sf_viewport sfv; GLfloat y_scale, y_bias; - const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0); const GLfloat *v = ctx->Viewport._WindowMap.m; memset(&sfv, 0, sizeof(sfv)); - if (render_to_fbo) { - y_scale = 1.0; - y_bias = 0; - } - else { - y_scale = -1.0; - y_bias = ctx->DrawBuffer->Height; - } + y_scale = 1.0; + y_bias = 0; /* _NEW_VIEWPORT */ @@ -73,20 +66,11 @@ static void upload_sf_vp(struct brw_context *brw) * Note that the hardware's coordinates are inclusive, while Mesa's min is * inclusive but max is exclusive. */ - if (render_to_fbo) { - /* texmemory: Y=0=bottom */ - sfv.scissor.xmin = ctx->DrawBuffer->_Xmin; - sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1; - sfv.scissor.ymin = ctx->DrawBuffer->_Ymin; - sfv.scissor.ymax = ctx->DrawBuffer->_Ymax - 1; - } - else { - /* memory: Y=0=top */ - sfv.scissor.xmin = ctx->DrawBuffer->_Xmin; - sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1; - sfv.scissor.ymin = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax; - sfv.scissor.ymax = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin - 1; - } + /* Y=0=bottom */ + sfv.scissor.xmin = ctx->DrawBuffer->_Xmin; + sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1; + sfv.scissor.ymin = ctx->DrawBuffer->_Ymin; + sfv.scissor.ymax = ctx->DrawBuffer->_Ymax - 1; brw->sws->bo_unreference(brw->sf.vp_bo); brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 ); @@ -151,7 +135,7 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) /* _NEW_LIGHT */ key->provoking_vertex = ctx->Light.ProvokingVertex; - key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; + key->render_to_fbo = 1; } static struct brw_winsys_buffer * @@ -211,11 +195,6 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, else sf.sf5.front_winding = BRW_FRONTWINDING_CW; - /* The viewport is inverted for rendering to a FBO, and that inverts - * polygon front/back orientation. - */ - sf.sf5.front_winding ^= key->render_to_fbo; - switch (key->cull_face) { case GL_FRONT: sf.sf6.cull_mode = BRW_CULLMODE_FRONT; @@ -245,7 +224,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, sf.sf6.line_width = 0; /* _NEW_BUFFERS */ - key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; + key->render_to_fbo = 1; if (!key->render_to_fbo) { /* Rendering to an OpenGL window */ sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT; diff --git a/src/gallium/drivers/i965/brw_state.h b/src/gallium/drivers/i965/brw_state.h index 02657eaba7..9bf34c3fe4 100644 --- a/src/gallium/drivers/i965/brw_state.h +++ b/src/gallium/drivers/i965/brw_state.h @@ -109,8 +109,8 @@ struct brw_surface_key { /*********************************************************************** * brw_state.c */ -void brw_validate_state(struct brw_context *brw); -void brw_upload_state(struct brw_context *brw); +int brw_validate_state(struct brw_context *brw); +int brw_upload_state(struct brw_context *brw); void brw_init_state(struct brw_context *brw); void brw_destroy_state(struct brw_context *brw); @@ -157,7 +157,7 @@ void brw_state_cache_bo_delete(struct brw_cache *cache, struct brw_winsys_buffer /*********************************************************************** * brw_state_batch.c */ -#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->intel.batch, (s), sizeof(*(s)), IGNORE_CLIPRECTS) +#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->batch, (s), sizeof(*(s)), IGNORE_CLIPRECTS) #define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) ) GLboolean brw_cached_batch_struct( struct brw_context *brw, diff --git a/src/gallium/drivers/i965/brw_state_batch.c b/src/gallium/drivers/i965/brw_state_batch.c index b285837070..324fce5163 100644 --- a/src/gallium/drivers/i965/brw_state_batch.c +++ b/src/gallium/drivers/i965/brw_state_batch.c @@ -47,7 +47,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw, struct header *newheader = (struct header *)data; if (brw->emit_state_always) { - brw_batchbuffer_data(brw->intel.batch, data, sz, IGNORE_CLIPRECTS); + brw_batchbuffer_data(brw->batch, data, sz, IGNORE_CLIPRECTS); return GL_TRUE; } @@ -74,7 +74,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw, emit: memcpy(item->header, newheader, sz); - brw_batchbuffer_data(brw->intel.batch, data, sz, IGNORE_CLIPRECTS); + brw_batchbuffer_data(brw->batch, data, sz, IGNORE_CLIPRECTS); return GL_TRUE; } diff --git a/src/gallium/drivers/i965/brw_swtnl.c b/src/gallium/drivers/i965/brw_swtnl.c index 83f138f67a..d2df8af9f4 100644 --- a/src/gallium/drivers/i965/brw_swtnl.c +++ b/src/gallium/drivers/i965/brw_swtnl.c @@ -12,13 +12,13 @@ static GLboolean check_fallbacks( struct brw_context *brw, * use fallbacks. If we're forcing fallbacks, always * use fallfacks. */ - if (brw->intel.conformance_mode == 0) + if (brw->flags.no_swtnl) return GL_FALSE; - if (brw->intel.conformance_mode == 2) + if (brw->flags.force_swtnl) return GL_TRUE; - if (ctx->Polygon.SmoothFlag) { + if (brw->curr.rast->tmpl.smooth_polys) { for (i = 0; i < nr_prims; i++) if (reduced_prim[prim[i].mode] == GL_TRIANGLES) return GL_TRUE; diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index 82cd8007ac..51e23b9640 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -161,6 +161,13 @@ struct brw_winsys_screen { size_t size, const void *data); + /* XXX: couldn't this be handled by returning true/false on + * bo_emit_reloc? + */ + boolean (*check_aperture_space)( struct brw_winsys_screen *iws, + struct brw_winsys_buffer **buffers, + unsigned count ); + /** * Map a buffer. */ diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 284cf42f8b..4948ea0dff 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -158,7 +158,7 @@ static void do_wm_prog( struct brw_context *brw, memcpy(&c->key, key, sizeof(*key)); c->fp = fp; - c->env_param = brw->intel.ctx.FragmentProgram.Parameters; + c->env_param = NULL; /*brw->intel.ctx.FragmentProgram.Parameters;*/ brw_init_compile(brw, &c->func); diff --git a/src/gallium/drivers/i965/brw_wm.h b/src/gallium/drivers/i965/brw_wm.h index 18775830f9..e06de95a8a 100644 --- a/src/gallium/drivers/i965/brw_wm.h +++ b/src/gallium/drivers/i965/brw_wm.h @@ -131,9 +131,9 @@ struct brw_wm_ref { GLuint insn:24; }; -struct brw_wm_constref { +struct brw_wm_imm_ref { const struct brw_wm_ref *ref; - GLfloat constval; + GLfloat imm1f; }; @@ -232,8 +232,8 @@ struct brw_wm_compile { struct brw_wm_instruction instruction[BRW_WM_MAX_INSN]; GLuint nr_insns; - struct brw_wm_constref constref[BRW_WM_MAX_CONST]; - GLuint nr_constrefs; + struct brw_wm_imm_ref imm_ref[BRW_WM_MAX_CONST]; + GLuint nr_imm_refs; struct brw_wm_grf pass2_grf[BRW_WM_MAX_GRF/2]; diff --git a/src/gallium/drivers/i965/brw_wm_glsl.c b/src/gallium/drivers/i965/brw_wm_glsl.c index c4f0711793..a8de5fdd0b 100644 --- a/src/gallium/drivers/i965/brw_wm_glsl.c +++ b/src/gallium/drivers/i965/brw_wm_glsl.c @@ -7,34 +7,6 @@ static struct brw_reg get_dst_reg(struct brw_wm_compile *c, const struct prog_instruction *inst, GLuint component); -/** - * Determine if the given fragment program uses GLSL features such - * as flow conditionals, loops, subroutines. - * Some GLSL shaders may use these features, others might not. - */ -GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp) -{ - int i; - - for (i = 0; i < fp->Base.NumInstructions; i++) { - const struct prog_instruction *inst = &fp->Base.Instructions[i]; - switch (inst->Opcode) { - case OPCODE_ARL: - case OPCODE_IF: - case OPCODE_ENDIF: - case OPCODE_CAL: - case OPCODE_BRK: - case OPCODE_RET: - case OPCODE_BGNLOOP: - return GL_TRUE; - default: - break; - } - } - return GL_FALSE; -} - - static void reclaim_temps(struct brw_wm_compile *c); diff --git a/src/gallium/drivers/i965/brw_wm_pass0.c b/src/gallium/drivers/i965/brw_wm_pass0.c index de5f5fe821..31b0270e84 100644 --- a/src/gallium/drivers/i965/brw_wm_pass0.c +++ b/src/gallium/drivers/i965/brw_wm_pass0.c @@ -124,33 +124,33 @@ static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c, } -/** Return a ref to a constant/literal value */ -static const struct brw_wm_ref *get_const_ref( struct brw_wm_compile *c, - const GLfloat *constval ) +/** Return a ref to an immediate value */ +static const struct brw_wm_ref *get_imm_ref( struct brw_wm_compile *c, + const GLfloat *imm1f ) { GLuint i; /* Search for an existing const value matching the request: */ - for (i = 0; i < c->nr_constrefs; i++) { - if (c->constref[i].constval == *constval) - return c->constref[i].ref; + for (i = 0; i < c->nr_imm_refs; i++) { + if (c->imm_ref[i].imm_val == *imm1f) + return c->imm_ref[i].ref; } /* Else try to add a new one: */ - if (c->nr_constrefs < BRW_WM_MAX_CONST) { - GLuint i = c->nr_constrefs++; + if (c->nr_imm_refs < BRW_WM_MAX_IMM) { + GLuint i = c->nr_imm_refs++; - /* A constant is a special type of parameter: + /* An immediate is a special type of parameter: */ - c->constref[i].constval = *constval; - c->constref[i].ref = get_param_ref(c, constval); + c->imm_ref[i].imm_val = *imm_val; + c->imm_ref[i].ref = get_param_ref(c, imm_val); - return c->constref[i].ref; + return c->imm_ref[i].ref; } else { - _mesa_printf("%s: out of constrefs\n", __FUNCTION__); + _mesa_printf("%s: out of imm_refs\n", __FUNCTION__); c->prog_data.error = 1; return NULL; } @@ -200,7 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c, case PROGRAM_CONSTANT: /* These are invarient: */ - ref = get_const_ref(c, &plist->ParameterValues[idx][component]); + ref = get_imm_ref(c, &plist->ParameterValues[idx][component]); break; case PROGRAM_STATE_VAR: @@ -266,9 +266,9 @@ static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c, static const GLfloat const_one = 1.0; if (component == SWIZZLE_ZERO) - src_ref = get_const_ref(c, &const_zero); + src_ref = get_imm_ref(c, &const_zero); else if (component == SWIZZLE_ONE) - src_ref = get_const_ref(c, &const_one); + src_ref = get_imm_ref(c, &const_one); else src_ref = pass0_get_reg(c, src.File, src.Index, component); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index c76bff9181..ec9c859fcb 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -554,7 +554,8 @@ st_draw_vbo(GLcontext *ctx, /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) - vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); + if (!vbo_all_varyings_in_vbos(arrays)) + vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); /* sanity check for pointer arithmetic below */ assert(sizeof(arrays[0]->Ptr[0]) == 1); -- cgit v1.2.3 From efda453d646c767fbf0f8e85aa09178095ab04d6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 1 Nov 2009 17:55:16 +0000 Subject: i965g: the whole drivers/i965 directory is compiling That was a lot more work than I expected. Still the winsys to go, then the small matter of making it work and re-enabling the missing functionality. --- src/gallium/drivers/i965/brw_batchbuffer.c | 85 ++++++++++++------------ src/gallium/drivers/i965/brw_batchbuffer.h | 64 ++++++++++++++---- src/gallium/drivers/i965/brw_winsys.h | 102 +++++------------------------ 3 files changed, 108 insertions(+), 143 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index 1cffc0ab39..080c92046b 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -25,38 +25,42 @@ * **************************************************************************/ +#include "util/u_memory.h" + +#include "pipe/p_error.h" + #include "brw_batchbuffer.h" -#include "brw_decode.h" +//#include "brw_decode.h" #include "brw_reg.h" #include "brw_winsys.h" +#include "brw_debug.h" +#include "brw_structs.h" +#define BATCH_SIZE (32*1024) +#define USE_LOCAL_BUFFER 1 +#define ALWAYS_EMIT_MI_FLUSH 1 void brw_batchbuffer_reset(struct brw_batchbuffer *batch) { - struct intel_context *intel = batch->intel; - if (batch->buf != NULL) { - brw->sws->bo_unreference(batch->buf); + batch->sws->bo_unreference(batch->buf); batch->buf = NULL; } - if (!batch->buffer && intel->ttm == GL_TRUE) - batch->buffer = malloc (intel->maxBatchSize); + if (USE_LOCAL_BUFFER && !batch->buffer) + batch->buffer = MALLOC(BATCH_SIZE); batch->buf = batch->sws->bo_alloc(batch->sws, BRW_BUFFER_TYPE_BATCH, - intel->maxBatchSize, 4096); + BATCH_SIZE, 4096); if (batch->buffer) batch->map = batch->buffer; - else { - batch->sws->bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - } - batch->size = intel->maxBatchSize; + else + batch->map = batch->sws->bo_map(batch->buf, GL_TRUE); + + batch->size = BATCH_SIZE; batch->ptr = batch->map; - batch->dirty_state = ~0; - batch->cliprect_mode = IGNORE_CLIPRECTS; } struct brw_batchbuffer * @@ -74,79 +78,74 @@ void brw_batchbuffer_free(struct brw_batchbuffer *batch) { if (batch->map) { - dri_bo_unmap(batch->buf); + batch->sws->bo_unmap(batch->buf); batch->map = NULL; } - brw->sws->bo_unreference(batch->buf); + + batch->sws->bo_unreference(batch->buf); batch->buf = NULL; + + FREE(batch->buffer); FREE(batch); } void -_brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file, - int line) +_brw_batchbuffer_flush(struct brw_batchbuffer *batch, + const char *file, + int line) { - struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; if (used == 0) return; - if (intel->first_post_swapbuffers_batch == NULL) { - intel->first_post_swapbuffers_batch = intel->batch->buf; - batch->sws->bo_reference(intel->first_post_swapbuffers_batch); - } - - if (intel->first_post_swapbuffers_batch == NULL) { - intel->first_post_swapbuffers_batch = intel->batch->buf; - batch->sws->bo_reference(intel->first_post_swapbuffers_batch); - } - + /* Post-swap throttling done by the state tracker. + */ if (BRW_DEBUG & DEBUG_BATCH) - debug_printf("%s:%d: Batchbuffer flush with %db used\n", file, line, - used); + debug_printf("%s:%d: Batchbuffer flush with %db used\n", + file, line, used); -#if 0 - if (intel->always_flush_cache || 1) { - *(GLuint *) (batch->ptr) = ((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE); + if (ALWAYS_EMIT_MI_FLUSH) { + *(GLuint *) (batch->ptr) = ((MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE); batch->ptr += 4; used = batch->ptr - batch->map; } -#endif - - /* Round batchbuffer usage to 2 DWORDs. */ + /* Round batchbuffer usage to 2 DWORDs. + */ if ((used & 4) == 0) { *(GLuint *) (batch->ptr) = 0; /* noop */ batch->ptr += 4; used = batch->ptr - batch->map; } - /* Mark the end of the buffer. */ - *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END; /* noop */ + /* Mark the end of the buffer. + */ + *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END; batch->ptr += 4; used = batch->ptr - batch->map; batch->sws->bo_unmap(batch->buf); - batch->map = NULL; batch->ptr = NULL; batch->sws->bo_exec(batch->buf, used, NULL, 0, 0 ); - + +#if 0 if (BRW_DEBUG & DEBUG_BATCH) { void *ptr = batch->sws->bo_map(batch->buf, GL_FALSE); intel_decode(ptr, used / 4, batch->buf->offset, - batch->chipset); + batch->chipset.pci_id); batch->sws->bo_unmap(batch->buf); } +#endif if (BRW_DEBUG & DEBUG_SYNC) { /* Abuse map/unmap to achieve wait-for-fence. @@ -214,7 +213,7 @@ brw_batchbuffer_data(struct brw_batchbuffer *batch, if (ret) return ret; - __memcpy(batch->ptr, data, bytes); + memcpy(batch->ptr, data, bytes); batch->ptr += bytes; return 0; } diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 25bb9cefca..d687b79f93 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -18,6 +18,43 @@ enum cliprect_mode { REFERENCES_CLIPRECTS }; + + + +struct brw_batchbuffer { + + struct brw_winsys_screen *sws; + struct brw_winsys_buffer *buf; + + /* Main-memory copy of the batch-buffer, built up incrementally & + * then copied as one to the true buffer. + * + * XXX: is this still necessary? + * XXX: if so, can this be hidden inside the GEM-specific winsys code? + */ + uint8_t *buffer; + + /** + * Values exported to speed up the writing the batchbuffer, + * instead of having to go trough a accesor function for + * each dword written. + */ + /*{@*/ + uint8_t *map; + uint8_t *ptr; + size_t size; + struct { + uint8_t *end_ptr; + } emit; + + + size_t relocs; + size_t max_relocs; + /*@}*/ +}; + +struct brw_batchbuffer *brw_batchbuffer_alloc( struct brw_winsys_screen *sws ); + void brw_batchbuffer_free(struct brw_batchbuffer *batch); void _brw_batchbuffer_flush(struct brw_batchbuffer *batch, @@ -83,26 +120,27 @@ brw_batchbuffer_require_space(struct brw_batchbuffer *batch, /* Here are the crusty old macros, to be removed: */ #define BEGIN_BATCH(n, cliprect_mode) do { \ - brw_batchbuffer_require_space(brw->batch, (n)*4); \ -} while (0) + brw_batchbuffer_require_space(brw->batch, (n)*4); \ + } while (0) #define OUT_BATCH(d) brw_batchbuffer_emit_dword(brw->batch, d) #define OUT_RELOC(buf, read_domains, write_domain, delta) do { \ - assert((unsigned) (delta) < buf->size); \ - brw_batchbuffer_emit_reloc(brw->batch, buf, \ - read_domains, write_domain, delta); \ -} while (0) + assert((unsigned) (delta) < buf->size); \ + brw_batchbuffer_emit_reloc(brw->batch, buf, \ + read_domains, write_domain, delta); \ + } while (0) #ifdef DEBUG #define ADVANCE_BATCH() do { \ - unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr; \ - if (_n != 0) { \ - debug_printf("%s: %d too many bytes emitted to batch\n", __FUNCTION__, _n); \ - abort(); \ - } \ - brw->batch->emit.end_ptr = NULL; \ -} while(0) + unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr; \ + if (_n != 0) { \ + debug_printf("%s: %d too many bytes emitted to batch\n", \ + __FUNCTION__, _n); \ + abort(); \ + } \ + brw->batch->emit.end_ptr = NULL; \ + } while(0) #else #define ADVANCE_BATCH() #endif diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index 66a94b4b00..bc3d31196c 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -72,66 +72,8 @@ enum brw_buffer_type BRW_BUFFER_TYPE_STATE_CACHE, }; - -/* AKA winsys context: - */ -struct brw_batchbuffer { - - struct brw_winsys *iws; - struct brw_winsys_buffer *buf; - - /** - * Values exported to speed up the writing the batchbuffer, - * instead of having to go trough a accesor function for - * each dword written. - */ - /*{@*/ - uint8_t *map; - uint8_t *ptr; - size_t size; - struct { - uint8_t *end_ptr; - } emit; - - - size_t relocs; - size_t max_relocs; - /*@}*/ -}; - struct brw_winsys_screen { - /** - * Batchbuffer functions. - */ - /*@{*/ - /** - * Create a new batchbuffer. - */ - struct brw_batchbuffer *(*batchbuffer_create)(struct brw_winsys_screen *iws); - - /** - * Emit a relocation to a buffer. - * Target position in batchbuffer is the same as ptr. - */ - int (*batchbuffer_reloc)(struct brw_batchbuffer *batch, - unsigned offset, - struct brw_winsys_buffer *reloc, - unsigned pre_add, - enum brw_buffer_usage usage); - - /** - * Flush a bufferbatch. - */ - void (*batchbuffer_flush)(struct brw_batchbuffer *batch, - struct pipe_fence_handle **fence); - - /** - * Destroy a batchbuffer. - */ - void (*batchbuffer_destroy)(struct brw_batchbuffer *batch); - /*@}*/ - /** * Buffer functions. @@ -150,12 +92,21 @@ struct brw_winsys_screen { */ void (*bo_reference)( struct brw_winsys_buffer *buffer ); void (*bo_unreference)( struct brw_winsys_buffer *buffer ); - void (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, - unsigned domain, - unsigned a, - unsigned b, - unsigned offset, - struct brw_winsys_buffer *b2); + + /* XXX: parameter names!! + */ + int (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, + unsigned domain, + unsigned a, + unsigned b, + unsigned offset, + struct brw_winsys_buffer *b2); + + int (*bo_exec)( struct brw_winsys_buffer *buffer, + unsigned bytes_used, + void *foo, + int a, + int b ); void (*bo_subdata)(struct brw_winsys_buffer *buffer, size_t offset, @@ -186,29 +137,6 @@ struct brw_winsys_screen { /*@}*/ - /** - * Fence functions. - */ - /*@{*/ - /** - * Reference fence and set ptr to fence. - */ - void (*fence_reference)(struct brw_winsys *iws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence); - - /** - * Check if a fence has finished. - */ - int (*fence_signalled)(struct brw_winsys *iws, - struct pipe_fence_handle *fence); - - /** - * Wait on a fence to finish. - */ - int (*fence_finish)(struct brw_winsys *iws, - struct pipe_fence_handle *fence); - /*@}*/ /** -- cgit v1.2.3 From a277bb20debc413f6ccf46f529497bf8bafa64dd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 3 Nov 2009 23:16:02 +0000 Subject: i965g: convert read/write domain pairs into single usage value Easier to understand what's going on in the driver sources, convert stereotype usage values back to GEM read/write domain flags in the winsys. --- src/gallium/drivers/i965/brw_batchbuffer.c | 9 +++-- src/gallium/drivers/i965/brw_batchbuffer.h | 7 ++-- src/gallium/drivers/i965/brw_cc.c | 2 +- src/gallium/drivers/i965/brw_clip_state.c | 2 +- src/gallium/drivers/i965/brw_curbe.c | 2 +- src/gallium/drivers/i965/brw_draw_upload.c | 8 ++--- src/gallium/drivers/i965/brw_gs_state.c | 2 +- src/gallium/drivers/i965/brw_misc_state.c | 18 +++++----- src/gallium/drivers/i965/brw_pipe_query.c | 4 +-- src/gallium/drivers/i965/brw_sf_state.c | 4 +-- src/gallium/drivers/i965/brw_vs_state.c | 2 +- src/gallium/drivers/i965/brw_vs_surface_state.c | 2 +- src/gallium/drivers/i965/brw_winsys.h | 40 ++++++++++----------- src/gallium/drivers/i965/brw_wm_constant_buffer.c | 2 +- src/gallium/drivers/i965/brw_wm_sampler_state.c | 2 +- src/gallium/drivers/i965/brw_wm_state.c | 26 +++++++------- src/gallium/drivers/i965/brw_wm_surface_state.c | 6 ++-- src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c | 42 ++++++++++++++++++++--- 18 files changed, 104 insertions(+), 76 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index 72650cdb5d..fd6b34cb8a 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -168,9 +168,9 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, */ enum pipe_error brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, - struct brw_winsys_buffer *buffer, - uint32_t read_domains, uint32_t write_domain, - uint32_t delta) + struct brw_winsys_buffer *buffer, + uint32_t usage, + uint32_t delta) { int ret; @@ -182,8 +182,7 @@ brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, } ret = batch->sws->bo_emit_reloc(batch->buf, - read_domains, - write_domain, + usage, delta, batch->ptr - batch->map, buffer); diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index d687b79f93..b7186b3757 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -77,8 +77,7 @@ int brw_batchbuffer_data(struct brw_batchbuffer *batch, int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, struct brw_winsys_buffer *buffer, - uint32_t read_domains, - uint32_t write_domain, + enum brw_buffer_usage usage, uint32_t offset); /* Inline functions - might actually be better off with these @@ -125,10 +124,10 @@ brw_batchbuffer_require_space(struct brw_batchbuffer *batch, #define OUT_BATCH(d) brw_batchbuffer_emit_dword(brw->batch, d) -#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \ +#define OUT_RELOC(buf, usage, delta) do { \ assert((unsigned) (delta) < buf->size); \ brw_batchbuffer_emit_reloc(brw->batch, buf, \ - read_domains, write_domain, delta); \ + usage, delta); \ } while (0) #ifdef DEBUG diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index c6267e1c60..20967f0191 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -151,7 +151,7 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) /* Emit CC viewport relocation */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 0, offsetof(struct brw_cc_unit_state, cc4), brw->cc.vp_bo); diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c index 8be53e4bfb..6f8309fea9 100644 --- a/src/gallium/drivers/i965/brw_clip_state.c +++ b/src/gallium/drivers/i965/brw_clip_state.c @@ -150,7 +150,7 @@ clip_unit_create_from_key(struct brw_context *brw, /* Emit clip program relocation */ assert(brw->clip.prog_bo); brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, clip.thread0.grf_reg_count << 1, offsetof(struct brw_clip_unit_state, thread0), brw->clip.prog_bo); diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index ed5b250f82..3910174bda 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -323,7 +323,7 @@ static int emit_curbe_buffer(struct brw_context *brw) } else { OUT_BATCH((CMD_CONST_BUFFER << 16) | (1 << 8) | (2 - 2)); OUT_RELOC(brw->curbe.curbe_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, (sz - 1) + brw->curbe.curbe_offset); } ADVANCE_BATCH(); diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 040d8ca93a..f0b7c741c0 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -300,11 +300,11 @@ static int brw_emit_vertex_buffers( struct brw_context *brw ) BRW_VB0_ACCESS_VERTEXDATA | (brw->vb.vb[i].stride << BRW_VB0_PITCH_SHIFT)); OUT_RELOC(brw->vb.vb[i].bo, - I915_GEM_DOMAIN_VERTEX, 0, + BRW_USAGE_VERTEX, brw->vb.vb[i].offset); if (BRW_IS_IGDNG(brw)) { OUT_RELOC(brw->vb.vb[i].bo, - I915_GEM_DOMAIN_VERTEX, 0, + BRW_USAGE_VERTEX, brw->vb.vb[i].bo->size - 1); } else OUT_BATCH(brw->vb.vb[i].stride ? brw->vb.vb[i].vertex_count : 0); @@ -527,10 +527,10 @@ static int brw_emit_index_buffer(struct brw_context *brw) BEGIN_BATCH(4, IGNORE_CLIPRECTS); OUT_BATCH( ib.header.dword ); OUT_RELOC(brw->ib.bo, - I915_GEM_DOMAIN_VERTEX, 0, + BRW_USAGE_VERTEX, brw->ib.offset); OUT_RELOC(brw->ib.bo, - I915_GEM_DOMAIN_VERTEX, 0, + BRW_USAGE_VERTEX, brw->ib.offset + brw->ib.size - 1); OUT_BATCH( 0 ); ADVANCE_BATCH(); diff --git a/src/gallium/drivers/i965/brw_gs_state.c b/src/gallium/drivers/i965/brw_gs_state.c index 9046969394..f27f886a65 100644 --- a/src/gallium/drivers/i965/brw_gs_state.c +++ b/src/gallium/drivers/i965/brw_gs_state.c @@ -113,7 +113,7 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) if (key->prog_active) { /* Emit GS program relocation */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, gs.thread0.grf_reg_count << 1, offsetof(struct brw_gs_unit_state, thread0), brw->gs.prog_bo); diff --git a/src/gallium/drivers/i965/brw_misc_state.c b/src/gallium/drivers/i965/brw_misc_state.c index 06b9a2d2df..e786ea1100 100644 --- a/src/gallium/drivers/i965/brw_misc_state.c +++ b/src/gallium/drivers/i965/brw_misc_state.c @@ -111,7 +111,7 @@ static int upload_binding_table_pointers(struct brw_context *brw) OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2)); if (brw->vs.bind_bo != NULL) OUT_RELOC(brw->vs.bind_bo, - I915_GEM_DOMAIN_SAMPLER, 0, + BRW_USAGE_SAMPLER, 0); /* vs */ else OUT_BATCH(0); @@ -119,7 +119,7 @@ static int upload_binding_table_pointers(struct brw_context *brw) OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ OUT_RELOC(brw->wm.bind_bo, - I915_GEM_DOMAIN_SAMPLER, 0, + BRW_USAGE_SAMPLER, 0); /* wm/ps */ ADVANCE_BATCH(); return 0; @@ -147,25 +147,25 @@ static int upload_pipelined_state_pointers(struct brw_context *brw ) BEGIN_BATCH(7, IGNORE_CLIPRECTS); OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2)); OUT_RELOC(brw->vs.state_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 0); if (brw->gs.prog_active) OUT_RELOC(brw->gs.state_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 1); else OUT_BATCH(0); OUT_RELOC(brw->clip.state_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 1); OUT_RELOC(brw->sf.state_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 0); OUT_RELOC(brw->wm.state_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 0); OUT_RELOC(brw->cc.state_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 0); ADVANCE_BATCH(); @@ -288,7 +288,7 @@ static int emit_depthbuffer(struct brw_context *brw) ((surface->layout != PIPE_SURFACE_LAYOUT_LINEAR) << 27) | (BRW_SURFACE_2D << 29)); OUT_RELOC(bo, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + BRW_USAGE_DEPTH_BUFFER, surface->offset); OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) | ((pitch - 1) << 6) | diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 18a9b71af0..1fe2f4da4f 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -193,7 +193,7 @@ brw_emit_query_begin(struct brw_context *brw) * to pick up the results. */ OUT_RELOC(brw->query.bo, - I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, + BRW_USAGE_QUERY_RESULT, PIPE_CONTROL_GLOBAL_GTT_WRITE | ((brw->query.index * 2) * sizeof(uint64_t))); OUT_BATCH(0); @@ -234,7 +234,7 @@ brw_emit_query_end(struct brw_context *brw) PIPE_CONTROL_DEPTH_STALL | PIPE_CONTROL_WRITE_DEPTH_COUNT); OUT_RELOC(brw->query.bo, - I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, + BRW_USAGE_QUERY_RESULT, PIPE_CONTROL_GLOBAL_GTT_WRITE | ((brw->query.index * 2 + 1) * sizeof(uint64_t))); OUT_BATCH(0); diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c index 4ab5709d53..31343ff245 100644 --- a/src/gallium/drivers/i965/brw_sf_state.c +++ b/src/gallium/drivers/i965/brw_sf_state.c @@ -284,14 +284,14 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, */ /* Emit SF program relocation */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, sf.thread0.grf_reg_count << 1, offsetof(struct brw_sf_unit_state, thread0), brw->sf.prog_bo); /* Emit SF viewport relocation */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, sf.sf5.front_winding | (sf.sf5.viewport_transform << 1), offsetof(struct brw_sf_unit_state, sf5), brw->sf.vp_bo); diff --git a/src/gallium/drivers/i965/brw_vs_state.c b/src/gallium/drivers/i965/brw_vs_state.c index 6a2395dd96..26d5d005fa 100644 --- a/src/gallium/drivers/i965/brw_vs_state.c +++ b/src/gallium/drivers/i965/brw_vs_state.c @@ -149,7 +149,7 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) /* Emit VS program relocation */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, vs.thread0.grf_reg_count << 1, offsetof(struct brw_vs_unit_state, thread0), brw->vs.prog_bo); diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 9a9d47a8a3..32fb9b2a8b 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -170,7 +170,7 @@ brw_vs_get_binding_table(struct brw_context *brw) */ drm_intel_bo_emit_reloc(bind_bo, i * 4, brw->vs.surf_bo[i], 0, - I915_GEM_DOMAIN_INSTRUCTION, 0); + BRW_USAGE_STATE); } } diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index d19cd5d248..d0bd97d994 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -43,25 +43,22 @@ struct brw_winsys_buffer { unsigned size; }; +/* Describe the usage of a particular buffer in a relocation. The DRM + * winsys will translate these back to GEM read/write domain flags. + */ enum brw_buffer_usage { - I915_GEM_DOMAIN_RENDER, - I915_GEM_DOMAIN_SAMPLER, - I915_GEM_DOMAIN_VERTEX, - I915_GEM_DOMAIN_INSTRUCTION, - - - /* XXX: migrate from domains to explicit usage cases, eg below: - */ - - /* use on textures */ - BRW_USAGE_RENDER = 0x01, - BRW_USAGE_SAMPLER = 0x02, - BRW_USAGE_2D_TARGET = 0x04, - BRW_USAGE_2D_SOURCE = 0x08, - /* use on vertex */ - BRW_USAGE_VERTEX = 0x10, + BRW_USAGE_STATE, /* INSTRUCTION, 0 */ + BRW_USAGE_QUERY_RESULT, /* INSTRUCTION, INSTRUCTION */ + BRW_USAGE_RENDER_TARGET, /* RENDER, 0 */ + BRW_USAGE_DEPTH_BUFFER, /* RENDER, RENDER */ + BRW_USAGE_SAMPLER, /* SAMPLER, 0 */ + BRW_USAGE_VERTEX, /* VERTEX, 0 */ + BRW_USAGE_SCRATCH, /* 0, 0 */ }; +/* Should be possible to validate usages above against buffer creation + * types, below: + */ enum brw_buffer_type { BRW_BUFFER_TYPE_TEXTURE, @@ -70,10 +67,9 @@ enum brw_buffer_type BRW_BUFFER_TYPE_CURBE, BRW_BUFFER_TYPE_QUERY, BRW_BUFFER_TYPE_SHADER_CONSTANTS, - BRW_BUFFER_TYPE_WM_SCRATCH, + BRW_BUFFER_TYPE_SHADER_SCRATCH, BRW_BUFFER_TYPE_BATCH, BRW_BUFFER_TYPE_STATE_CACHE, - BRW_BUFFER_TYPE_MAX /* Count of possible values */ }; @@ -98,12 +94,12 @@ struct brw_winsys_screen { void (*bo_reference)( struct brw_winsys_buffer *buffer ); void (*bo_unreference)( struct brw_winsys_buffer *buffer ); - /* XXX: parameter names!! + /* delta -- added to b2->offset, and written into buffer + * offset -- location above value is written to within buffer */ int (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, - unsigned domain, - unsigned a, - unsigned b, + enum brw_buffer_usage usage, + unsigned delta, unsigned offset, struct brw_winsys_buffer *b2); diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c index 7d2533b104..50ecef29a4 100644 --- a/src/gallium/drivers/i965/brw_wm_constant_buffer.c +++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c @@ -37,7 +37,7 @@ brw_create_constant_surface( struct brw_context *brw, if (key->bo) { /* Emit relocation to surface contents */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_SAMPLER, 0, + BRW_USAGE_SAMPLER, 0, offsetof(struct brw_surface_state, ss1), key->bo); diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index d43968c85a..2909dd3876 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -182,7 +182,7 @@ static int upload_wm_samplers( struct brw_context *brw ) /* Emit SDC relocations */ for (i = 0; i < key.sampler_count; i++) { brw->sws->bo_emit_reloc(brw->wm.sampler_bo, - I915_GEM_DOMAIN_SAMPLER, 0, + BRW_USAGE_SAMPLER, 0, i * sizeof(struct brw_sampler_state) + offsetof(struct brw_sampler_state, ss2), diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c index 5cfa8fe2d1..ccbb647bcd 100644 --- a/src/gallium/drivers/i965/brw_wm_state.c +++ b/src/gallium/drivers/i965/brw_wm_state.c @@ -230,27 +230,27 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, /* Emit WM program relocation */ brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, - wm.thread0.grf_reg_count << 1, - offsetof(struct brw_wm_unit_state, thread0), - brw->wm.prog_bo); + BRW_USAGE_STATE, + wm.thread0.grf_reg_count << 1, + offsetof(struct brw_wm_unit_state, thread0), + brw->wm.prog_bo); /* Emit scratch space relocation */ if (key->total_scratch != 0) { brw->sws->bo_emit_reloc(bo, - 0, 0, - wm.thread2.per_thread_scratch_space, - offsetof(struct brw_wm_unit_state, thread2), - brw->wm.scratch_bo); + BRW_USAGE_SCRATCH, + wm.thread2.per_thread_scratch_space, + offsetof(struct brw_wm_unit_state, thread2), + brw->wm.scratch_bo); } /* Emit sampler state relocation */ if (key->sampler_count != 0) { brw->sws->bo_emit_reloc(bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, - wm.wm4.stats_enable | (wm.wm4.sampler_count << 2), - offsetof(struct brw_wm_unit_state, wm4), - brw->wm.sampler_bo); + BRW_USAGE_STATE, + wm.wm4.stats_enable | (wm.wm4.sampler_count << 2), + offsetof(struct brw_wm_unit_state, wm4), + brw->wm.sampler_bo); } return bo; @@ -277,7 +277,7 @@ static int upload_wm_unit( struct brw_context *brw ) } if (brw->wm.scratch_bo == NULL) { brw->wm.scratch_bo = brw->sws->bo_alloc(brw->sws, - BRW_BUFFER_TYPE_WM_SCRATCH, + BRW_BUFFER_TYPE_SHADER_SCRATCH, total, 4096); } diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index f55a6c4af2..e5a0ed7d61 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -60,7 +60,7 @@ brw_update_texture_surface( struct brw_context *brw, /* Emit relocation to surface contents */ brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf], - I915_GEM_DOMAIN_SAMPLER, 0, + BRW_USAGE_SAMPLER, 0, offsetof(struct brw_surface_state, ss1), tex->bo); @@ -117,7 +117,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, /* XXX: we will only be rendering to this surface: */ brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit], - I915_GEM_DOMAIN_RENDER, 0, + BRW_USAGE_RENDER_TARGET, ss.ss1.base_addr - surface->bo->offset[0], /* XXX */ offsetof(struct brw_surface_state, ss1), surface->bo); @@ -161,7 +161,7 @@ brw_wm_get_binding_table(struct brw_context *brw) /* Emit binding table relocations to surface state */ for (i = 0; i < brw->wm.nr_surfaces; i++) { brw->sws->bo_emit_reloc(bind_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, + BRW_USAGE_STATE, 0, i * sizeof(GLuint), brw->wm.surf_bo[i]); diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c index 5dbfd2e6b0..61717d2942 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c @@ -93,17 +93,51 @@ i965_libdrm_bo_unreference( struct brw_winsys_buffer *buffer ) */ static int i965_libdrm_bo_emit_reloc( struct brw_winsys_buffer *buffer, - unsigned domain, - unsigned a, - unsigned b, + enum brw_buffer_usage usage, + unsigned delta, unsigned offset, struct brw_winsys_buffer *buffer2) { struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer); struct i965_libdrm_buffer *buf2 = i965_libdrm_buffer(buffer2); + int read, write; int ret; - ret = dri_bo_emit_reloc( buf->bo, domain, a, b, offset, buf2->bo ); + switch (usage) { + case BRW_USAGE_STATE: + read = I915_GEM_DOMAIN_INSTRUCTION; + write = 0; + break; + case BRW_USAGE_QUERY_RESULT: + read = I915_GEM_DOMAIN_INSTRUCTION; + write = I915_GEM_DOMAIN_INSTRUCTION; + break; + case BRW_USAGE_RENDER_TARGET: + read = I915_GEM_DOMAIN_RENDER; + write = 0; + break; + case BRW_USAGE_DEPTH_BUFFER: + read = I915_GEM_DOMAIN_RENDER; + write = I915_GEM_DOMAIN_RENDER; + break; + case BRW_USAGE_SAMPLER: + read = I915_GEM_DOMAIN_SAMPLER; + write = 0; + break; + case BRW_USAGE_VERTEX: + read = I915_GEM_DOMAIN_VERTEX; + write = 0; + break; + case BRW_USAGE_SCRATCH: + read = 0; + write = 0; + break; + default: + assert(0); + return -1; + } + + ret = dri_bo_emit_reloc( buf->bo, read, write, delta, offset, buf2->bo ); if (ret) return -1; -- cgit v1.2.3 From 9706a83bc959ba8445d0258e47639b44da2238fc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Nov 2009 15:25:42 +0000 Subject: i965g: hook up more pipe_context functions --- src/gallium/drivers/i965/Makefile | 1 + src/gallium/drivers/i965/brw_batchbuffer.h | 2 -- src/gallium/drivers/i965/brw_context.c | 23 ++++++++++++- src/gallium/drivers/i965/brw_context.h | 3 ++ src/gallium/drivers/i965/brw_draw.c | 4 +-- src/gallium/drivers/i965/brw_pipe_flush.c | 51 ++++++++++++++++------------- src/gallium/drivers/i965/brw_pipe_misc.c | 21 ++++++++++-- src/gallium/drivers/i965/brw_pipe_query.c | 2 +- src/gallium/drivers/i965/brw_pipe_sampler.c | 6 +++- 9 files changed, 81 insertions(+), 32 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index 38b7a30944..b42d9a92c4 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -31,6 +31,7 @@ C_SOURCES = \ brw_pipe_query.c \ brw_pipe_shader.c \ brw_pipe_flush.c \ + brw_pipe_misc.c \ brw_pipe_rast.c \ brw_sf.c \ brw_sf_emit.c \ diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index b7186b3757..04ca6265ed 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -60,8 +60,6 @@ void brw_batchbuffer_free(struct brw_batchbuffer *batch); void _brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file, int line); -#define brw_batchbuffer_flush(batch) \ - _brw_batchbuffer_flush(batch, __FILE__, __LINE__) void brw_batchbuffer_reset(struct brw_batchbuffer *batch); diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index e10b7d8bf5..30cc243255 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -50,6 +50,17 @@ static void brw_destroy_context( struct pipe_context *pipe ) brw_draw_cleanup( brw ); + brw_pipe_blend_cleanup( brw ); + brw_pipe_depth_stencil_cleanup( brw ); + brw_pipe_framebuffer_cleanup( brw ); + brw_pipe_flush_cleanup( brw ); + brw_pipe_misc_cleanup( brw ); + brw_pipe_query_cleanup( brw ); + brw_pipe_rast_cleanup( brw ); + brw_pipe_sampler_cleanup( brw ); + brw_pipe_shader_cleanup( brw ); + brw_pipe_vertex_cleanup( brw ); + FREE(brw->wm.compile_data); for (i = 0; i < brw->curr.fb.nr_cbufs; i++) @@ -98,7 +109,17 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen) brw->base.destroy = brw_destroy_context; - brw_init_query( brw ); + brw_pipe_blend_init( brw ); + brw_pipe_depth_stencil_init( brw ); + brw_pipe_framebuffer_init( brw ); + brw_pipe_flush_init( brw ); + brw_pipe_misc_init( brw ); + brw_pipe_query_init( brw ); + brw_pipe_rast_init( brw ); + brw_pipe_sampler_init( brw ); + brw_pipe_shader_init( brw ); + brw_pipe_vertex_init( brw ); + brw_init_state( brw ); brw_draw_init( brw ); diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 97b2a8e27d..a4c48e6fd2 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -777,6 +777,9 @@ void brw_pipe_shader_cleanup( struct brw_context *brw ); void brw_pipe_vertex_cleanup( struct brw_context *brw ); +void brw_context_flush( struct brw_context *brw ); + + /* brw_urb.c */ int brw_upload_urb_fence(struct brw_context *brw); diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index b5fe7c9601..a2bed6256b 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -166,7 +166,7 @@ try_draw_range_elements(struct brw_context *brw, return ret; if (brw->flags.always_flush_batch) - brw_batchbuffer_flush(brw->batch); + brw_context_flush( brw ); return 0; } @@ -217,7 +217,7 @@ brw_draw_range_elements(struct pipe_context *pipe, /* Otherwise, flush and retry: */ if (ret != 0) { - brw_batchbuffer_flush(brw->batch); + brw_context_flush( brw ); ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); assert(ret == 0); } diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c index 1b43428760..9b52b56eae 100644 --- a/src/gallium/drivers/i965/brw_pipe_flush.c +++ b/src/gallium/drivers/i965/brw_pipe_flush.c @@ -2,50 +2,55 @@ #include "util/u_upload_mgr.h" #include "brw_context.h" +#include "brw_batchbuffer.h" -/** - * called from brw_batchbuffer_flush and children before sending a - * batchbuffer off. + +/* All batchbuffer flushes must go through this function. */ -static void brw_finish_batch(struct brw_context *brw) +void brw_context_flush( struct brw_context *brw ) { + /* + * + */ brw_emit_query_end(brw); -} + /* Move to the end of the current upload buffer so that we'll force choosing + * a new buffer next time. + */ + u_upload_flush( brw->vb.upload_vertex ); + u_upload_flush( brw->vb.upload_index ); -/** - * called from intelFlushBatchLocked - */ -static void brw_new_batch( struct brw_context *brw ) -{ - brw->curbe.need_new_bo = GL_TRUE; + _brw_batchbuffer_flush( brw->batch, __FILE__, __LINE__ ); /* Mark all context state as needing to be re-emitted. * This is probably not as severe as on 915, since almost all of our state * is just in referenced buffers. */ brw->state.dirty.brw |= BRW_NEW_CONTEXT; - brw->state.dirty.mesa |= ~0; brw->state.dirty.brw |= ~0; brw->state.dirty.cache |= ~0; - /* Move to the end of the current upload buffer so that we'll force choosing - * a new buffer next time. - */ - u_upload_flush( brw->vb.upload_vertex ); - u_upload_flush( brw->vb.upload_index ); + brw->curbe.need_new_bo = GL_TRUE; +} +static void +brw_flush( struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence ) +{ + brw_context_flush( brw_context( pipe ) ); + *fence = NULL; } -/* called from intelWaitForIdle() and intelFlush() - * - * For now, just flush everything. Could be smarter later. - */ -static GLuint brw_flush_cmd( void ) + +void brw_pipe_flush_init( struct brw_context *brw ) { - return ((MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE); + brw->base.flush = brw_flush; } +void brw_pipe_flush_cleanup( struct brw_context *brw ) +{ +} diff --git a/src/gallium/drivers/i965/brw_pipe_misc.c b/src/gallium/drivers/i965/brw_pipe_misc.c index fb8d7ecc59..a7ccde5917 100644 --- a/src/gallium/drivers/i965/brw_pipe_misc.c +++ b/src/gallium/drivers/i965/brw_pipe_misc.c @@ -1,7 +1,12 @@ +#include "brw_context.h" +#include "brw_structs.h" +#include "brw_defines.h" + static void brw_set_polygon_stipple( struct pipe_context *pipe, - const unsigned *stipple ) + const struct pipe_poly_stipple *stip ) { + struct brw_context *brw = brw_context(pipe); struct brw_polygon_stipple *bps = &brw->curr.bps; GLuint i; @@ -10,5 +15,17 @@ static void brw_set_polygon_stipple( struct pipe_context *pipe, bps->header.length = sizeof *bps/4-2; for (i = 0; i < 32; i++) - bps->stipple[i] = brw->curr.poly_stipple[i]; /* don't invert */ + bps->stipple[i] = stip->stipple[i]; /* don't invert */ +} + + + +void brw_pipe_misc_init( struct brw_context *brw ) +{ + brw->base.set_polygon_stipple = brw_set_polygon_stipple; +} + + +void brw_pipe_misc_cleanup( struct brw_context *brw ) +{ } diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 1fe2f4da4f..d3e173f5ec 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -137,7 +137,7 @@ brw_query_end(struct pipe_context *pipe, struct pipe_query *q) */ if (query->bo) { brw_emit_query_end(brw); - brw_batchbuffer_flush(brw->batch); + brw_context_flush( brw ); brw->sws->bo_unreference(brw->query.bo); brw->query.bo = NULL; diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index 08a5d22009..56cf95c4cd 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -156,10 +156,14 @@ static void brw_set_sampler_textures(struct pipe_context *pipe, } -void brw_sampler_init( struct brw_context *brw ) +void brw_pipe_sampler_init( struct brw_context *brw ) { brw->base.set_sampler_textures = brw_set_sampler_textures; brw->base.create_sampler_state = brw_create_sampler_state; brw->base.bind_sampler_state = brw_bind_sampler_state; brw->base.destroy_sampler_state = brw_destroy_sampler_state; } + +void brw_pipe_sampler_cleanup( struct brw_context *brw ) +{ +} -- cgit v1.2.3 From e18f223da710a6e1f6a08d346951ea66c6a1de99 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Nov 2009 20:26:41 +0000 Subject: i965g: hook up pipe_clear functions --- src/gallium/drivers/i965/Makefile | 1 + src/gallium/drivers/i965/brw_batchbuffer.h | 5 +- src/gallium/drivers/i965/brw_context.c | 2 + src/gallium/drivers/i965/brw_context.h | 2 + src/gallium/drivers/i965/brw_pipe_clear.c | 222 +++++++++++++++++++++++++++++ src/gallium/drivers/i965/brw_screen.h | 6 + 6 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 src/gallium/drivers/i965/brw_pipe_clear.c (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index d7262cf07c..870d67b13d 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -34,6 +34,7 @@ C_SOURCES = \ brw_pipe_misc.c \ brw_pipe_sampler.c \ brw_pipe_vertex.c \ + brw_pipe_clear.c \ brw_pipe_rast.c \ brw_sf.c \ brw_sf_emit.c \ diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 04ca6265ed..61374ffb00 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -1,10 +1,13 @@ #ifndef BRW_BATCHBUFFER_H #define BRW_BATCHBUFFER_H +#include "util/u_debug.h" + +#include "pipe/p_error.h" + #include "brw_types.h" #include "brw_winsys.h" #include "brw_reg.h" -#include "util/u_debug.h" #define BATCH_SZ 16384 #define BATCH_RESERVED 16 diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index 0692412b32..5accc858a9 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -60,6 +60,7 @@ static void brw_destroy_context( struct pipe_context *pipe ) brw_pipe_sampler_cleanup( brw ); brw_pipe_shader_cleanup( brw ); brw_pipe_vertex_cleanup( brw ); + brw_pipe_clear_cleanup( brw ); FREE(brw->wm.compile_data); @@ -120,6 +121,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen) brw_pipe_sampler_init( brw ); brw_pipe_shader_init( brw ); brw_pipe_vertex_init( brw ); + brw_pipe_clear_init( brw ); brw_init_state( brw ); brw_draw_init( brw ); diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index b6f77d1253..e32452f49a 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -764,6 +764,7 @@ void brw_pipe_rast_init( struct brw_context *brw ); void brw_pipe_sampler_init( struct brw_context *brw ); void brw_pipe_shader_init( struct brw_context *brw ); void brw_pipe_vertex_init( struct brw_context *brw ); +void brw_pipe_clear_init( struct brw_context *brw ); void brw_pipe_blend_cleanup( struct brw_context *brw ); void brw_pipe_depth_stencil_cleanup( struct brw_context *brw ); @@ -775,6 +776,7 @@ void brw_pipe_rast_cleanup( struct brw_context *brw ); void brw_pipe_sampler_cleanup( struct brw_context *brw ); void brw_pipe_shader_cleanup( struct brw_context *brw ); void brw_pipe_vertex_cleanup( struct brw_context *brw ); +void brw_pipe_clear_cleanup( struct brw_context *brw ); void brw_context_flush( struct brw_context *brw ); diff --git a/src/gallium/drivers/i965/brw_pipe_clear.c b/src/gallium/drivers/i965/brw_pipe_clear.c new file mode 100644 index 0000000000..f48175c0f7 --- /dev/null +++ b/src/gallium/drivers/i965/brw_pipe_clear.c @@ -0,0 +1,222 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_pack_color.h" + +#include "pipe/p_error.h" +#include "pipe/p_state.h" + +#include "brw_batchbuffer.h" +#include "brw_screen.h" +#include "brw_context.h" + +#define MASK16 0xffff +#define MASK24 0xffffff + + +/** + * Use blitting to clear the renderbuffers named by 'flags'. + * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field + * since that might include software renderbuffers or renderbuffers + * which we're clearing with triangles. + * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear + */ +static enum pipe_error +try_clear( struct brw_context *brw, + struct brw_surface *surface, + unsigned value ) +{ + uint32_t BR13, CMD; + int x1 = 0; + int y1 = 0; + int x2 = surface->base.width; + int y2 = surface->base.height; + int pitch = surface->pitch; + int cpp = surface->cpp; + + if (x2 == 0 || y2 == 0) + return 0; + + debug_printf("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + (void *)surface->bo, pitch * cpp, + surface->draw_offset, + x1, y1, x2 - x1, y2 - y1); + + BR13 = 0xf0 << 16; + CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA; + + /* Setup the blit command */ + if (cpp == 4) { + BR13 |= BR13_8888; + CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + } + else { + assert(cpp == 2); + BR13 |= BR13_565; + } + + assert(surface->tiling != BRW_TILING_Y); + + if (surface->tiling == BRW_TILING_X) { + CMD |= XY_DST_TILED; + pitch /= 4; + } + + BR13 |= (pitch * cpp); + + BEGIN_BATCH(6, 0); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y1 << 16) | x1); + OUT_BATCH((y2 << 16) | x2); + OUT_RELOC(surface->bo, + BRW_USAGE_BLIT_DEST, + surface->draw_offset); + OUT_BATCH(value); + ADVANCE_BATCH(); + + return 0; +} + + + + +static void color_clear(struct brw_context *brw, + struct brw_surface *bsurface, + const float *rgba ) +{ + enum pipe_error ret; + unsigned value; + + util_pack_color( rgba, bsurface->base.format, &value ); + + if (bsurface->cpp == 2) + value |= value << 16; + + ret = try_clear( brw, bsurface, value ); + + if (ret != 0) { + brw_context_flush( brw ); + ret = try_clear( brw, bsurface, value ); + assert( ret == 0 ); + } +} + +static void zstencil_clear(struct brw_context *brw, + struct brw_surface *bsurface, + double depth, + unsigned stencil ) +{ + enum pipe_error ret; + unsigned value; + + switch (bsurface->base.format) { + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + value = ((unsigned)(depth * MASK24) & MASK24); + break; + case PIPE_FORMAT_Z16_UNORM: + value = ((unsigned)(depth * MASK16) & MASK16); + break; + default: + assert(0); + return; + } + + switch (bsurface->base.format) { + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: + value = (value << 8) | stencil; + break; + + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + value = value | (stencil << 24); + break; + + case PIPE_FORMAT_Z16_UNORM: + value = value | (value << 16); + break; + + default: + break; + } + + ret = try_clear( brw, bsurface, value ); + + if (ret != 0) { + brw_context_flush( brw ); + ret = try_clear( brw, bsurface, value ); + assert( ret == 0 ); + } +} + + + +/** + * Clear the given surface to the specified value. + * No masking, no scissor (clear entire buffer). + */ +static void brw_clear(struct pipe_context *pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) +{ + struct brw_context *brw = brw_context( pipe ); + int i; + + if (buffers & PIPE_CLEAR_COLOR) { + for (i = 0; i < brw->curr.fb.nr_cbufs; i++) { + color_clear( brw, + brw_surface(brw->curr.fb.cbufs[i]), + rgba ); + } + } + + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + if (brw->curr.fb.zsbuf) { + zstencil_clear( brw, + brw_surface(brw->curr.fb.zsbuf), + depth, stencil ); + } + } +} + + +void brw_pipe_clear_init( struct brw_context *brw ) +{ + brw->base.clear = brw_clear; +} + + +void brw_pipe_clear_cleanup( struct brw_context *brw ) +{ +} diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h index 820c6a6679..f7267cc78a 100644 --- a/src/gallium/drivers/i965/brw_screen.h +++ b/src/gallium/drivers/i965/brw_screen.h @@ -89,7 +89,13 @@ union brw_surface_id { struct brw_surface { struct pipe_surface base; + union brw_surface_id id; + unsigned cpp; + unsigned pitch; + unsigned draw_offset; + unsigned tiling; + struct brw_surface_state ss; struct brw_winsys_buffer *bo; struct brw_surface *next, *prev; -- cgit v1.2.3 From b8bb48f4528227e36400cd1599a82bb73415ef60 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Nov 2009 21:05:34 +0000 Subject: i965g: fix up batchbuffer confusion --- src/gallium/drivers/i965/brw_batchbuffer.c | 35 +++++++++++++++++++----------- src/gallium/drivers/i965/brw_batchbuffer.h | 3 ++- src/gallium/drivers/i965/brw_pipe_flush.c | 3 ++- 3 files changed, 26 insertions(+), 15 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index fd6b34cb8a..bfb7175f75 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -36,25 +36,26 @@ #include "brw_debug.h" #include "brw_structs.h" -#define USE_LOCAL_BUFFER 1 +#define USE_MALLOC_BUFFER 1 #define ALWAYS_EMIT_MI_FLUSH 1 void brw_batchbuffer_reset(struct brw_batchbuffer *batch) { - if (batch->buf != NULL) { + if (batch->buf) { batch->sws->bo_unreference(batch->buf); batch->buf = NULL; } - if (USE_LOCAL_BUFFER && !batch->buffer) - batch->buffer = MALLOC(BRW_BATCH_SIZE); + if (batch->use_malloc_buffer && !batch->malloc_buffer) + batch->malloc_buffer = MALLOC(BRW_BATCH_SIZE); batch->buf = batch->sws->bo_alloc(batch->sws, BRW_BUFFER_TYPE_BATCH, BRW_BATCH_SIZE, 4096); - if (batch->buffer) - batch->map = batch->buffer; + + if (batch->malloc_buffer) + batch->map = batch->malloc_buffer; else batch->map = batch->sws->bo_map(batch->buf, GL_TRUE); @@ -67,6 +68,7 @@ brw_batchbuffer_alloc(struct brw_winsys_screen *sws) { struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer); + batch->use_malloc_buffer = USE_MALLOC_BUFFER; batch->sws = sws; brw_batchbuffer_reset(batch); @@ -76,16 +78,16 @@ brw_batchbuffer_alloc(struct brw_winsys_screen *sws) void brw_batchbuffer_free(struct brw_batchbuffer *batch) { - if (batch->map) { + if (batch->malloc_buffer) { + FREE(batch->malloc_buffer); + batch->map = NULL; + } + else if (batch->map) { batch->sws->bo_unmap(batch->buf); batch->map = NULL; } - batch->sws->bo_unreference(batch->buf); - batch->buf = NULL; - - FREE(batch->buffer); FREE(batch); } @@ -127,8 +129,15 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, batch->ptr += 4; used = batch->ptr - batch->map; - batch->sws->bo_unmap(batch->buf); - batch->map = NULL; + if (batch->use_malloc_buffer) { + batch->sws->bo_subdata(batch->buf, 0, used, batch->map ); + batch->map = NULL; + } + else { + batch->sws->bo_unmap(batch->buf); + batch->map = NULL; + } + batch->ptr = NULL; batch->sws->bo_exec(batch->buf, used ); diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 61374ffb00..1828324cc0 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -35,7 +35,8 @@ struct brw_batchbuffer { * XXX: is this still necessary? * XXX: if so, can this be hidden inside the GEM-specific winsys code? */ - uint8_t *buffer; + boolean use_malloc_buffer; + uint8_t *malloc_buffer; /** * Values exported to speed up the writing the batchbuffer, diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c index 6ae3c57765..9dff2beeb1 100644 --- a/src/gallium/drivers/i965/brw_pipe_flush.c +++ b/src/gallium/drivers/i965/brw_pipe_flush.c @@ -42,7 +42,8 @@ brw_flush( struct pipe_context *pipe, struct pipe_fence_handle **fence ) { brw_context_flush( brw_context( pipe ) ); - *fence = NULL; + if (fence) + *fence = NULL; } static unsigned brw_is_buffer_referenced(struct pipe_context *pipe, -- cgit v1.2.3 From 951fdac566c3f2124f82aa94da08f55a10608f25 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Nov 2009 21:35:29 +0000 Subject: i965g: pull in a copy of intel_decode.c for now With the stubbed out, non-hardware xlib winsys, trivial/clear runs and prints a plausible command stream --- src/gallium/drivers/i965/Makefile | 3 +- src/gallium/drivers/i965/brw_batchbuffer.c | 18 +- src/gallium/drivers/i965/brw_batchbuffer.h | 4 +- src/gallium/drivers/i965/brw_context.c | 2 +- src/gallium/drivers/i965/intel_decode.c | 1790 ++++++++++++++++++++++++++++ src/gallium/drivers/i965/intel_decode.h | 29 + 6 files changed, 1835 insertions(+), 11 deletions(-) create mode 100644 src/gallium/drivers/i965/intel_decode.c create mode 100644 src/gallium/drivers/i965/intel_decode.h (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile index 870d67b13d..2188a1d4bc 100644 --- a/src/gallium/drivers/i965/Makefile +++ b/src/gallium/drivers/i965/Makefile @@ -66,6 +66,7 @@ C_SOURCES = \ brw_screen_tex_layout.c \ brw_screen_texture.c \ brw_screen_surface.c \ - brw_batchbuffer.c + brw_batchbuffer.c \ + intel_decode.c include ../../Makefile.template diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index bfb7175f75..64d6754df5 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -35,6 +35,7 @@ #include "brw_winsys.h" #include "brw_debug.h" #include "brw_structs.h" +#include "intel_decode.h" #define USE_MALLOC_BUFFER 1 #define ALWAYS_EMIT_MI_FLUSH 1 @@ -47,9 +48,6 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch) batch->buf = NULL; } - if (batch->use_malloc_buffer && !batch->malloc_buffer) - batch->malloc_buffer = MALLOC(BRW_BATCH_SIZE); - batch->buf = batch->sws->bo_alloc(batch->sws, BRW_BUFFER_TYPE_BATCH, BRW_BATCH_SIZE, 4096); @@ -64,12 +62,18 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch) } struct brw_batchbuffer * -brw_batchbuffer_alloc(struct brw_winsys_screen *sws) +brw_batchbuffer_alloc(struct brw_winsys_screen *sws, + struct brw_chipset chipset) { struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer); batch->use_malloc_buffer = USE_MALLOC_BUFFER; + if (batch->use_malloc_buffer) { + batch->malloc_buffer = MALLOC(BRW_BATCH_SIZE); + } + batch->sws = sws; + batch->chipset = chipset; brw_batchbuffer_reset(batch); return batch; @@ -142,18 +146,16 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, batch->sws->bo_exec(batch->buf, used ); -#if 0 - if (BRW_DEBUG & DEBUG_BATCH) { + if (1 /*BRW_DEBUG & DEBUG_BATCH*/) { void *ptr = batch->sws->bo_map(batch->buf, GL_FALSE); intel_decode(ptr, used / 4, - batch->buf->offset, + batch->buf->offset[0], batch->chipset.pci_id); batch->sws->bo_unmap(batch->buf); } -#endif if (BRW_DEBUG & DEBUG_SYNC) { /* Abuse map/unmap to achieve wait-for-fence. diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 1828324cc0..b051638296 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -28,6 +28,7 @@ struct brw_batchbuffer { struct brw_winsys_screen *sws; struct brw_winsys_buffer *buf; + struct brw_chipset chipset; /* Main-memory copy of the batch-buffer, built up incrementally & * then copied as one to the true buffer. @@ -57,7 +58,8 @@ struct brw_batchbuffer { /*@}*/ }; -struct brw_batchbuffer *brw_batchbuffer_alloc( struct brw_winsys_screen *sws ); +struct brw_batchbuffer *brw_batchbuffer_alloc( struct brw_winsys_screen *sws, + struct brw_chipset chipset ); void brw_batchbuffer_free(struct brw_batchbuffer *batch); diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index cd8963bebc..aaf7d1834e 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -133,7 +133,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen) make_empty_list(&brw->query.active_head); - brw->batch = brw_batchbuffer_alloc( brw->sws ); + brw->batch = brw_batchbuffer_alloc( brw->sws, brw->chipset ); if (brw->batch == NULL) goto fail; diff --git a/src/gallium/drivers/i965/intel_decode.c b/src/gallium/drivers/i965/intel_decode.c new file mode 100644 index 0000000000..1fb1b66cc8 --- /dev/null +++ b/src/gallium/drivers/i965/intel_decode.c @@ -0,0 +1,1790 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +/** @file intel_decode.c + * This file contains code to print out batchbuffer contents in a + * human-readable format. + * + * The current version only supports i915 packets, and only pretty-prints a + * subset of them. The intention is for it to make just a best attempt to + * decode, but never crash in the process. + */ + +#include +#include +#include +#include + +#include "intel_decode.h" + +/*#include "intel_chipset.h"*/ +#define IS_965(x) 1 /* XXX */ +#define IS_9XX(x) 1 /* XXX */ + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x:%s ", hw_offset + index * 4, data[index], + index == 0 ? "" : " "); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int len_mask; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 0, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 0, 1, 1, "MI_FLUSH" }, + { 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 0, 1, 1, "MI_NOOP" }, + { 0x11, 0x3f, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 0, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 0x3f, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 0x3f, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 0x3f, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 0x3f, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 0, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1f800000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & opcodes_mi[opcode].len_mask) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length (%d) in %s, [%d, %d]\n", + len, opcodes_mi[opcode].name, + opcodes_mi[opcode].min_len, + opcodes_mi[opcode].max_len); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode, len; + char *format = NULL; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled, dst tile %d)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis", + (data[0] >> 11) & 1); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + (short)(data[1] & 0xffff), + data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[3] & 0xffff, data[3] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled, " + "src tile %d, dst tile %d)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis", + (data[0] >> 15) & 1, + (data[0] >> 11) & 1); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + (short)(data[1] & 0xffff), + data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[3] & 0xffff, data[3] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + (short)(data[6] & 0xffff)); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int i; + + len = 1; + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_COORD_SET_I830\n"); + return 1; + case 0x0a: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_CUBE_I830\n"); + return 1; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** Sets the string dstname to describe the destination of the PS instruction */ +static void +i915_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask) +{ + uint32_t a0 = data[i]; + int dst_nr = (a0 >> 14) & 0xf; + char dstmask[8]; + char *sat; + + if (do_mask) { + if (((a0 >> 10) & 0xf) == 0xf) { + dstmask[0] = 0; + } else { + int dstmask_index = 0; + + dstmask[dstmask_index++] = '.'; + if (a0 & (1 << 10)) + dstmask[dstmask_index++] = 'x'; + if (a0 & (1 << 11)) + dstmask[dstmask_index++] = 'y'; + if (a0 & (1 << 12)) + dstmask[dstmask_index++] = 'z'; + if (a0 & (1 << 13)) + dstmask[dstmask_index++] = 'w'; + dstmask[dstmask_index++] = 0; + } + + if (a0 & (1 << 22)) + sat = ".sat"; + else + sat = ""; + } else { + dstmask[0] = 0; + sat = ""; + } + + switch ((a0 >> 19) & 0x7) { + case 0: + if (dst_nr > 15) + fprintf(out, "bad destination reg R%d\n", dst_nr); + sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat); + break; + case 4: + if (dst_nr > 0) + fprintf(out, "bad destination reg oC%d\n", dst_nr); + sprintf(dstname, "oC%s%s", dstmask, sat); + break; + case 5: + if (dst_nr > 0) + fprintf(out, "bad destination reg oD%d\n", dst_nr); + sprintf(dstname, "oD%s%s", dstmask, sat); + break; + case 6: + if (dst_nr > 2) + fprintf(out, "bad destination reg U%d\n", dst_nr); + sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat); + break; + default: + sprintf(dstname, "RESERVED"); + break; + } +} + +static char * +i915_get_channel_swizzle(uint32_t select) +{ + switch (select & 0x7) { + case 0: + return (select & 8) ? "-x" : "x"; + case 1: + return (select & 8) ? "-y" : "y"; + case 2: + return (select & 8) ? "-z" : "z"; + case 3: + return (select & 8) ? "-w" : "w"; + case 4: + return (select & 8) ? "-0" : "0"; + case 5: + return (select & 8) ? "-1" : "1"; + default: + return (select & 8) ? "-bad" : "bad"; + } +} + +static void +i915_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name) +{ + switch (src_type) { + case 0: + sprintf(name, "R%d", src_nr); + if (src_nr > 15) + fprintf(out, "bad src reg %s\n", name); + break; + case 1: + if (src_nr < 8) + sprintf(name, "T%d", src_nr); + else if (src_nr == 8) + sprintf(name, "DIFFUSE"); + else if (src_nr == 9) + sprintf(name, "SPECULAR"); + else if (src_nr == 10) + sprintf(name, "FOG"); + else { + fprintf(out, "bad src reg T%d\n", src_nr); + sprintf(name, "RESERVED"); + } + break; + case 2: + sprintf(name, "C%d", src_nr); + if (src_nr > 31) + fprintf(out, "bad src reg %s\n", name); + break; + case 4: + sprintf(name, "oC"); + if (src_nr > 0) + fprintf(out, "bad src reg oC%d\n", src_nr); + break; + case 5: + sprintf(name, "oD"); + if (src_nr > 0) + fprintf(out, "bad src reg oD%d\n", src_nr); + break; + case 6: + sprintf(name, "U%d", src_nr); + if (src_nr > 2) + fprintf(out, "bad src reg %s\n", name); + break; + default: + fprintf(out, "bad src reg type %d\n", src_type); + sprintf(name, "RESERVED"); + break; + } +} + +static void +i915_get_instruction_src0(uint32_t *data, int i, char *srcname) +{ + uint32_t a0 = data[i]; + uint32_t a1 = data[i + 1]; + int src_nr = (a0 >> 2) & 0x1f; + char *swizzle_x = i915_get_channel_swizzle((a1 >> 28) & 0xf); + char *swizzle_y = i915_get_channel_swizzle((a1 >> 24) & 0xf); + char *swizzle_z = i915_get_channel_swizzle((a1 >> 20) & 0xf); + char *swizzle_w = i915_get_channel_swizzle((a1 >> 16) & 0xf); + char swizzle[100]; + + i915_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname); + sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); + if (strcmp(swizzle, ".xyzw") != 0) + strcat(srcname, swizzle); +} + +static void +i915_get_instruction_src1(uint32_t *data, int i, char *srcname) +{ + uint32_t a1 = data[i + 1]; + uint32_t a2 = data[i + 2]; + int src_nr = (a1 >> 8) & 0x1f; + char *swizzle_x = i915_get_channel_swizzle((a1 >> 4) & 0xf); + char *swizzle_y = i915_get_channel_swizzle((a1 >> 0) & 0xf); + char *swizzle_z = i915_get_channel_swizzle((a2 >> 28) & 0xf); + char *swizzle_w = i915_get_channel_swizzle((a2 >> 24) & 0xf); + char swizzle[100]; + + i915_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname); + sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); + if (strcmp(swizzle, ".xyzw") != 0) + strcat(srcname, swizzle); +} + +static void +i915_get_instruction_src2(uint32_t *data, int i, char *srcname) +{ + uint32_t a2 = data[i + 2]; + int src_nr = (a2 >> 16) & 0x1f; + char *swizzle_x = i915_get_channel_swizzle((a2 >> 12) & 0xf); + char *swizzle_y = i915_get_channel_swizzle((a2 >> 8) & 0xf); + char *swizzle_z = i915_get_channel_swizzle((a2 >> 4) & 0xf); + char *swizzle_w = i915_get_channel_swizzle((a2 >> 0) & 0xf); + char swizzle[100]; + + i915_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname); + sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); + if (strcmp(swizzle, ".xyzw") != 0) + strcat(srcname, swizzle); +} + +static void +i915_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name) +{ + switch (src_type) { + case 0: + sprintf(name, "R%d", src_nr); + if (src_nr > 15) + fprintf(out, "bad src reg %s\n", name); + break; + case 1: + if (src_nr < 8) + sprintf(name, "T%d", src_nr); + else if (src_nr == 8) + sprintf(name, "DIFFUSE"); + else if (src_nr == 9) + sprintf(name, "SPECULAR"); + else if (src_nr == 10) + sprintf(name, "FOG"); + else { + fprintf(out, "bad src reg T%d\n", src_nr); + sprintf(name, "RESERVED"); + } + break; + case 4: + sprintf(name, "oC"); + if (src_nr > 0) + fprintf(out, "bad src reg oC%d\n", src_nr); + break; + case 5: + sprintf(name, "oD"); + if (src_nr > 0) + fprintf(out, "bad src reg oD%d\n", src_nr); + break; + default: + fprintf(out, "bad src reg type %d\n", src_type); + sprintf(name, "RESERVED"); + break; + } +} + +static void +i915_decode_alu1(uint32_t *data, uint32_t hw_offset, + int i, char *instr_prefix, char *op_name) +{ + char dst[100], src0[100]; + + i915_get_instruction_dst(data, i, dst, 1); + i915_get_instruction_src0(data, i, src0); + + instr_out(data, hw_offset, i++, "%s: %s %s, %s\n", instr_prefix, + op_name, dst, src0); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); +} + +static void +i915_decode_alu2(uint32_t *data, uint32_t hw_offset, + int i, char *instr_prefix, char *op_name) +{ + char dst[100], src0[100], src1[100]; + + i915_get_instruction_dst(data, i, dst, 1); + i915_get_instruction_src0(data, i, src0); + i915_get_instruction_src1(data, i, src1); + + instr_out(data, hw_offset, i++, "%s: %s %s, %s, %s\n", instr_prefix, + op_name, dst, src0, src1); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); +} + +static void +i915_decode_alu3(uint32_t *data, uint32_t hw_offset, + int i, char *instr_prefix, char *op_name) +{ + char dst[100], src0[100], src1[100], src2[100]; + + i915_get_instruction_dst(data, i, dst, 1); + i915_get_instruction_src0(data, i, src0); + i915_get_instruction_src1(data, i, src1); + i915_get_instruction_src2(data, i, src2); + + instr_out(data, hw_offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix, + op_name, dst, src0, src1, src2); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); +} + +static void +i915_decode_tex(uint32_t *data, uint32_t hw_offset, int i, char *instr_prefix, + char *tex_name) +{ + uint32_t t0 = data[i]; + uint32_t t1 = data[i + 1]; + char dst_name[100]; + char addr_name[100]; + int sampler_nr; + + i915_get_instruction_dst(data, i, dst_name, 0); + i915_get_instruction_addr((t1 >> 24) & 0x7, + (t1 >> 17) & 0xf, + addr_name); + sampler_nr = t0 & 0xf; + + instr_out(data, hw_offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix, + tex_name, dst_name, sampler_nr, addr_name); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); +} + +static void +i915_decode_dcl(uint32_t *data, uint32_t hw_offset, int i, char *instr_prefix) +{ + uint32_t d0 = data[i]; + char *sampletype; + int dcl_nr = (d0 >> 14) & 0xf; + char *dcl_x = d0 & (1 << 10) ? "x" : ""; + char *dcl_y = d0 & (1 << 11) ? "y" : ""; + char *dcl_z = d0 & (1 << 12) ? "z" : ""; + char *dcl_w = d0 & (1 << 13) ? "w" : ""; + char dcl_mask[10]; + + switch ((d0 >> 19) & 0x3) { + case 1: + sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w); + if (strcmp(dcl_mask, ".") == 0) + fprintf(out, "bad (empty) dcl mask\n"); + + if (dcl_nr > 10) + fprintf(out, "bad T%d dcl register number\n", dcl_nr); + if (dcl_nr < 8) { + if (strcmp(dcl_mask, ".x") != 0 && + strcmp(dcl_mask, ".xy") != 0 && + strcmp(dcl_mask, ".xz") != 0 && + strcmp(dcl_mask, ".w") != 0 && + strcmp(dcl_mask, ".xyzw") != 0) { + fprintf(out, "bad T%d.%s dcl mask\n", dcl_nr, dcl_mask); + } + instr_out(data, hw_offset, i++, "%s: DCL T%d%s\n", instr_prefix, + dcl_nr, dcl_mask); + } else { + if (strcmp(dcl_mask, ".xz") == 0) + fprintf(out, "errataed bad dcl mask %s\n", dcl_mask); + else if (strcmp(dcl_mask, ".xw") == 0) + fprintf(out, "errataed bad dcl mask %s\n", dcl_mask); + else if (strcmp(dcl_mask, ".xzw") == 0) + fprintf(out, "errataed bad dcl mask %s\n", dcl_mask); + + if (dcl_nr == 8) { + instr_out(data, hw_offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix, + dcl_mask); + } else if (dcl_nr == 9) { + instr_out(data, hw_offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix, + dcl_mask); + } else if (dcl_nr == 10) { + instr_out(data, hw_offset, i++, "%s: DCL FOG%s\n", instr_prefix, + dcl_mask); + } + } + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + break; + case 3: + switch ((d0 >> 22) & 0x3) { + case 0: + sampletype = "2D"; + break; + case 1: + sampletype = "CUBE"; + break; + case 2: + sampletype = "3D"; + break; + default: + sampletype = "RESERVED"; + break; + } + if (dcl_nr > 15) + fprintf(out, "bad S%d dcl register number\n", dcl_nr); + instr_out(data, hw_offset, i++, "%s: DCL S%d %s\n", instr_prefix, + dcl_nr, sampletype); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + break; + default: + instr_out(data, hw_offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + } +} + +static void +i915_decode_instruction(uint32_t *data, uint32_t hw_offset, + int i, char *instr_prefix) +{ + switch ((data[i] >> 24) & 0x1f) { + case 0x0: + instr_out(data, hw_offset, i++, "%s: NOP\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + break; + case 0x01: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "ADD"); + break; + case 0x02: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "MOV"); + break; + case 0x03: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "MUL"); + break; + case 0x04: + i915_decode_alu3(data, hw_offset, i, instr_prefix, "MAD"); + break; + case 0x05: + i915_decode_alu3(data, hw_offset, i, instr_prefix, "DP2ADD"); + break; + case 0x06: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "DP3"); + break; + case 0x07: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "DP4"); + break; + case 0x08: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "FRC"); + break; + case 0x09: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "RCP"); + break; + case 0x0a: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "RSQ"); + break; + case 0x0b: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "EXP"); + break; + case 0x0c: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "LOG"); + break; + case 0x0d: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "CMP"); + break; + case 0x0e: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "MIN"); + break; + case 0x0f: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "MAX"); + break; + case 0x10: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "FLR"); + break; + case 0x11: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "MOD"); + break; + case 0x12: + i915_decode_alu1(data, hw_offset, i, instr_prefix, "TRC"); + break; + case 0x13: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "SGE"); + break; + case 0x14: + i915_decode_alu2(data, hw_offset, i, instr_prefix, "SLT"); + break; + case 0x15: + i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLD"); + break; + case 0x16: + i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLDP"); + break; + case 0x17: + i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLDB"); + break; + case 0x19: + i915_decode_dcl(data, hw_offset, i, instr_prefix); + break; + default: + instr_out(data, hw_offset, i++, "%s: unknown\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + instr_out(data, hw_offset, i++, "%s\n", instr_prefix); + break; + } +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + char *format; + + struct { + uint32_t opcode; + int i830_only; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 0, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 0, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 0, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 0, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 0, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 0, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 0, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 0, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 0, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 0, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 0, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 0, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 0, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + { 0x8c, 1, 2, 2, "3DSTATE_MAP_COORD_TRANSFORM_I830" }, + { 0x8b, 1, 2, 2, "3DSTATE_MAP_VERTEX_TRANSFORM_I830" }, + { 0x8d, 1, 3, 3, "3DSTATE_W_STATE_I830" }, + { 0x01, 1, 2, 2, "3DSTATE_COLOR_FACTOR_I830" }, + { 0x02, 1, 2, 2, "3DSTATE_MAP_COORD_SETBIND_I830" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + instr_out(data, hw_offset, 1, "mask\n"); + + i = 2; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 2; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + char instr_prefix[10]; + + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_PROGRAM"); + sprintf(instr_prefix, "PS%03d", instr); + i915_decode_instruction(data, hw_offset, i, instr_prefix); + i += 3; + } + return len; + case 0x01: + if (i830) + break; + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + instr_out(data, hw_offset, 1, "mask\n"); + len = (data[0] & 0x0000003f) + 2; + i = 2; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + case 0x85: + len = (data[0] & 0x0000000f) + 2; + + if (len != 2) + fprintf(out, "Bad count in 3DSTATE_DEST_BUFFER_VARIABLES\n"); + if (count < 2) + BUFFER_FAIL(count, len, "3DSTATE_DEST_BUFFER_VARIABLES"); + + instr_out(data, hw_offset, 0, + "3DSTATE_DEST_BUFFER_VARIABLES\n"); + + switch ((data[1] >> 8) & 0xf) { + case 0x0: format = "g8"; break; + case 0x1: format = "x1r5g5b5"; break; + case 0x2: format = "r5g6b5"; break; + case 0x3: format = "a8r8g8b8"; break; + case 0x4: format = "ycrcb_swapy"; break; + case 0x5: format = "ycrcb_normal"; break; + case 0x6: format = "ycrcb_swapuv"; break; + case 0x7: format = "ycrcb_swapuvy"; break; + case 0x8: format = "a4r4g4b4"; break; + case 0x9: format = "a1r5g5b5"; break; + case 0xa: format = "a2r10g10b10"; break; + default: format = "BAD"; break; + } + instr_out(data, hw_offset, 1, "%s format, early Z %sabled\n", + format, + (data[1] & (1 << 31)) ? "en" : "dis"); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (opcodes_3d_1d[opcode].i830_only && !i830) + continue; + + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures, 0); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static const char * +get_965_surfacetype(unsigned int surfacetype) +{ + switch (surfacetype) { + case 0: return "1D"; + case 1: return "2D"; + case 2: return "3D"; + case 3: return "CUBE"; + case 4: return "BUFFER"; + case 7: return "NULL"; + default: return "unknown"; + } +} + +static const char * +get_965_depthformat(unsigned int depthformat) +{ + switch (depthformat) { + case 0: return "s8_z24float"; + case 1: return "z32float"; + case 2: return "z24s8"; + case 5: return "z16"; + default: return "unknown"; + } +} + +static const char * +get_965_element_component(uint32_t data, int component) +{ + uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; + + switch (component_control) { + case 0: + return "nostore"; + case 1: + switch (component) { + case 0: return "X"; + case 1: return "Y"; + case 2: return "Z"; + case 3: return "W"; + default: return "fail"; + } + case 2: + return "0.0"; + case 3: + return "1.0"; + case 4: + return "0x1"; + case 5: + return "VID"; + default: + return "fail"; + } +} + +static const char * +get_965_prim_type(uint32_t data) +{ + uint32_t primtype = (data >> 10) & 0x1f; + + switch (primtype) { + case 0x01: return "point list"; + case 0x02: return "line list"; + case 0x03: return "line strip"; + case 0x04: return "tri list"; + case 0x05: return "tri strip"; + case 0x06: return "tri fan"; + case 0x07: return "quad list"; + case 0x08: return "quad strip"; + case 0x09: return "line list adj"; + case 0x0a: return "line strip adj"; + case 0x0b: return "tri list adj"; + case 0x0c: return "tri strip adj"; + case 0x0d: return "tri strip reverse"; + case 0x0e: return "polygon"; + case 0x0f: return "rect list"; + case 0x10: return "line loop"; + case 0x11: return "point list bf"; + case 0x12: return "line strip cont"; + case 0x13: return "line strip bf"; + case 0x14: return "line strip cont bf"; + case 0x15: return "tri fan no stipple"; + default: return "fail"; + } +} + +static int +decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode, len; + int i; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x6000, 3, 3, "URB_FENCE" }, + { 0x6001, 2, 2, "CS_URB_STATE" }, + { 0x6002, 2, 2, "CONSTANT_BUFFER" }, + { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, + { 0x6102, 2, 2 , "STATE_SIP" }, + { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, + { 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" }, + { 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" }, + { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, + { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, + { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, + { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, + { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, + { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, + { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, + { 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" }, + { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, + { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, + { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, + { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, + { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, + { 0x7b00, 6, 6, "3DPRIMITIVE" }, + }; + + len = (data[0] & 0x0000ffff) + 2; + + switch ((data[0] & 0xffff0000) >> 16) { + case 0x6101: + if (len != 6) + fprintf(out, "Bad count in STATE_BASE_ADDRESS\n"); + if (count < 6) + BUFFER_FAIL(count, len, "STATE_BASE_ADDRESS"); + + instr_out(data, hw_offset, 0, + "STATE_BASE_ADDRESS\n"); + + if (data[1] & 1) { + instr_out(data, hw_offset, 1, "General state at 0x%08x\n", + data[1] & ~1); + } else + instr_out(data, hw_offset, 1, "General state not updated\n"); + + if (data[2] & 1) { + instr_out(data, hw_offset, 2, "Surface state at 0x%08x\n", + data[2] & ~1); + } else + instr_out(data, hw_offset, 2, "Surface state not updated\n"); + + if (data[3] & 1) { + instr_out(data, hw_offset, 3, "Indirect state at 0x%08x\n", + data[3] & ~1); + } else + instr_out(data, hw_offset, 3, "Indirect state not updated\n"); + + if (data[4] & 1) { + instr_out(data, hw_offset, 4, "General state upper bound 0x%08x\n", + data[4] & ~1); + } else + instr_out(data, hw_offset, 4, "General state not updated\n"); + + if (data[5] & 1) { + instr_out(data, hw_offset, 5, "Indirect state upper bound 0x%08x\n", + data[5] & ~1); + } else + instr_out(data, hw_offset, 5, "Indirect state not updated\n"); + + return len; + case 0x7800: + if (len != 7) + fprintf(out, "Bad count in 3DSTATE_PIPELINED_POINTERS\n"); + if (count < 7) + BUFFER_FAIL(count, len, "3DSTATE_PIPELINED_POINTERS"); + + instr_out(data, hw_offset, 0, + "3DSTATE_PIPELINED_POINTERS\n"); + instr_out(data, hw_offset, 1, "VS state\n"); + instr_out(data, hw_offset, 2, "GS state\n"); + instr_out(data, hw_offset, 3, "Clip state\n"); + instr_out(data, hw_offset, 4, "SF state\n"); + instr_out(data, hw_offset, 5, "WM state\n"); + instr_out(data, hw_offset, 6, "CC state\n"); + return len; + case 0x7801: + if (len != 6) + fprintf(out, "Bad count in 3DSTATE_BINDING_TABLE_POINTERS\n"); + if (count < 6) + BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS"); + + instr_out(data, hw_offset, 0, + "3DSTATE_BINDING_TABLE_POINTERS\n"); + instr_out(data, hw_offset, 1, "VS binding table\n"); + instr_out(data, hw_offset, 2, "GS binding table\n"); + instr_out(data, hw_offset, 3, "Clip binding table\n"); + instr_out(data, hw_offset, 4, "SF binding table\n"); + instr_out(data, hw_offset, 5, "WM binding table\n"); + + return len; + + case 0x7808: + len = (data[0] & 0xff) + 2; + if ((len - 1) % 4 != 0) + fprintf(out, "Bad count in 3DSTATE_VERTEX_BUFFERS\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DSTATE_VERTEX_BUFFERS"); + instr_out(data, hw_offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); + + for (i = 1; i < len;) { + instr_out(data, hw_offset, i, "buffer %d: %s, pitch %db\n", + data[i] >> 27, + data[i] & (1 << 26) ? "random" : "sequential", + data[i] & 0x07ff); + i++; + instr_out(data, hw_offset, i++, "buffer address\n"); + instr_out(data, hw_offset, i++, "max index\n"); + instr_out(data, hw_offset, i++, "mbz\n"); + } + return len; + + case 0x7809: + len = (data[0] & 0xff) + 2; + if ((len + 1) % 2 != 0) + fprintf(out, "Bad count in 3DSTATE_VERTEX_ELEMENTS\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DSTATE_VERTEX_ELEMENTS"); + instr_out(data, hw_offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); + + for (i = 1; i < len;) { + instr_out(data, hw_offset, i, "buffer %d: %svalid, type 0x%04x, " + "src offset 0x%04x bytes\n", + data[i] >> 27, + data[i] & (1 << 26) ? "" : "in", + (data[i] >> 16) & 0x1ff, + data[i] & 0x07ff); + i++; + instr_out(data, hw_offset, i, "(%s, %s, %s, %s), " + "dst offset 0x%02x bytes\n", + get_965_element_component(data[i], 0), + get_965_element_component(data[i], 1), + get_965_element_component(data[i], 2), + get_965_element_component(data[i], 3), + (data[i] & 0xff) * 4); + i++; + } + return len; + + case 0x780a: + len = (data[0] & 0xff) + 2; + if (len != 3) + fprintf(out, "Bad count in 3DSTATE_INDEX_BUFFER\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DSTATE_INDEX_BUFFER"); + instr_out(data, hw_offset, 0, "3DSTATE_INDEX_BUFFER\n"); + instr_out(data, hw_offset, 1, "beginning buffer address\n"); + instr_out(data, hw_offset, 2, "ending buffer address\n"); + return len; + + case 0x7900: + if (len != 4) + fprintf(out, "Bad count in 3DSTATE_DRAWING_RECTANGLE\n"); + if (count < 4) + BUFFER_FAIL(count, len, "3DSTATE_DRAWING_RECTANGLE"); + + instr_out(data, hw_offset, 0, + "3DSTATE_DRAWING_RECTANGLE\n"); + instr_out(data, hw_offset, 1, "top left: %d,%d\n", + data[1] & 0xffff, + (data[1] >> 16) & 0xffff); + instr_out(data, hw_offset, 2, "bottom right: %d,%d\n", + data[2] & 0xffff, + (data[2] >> 16) & 0xffff); + instr_out(data, hw_offset, 3, "origin: %d,%d\n", + (int)data[3] & 0xffff, + ((int)data[3] >> 16) & 0xffff); + + return len; + + case 0x7905: + if (len != 5 && len != 6) + fprintf(out, "Bad count in 3DSTATE_DEPTH_BUFFER\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DSTATE_DEPTH_BUFFER"); + + instr_out(data, hw_offset, 0, + "3DSTATE_DEPTH_BUFFER\n"); + instr_out(data, hw_offset, 1, "%s, %s, pitch = %d bytes, %stiled\n", + get_965_surfacetype(data[1] >> 29), + get_965_depthformat((data[1] >> 18) & 0x7), + (data[1] & 0x0001ffff) + 1, + data[1] & (1 << 27) ? "" : "not "); + instr_out(data, hw_offset, 2, "depth offset\n"); + instr_out(data, hw_offset, 3, "%dx%d\n", + ((data[3] & 0x0007ffc0) >> 6) + 1, + ((data[3] & 0xfff80000) >> 19) + 1); + instr_out(data, hw_offset, 4, "volume depth\n"); + if (len == 6) + instr_out(data, hw_offset, 5, "\n"); + + return len; + + case 0x7b00: + len = (data[0] & 0xff) + 2; + if (len != 6) + fprintf(out, "Bad count in 3DPRIMITIVE\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE"); + + instr_out(data, hw_offset, 0, + "3DPRIMITIVE: %s %s\n", + get_965_prim_type(data[0]), + (data[0] & (1 << 15)) ? "random" : "sequential"); + instr_out(data, hw_offset, 1, "vertex count\n"); + instr_out(data, hw_offset, 2, "start vertex\n"); + instr_out(data, hw_offset, 3, "instance count\n"); + instr_out(data, hw_offset, 4, "start instance\n"); + instr_out(data, hw_offset, 5, "index bias\n"); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) { + unsigned int i; + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x02, 1, 1, "3DSTATE_MODES_3" }, + { 0x03, 1, 1, "3DSTATE_ENABLES_1"}, + { 0x04, 1, 1, "3DSTATE_ENABLES_2"}, + { 0x05, 1, 1, "3DSTATE_VFT0"}, + { 0x06, 1, 1, "3DSTATE_AA"}, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + { 0x08, 1, 1, "3DSTATE_MODES_1" }, + { 0x09, 1, 1, "3DSTATE_STENCIL_TEST" }, + { 0x0a, 1, 1, "3DSTATE_VFT1"}, + { 0x0b, 1, 1, "3DSTATE_INDPT_ALPHA_BLEND" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x0d, 1, 1, "3DSTATE_MAP_BLEND_OP" }, + { 0x0e, 1, 1, "3DSTATE_MAP_BLEND_ARG" }, + { 0x0f, 1, 1, "3DSTATE_MODES_2" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x16, 1, 1, "3DSTATE_MODES_4" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures, 1); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid) +{ + int index = 0; + int failures = 0; + + out = stderr; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + if (IS_965(devid)) { + index += decode_3d_965(data + index, count - index, + hw_offset + index * 4, &failures); + } else if (IS_9XX(devid)) { + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + } else { + index += decode_3d_i830(data + index, count - index, + hw_offset + index * 4, &failures); + } + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} + +void intel_decode_context_reset(void) +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/gallium/drivers/i965/intel_decode.h b/src/gallium/drivers/i965/intel_decode.h new file mode 100644 index 0000000000..c50644a46b --- /dev/null +++ b/src/gallium/drivers/i965/intel_decode.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid); +void intel_decode_context_reset(void); -- cgit v1.2.3 From 220566d8dc4ff023ef833fd6519ab7b187e598d2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Nov 2009 23:37:52 +0000 Subject: i965g: consolidate some includes --- src/gallium/drivers/i965/brw_batchbuffer.c | 2 -- src/gallium/drivers/i965/brw_batchbuffer.h | 2 -- src/gallium/drivers/i965/brw_draw_upload.c | 1 - src/gallium/drivers/i965/brw_pipe_clear.c | 1 - src/gallium/drivers/i965/brw_winsys.h | 7 ++++--- src/gallium/drivers/i965/brw_wm.c | 2 -- src/gallium/drivers/i965/brw_wm_fp.c | 1 - src/gallium/winsys/drm/i965/xlib/xlib_i965.c | 5 +++-- 8 files changed, 7 insertions(+), 14 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index 64d6754df5..673bd1ed44 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -27,8 +27,6 @@ #include "util/u_memory.h" -#include "pipe/p_error.h" - #include "brw_batchbuffer.h" //#include "brw_decode.h" #include "brw_reg.h" diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index b051638296..781cd698e4 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -3,8 +3,6 @@ #include "util/u_debug.h" -#include "pipe/p_error.h" - #include "brw_types.h" #include "brw_winsys.h" #include "brw_reg.h" diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 6e12e8f4b3..acebd44080 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -26,7 +26,6 @@ **************************************************************************/ #include "pipe/p_context.h" -#include "pipe/p_error.h" #include "util/u_upload_mgr.h" #include "util/u_math.h" diff --git a/src/gallium/drivers/i965/brw_pipe_clear.c b/src/gallium/drivers/i965/brw_pipe_clear.c index 69bc95e51a..34cad62977 100644 --- a/src/gallium/drivers/i965/brw_pipe_clear.c +++ b/src/gallium/drivers/i965/brw_pipe_clear.c @@ -27,7 +27,6 @@ #include "util/u_pack_color.h" -#include "pipe/p_error.h" #include "pipe/p_state.h" #include "brw_batchbuffer.h" diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index b2ba3e86f9..f5ce9d13d7 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -27,6 +27,7 @@ #define BRW_WINSYS_H #include "pipe/p_compiler.h" +#include "pipe/p_error.h" struct brw_winsys; struct pipe_fence_handle; @@ -123,9 +124,9 @@ struct brw_winsys_screen { /* XXX: couldn't this be handled by returning true/false on * bo_emit_reloc? */ - boolean (*check_aperture_space)( struct brw_winsys_screen *iws, - struct brw_winsys_buffer **buffers, - unsigned count ); + enum pipe_error (*check_aperture_space)( struct brw_winsys_screen *iws, + struct brw_winsys_buffer **buffers, + unsigned count ); /** * Map a buffer. diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 90780272da..815ae8c51a 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -28,8 +28,6 @@ * Authors: * Keith Whitwell */ -#include "pipe/p_error.h" - #include "tgsi/tgsi_info.h" #include "brw_context.h" diff --git a/src/gallium/drivers/i965/brw_wm_fp.c b/src/gallium/drivers/i965/brw_wm_fp.c index 58f1d35b7d..bba448815b 100644 --- a/src/gallium/drivers/i965/brw_wm_fp.c +++ b/src/gallium/drivers/i965/brw_wm_fp.c @@ -31,7 +31,6 @@ #include "pipe/p_shader_tokens.h" -#include "pipe/p_error.h" #include "util/u_math.h" #include "util/u_memory.h" diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c index 08fce4b20b..71d8f4bafc 100644 --- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c +++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c @@ -35,6 +35,7 @@ #include "util/u_memory.h" #include "util/u_math.h" +#include "pipe/p_error.h" #include "pipe/p_context.h" #include "xm_winsys.h" @@ -226,7 +227,7 @@ xlib_brw_bo_references(struct brw_winsys_buffer *a, return TRUE; } -static boolean +static enum pipe_error xlib_brw_check_aperture_space( struct brw_winsys_screen *iws, struct brw_winsys_buffer **buffers, unsigned count ) @@ -241,7 +242,7 @@ xlib_brw_check_aperture_space( struct brw_winsys_screen *iws, __FUNCTION__, count, (tot_size + 1023) / 1024); - return TRUE; + return PIPE_OK; } static void * -- cgit v1.2.3 From b2bf5f98d923b8d52473e069576fc6514c0ffd0a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 5 Nov 2009 08:01:48 +0000 Subject: i965g: use pipe_error return value for brw_batchbuffer_require_space trivial/tri runs without crashing (on debug winsys) but still produces obviously incorrect command buffers. --- src/gallium/drivers/i965/brw_batchbuffer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 781cd698e4..1f04826aea 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -103,19 +103,19 @@ brw_batchbuffer_emit_dword(struct brw_batchbuffer *batch, GLuint dword) batch->ptr += 4; } -static INLINE boolean +static INLINE enum pipe_error brw_batchbuffer_require_space(struct brw_batchbuffer *batch, GLuint sz) { assert(sz < batch->size - 8); if (brw_batchbuffer_space(batch) < sz) { assert(0); - return FALSE; + return PIPE_ERROR_OUT_OF_MEMORY; } #ifdef DEBUG batch->emit.end_ptr = batch->ptr + sz; #endif - return TRUE; + return 0; } /* Here are the crusty old macros, to be removed: -- cgit v1.2.3 From c796aed5ddad011d66e631c4cafdbf779e73f213 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 5 Nov 2009 13:57:05 +0000 Subject: i965g: add lots of error checks and early returns Any allocation that may fail should be checked, and propogate the error upwards. At the highest level we will flush batch and retry. This is an alternate strategy to what the original DRI driver did of attempting to flush batch from the lowest levels (eg inside BEGIN_BATCH). The trouble with that strategy was that flushes could occur at unexpected times, and additionally there was a need for a wierd notification mechanism to propogate the 'lost context' state back up to higher levels. Propogating the errors directly gives us a lot of flexibility how to deal with these states, at the expense of a lot more checking in the code. Will add some sanity checks later to make sure that out-of-memory conditions are properly escalated and not lost halfway up the stack. --- src/gallium/drivers/i965/brw_batchbuffer.c | 19 +- src/gallium/drivers/i965/brw_batchbuffer.h | 3 +- src/gallium/drivers/i965/brw_cc.c | 73 ++++--- src/gallium/drivers/i965/brw_clip.c | 60 ++++-- src/gallium/drivers/i965/brw_clip_state.c | 60 +++--- src/gallium/drivers/i965/brw_context.c | 46 +++-- src/gallium/drivers/i965/brw_context.h | 2 +- src/gallium/drivers/i965/brw_curbe.c | 18 +- src/gallium/drivers/i965/brw_draw.c | 3 +- src/gallium/drivers/i965/brw_draw_upload.c | 18 +- src/gallium/drivers/i965/brw_eu.c | 13 +- src/gallium/drivers/i965/brw_eu.h | 8 +- src/gallium/drivers/i965/brw_gs.c | 69 ++++--- src/gallium/drivers/i965/brw_gs_state.c | 48 +++-- src/gallium/drivers/i965/brw_pipe_query.c | 31 +-- src/gallium/drivers/i965/brw_pipe_shader.c | 3 +- src/gallium/drivers/i965/brw_pipe_vertex.c | 2 +- src/gallium/drivers/i965/brw_screen_buffers.c | 16 +- src/gallium/drivers/i965/brw_screen_surface.c | 7 +- src/gallium/drivers/i965/brw_screen_texture.c | 17 +- src/gallium/drivers/i965/brw_sf.c | 52 +++-- src/gallium/drivers/i965/brw_sf_state.c | 86 ++++---- src/gallium/drivers/i965/brw_state.h | 71 +++---- src/gallium/drivers/i965/brw_state_cache.c | 115 +++++------ src/gallium/drivers/i965/brw_state_upload.c | 3 +- src/gallium/drivers/i965/brw_vs.c | 56 +++--- src/gallium/drivers/i965/brw_vs_state.c | 58 +++--- src/gallium/drivers/i965/brw_vs_surface_state.c | 97 ++++++---- src/gallium/drivers/i965/brw_winsys.h | 56 ++++-- src/gallium/drivers/i965/brw_wm.c | 78 ++++---- src/gallium/drivers/i965/brw_wm_constant_buffer.c | 87 +++++---- src/gallium/drivers/i965/brw_wm_sampler_state.c | 98 ++++++---- src/gallium/drivers/i965/brw_wm_state.c | 103 ++++++---- src/gallium/drivers/i965/brw_wm_surface_state.c | 226 ++++++++++++---------- src/gallium/winsys/drm/i965/xlib/xlib_i965.c | 46 ++--- 35 files changed, 1003 insertions(+), 745 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index ca612e5ed0..e5f73bd6a3 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -38,17 +38,17 @@ #define USE_MALLOC_BUFFER 1 #define ALWAYS_EMIT_MI_FLUSH 1 -void +enum pipe_error brw_batchbuffer_reset(struct brw_batchbuffer *batch) { - if (batch->buf) { - batch->sws->bo_unreference(batch->buf); - batch->buf = NULL; - } + enum pipe_error ret; - batch->buf = batch->sws->bo_alloc(batch->sws, - BRW_BUFFER_TYPE_BATCH, - BRW_BATCH_SIZE, 4096); + ret = batch->sws->bo_alloc( batch->sws, + BRW_BUFFER_TYPE_BATCH, + BRW_BATCH_SIZE, 4096, + &batch->buf ); + if (ret) + return ret; if (batch->malloc_buffer) batch->map = batch->malloc_buffer; @@ -59,6 +59,7 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch) batch->size = BRW_BATCH_SIZE; batch->ptr = batch->map; + return PIPE_OK; } struct brw_batchbuffer * @@ -91,7 +92,7 @@ brw_batchbuffer_free(struct brw_batchbuffer *batch) batch->map = NULL; } - batch->sws->bo_unreference(batch->buf); + bo_reference(&batch->buf, NULL); FREE(batch); } diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 1f04826aea..288a9d2755 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -65,7 +65,8 @@ void _brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file, int line); -void brw_batchbuffer_reset(struct brw_batchbuffer *batch); +enum pipe_error +brw_batchbuffer_reset(struct brw_batchbuffer *batch); /* Unlike bmBufferData, this currently requires the buffer be mapped. diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index 20967f0191..8e25fe8585 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -57,10 +57,11 @@ static void calc_sane_viewport( const struct pipe_viewport_state *vp, svp->far = 1; } -static int prepare_cc_vp( struct brw_context *brw ) +static enum pipe_error prepare_cc_vp( struct brw_context *brw ) { struct brw_cc_viewport ccv; struct sane_viewport svp; + enum pipe_error ret; memset(&ccv, 0, sizeof(ccv)); @@ -70,10 +71,12 @@ static int prepare_cc_vp( struct brw_context *brw ) ccv.min_depth = svp.near; ccv.max_depth = svp.far; - brw->sws->bo_unreference(brw->cc.vp_bo); - brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 ); - - return 0; + ret = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0, + &brw->cc.vp_bo ); + if (ret) + return ret; + + return PIPE_OK; } const struct brw_tracked_state brw_cc_vp = { @@ -123,11 +126,13 @@ cc_unit_populate_key(const struct brw_context *brw, /** * Creates the state cache entry for the given CC unit key. */ -static struct brw_winsys_buffer * -cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) +static enum pipe_error +cc_unit_create_from_key(struct brw_context *brw, + struct brw_cc_unit_key *key, + struct brw_winsys_buffer **bo_out) { struct brw_cc_unit_state cc; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&cc, 0, sizeof(cc)); @@ -143,38 +148,48 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) cc.cc6 = key->cc6; cc.cc7 = key->cc7; - bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT, - key, sizeof(*key), - &brw->cc.vp_bo, 1, - &cc, sizeof(cc), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_CC_UNIT, + key, sizeof(*key), + &brw->cc.vp_bo, 1, + &cc, sizeof(cc), + NULL, NULL, + bo_out); + if (ret) + return ret; - /* Emit CC viewport relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - 0, - offsetof(struct brw_cc_unit_state, cc4), - brw->cc.vp_bo); - return bo; + /* Emit CC viewport relocation */ + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + 0, + offsetof(struct brw_cc_unit_state, cc4), + brw->cc.vp_bo); + if (ret) + return ret; + + return PIPE_OK; } static int prepare_cc_unit( struct brw_context *brw ) { struct brw_cc_unit_key key; + enum pipe_error ret; cc_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->cc.state_bo); - brw->cc.state_bo = brw_search_cache(&brw->cache, BRW_CC_UNIT, - &key, sizeof(key), - &brw->cc.vp_bo, 1, - NULL); - - if (brw->cc.state_bo == NULL) - brw->cc.state_bo = cc_unit_create_from_key(brw, &key); + if (brw_search_cache(&brw->cache, BRW_CC_UNIT, + &key, sizeof(key), + &brw->cc.vp_bo, 1, + NULL, + &brw->cc.state_bo)) + return PIPE_OK; + + ret = cc_unit_create_from_key(brw, &key, + &brw->cc.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_cc_unit = { diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c index 1a52fa771b..35e1d2fdbd 100644 --- a/src/gallium/drivers/i965/brw_clip.c +++ b/src/gallium/drivers/i965/brw_clip.c @@ -48,9 +48,12 @@ #define BACK_UNFILLED_BIT 0x2 -static void compile_clip_prog( struct brw_context *brw, - struct brw_clip_prog_key *key ) +static enum pipe_error +compile_clip_prog( struct brw_context *brw, + struct brw_clip_prog_key *key, + struct brw_winsys_buffer **bo_out ) { + enum pipe_error ret; struct brw_clip_compile c; const GLuint *program; GLuint program_size; @@ -123,31 +126,39 @@ static void compile_clip_prog( struct brw_context *brw, break; default: assert(0); - return; + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_upload_cache( &brw->cache, - BRW_CLIP_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->clip.prog_data ); + ret = brw_upload_cache( &brw->cache, + BRW_CLIP_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->clip.prog_data, + bo_out ); + if (ret) + return ret; + + return PIPE_OK; } /* Calculate interpolants for triangle and line rasterization. */ -static int upload_clip_prog(struct brw_context *brw) +static enum pipe_error +upload_clip_prog(struct brw_context *brw) { + enum pipe_error ret; struct brw_clip_prog_key key; /* Populate the key, starting from the almost-complete version from @@ -166,15 +177,22 @@ static int upload_clip_prog(struct brw_context *brw) /* PIPE_NEW_CLIP */ key.nr_userclip = brw->curr.ucp.nr; - brw->sws->bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG, - &key, sizeof(key), - NULL, 0, - &brw->clip.prog_data); - if (brw->clip.prog_bo == NULL) - compile_clip_prog( brw, &key ); + /* Already cached? + */ + if (brw_search_cache(&brw->cache, BRW_CLIP_PROG, + &key, sizeof(key), + NULL, 0, + &brw->clip.prog_data, + &brw->clip.prog_bo)) + return PIPE_OK; + + /* Compile new program: + */ + ret = compile_clip_prog( brw, &key, &brw->clip.prog_bo ); + if (ret) + return ret; - return 0; + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c index 6f8309fea9..d4e3c43c61 100644 --- a/src/gallium/drivers/i965/brw_clip_state.c +++ b/src/gallium/drivers/i965/brw_clip_state.c @@ -72,12 +72,13 @@ clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key) key->depth_clamp = 0; // XXX: add this to gallium: ctx->Transform.DepthClamp; } -static struct brw_winsys_buffer * +static enum pipe_error clip_unit_create_from_key(struct brw_context *brw, - struct brw_clip_unit_key *key) + struct brw_clip_unit_key *key, + struct brw_winsys_buffer **bo_out) { struct brw_clip_unit_state clip; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&clip, 0, sizeof(clip)); @@ -141,39 +142,50 @@ clip_unit_create_from_key(struct brw_context *brw, clip.viewport_ymin = -1; clip.viewport_ymax = 1; - bo = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT, - key, sizeof(*key), - &brw->clip.prog_bo, 1, - &clip, sizeof(clip), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT, + key, sizeof(*key), + &brw->clip.prog_bo, 1, + &clip, sizeof(clip), + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit clip program relocation */ assert(brw->clip.prog_bo); - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - clip.thread0.grf_reg_count << 1, - offsetof(struct brw_clip_unit_state, thread0), - brw->clip.prog_bo); - - return bo; + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + clip.thread0.grf_reg_count << 1, + offsetof(struct brw_clip_unit_state, thread0), + brw->clip.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } static int upload_clip_unit( struct brw_context *brw ) { struct brw_clip_unit_key key; + enum pipe_error ret; clip_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->clip.state_bo); - brw->clip.state_bo = brw_search_cache(&brw->cache, BRW_CLIP_UNIT, - &key, sizeof(key), - &brw->clip.prog_bo, 1, - NULL); - if (brw->clip.state_bo == NULL) { - brw->clip.state_bo = clip_unit_create_from_key(brw, &key); - } + if (brw_search_cache(&brw->cache, BRW_CLIP_UNIT, + &key, sizeof(key), + &brw->clip.prog_bo, 1, + NULL, + &brw->clip.state_bo)) + return PIPE_OK; + + /* Create new: + */ + ret = clip_unit_create_from_key(brw, &key, + &brw->clip.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_clip_unit = { diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index aaf7d1834e..2cee7a7a3c 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -72,29 +72,33 @@ static void brw_destroy_context( struct pipe_context *pipe ) brw->curr.fb.nr_cbufs = 0; pipe_surface_reference(&brw->curr.fb.zsbuf, NULL); - brw->sws->bo_unreference(brw->curbe.curbe_bo); - brw->sws->bo_unreference(brw->vs.prog_bo); - brw->sws->bo_unreference(brw->vs.state_bo); - brw->sws->bo_unreference(brw->vs.bind_bo); - brw->sws->bo_unreference(brw->gs.prog_bo); - brw->sws->bo_unreference(brw->gs.state_bo); - brw->sws->bo_unreference(brw->clip.prog_bo); - brw->sws->bo_unreference(brw->clip.state_bo); - brw->sws->bo_unreference(brw->clip.vp_bo); - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sws->bo_unreference(brw->sf.state_bo); - brw->sws->bo_unreference(brw->sf.vp_bo); + bo_reference(&brw->curbe.curbe_bo, NULL); + bo_reference(&brw->vs.prog_bo, NULL); + bo_reference(&brw->vs.state_bo, NULL); + bo_reference(&brw->vs.bind_bo, NULL); + bo_reference(&brw->gs.prog_bo, NULL); + bo_reference(&brw->gs.state_bo, NULL); + bo_reference(&brw->clip.prog_bo, NULL); + bo_reference(&brw->clip.state_bo, NULL); + bo_reference(&brw->clip.vp_bo, NULL); + bo_reference(&brw->sf.prog_bo, NULL); + bo_reference(&brw->sf.state_bo, NULL); + bo_reference(&brw->sf.vp_bo, NULL); + for (i = 0; i < BRW_MAX_TEX_UNIT; i++) - brw->sws->bo_unreference(brw->wm.sdc_bo[i]); - brw->sws->bo_unreference(brw->wm.bind_bo); + bo_reference(&brw->wm.sdc_bo[i], NULL); + + bo_reference(&brw->wm.bind_bo, NULL); + for (i = 0; i < BRW_WM_MAX_SURF; i++) - brw->sws->bo_unreference(brw->wm.surf_bo[i]); - brw->sws->bo_unreference(brw->wm.sampler_bo); - brw->sws->bo_unreference(brw->wm.prog_bo); - brw->sws->bo_unreference(brw->wm.state_bo); - brw->sws->bo_unreference(brw->cc.prog_bo); - brw->sws->bo_unreference(brw->cc.state_bo); - brw->sws->bo_unreference(brw->cc.vp_bo); + bo_reference(&brw->wm.surf_bo[i], NULL); + + bo_reference(&brw->wm.sampler_bo, NULL); + bo_reference(&brw->wm.prog_bo, NULL); + bo_reference(&brw->wm.state_bo, NULL); + bo_reference(&brw->cc.prog_bo, NULL); + bo_reference(&brw->cc.state_bo, NULL); + bo_reference(&brw->cc.vp_bo, NULL); } diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 09d34615c7..580251d2f1 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -744,7 +744,7 @@ struct brw_context * brw_queryobj.c */ void brw_init_query(struct brw_context *brw); -void brw_prepare_query_begin(struct brw_context *brw); +enum pipe_error brw_prepare_query_begin(struct brw_context *brw); void brw_emit_query_begin(struct brw_context *brw); void brw_emit_query_end(struct brw_context *brw); diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index 1e2e232204..ca7774a7cc 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -160,10 +160,11 @@ static GLfloat fixed_plane[6][4] = { * cache mechanism, but maybe would benefit from a comparison against * the current uploaded set of constants. */ -static int prepare_curbe_buffer(struct brw_context *brw) +static enum pipe_error prepare_curbe_buffer(struct brw_context *brw) { const GLuint sz = brw->curbe.total_size; const GLuint bufsz = sz * 16 * sizeof(GLfloat); + enum pipe_error ret; GLfloat *buf; GLuint i; @@ -267,17 +268,20 @@ static int prepare_curbe_buffer(struct brw_context *brw) (brw->curbe.need_new_bo || brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size)) { - brw->sws->bo_unreference(brw->curbe.curbe_bo); - brw->curbe.curbe_bo = NULL; + bo_reference(&brw->curbe.curbe_bo, NULL); } if (brw->curbe.curbe_bo == NULL) { /* Allocate a single page for CURBE entries for this batchbuffer. * They're generally around 64b. */ - brw->curbe.curbe_bo = brw->sws->bo_alloc(brw->sws, - BRW_BUFFER_TYPE_CURBE, - 4096, 1 << 6); + ret = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_CURBE, + 4096, 1 << 6, + &brw->curbe.curbe_bo); + if (ret) + return ret; + brw->curbe.curbe_next_offset = 0; } @@ -313,7 +317,7 @@ static int prepare_curbe_buffer(struct brw_context *brw) return 0; } -static int emit_curbe_buffer(struct brw_context *brw) +static enum pipe_error emit_curbe_buffer(struct brw_context *brw) { GLuint sz = brw->curbe.total_size; diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 6d6b1c7c5c..88cb31ad54 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -280,6 +280,5 @@ void brw_draw_cleanup( struct brw_context *brw ) u_upload_destroy( brw->vb.upload_vertex ); u_upload_destroy( brw->vb.upload_index ); - brw->sws->bo_unreference(brw->ib.bo); - brw->ib.bo = NULL; + bo_reference(&brw->ib.bo, NULL); } diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 4fa7d549eb..188605a0c1 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -251,9 +251,8 @@ static int brw_prepare_vertices(struct brw_context *brw) brw->vb.vb[i].vertex_count = (vb->stride == 0 ? 1 : (bo->size - offset) / vb->stride); - brw->sws->bo_unreference(brw->vb.vb[i].bo); - brw->vb.vb[i].bo = bo; - brw->sws->bo_reference(brw->vb.vb[i].bo); + + bo_reference( &brw->vb.vb[i].bo, bo ); /* Don't need to retain this reference. We have a reference on * the underlying winsys buffer: @@ -417,6 +416,7 @@ const struct brw_tracked_state brw_vertices = { static int brw_prepare_indices(struct brw_context *brw) { struct pipe_buffer *index_buffer = brw->curr.index_buffer; + struct pipe_buffer *upload_buf = NULL; struct brw_winsys_buffer *bo = NULL; GLuint offset; GLuint index_size; @@ -438,7 +438,6 @@ static int brw_prepare_indices(struct brw_context *brw) /* Turn userbuffer into a proper hardware buffer? */ if (brw_buffer_is_user_buffer(index_buffer)) { - struct pipe_buffer *upload_buf; ret = u_upload_buffer( brw->vb.upload_index, 0, @@ -450,8 +449,6 @@ static int brw_prepare_indices(struct brw_context *brw) return ret; bo = brw_buffer(upload_buf)->bo; - brw->sws->bo_reference(bo); - pipe_buffer_reference( &upload_buf, NULL ); /* XXX: annotate the userbuffer with the upload information so * that successive calls don't get re-uploaded. @@ -459,8 +456,6 @@ static int brw_prepare_indices(struct brw_context *brw) } else { bo = brw_buffer(index_buffer)->bo; - brw->sws->bo_reference(bo); - ib_size = bo->size; offset = 0; } @@ -486,15 +481,12 @@ static int brw_prepare_indices(struct brw_context *brw) if (brw->ib.bo != bo || brw->ib.size != ib_size) { - brw->sws->bo_unreference(brw->ib.bo); - brw->ib.bo = bo; + bo_reference(&brw->ib.bo, bo); brw->ib.size = ib_size; brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; } - else { - brw->sws->bo_unreference(bo); - } + pipe_buffer_reference( &upload_buf, NULL ); brw_add_validated_bo(brw, brw->ib.bo); return 0; } diff --git a/src/gallium/drivers/i965/brw_eu.c b/src/gallium/drivers/i965/brw_eu.c index de43b14512..a8fcb5f97e 100644 --- a/src/gallium/drivers/i965/brw_eu.c +++ b/src/gallium/drivers/i965/brw_eu.c @@ -118,16 +118,23 @@ void brw_init_compile( struct brw_context *brw, struct brw_compile *p ) } -const GLuint *brw_get_program( struct brw_compile *p, - GLuint *sz ) +enum pipe_error brw_get_program( struct brw_compile *p, + const GLuint **data, + GLuint *sz ) { GLuint i; for (i = 0; i < 8; i++) brw_NOP(p); + /* Is the generated program malformed for some reason? + */ + if (p->error) + return PIPE_ERROR_BAD_INPUT; + *sz = p->nr_insn * sizeof(struct brw_instruction); - return (const GLuint *)p->store; + *data = (const GLuint *)p->store; + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_eu.h b/src/gallium/drivers/i965/brw_eu.h index 7bddc3859c..565f4ef1c5 100644 --- a/src/gallium/drivers/i965/brw_eu.h +++ b/src/gallium/drivers/i965/brw_eu.h @@ -34,6 +34,7 @@ #define BRW_EU_H #include "util/u_debug.h" +#include "pipe/p_error.h" #include "brw_structs.h" #include "brw_defines.h" @@ -132,6 +133,8 @@ struct brw_compile { struct brw_eu_label *first_label; /**< linked list of labels */ struct brw_eu_call *first_call; /**< linked list of CALs */ + + boolean error; }; @@ -772,7 +775,10 @@ void brw_set_predicate_control( struct brw_compile *p, GLuint pc ); void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional ); void brw_init_compile( struct brw_context *, struct brw_compile *p ); -const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz ); + +enum pipe_error brw_get_program( struct brw_compile *p, + const GLuint **program, + GLuint *sz ); /* Helpers for regular instructions: diff --git a/src/gallium/drivers/i965/brw_gs.c b/src/gallium/drivers/i965/brw_gs.c index 693d8bfdf8..ce77be24f6 100644 --- a/src/gallium/drivers/i965/brw_gs.c +++ b/src/gallium/drivers/i965/brw_gs.c @@ -40,10 +40,12 @@ -static void compile_gs_prog( struct brw_context *brw, - struct brw_gs_prog_key *key ) +static enum pipe_error compile_gs_prog( struct brw_context *brw, + struct brw_gs_prog_key *key, + struct brw_winsys_buffer **bo_out ) { struct brw_gs_compile c; + enum pipe_error ret; const GLuint *program; GLuint program_size; @@ -57,9 +59,9 @@ static void compile_gs_prog( struct brw_context *brw, c.nr_attrs = c.key.nr_attrs; if (BRW_IS_IGDNG(brw)) - c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */ + c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */ else - c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ c.nr_bytes = c.nr_regs * REG_SIZE; @@ -93,40 +95,47 @@ static void compile_gs_prog( struct brw_context *brw, if (key->hint_gs_always) brw_gs_lines( &c ); else { - return; + return PIPE_OK; } break; case PIPE_PRIM_TRIANGLES: if (key->hint_gs_always) brw_gs_tris( &c ); else { - return; + return PIPE_OK; } break; case PIPE_PRIM_POINTS: if (key->hint_gs_always) brw_gs_points( &c ); else { - return; + return PIPE_OK; } - break; + break; default: - return; + assert(0); + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_upload_cache( &brw->cache, BRW_GS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->gs.prog_data ); + ret = brw_upload_cache( &brw->cache, BRW_GS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->gs.prog_data, + bo_out ); + if (ret) + return ret; + + return PIPE_OK; } static const unsigned gs_prim[PIPE_PRIM_MAX] = { @@ -166,6 +175,8 @@ static void populate_key( struct brw_context *brw, static int prepare_gs_prog(struct brw_context *brw) { struct brw_gs_prog_key key; + enum pipe_error ret; + /* Populate the key: */ populate_key(brw, &key); @@ -175,17 +186,21 @@ static int prepare_gs_prog(struct brw_context *brw) brw->gs.prog_active = key.need_gs_prog; } - if (brw->gs.prog_active) { - brw->sws->bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG, - &key, sizeof(key), - NULL, 0, - &brw->gs.prog_data); - if (brw->gs.prog_bo == NULL) - compile_gs_prog( brw, &key ); - } + if (!brw->gs.prog_active) + return PIPE_OK; + + if (brw_search_cache(&brw->cache, BRW_GS_PROG, + &key, sizeof(key), + NULL, 0, + &brw->gs.prog_data, + &brw->gs.prog_bo)) + return PIPE_OK; + + ret = compile_gs_prog( brw, &key, &brw->gs.prog_bo ); + if (ret) + return ret; - return 0; + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_gs_state.c b/src/gallium/drivers/i965/brw_gs_state.c index f27f886a65..18a66da538 100644 --- a/src/gallium/drivers/i965/brw_gs_state.c +++ b/src/gallium/drivers/i965/brw_gs_state.c @@ -69,11 +69,13 @@ gs_unit_populate_key(struct brw_context *brw, struct brw_gs_unit_key *key) key->urb_size = brw->urb.vsize; } -static struct brw_winsys_buffer * -gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) +static enum pipe_error +gs_unit_create_from_key(struct brw_context *brw, + struct brw_gs_unit_key *key, + struct brw_winsys_buffer **bo_out) { struct brw_gs_unit_state gs; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&gs, 0, sizeof(gs)); @@ -104,40 +106,46 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) if (BRW_DEBUG & DEBUG_STATS) gs.thread4.stats_enable = 1; - bo = brw_upload_cache(&brw->cache, BRW_GS_UNIT, - key, sizeof(*key), - &brw->gs.prog_bo, 1, - &gs, sizeof(gs), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_GS_UNIT, + key, sizeof(*key), + &brw->gs.prog_bo, 1, + &gs, sizeof(gs), + NULL, NULL, + bo_out); + if (ret) + return ret; if (key->prog_active) { /* Emit GS program relocation */ - brw->sws->bo_emit_reloc(bo, + brw->sws->bo_emit_reloc(*bo_out, BRW_USAGE_STATE, gs.thread0.grf_reg_count << 1, offsetof(struct brw_gs_unit_state, thread0), brw->gs.prog_bo); } - return bo; + return PIPE_OK; } -static int prepare_gs_unit(struct brw_context *brw) +static enum pipe_error prepare_gs_unit(struct brw_context *brw) { struct brw_gs_unit_key key; + enum pipe_error ret; gs_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->gs.state_bo); - brw->gs.state_bo = brw_search_cache(&brw->cache, BRW_GS_UNIT, - &key, sizeof(key), - &brw->gs.prog_bo, 1, - NULL); - if (brw->gs.state_bo == NULL) { - brw->gs.state_bo = gs_unit_create_from_key(brw, &key); - } + if (brw_search_cache(&brw->cache, BRW_GS_UNIT, + &key, sizeof(key), + &brw->gs.prog_bo, 1, + NULL, + &brw->gs.state_bo)) + return PIPE_OK; + + ret = gs_unit_create_from_key(brw, &key, &brw->gs.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_gs_unit = { diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 3370ebd262..6a01173787 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -72,8 +72,7 @@ brw_query_get_result(struct pipe_context *pipe, } brw->sws->bo_unmap(query->bo); - brw->sws->bo_unreference(query->bo); - query->bo = NULL; + bo_reference(&query->bo, NULL); } *result = query->result; @@ -100,10 +99,9 @@ brw_query_create(struct pipe_context *pipe, unsigned type ) static void brw_query_destroy(struct pipe_context *pipe, struct pipe_query *q) { - struct brw_context *brw = brw_context(pipe); struct brw_query_object *query = (struct brw_query_object *)q; - brw->sws->bo_unreference(query->bo); + bo_reference(&query->bo, NULL); FREE(query); } @@ -114,9 +112,8 @@ brw_query_begin(struct pipe_context *pipe, struct pipe_query *q) struct brw_query_object *query = (struct brw_query_object *)q; /* Reset our driver's tracking of query state. */ - brw->sws->bo_unreference(query->bo); + bo_reference(&query->bo, NULL); query->result = 0; - query->bo = NULL; query->first_index = -1; query->last_index = -1; @@ -139,8 +136,7 @@ brw_query_end(struct pipe_context *pipe, struct pipe_query *q) brw_emit_query_end(brw); brw_context_flush( brw ); - brw->sws->bo_unreference(brw->query.bo); - brw->query.bo = NULL; + bo_reference(&brw->query.bo, NULL); } remove_from_list(query); @@ -153,24 +149,30 @@ brw_query_end(struct pipe_context *pipe, struct pipe_query *q) */ /** Called to set up the query BO and account for its aperture space */ -void +enum pipe_error brw_prepare_query_begin(struct brw_context *brw) { + enum pipe_error ret; + /* Skip if we're not doing any queries. */ if (is_empty_list(&brw->query.active_head)) - return; + return PIPE_OK; /* Get a new query BO if we're going to need it. */ if (brw->query.bo == NULL || brw->query.index * 2 + 1 >= 4096 / sizeof(uint64_t)) { - brw->sws->bo_unreference(brw->query.bo); - brw->query.bo = NULL; - brw->query.bo = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1); + ret = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1, + &brw->query.bo); + if (ret) + return ret; + brw->query.index = 0; } brw_add_validated_bo(brw, brw->query.bo); + + return PIPE_OK; } /** Called just before primitive drawing to get a beginning PS_DEPTH_COUNT. */ @@ -213,8 +215,7 @@ brw_emit_query_begin(struct brw_context *brw) FALSE, &tmp ); - brw->sws->bo_reference(brw->query.bo); - query->bo = brw->query.bo; + bo_reference( &query->bo, brw->query.bo ); query->first_index = brw->query.index; } query->last_index = brw->query.index; diff --git a/src/gallium/drivers/i965/brw_pipe_shader.c b/src/gallium/drivers/i965/brw_pipe_shader.c index 2833f2bce0..662c43c3e5 100644 --- a/src/gallium/drivers/i965/brw_pipe_shader.c +++ b/src/gallium/drivers/i965/brw_pipe_shader.c @@ -146,10 +146,9 @@ fail: static void brw_delete_fs_state( struct pipe_context *pipe, void *prog ) { - struct brw_context *brw = brw_context(pipe); struct brw_fragment_shader *fs = (struct brw_fragment_shader *)prog; - brw->sws->bo_unreference(fs->const_buffer); + bo_reference(&fs->const_buffer, NULL); FREE( (void *)fs->tokens ); FREE( fs ); } diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c index 97e9a23688..73bba5b088 100644 --- a/src/gallium/drivers/i965/brw_pipe_vertex.c +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -56,7 +56,7 @@ brw_pipe_vertex_cleanup( struct brw_context *brw ) */ #if 0 for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - brw->sws->bo_unreference(brw->vb.inputs[i].bo); + bo_reference(&brw->vb.inputs[i].bo, NULL); brw->vb.inputs[i].bo = NULL; } #endif diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c index ba54740225..7ae386ffb3 100644 --- a/src/gallium/drivers/i965/brw_screen_buffers.c +++ b/src/gallium/drivers/i965/brw_screen_buffers.c @@ -43,15 +43,11 @@ brw_buffer_unmap( struct pipe_screen *screen, static void brw_buffer_destroy( struct pipe_buffer *buffer ) { - struct brw_screen *bscreen = brw_screen( buffer->screen ); - struct brw_winsys_screen *sws = bscreen->sws; struct brw_buffer *buf = brw_buffer( buffer ); assert(!p_atomic_read(&buffer->reference.count)); - if (buf->bo) - sws->bo_unreference(buf->bo); - + bo_reference(&buf->bo, NULL); FREE(buf); } @@ -66,6 +62,7 @@ brw_buffer_create(struct pipe_screen *screen, struct brw_winsys_screen *sws = bscreen->sws; struct brw_buffer *buf; unsigned buffer_type; + enum pipe_error ret; buf = CALLOC_STRUCT(brw_buffer); if (!buf) @@ -101,10 +98,11 @@ brw_buffer_create(struct pipe_screen *screen, break; } - buf->bo = sws->bo_alloc( sws, - buffer_type, - size, - alignment ); + ret = sws->bo_alloc( sws, buffer_type, + size, alignment, + &buf->bo ); + if (ret != PIPE_OK) + return NULL; return &buf->base; } diff --git a/src/gallium/drivers/i965/brw_screen_surface.c b/src/gallium/drivers/i965/brw_screen_surface.c index 1c408e9f2e..21a7382873 100644 --- a/src/gallium/drivers/i965/brw_screen_surface.c +++ b/src/gallium/drivers/i965/brw_screen_surface.c @@ -150,9 +150,7 @@ static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen, surface->pitch = tex->pitch; surface->tiling = tex->tiling; - surface->bo = tex->bo; - brw_screen->sws->bo_reference(surface->bo); - + bo_reference( &surface->bo, tex->bo ); pipe_texture_reference( &surface->base.texture, &tex->base ); surface->ss.ss0.surface_format = tex->ss.ss0.surface_format; @@ -244,11 +242,10 @@ static struct pipe_surface *brw_get_tex_surface(struct pipe_screen *screen, static void brw_tex_surface_destroy( struct pipe_surface *surf ) { struct brw_surface *surface = brw_surface(surf); - struct brw_screen *screen = brw_screen(surf->texture->screen); /* Unreference texture, shared buffer: */ - screen->sws->bo_unreference(surface->bo); + bo_reference(&surface->bo, NULL); pipe_texture_reference( &surface->base.texture, NULL ); diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c index ba6dc7dfde..355abf0b89 100644 --- a/src/gallium/drivers/i965/brw_screen_texture.c +++ b/src/gallium/drivers/i965/brw_screen_texture.c @@ -187,6 +187,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, struct brw_screen *bscreen = brw_screen(screen); struct brw_texture *tex; enum brw_buffer_type buffer_type; + enum pipe_error ret; tex = CALLOC_STRUCT(brw_texture); if (tex == NULL) @@ -235,10 +236,13 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, buffer_type = BRW_BUFFER_TYPE_TEXTURE; } - tex->bo = bscreen->sws->bo_alloc( bscreen->sws, - buffer_type, - tex->pitch * tex->total_height * tex->cpp, - 64 ); + ret = bscreen->sws->bo_alloc( bscreen->sws, + buffer_type, + tex->pitch * tex->total_height * tex->cpp, + 64, + &tex->bo ); + if (ret) + goto fail; tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; tex->ss.ss0.surface_type = translate_tex_target(tex->base.target); @@ -289,7 +293,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, return &tex->base; fail: - bscreen->sws->bo_unreference(tex->bo); + bo_reference(&tex->bo, NULL); FREE(tex); return NULL; } @@ -306,7 +310,8 @@ static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen, static void brw_texture_destroy(struct pipe_texture *pt) { - //bscreen->sws->bo_unreference(tex->bo); + struct brw_texture *tex = brw_texture(pt); + bo_reference(&tex->bo, NULL); FREE(pt); } diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index 013d839e37..24d1015bbd 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -40,9 +40,11 @@ #include "brw_sf.h" #include "brw_state.h" -static void compile_sf_prog( struct brw_context *brw, - struct brw_sf_prog_key *key ) +static enum pipe_error compile_sf_prog( struct brw_context *brw, + struct brw_sf_prog_key *key, + struct brw_winsys_buffer **bo_out ) { + enum pipe_error ret; struct brw_sf_compile c; const GLuint *program; GLuint program_size; @@ -87,28 +89,35 @@ static void compile_sf_prog( struct brw_context *brw, break; default: assert(0); - return; + return PIPE_ERROR_BAD_INPUT; } /* get the program */ - program = brw_get_program(&c.func, &program_size); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; /* Upload */ - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_upload_cache( &brw->cache, BRW_SF_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->sf.prog_data ); + ret = brw_upload_cache( &brw->cache, BRW_SF_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->sf.prog_data, + bo_out); + if (ret) + return ret; + + return PIPE_OK; } /* Calculate interpolants for triangle and line rasterization. */ -static int upload_sf_prog(struct brw_context *brw) +static enum pipe_error upload_sf_prog(struct brw_context *brw) { + enum pipe_error ret; struct brw_sf_prog_key key; memset(&key, 0, sizeof(key)); @@ -161,15 +170,18 @@ static int upload_sf_prog(struct brw_context *brw) PIPE_WINDING_CCW); } - brw->sws->bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG, - &key, sizeof(key), - NULL, 0, - &brw->sf.prog_data); - if (brw->sf.prog_bo == NULL) - compile_sf_prog( brw, &key ); + if (brw_search_cache(&brw->cache, BRW_SF_PROG, + &key, sizeof(key), + NULL, 0, + &brw->sf.prog_data, + &brw->sf.prog_bo)) + return PIPE_OK; - return 0; + ret = compile_sf_prog( brw, &key, &brw->sf.prog_bo ); + if (ret) + return ret; + + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c index 31343ff245..f030f26c19 100644 --- a/src/gallium/drivers/i965/brw_sf_state.c +++ b/src/gallium/drivers/i965/brw_sf_state.c @@ -39,11 +39,12 @@ #include "brw_debug.h" #include "brw_pipe_rast.h" -static int upload_sf_vp(struct brw_context *brw) +static enum pipe_error upload_sf_vp(struct brw_context *brw) { const struct pipe_viewport_state *vp = &brw->curr.vp; const struct pipe_scissor_state *scissor = &brw->curr.scissor; struct brw_sf_viewport sfv; + enum pipe_error ret; memset(&sfv, 0, sizeof(sfv)); @@ -61,10 +62,12 @@ static int upload_sf_vp(struct brw_context *brw) sfv.scissor.ymin = scissor->miny; sfv.scissor.ymax = scissor->maxy; /* -1 ?? */ - brw->sws->bo_unreference(brw->sf.vp_bo); - brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 ); + ret = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0, + &brw->sf.vp_bo ); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_sf_vp = { @@ -128,12 +131,13 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) rast->point_size_max); } -static struct brw_winsys_buffer * +static enum pipe_error sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, - struct brw_winsys_buffer **reloc_bufs) + struct brw_winsys_buffer **reloc_bufs, + struct brw_winsys_buffer **bo_out) { struct brw_sf_unit_state sf; - struct brw_winsys_buffer *bo; + enum pipe_error ret; int chipset_max_threads; memset(&sf, 0, sizeof(sf)); @@ -273,51 +277,65 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, sf.sf6.dest_org_hbias = 0x0; } - bo = brw_upload_cache(&brw->cache, BRW_SF_UNIT, - key, sizeof(*key), - reloc_bufs, 2, - &sf, sizeof(sf), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_SF_UNIT, + key, sizeof(*key), + reloc_bufs, 2, + &sf, sizeof(sf), + NULL, NULL, + bo_out); + if (ret) + return ret; /* STATE_PREFETCH command description describes this state as being * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain. */ /* Emit SF program relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - sf.thread0.grf_reg_count << 1, - offsetof(struct brw_sf_unit_state, thread0), - brw->sf.prog_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + sf.thread0.grf_reg_count << 1, + offsetof(struct brw_sf_unit_state, thread0), + brw->sf.prog_bo); + if (ret) + return ret; - /* Emit SF viewport relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - sf.sf5.front_winding | (sf.sf5.viewport_transform << 1), - offsetof(struct brw_sf_unit_state, sf5), - brw->sf.vp_bo); - return bo; + /* Emit SF viewport relocation */ + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + sf.sf5.front_winding | (sf.sf5.viewport_transform << 1), + offsetof(struct brw_sf_unit_state, sf5), + brw->sf.vp_bo); + if (ret) + return ret; + + return PIPE_OK; } -static int upload_sf_unit( struct brw_context *brw ) +static enum pipe_error upload_sf_unit( struct brw_context *brw ) { struct brw_sf_unit_key key; struct brw_winsys_buffer *reloc_bufs[2]; + enum pipe_error ret; sf_unit_populate_key(brw, &key); reloc_bufs[0] = brw->sf.prog_bo; reloc_bufs[1] = brw->sf.vp_bo; - brw->sws->bo_unreference(brw->sf.state_bo); - brw->sf.state_bo = brw_search_cache(&brw->cache, BRW_SF_UNIT, - &key, sizeof(key), - reloc_bufs, 2, - NULL); - if (brw->sf.state_bo == NULL) { - brw->sf.state_bo = sf_unit_create_from_key(brw, &key, reloc_bufs); - } - return 0; + if (brw_search_cache(&brw->cache, BRW_SF_UNIT, + &key, sizeof(key), + reloc_bufs, 2, + NULL, + &brw->sf.state_bo)) + return PIPE_OK; + + + ret = sf_unit_create_from_key(brw, &key, reloc_bufs, + &brw->sf.state_bo); + if (ret) + return ret; + + return PIPE_OK; } const struct brw_tracked_state brw_sf_unit = { diff --git a/src/gallium/drivers/i965/brw_state.h b/src/gallium/drivers/i965/brw_state.h index 94d2cb6f82..e219a1d870 100644 --- a/src/gallium/drivers/i965/brw_state.h +++ b/src/gallium/drivers/i965/brw_state.h @@ -44,8 +44,8 @@ brw_add_validated_bo(struct brw_context *brw, struct brw_winsys_buffer *bo) assert(brw->state.validated_bo_count < Elements(brw->state.validated_bos)); if (bo != NULL) { - brw->sws->bo_reference(bo); - brw->state.validated_bos[brw->state.validated_bo_count++] = bo; + bo_reference( &brw->state.validated_bos[brw->state.validated_bo_count++], + bo ); } } @@ -106,37 +106,42 @@ void brw_destroy_state(struct brw_context *brw); /*********************************************************************** * brw_state_cache.c */ -struct brw_winsys_buffer *brw_cache_data(struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *data, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs); - -struct brw_winsys_buffer *brw_cache_data_sz(struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *data, - GLuint data_size, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs); - -struct brw_winsys_buffer *brw_upload_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_sz, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs, - const void *data, - GLuint data_sz, - const void *aux, - void *aux_return ); - -struct brw_winsys_buffer *brw_search_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_size, - struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs, - void *aux_return); +enum pipe_error brw_cache_data(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *data, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out ); + +enum pipe_error brw_cache_data_sz(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *data, + GLuint data_size, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out); + +enum pipe_error brw_upload_cache( struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_sz, + const void *aux, + void *aux_return , + struct brw_winsys_buffer **bo_out); + +boolean brw_search_cache( struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + struct brw_winsys_buffer **reloc_bufs, + GLuint nr_reloc_bufs, + void *aux_return, + struct brw_winsys_buffer **bo_out); + void brw_state_cache_check_size( struct brw_context *brw ); void brw_init_caches( struct brw_context *brw ); diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c index cbd1f02d77..f8369d31ec 100644 --- a/src/gallium/drivers/i965/brw_state_cache.c +++ b/src/gallium/drivers/i965/brw_state_cache.c @@ -109,9 +109,8 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, if (bo == cache->last_bo[cache_id]) return; /* no change */ - cache->sws->bo_unreference(cache->last_bo[cache_id]); - cache->last_bo[cache_id] = bo; - cache->sws->bo_reference(cache->last_bo[cache_id]); + bo_reference( &cache->last_bo[cache_id], bo ); + cache->brw->state.dirty.cache |= 1 << cache_id; } @@ -174,14 +173,15 @@ rehash(struct brw_cache *cache) /** * Returns the buffer object matching cache_id and key, or NULL. */ -struct brw_winsys_buffer * +boolean brw_search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, const void *key, GLuint key_size, struct brw_winsys_buffer **reloc_bufs, GLuint nr_reloc_bufs, - void *aux_return) + void *aux_return, + struct brw_winsys_buffer **bo_out) { struct brw_cache_item *item; GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); @@ -189,20 +189,20 @@ brw_search_cache(struct brw_cache *cache, item = search_cache(cache, cache_id, hash, key, key_size, reloc_bufs, nr_reloc_bufs); - if (item == NULL) - return NULL; - - if (aux_return) - *(void **)aux_return = (void *)((char *)item->key + item->key_size); - - update_cache_last(cache, cache_id, item->bo); - - cache->sws->bo_reference(item->bo); - return item->bo; + if (item) { + if (aux_return) + *(void **)aux_return = (void *)((char *)item->key + item->key_size); + + update_cache_last(cache, cache_id, item->bo); + bo_reference(bo_out, item->bo); + return TRUE; + } + + return FALSE; } -struct brw_winsys_buffer * +enum pipe_error brw_upload_cache( struct brw_cache *cache, enum brw_cache_id cache_id, const void *key, @@ -212,14 +212,15 @@ brw_upload_cache( struct brw_cache *cache, const void *data, GLuint data_size, const void *aux, - void *aux_return ) + void *aux_return, + struct brw_winsys_buffer **bo_out) { struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item); GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); GLuint relocs_size = nr_reloc_bufs * sizeof(struct brw_winsys_buffer *); GLuint aux_size = cache->aux_size[cache_id]; + enum pipe_error ret; void *tmp; - struct brw_winsys_buffer *bo; int i; /* Create the buffer object to contain the data. For now, use a @@ -227,9 +228,12 @@ brw_upload_cache( struct brw_cache *cache, * may want to take advantage of hardware distinctions between * these various entities. */ - bo = cache->sws->bo_alloc(cache->sws, - cache->buffer_type, - data_size, 1 << 6); + ret = cache->sws->bo_alloc(cache->sws, + cache->buffer_type, + data_size, 1 << 6, + bo_out); + if (ret) + return ret; /* Set up the memory containing the key, aux_data, and reloc_bufs */ @@ -240,7 +244,7 @@ brw_upload_cache( struct brw_cache *cache, memcpy((char *)tmp + key_size + aux_size, reloc_bufs, relocs_size); for (i = 0; i < nr_reloc_bufs; i++) { if (reloc_bufs[i] != NULL) - cache->sws->bo_reference(reloc_bufs[i]); + p_atomic_inc(&reloc_bufs[i]->reference.count); } item->cache_id = cache_id; @@ -249,9 +253,7 @@ brw_upload_cache( struct brw_cache *cache, item->key_size = key_size; item->reloc_bufs = (struct brw_winsys_buffer **)((char *)tmp + key_size + aux_size); item->nr_reloc_bufs = nr_reloc_bufs; - - item->bo = bo; - cache->sws->bo_reference(bo); + bo_reference( &item->bo, *bo_out ); item->data_size = data_size; if (cache->n_items > cache->size * 1.5) @@ -273,28 +275,28 @@ brw_upload_cache( struct brw_cache *cache, data_size, cache_id); /* Copy data to the buffer */ - cache->sws->bo_subdata(bo, + cache->sws->bo_subdata(item->bo, cache_id, 0, data_size, data); - update_cache_last(cache, cache_id, bo); + update_cache_last(cache, cache_id, item->bo); - return bo; + return PIPE_OK; } /** * This doesn't really work with aux data. Use search/upload instead */ -struct brw_winsys_buffer * +enum pipe_error brw_cache_data_sz(struct brw_cache *cache, enum brw_cache_id cache_id, const void *data, GLuint data_size, struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs) + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out) { - struct brw_winsys_buffer *bo; struct brw_cache_item *item; GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs); @@ -302,17 +304,17 @@ brw_cache_data_sz(struct brw_cache *cache, reloc_bufs, nr_reloc_bufs); if (item) { update_cache_last(cache, cache_id, item->bo); - cache->sws->bo_reference(item->bo); - return item->bo; - } - bo = brw_upload_cache(cache, cache_id, - data, data_size, - reloc_bufs, nr_reloc_bufs, - data, data_size, - NULL, NULL); + bo_reference(bo_out, item->bo); + return PIPE_OK; + } - return bo; + return brw_upload_cache(cache, cache_id, + data, data_size, + reloc_bufs, nr_reloc_bufs, + data, data_size, + NULL, NULL, + bo_out); } @@ -323,15 +325,16 @@ brw_cache_data_sz(struct brw_cache *cache, * better to use, as the potentially changing offsets in the data-used-as-key * will result in excessive cache misses. */ -struct brw_winsys_buffer * +enum pipe_error brw_cache_data(struct brw_cache *cache, enum brw_cache_id cache_id, const void *data, struct brw_winsys_buffer **reloc_bufs, - GLuint nr_reloc_bufs) + GLuint nr_reloc_bufs, + struct brw_winsys_buffer **bo_out) { return brw_cache_data_sz(cache, cache_id, data, cache->key_size[cache_id], - reloc_bufs, nr_reloc_bufs); + reloc_bufs, nr_reloc_bufs, bo_out); } @@ -506,11 +509,13 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) int j; next = c->next; + for (j = 0; j < c->nr_reloc_bufs; j++) - brw->sws->bo_unreference(c->reloc_bufs[j]); - brw->sws->bo_unreference(c->bo); - free((void *)c->key); - free(c); + bo_reference(&c->reloc_bufs[j], NULL); + + bo_reference(&c->bo, NULL); + FREE((void *)c->key); + FREE(c); } cache->items[i] = NULL; } @@ -551,10 +556,12 @@ brw_state_cache_bo_delete(struct brw_cache *cache, struct brw_winsys_buffer *bo) *prev = c->next; for (j = 0; j < c->nr_reloc_bufs; j++) - cache->sws->bo_unreference(c->reloc_bufs[j]); - cache->sws->bo_unreference(c->bo); - free((void *)c->key); - free(c); + bo_reference(&c->reloc_bufs[j], NULL); + + bo_reference(&c->bo, NULL); + + FREE((void *)c->key); + FREE(c); cache->n_items--; } else { prev = &c->next; @@ -590,10 +597,10 @@ brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache) brw_clear_cache(brw, cache); for (i = 0; i < BRW_MAX_CACHE; i++) { - brw->sws->bo_unreference(cache->last_bo[i]); - free(cache->name[i]); + bo_reference(&cache->last_bo[i], NULL); + FREE(cache->name[i]); } - free(cache->items); + FREE(cache->items); cache->items = NULL; cache->size = 0; } diff --git a/src/gallium/drivers/i965/brw_state_upload.c b/src/gallium/drivers/i965/brw_state_upload.c index a71af4d2b9..fdcdd59129 100644 --- a/src/gallium/drivers/i965/brw_state_upload.c +++ b/src/gallium/drivers/i965/brw_state_upload.c @@ -140,8 +140,7 @@ brw_clear_validated_bos(struct brw_context *brw) /* Clear the last round of validated bos */ for (i = 0; i < brw->state.validated_bo_count; i++) { - brw->sws->bo_unreference(brw->state.validated_bos[i]); - brw->state.validated_bos[i] = NULL; + bo_reference(&brw->state.validated_bos[i], NULL); } brw->state.validated_bo_count = 0; } diff --git a/src/gallium/drivers/i965/brw_vs.c b/src/gallium/drivers/i965/brw_vs.c index 26a28114d9..966940ceac 100644 --- a/src/gallium/drivers/i965/brw_vs.c +++ b/src/gallium/drivers/i965/brw_vs.c @@ -39,10 +39,12 @@ -static void do_vs_prog( struct brw_context *brw, - struct brw_vertex_shader *vp, - struct brw_vs_prog_key *key ) +static enum pipe_error do_vs_prog( struct brw_context *brw, + struct brw_vertex_shader *vp, + struct brw_vs_prog_key *key, + struct brw_winsys_buffer **bo_out) { + enum pipe_error ret; GLuint program_size; const GLuint *program; struct brw_vs_compile c; @@ -66,22 +68,29 @@ static void do_vs_prog( struct brw_context *brw, /* get the program */ - program = brw_get_program(&c.func, &program_size); - - brw->sws->bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_upload_cache( &brw->cache, BRW_VS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->vs.prog_data ); + ret = brw_get_program(&c.func, &program, &program_size); + if (ret) + return ret; + + ret = brw_upload_cache( &brw->cache, BRW_VS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + &brw->vs.prog_data, + bo_out); + if (ret) + return ret; + + return PIPE_OK; } -static int brw_upload_vs_prog(struct brw_context *brw) +static enum pipe_error brw_upload_vs_prog(struct brw_context *brw) { struct brw_vs_prog_key key; struct brw_vertex_shader *vp = brw->curr.vertex_shader; + enum pipe_error ret; memset(&key, 0, sizeof(key)); @@ -95,15 +104,18 @@ static int brw_upload_vs_prog(struct brw_context *brw) /* Make an early check for the key. */ - brw->sws->bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG, - &key, sizeof(key), - NULL, 0, - &brw->vs.prog_data); - if (brw->vs.prog_bo == NULL) - do_vs_prog(brw, vp, &key); - - return 0; + if (brw_search_cache(&brw->cache, BRW_VS_PROG, + &key, sizeof(key), + NULL, 0, + &brw->vs.prog_data, + &brw->vs.prog_bo)) + return PIPE_OK; + + ret = do_vs_prog(brw, vp, &key, &brw->vs.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_vs_state.c b/src/gallium/drivers/i965/brw_vs_state.c index 26d5d005fa..22a4d7f01b 100644 --- a/src/gallium/drivers/i965/brw_vs_state.c +++ b/src/gallium/drivers/i965/brw_vs_state.c @@ -78,11 +78,13 @@ vs_unit_populate_key(struct brw_context *brw, struct brw_vs_unit_key *key) } } -static struct brw_winsys_buffer * -vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) +static enum pipe_error +vs_unit_create_from_key(struct brw_context *brw, + struct brw_vs_unit_key *key, + struct brw_winsys_buffer **bo_out) { + enum pipe_error ret; struct brw_vs_unit_state vs; - struct brw_winsys_buffer *bo; int chipset_max_threads; memset(&vs, 0, sizeof(vs)); @@ -141,38 +143,46 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) */ vs.vs6.vs_enable = 1; - bo = brw_upload_cache(&brw->cache, BRW_VS_UNIT, - key, sizeof(*key), - &brw->vs.prog_bo, 1, - &vs, sizeof(vs), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_VS_UNIT, + key, sizeof(*key), + &brw->vs.prog_bo, 1, + &vs, sizeof(vs), + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit VS program relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - vs.thread0.grf_reg_count << 1, - offsetof(struct brw_vs_unit_state, thread0), - brw->vs.prog_bo); - - return bo; + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + vs.thread0.grf_reg_count << 1, + offsetof(struct brw_vs_unit_state, thread0), + brw->vs.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } static int prepare_vs_unit(struct brw_context *brw) { struct brw_vs_unit_key key; + enum pipe_error ret; vs_unit_populate_key(brw, &key); - brw->sws->bo_unreference(brw->vs.state_bo); - brw->vs.state_bo = brw_search_cache(&brw->cache, BRW_VS_UNIT, - &key, sizeof(key), - &brw->vs.prog_bo, 1, - NULL); - if (brw->vs.state_bo == NULL) { - brw->vs.state_bo = vs_unit_create_from_key(brw, &key); - } + if (brw_search_cache(&brw->cache, BRW_VS_UNIT, + &key, sizeof(key), + &brw->vs.prog_bo, 1, + NULL, + &brw->vs.state_bo)) + return PIPE_OK; + + ret = vs_unit_create_from_key(brw, &key, &brw->vs.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_vs_unit = { diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 32fb9b2a8b..b12df0ec03 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -83,22 +83,23 @@ brw_update_vs_constant_surface( struct brw_context *brw, { struct brw_surface_key key; struct pipe_buffer *cb = brw->curr.vs_constants; + enum pipe_error ret; assert(surf == 0); /* If we're in this state update atom, we need to update VS constants, so * free the old buffer and create a new one for the new contents. */ - brw->sws->bo_unreference(vp->const_buffer); - vp->const_buffer = brw_vs_update_constant_buffer(brw); + ret = brw_vs_update_constant_buffer(brw, &vp->const_buffer); + if (ret) + return ret; /* If there's no constant buffer, then no surface BO is needed to point at * it. */ - if (vp->const_buffer == 0) { - drm_intel_bo_unreference(brw->vs.surf_bo[surf]); - brw->vs.surf_bo[surf] = NULL; - return; + if (vp->const_buffer == NULL) { + bo_reference(brw->vs.surf_bo[surf], NULL); + return PIPE_OK; } memset(&key, 0, sizeof(key)); @@ -118,15 +119,20 @@ brw_update_vs_constant_surface( struct brw_context *brw, key.width, key.height, key.depth, key.cpp, key.pitch); */ - drm_intel_bo_unreference(brw->vs.surf_bo[surf]); - brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, key.bo ? 1 : 0, - NULL); - if (brw->vs.surf_bo[surf] == NULL) { - brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key); - } + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, key.bo ? 1 : 0, + NULL, + &brw->vs.surf_bo[surf])) + return PIPE_OK; + + ret = brw_create_constant_surface(brw, &key + &brw->vs.surf_bo[surf]); + if (ret) + return ret; + + return PIPE_OK; } #endif @@ -134,18 +140,20 @@ brw_update_vs_constant_surface( struct brw_context *brw, /** * Constructs the binding table for the VS surface state. */ -static struct brw_winsys_buffer * -brw_vs_get_binding_table(struct brw_context *brw) +static enum pipe_error +brw_vs_get_binding_table(struct brw_context *brw, + struct brw_winsys_buffer **bo_out) { #if 0 - struct brw_winsys_buffer *bind_bo; - - bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->vs.surf_bo, BRW_VS_MAX_SURF, - NULL); - - if (bind_bo == NULL) { + if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->vs.surf_bo, BRW_VS_MAX_SURF, + NULL, + bo_out)) + { + return PIPE_OK; + } + else { GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint); uint32_t *data = malloc(data_size); int i; @@ -156,11 +164,14 @@ brw_vs_get_binding_table(struct brw_context *brw) else data[i] = 0; - bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->vs.surf_bo, BRW_VS_MAX_SURF, - data, data_size, - NULL, NULL); + ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->vs.surf_bo, BRW_VS_MAX_SURF, + data, data_size, + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit binding table relocations to surface state */ for (i = 0; i < BRW_VS_MAX_SURF; i++) { @@ -168,18 +179,19 @@ brw_vs_get_binding_table(struct brw_context *brw) /* The presumed offsets were set in the data values for * brw_upload_cache. */ - drm_intel_bo_emit_reloc(bind_bo, i * 4, - brw->vs.surf_bo[i], 0, - BRW_USAGE_STATE); + ret = sws->bo_emit_reloc(*bo_out, i * 4, + brw->vs.surf_bo[i], 0, + BRW_USAGE_STATE); + if (ret) + return ret; } } - free(data); + FREE(data); + return PIPE_OK; } - - return bind_bo; #else - return NULL; + return PIPE_OK; #endif } @@ -190,8 +202,10 @@ brw_vs_get_binding_table(struct brw_context *brw) * to be updated, and produces BRW_NEW_NR_VS_SURFACES for the VS unit and * CACHE_NEW_SURF_BIND for the binding table upload. */ -static int prepare_vs_surfaces(struct brw_context *brw ) +static enum pipe_error prepare_vs_surfaces(struct brw_context *brw ) { + enum pipe_error ret; + #if 0 int i; int nr_surfaces = 0; @@ -215,11 +229,12 @@ static int prepare_vs_surfaces(struct brw_context *brw ) * just slightly increases our working set size. */ if (brw->vs.nr_surfaces != 0) { - brw->sws->bo_unreference(brw->vs.bind_bo); - brw->vs.bind_bo = brw_vs_get_binding_table(brw); + ret = brw_vs_get_binding_table(brw, &brw->vs.bind_bo); + if (ret) + return ret; } - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_vs_surfaces = { diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index d941fbcebe..f61c541ad1 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -28,6 +28,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_error.h" +#include "pipe/p_refcnt.h" struct brw_winsys; struct pipe_fence_handle; @@ -36,10 +37,13 @@ struct pipe_fence_handle; */ #define BRW_BATCH_SIZE (32*1024) +struct brw_winsys_screen; /* Need a tiny bit of information inside the abstract buffer struct: */ struct brw_winsys_buffer { + struct pipe_reference reference; + struct brw_winsys_screen *sws; unsigned *offset; unsigned size; }; @@ -105,6 +109,10 @@ enum brw_buffer_data_type { BRW_DATA_MAX }; + + + + struct brw_winsys_screen { @@ -116,33 +124,33 @@ struct brw_winsys_screen { /** * Create a buffer. */ - struct brw_winsys_buffer *(*bo_alloc)( struct brw_winsys_screen *sws, - enum brw_buffer_type type, - unsigned size, - unsigned alignment ); + enum pipe_error (*bo_alloc)( struct brw_winsys_screen *sws, + enum brw_buffer_type type, + unsigned size, + unsigned alignment, + struct brw_winsys_buffer **bo_out ); - /* Reference and unreference buffers: + /* Destroy a buffer when our refcount goes to zero: */ - void (*bo_reference)( struct brw_winsys_buffer *buffer ); - void (*bo_unreference)( struct brw_winsys_buffer *buffer ); + void (*bo_destroy)( struct brw_winsys_buffer *buffer ); /* delta -- added to b2->offset, and written into buffer * offset -- location above value is written to within buffer */ - int (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, - enum brw_buffer_usage usage, - unsigned delta, - unsigned offset, - struct brw_winsys_buffer *b2); + enum pipe_error (*bo_emit_reloc)( struct brw_winsys_buffer *buffer, + enum brw_buffer_usage usage, + unsigned delta, + unsigned offset, + struct brw_winsys_buffer *b2); - int (*bo_exec)( struct brw_winsys_buffer *buffer, - unsigned bytes_used ); + enum pipe_error (*bo_exec)( struct brw_winsys_buffer *buffer, + unsigned bytes_used ); - int (*bo_subdata)(struct brw_winsys_buffer *buffer, - enum brw_buffer_data_type data_type, - size_t offset, - size_t size, - const void *data); + enum pipe_error (*bo_subdata)(struct brw_winsys_buffer *buffer, + enum brw_buffer_data_type data_type, + size_t offset, + size_t size, + const void *data); boolean (*bo_is_busy)(struct brw_winsys_buffer *buffer); boolean (*bo_references)(struct brw_winsys_buffer *a, @@ -175,6 +183,16 @@ struct brw_winsys_screen { }; +static INLINE void +bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf) +{ + struct brw_winsys_buffer *old_buf = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &buf->reference)) + old_buf->sws->bo_destroy(old_buf); +} + + /** * Create brw pipe_screen. */ diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index 815ae8c51a..93f90bf329 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -137,30 +137,26 @@ brw_wm_linear_shader_emit(struct brw_context *brw, struct brw_wm_compile *c) * Depending on the instructions used (i.e. flow control instructions) * we'll use one of two code generators. */ -static int do_wm_prog( struct brw_context *brw, - struct brw_fragment_shader *fp, - struct brw_wm_prog_key *key) +static enum pipe_error do_wm_prog( struct brw_context *brw, + struct brw_fragment_shader *fp, + struct brw_wm_prog_key *key, + struct brw_winsys_buffer **bo_out) { + enum pipe_error ret; struct brw_wm_compile *c; const GLuint *program; GLuint program_size; - c = brw->wm.compile_data; - if (c == NULL) { - brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data)); - c = brw->wm.compile_data; - if (c == NULL) { - /* Ouch - big out of memory problem. Can't continue - * without triggering a segfault, no way to signal, - * so just return. - */ + if (brw->wm.compile_data == NULL) { + brw->wm.compile_data = MALLOC(sizeof(*brw->wm.compile_data)); + if (!brw->wm.compile_data) return PIPE_ERROR_OUT_OF_MEMORY; - } - } else { - memset(c, 0, sizeof(*brw->wm.compile_data)); } - memcpy(&c->key, key, sizeof(*key)); + c = brw->wm.compile_data; + memset(c, 0, sizeof *c); + + c->key = *key; c->fp = fp; c->env_param = NULL; /*brw->intel.ctx.FragmentProgram.Parameters;*/ @@ -190,17 +186,21 @@ static int do_wm_prog( struct brw_context *brw, /* get the program */ - program = brw_get_program(&c->func, &program_size); - - brw->sws->bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_upload_cache( &brw->cache, BRW_WM_PROG, - &c->key, sizeof(c->key), - NULL, 0, - program, program_size, - &c->prog_data, - &brw->wm.prog_data ); - - return 0; + ret = brw_get_program(&c->func, &program, &program_size); + if (ret) + return ret; + + ret = brw_upload_cache( &brw->cache, BRW_WM_PROG, + &c->key, sizeof(c->key), + NULL, 0, + program, program_size, + &c->prog_data, + &brw->wm.prog_data, + bo_out ); + if (ret) + return ret; + + return PIPE_OK; } @@ -267,24 +267,28 @@ static void brw_wm_populate_key( struct brw_context *brw, } -static int brw_prepare_wm_prog(struct brw_context *brw) +static enum pipe_error brw_prepare_wm_prog(struct brw_context *brw) { struct brw_wm_prog_key key; struct brw_fragment_shader *fs = brw->curr.fragment_shader; + enum pipe_error ret; brw_wm_populate_key(brw, &key); /* Make an early check for the key. */ - brw->sws->bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG, - &key, sizeof(key), - NULL, 0, - &brw->wm.prog_data); - if (brw->wm.prog_bo == NULL) - return do_wm_prog(brw, fs, &key); - - return 0; + if (brw_search_cache(&brw->cache, BRW_WM_PROG, + &key, sizeof(key), + NULL, 0, + &brw->wm.prog_data, + &brw->wm.prog_bo)) + return PIPE_OK; + + ret = do_wm_prog(brw, fs, &key, &brw->wm.prog_bo); + if (ret) + return ret; + + return PIPE_OK; } diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c index 50ecef29a4..14568265dd 100644 --- a/src/gallium/drivers/i965/brw_wm_constant_buffer.c +++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c @@ -6,12 +6,14 @@ * Create the constant buffer surface. Vertex/fragment shader constants will be * read from this buffer with Data Port Read instructions/messages. */ -struct brw_winsys_buffer * +enum pipe_error brw_create_constant_surface( struct brw_context *brw, - struct brw_surface_key *key ) + struct brw_surface_key *key, + struct brw_winsys_buffer **bo_out ) { const GLint w = key->width - 1; struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&surf, 0, sizeof(surf)); @@ -28,22 +30,27 @@ brw_create_constant_surface( struct brw_context *brw, surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */ brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */ - bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, - key, sizeof(*key), - &key->bo, key->bo ? 1 : 0, - &surf, sizeof(surf), - NULL, NULL); + ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, + key, sizeof(*key), + &key->bo, key->bo ? 1 : 0, + &surf, sizeof(surf), + NULL, NULL, + &bo_out); + if (ret) + return ret; if (key->bo) { /* Emit relocation to surface contents */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_SAMPLER, - 0, - offsetof(struct brw_surface_state, ss1), - key->bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_SAMPLER, + 0, + offsetof(struct brw_surface_state, ss1), + key->bo); + if (ret) + return ret; } - return bo; + return PIPE_OK; } @@ -52,7 +59,7 @@ brw_create_constant_surface( struct brw_context *brw, * Update the surface state for a WM constant buffer. * The constant buffer will be (re)allocated here if needed. */ -static void +static enum pipe_error brw_update_wm_constant_surface( struct brw_context *brw, GLuint surf) { @@ -60,20 +67,21 @@ brw_update_wm_constant_surface( struct brw_context *brw, struct brw_fragment_shader *fp = brw->curr.fragment_shader; struct pipe_buffer *cbuf = brw->curr.fragment_constants; int pitch = cbuf->size / (4 * sizeof(float)); + enum pipe_error ret; /* If we're in this state update atom, we need to update WM constants, so * free the old buffer and create a new one for the new contents. */ - brw->sws->bo_unreference(fp->const_buffer); - fp->const_buffer = brw_wm_update_constant_buffer(brw); + ret = brw_wm_update_constant_buffer(brw, &fp->const_buffer); + if (ret) + return ret; /* If there's no constant buffer, then no surface BO is needed to point at * it. */ if (cbuf == NULL) { - drm_intel_bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = NULL; - return; + bo_reference(&brw->wm.surf_bo[surf], NULL); + return PIPE_OK; } memset(&key, 0, sizeof(key)); @@ -97,16 +105,20 @@ brw_update_wm_constant_surface( struct brw_context *brw, key.width, key.height, key.depth, key.cpp, key.pitch); */ - brw->sws->bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, 1, - NULL); - if (brw->wm.surf_bo[surf] == NULL) { - brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key); - } + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, 1, + NULL, + &brw->wm.surf_bo[surf])) + return PIPE_OK; + + ret = brw_create_constant_surface(brw, &key, &brw->wm.surf_bo[surf]); + if (ret) + return ret; + brw->state.dirty.brw |= BRW_NEW_WM_SURFACES; + return PIPE_OK; } /** @@ -117,28 +129,33 @@ brw_update_wm_constant_surface( struct brw_context *brw, * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for * inclusion in the binding table. */ -static void prepare_wm_constant_surface(struct brw_context *brw ) +static enum pipe_error prepare_wm_constant_surface(struct brw_context *brw ) { struct brw_fragment_program *fp = (struct brw_fragment_program *) brw->fragment_program; GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER; - drm_intel_bo_unreference(fp->const_buffer); - fp->const_buffer = brw_wm_update_constant_buffer(brw); + ret = brw_wm_update_constant_buffer(brw, + &fp->const_buffer); + if (ret) + return ret; /* If there's no constant buffer, then no surface BO is needed to point at * it. */ if (fp->const_buffer == 0) { if (brw->wm.surf_bo[surf] != NULL) { - drm_intel_bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = NULL; + bo_reference(&brw->wm.surf_bo[surf], NULL); brw->state.dirty.brw |= BRW_NEW_WM_SURFACES; } - return; + return PIPE_OK; } - brw_update_wm_constant_surface(ctx, surf); + ret = brw_update_wm_constant_surface(ctx, surf); + if (ret) + return ret; + + return PIPE_OK } const struct brw_tracked_state brw_wm_constant_surface = { diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index 2fddb4ad89..2861aa979f 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -43,16 +43,22 @@ -static struct brw_winsys_buffer * +static enum pipe_error upload_default_color( struct brw_context *brw, - const GLfloat *color ) + const GLfloat *color, + struct brw_winsys_buffer **bo_out ) { struct brw_sampler_default_color sdc; + enum pipe_error ret; COPY_4V(sdc.color, color); - return brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc, - NULL, 0 ); + ret = brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc, + NULL, 0, bo_out ); + if (ret) + return ret; + + return PIPE_OK; } @@ -111,9 +117,10 @@ brw_wm_sampler_populate_key(struct brw_context *brw, } -static void +static enum pipe_error brw_wm_sampler_update_default_colors(struct brw_context *brw) { + enum pipe_error ret; int nr = MIN2(brw->curr.num_textures, brw->curr.num_samplers); int i; @@ -121,8 +128,7 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) for (i = 0; i < nr; i++) { const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); const struct brw_sampler *sampler = brw->curr.sampler[i]; - - brw->sws->bo_unreference(brw->wm.sdc_bo[i]); + const float *bc; if (pf_is_depth_or_stencil(tex->base.format)) { float bordercolor[4] = { @@ -131,15 +137,25 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) sampler->border_color[0], sampler->border_color[0] }; - /* GL specs that border color for depth textures is taken from the - * R channel, while the hardware uses A. Spam R into all the - * channels for safety. - */ - brw->wm.sdc_bo[i] = upload_default_color(brw, bordercolor); - } else { - brw->wm.sdc_bo[i] = upload_default_color(brw, sampler->border_color); + + bc = bordercolor; + } + else { + bc = sampler->border_color; } + + /* GL specs that border color for depth textures is taken from the + * R channel, while the hardware uses A. Spam R into all the + * channels for safety. + */ + ret = upload_default_color(brw, + bc, + &brw->wm.sdc_bo[i]); + if (ret) + return ret; } + + return PIPE_OK; } @@ -149,6 +165,7 @@ brw_wm_sampler_update_default_colors(struct brw_context *brw) static int upload_wm_samplers( struct brw_context *brw ) { struct wm_sampler_key key; + enum pipe_error ret; int i; brw_wm_sampler_update_default_colors(brw); @@ -159,35 +176,40 @@ static int upload_wm_samplers( struct brw_context *brw ) brw->state.dirty.cache |= CACHE_NEW_SAMPLER; } - brw->sws->bo_unreference(brw->wm.sampler_bo); - brw->wm.sampler_bo = NULL; - if (brw->wm.sampler_count == 0) - return 0; + if (brw->wm.sampler_count == 0) { + bo_reference(&brw->wm.sampler_bo, NULL); + return PIPE_OK; + } - brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER, - &key, sizeof(key), - brw->wm.sdc_bo, key.sampler_count, - NULL); + if (brw_search_cache(&brw->cache, BRW_SAMPLER, + &key, sizeof(key), + brw->wm.sdc_bo, key.sampler_count, + NULL, + &brw->wm.sampler_bo)) + return PIPE_OK; /* If we didnt find it in the cache, compute the state and put it in the * cache. */ - if (brw->wm.sampler_bo == NULL) { - brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER, - &key, sizeof(key), - brw->wm.sdc_bo, key.sampler_count, - &key.sampler, sizeof(key.sampler), - NULL, NULL); - - /* Emit SDC relocations */ - for (i = 0; i < key.sampler_count; i++) { - brw->sws->bo_emit_reloc(brw->wm.sampler_bo, - BRW_USAGE_SAMPLER, - 0, - i * sizeof(struct brw_sampler_state) + - offsetof(struct brw_sampler_state, ss2), - brw->wm.sdc_bo[i]); - } + ret = brw_upload_cache(&brw->cache, BRW_SAMPLER, + &key, sizeof(key), + brw->wm.sdc_bo, key.sampler_count, + &key.sampler, sizeof(key.sampler), + NULL, NULL, + &brw->wm.sampler_bo); + if (ret) + return ret; + + /* Emit SDC relocations */ + for (i = 0; i < key.sampler_count; i++) { + ret = brw->sws->bo_emit_reloc(brw->wm.sampler_bo, + BRW_USAGE_SAMPLER, + 0, + i * sizeof(struct brw_sampler_state) + + offsetof(struct brw_sampler_state, ss2), + brw->wm.sdc_bo[i]); + if (ret) + return ret; } return 0; diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c index ccbb647bcd..86dc10540d 100644 --- a/src/gallium/drivers/i965/brw_wm_state.c +++ b/src/gallium/drivers/i965/brw_wm_state.c @@ -138,12 +138,13 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) /** * Setup wm hardware state. See page 225 of Volume 2 */ -static struct brw_winsys_buffer * +static enum pipe_error wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, - struct brw_winsys_buffer **reloc_bufs) + struct brw_winsys_buffer **reloc_bufs, + struct brw_winsys_buffer **bo_out) { struct brw_wm_unit_state wm; - struct brw_winsys_buffer *bo; + enum pipe_error ret; memset(&wm, 0, sizeof(wm)); @@ -222,45 +223,56 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, if (BRW_DEBUG & DEBUG_STATS || key->stats_wm) wm.wm4.stats_enable = 1; - bo = brw_upload_cache(&brw->cache, BRW_WM_UNIT, - key, sizeof(*key), - reloc_bufs, 3, - &wm, sizeof(wm), - NULL, NULL); + ret = brw_upload_cache(&brw->cache, BRW_WM_UNIT, + key, sizeof(*key), + reloc_bufs, 3, + &wm, sizeof(wm), + NULL, NULL, + bo_out); + if (ret) + return ret; /* Emit WM program relocation */ - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - wm.thread0.grf_reg_count << 1, - offsetof(struct brw_wm_unit_state, thread0), - brw->wm.prog_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + wm.thread0.grf_reg_count << 1, + offsetof(struct brw_wm_unit_state, thread0), + brw->wm.prog_bo); + if (ret) + return ret; /* Emit scratch space relocation */ if (key->total_scratch != 0) { - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_SCRATCH, - wm.thread2.per_thread_scratch_space, - offsetof(struct brw_wm_unit_state, thread2), - brw->wm.scratch_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_SCRATCH, + wm.thread2.per_thread_scratch_space, + offsetof(struct brw_wm_unit_state, thread2), + brw->wm.scratch_bo); + if (ret) + return ret; } /* Emit sampler state relocation */ if (key->sampler_count != 0) { - brw->sws->bo_emit_reloc(bo, - BRW_USAGE_STATE, - wm.wm4.stats_enable | (wm.wm4.sampler_count << 2), - offsetof(struct brw_wm_unit_state, wm4), - brw->wm.sampler_bo); + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + wm.wm4.stats_enable | (wm.wm4.sampler_count << 2), + offsetof(struct brw_wm_unit_state, wm4), + brw->wm.sampler_bo); + if (ret) + return ret; } - return bo; + return PIPE_OK; } -static int upload_wm_unit( struct brw_context *brw ) +static enum pipe_error upload_wm_unit( struct brw_context *brw ) { struct brw_wm_unit_key key; struct brw_winsys_buffer *reloc_bufs[3]; + enum pipe_error ret; + wm_unit_populate_key(brw, &key); /* Allocate the necessary scratch space if we haven't already. Don't @@ -271,15 +283,19 @@ static int upload_wm_unit( struct brw_context *brw ) if (key.total_scratch) { GLuint total = key.total_scratch * key.max_threads; - if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) { - brw->sws->bo_unreference(brw->wm.scratch_bo); - brw->wm.scratch_bo = NULL; - } + /* Do we need a new buffer: + */ + if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) + bo_reference(&brw->wm.scratch_bo, NULL); + if (brw->wm.scratch_bo == NULL) { - brw->wm.scratch_bo = brw->sws->bo_alloc(brw->sws, - BRW_BUFFER_TYPE_SHADER_SCRATCH, - total, - 4096); + ret = brw->sws->bo_alloc(brw->sws, + BRW_BUFFER_TYPE_SHADER_SCRATCH, + total, + 4096, + &brw->wm.scratch_bo); + if (ret) + return ret; } } @@ -287,16 +303,19 @@ static int upload_wm_unit( struct brw_context *brw ) reloc_bufs[1] = brw->wm.scratch_bo; reloc_bufs[2] = brw->wm.sampler_bo; - brw->sws->bo_unreference(brw->wm.state_bo); - brw->wm.state_bo = brw_search_cache(&brw->cache, BRW_WM_UNIT, - &key, sizeof(key), - reloc_bufs, 3, - NULL); - if (brw->wm.state_bo == NULL) { - brw->wm.state_bo = wm_unit_create_from_key(brw, &key, reloc_bufs); - } + if (brw_search_cache(&brw->cache, BRW_WM_UNIT, + &key, sizeof(key), + reloc_bufs, 3, + NULL, + &brw->wm.state_bo)) + return PIPE_OK; + + ret = wm_unit_create_from_key(brw, &key, reloc_bufs, + &brw->wm.state_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_wm_unit = { diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index b055dde20c..e5d0329967 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -40,31 +40,40 @@ -static void +static enum pipe_error brw_update_texture_surface( struct brw_context *brw, struct brw_texture *tex, - GLuint surf ) + struct brw_winsys_buffer **bo_out) { - brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &tex->ss, sizeof tex->ss, - &tex->bo, 1, - NULL); - - if (brw->wm.surf_bo[surf] == NULL) { - brw->wm.surf_bo[surf] = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, - &tex->ss, sizeof tex->ss, - &tex->bo, 1, - &tex->ss, sizeof tex->ss, - NULL, NULL); + enum pipe_error ret; + + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &tex->ss, sizeof tex->ss, + &tex->bo, 1, + NULL, + bo_out)) + return PIPE_OK; + + ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, + &tex->ss, sizeof tex->ss, + &tex->bo, 1, + &tex->ss, sizeof tex->ss, + NULL, NULL, + bo_out); + if (ret) + return ret; - /* Emit relocation to surface contents */ - brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf], - BRW_USAGE_SAMPLER, - 0, - offsetof(struct brw_surface_state, ss1), - tex->bo); - } + /* Emit relocation to surface contents */ + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_SAMPLER, + 0, + offsetof(struct brw_surface_state, ss1), + tex->bo); + if (ret) + return ret; + + return PIPE_OK; } @@ -79,13 +88,14 @@ brw_update_texture_surface( struct brw_context *brw, * While it is only used for the front/back buffer currently, it should be * usable for further buffers when doing ARB_draw_buffer support. */ -static void -brw_update_renderbuffer_surface(struct brw_context *brw, - struct brw_surface *surface, - unsigned int unit) +static enum pipe_error +brw_update_render_surface(struct brw_context *brw, + struct brw_surface *surface, + struct brw_winsys_buffer **bo_out) { struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0; struct brw_surface_state ss; + enum pipe_error ret; /* Surfaces are potentially shared between contexts, so can't * scribble the in-place ss0 value in the surface. @@ -98,30 +108,35 @@ brw_update_renderbuffer_surface(struct brw_context *brw, ss.ss0.writedisable_red = blend_ss0.writedisable_red; ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha; - brw->sws->bo_unreference(brw->wm.surf_bo[unit]); - brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &ss, sizeof(ss), - &surface->bo, 1, - NULL); - - if (brw->wm.surf_bo[unit] == NULL) { - - brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &ss, sizeof ss, - &surface->bo, 1, - &ss, sizeof ss, - NULL, NULL); + if (brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &ss, sizeof(ss), + &surface->bo, 1, + NULL, + bo_out)) + return PIPE_OK; + + ret = brw_upload_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &ss, sizeof ss, + &surface->bo, 1, + &ss, sizeof ss, + NULL, NULL, + bo_out); + if (ret) + return ret; /* XXX: we will only be rendering to this surface: */ - brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit], - BRW_USAGE_RENDER_TARGET, - ss.ss1.base_addr - surface->bo->offset[0], /* XXX */ - offsetof(struct brw_surface_state, ss1), - surface->bo); - } + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_RENDER_TARGET, + ss.ss1.base_addr - surface->bo->offset[0], /* XXX */ + offsetof(struct brw_surface_state, ss1), + surface->bo); + if (ret) + return ret; + + return PIPE_OK; } @@ -129,60 +144,60 @@ brw_update_renderbuffer_surface(struct brw_context *brw, * Constructs the binding table for the WM surface state, which maps unit * numbers to surface state objects. */ -static struct brw_winsys_buffer * -brw_wm_get_binding_table(struct brw_context *brw) +static enum pipe_error +brw_wm_get_binding_table(struct brw_context *brw, + struct brw_winsys_buffer **bo_out ) { - struct brw_winsys_buffer *bind_bo; + enum pipe_error ret; + uint32_t data[BRW_WM_MAX_SURF]; + GLuint data_size = brw->wm.nr_surfaces * sizeof data[0]; + int i; assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF); + assert(brw->wm.nr_surfaces > 0); /* Note there is no key for this search beyond the values in the * relocation array: */ - bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->wm.surf_bo, brw->wm.nr_surfaces, - NULL); - - if (bind_bo == NULL) { - uint32_t data[BRW_WM_MAX_SURF]; - GLuint data_size = brw->wm.nr_surfaces * sizeof data[0]; - int i; - - for (i = 0; i < brw->wm.nr_surfaces; i++) - data[i] = brw->wm.surf_bo[i]->offset[0]; - - bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->wm.surf_bo, brw->wm.nr_surfaces, - data, data_size, - NULL, NULL); - - /* Emit binding table relocations to surface state */ - for (i = 0; i < brw->wm.nr_surfaces; i++) { - brw->sws->bo_emit_reloc(bind_bo, - BRW_USAGE_STATE, - 0, - i * sizeof(GLuint), - brw->wm.surf_bo[i]); - } + if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->wm.surf_bo, + brw->wm.nr_surfaces, + NULL, + bo_out)) + return PIPE_OK; + + for (i = 0; i < brw->wm.nr_surfaces; i++) + data[i] = brw->wm.surf_bo[i]->offset[0]; + + ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->wm.surf_bo, brw->wm.nr_surfaces, + data, data_size, + NULL, NULL, + bo_out); + if (ret) + return ret; + + /* Emit binding table relocations to surface state */ + for (i = 0; i < brw->wm.nr_surfaces; i++) { + ret = brw->sws->bo_emit_reloc(*bo_out, + BRW_USAGE_STATE, + 0, + i * sizeof(GLuint), + brw->wm.surf_bo[i]); + if (ret) + return ret; } - return bind_bo; + return PIPE_OK; } -static int prepare_wm_surfaces(struct brw_context *brw ) +static enum pipe_error prepare_wm_surfaces(struct brw_context *brw ) { - GLuint i; + enum pipe_error ret; int nr_surfaces = 0; - - /* Unreference old buffers - */ - for (i = 0; i < brw->wm.nr_surfaces; i++) { - brw->sws->bo_unreference(brw->wm.surf_bo[i]); - brw->wm.surf_bo[i] = NULL; - } - + GLuint i; /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND * @@ -192,38 +207,51 @@ static int prepare_wm_surfaces(struct brw_context *brw ) * XXX: no color buffer case */ for (i = 0; i < brw->curr.fb.nr_cbufs; i++) { - brw_update_renderbuffer_surface(brw, - brw_surface(brw->curr.fb.cbufs[i]), - nr_surfaces++); + ret = brw_update_render_surface(brw, + brw_surface(brw->curr.fb.cbufs[i]), + &brw->wm.surf_bo[nr_surfaces++]); + if (ret) + return ret; } /* PIPE_NEW_TEXTURE */ for (i = 0; i < brw->curr.num_textures; i++) { - brw_update_texture_surface(brw, - brw_texture(brw->curr.texture[i]), - nr_surfaces++); + ret = brw_update_texture_surface(brw, + brw_texture(brw->curr.texture[i]), + &brw->wm.surf_bo[nr_surfaces++]); + if (ret) + return ret; } /* PIPE_NEW_FRAGMENT_CONSTANTS */ #if 0 if (brw->curr.fragment_constants) { - brw_update_fragment_constant_surface(brw, - brw->curr.fragment_constants, - nr_surfaces++); + ret = brw_update_fragment_constant_surface(brw, + brw->curr.fragment_constants, + &brw->wm.surf_bo[nr_surfaces++]); + if (ret) + return ret; } #endif if (brw->wm.nr_surfaces != nr_surfaces) { + + /* Unreference any left-over old buffers + */ + for (i = nr_surfaces; i < brw->wm.nr_surfaces; i++) + bo_reference(&brw->wm.surf_bo[i], NULL); + brw->wm.nr_surfaces = nr_surfaces; brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES; } - brw->sws->bo_unreference(brw->wm.bind_bo); - brw->wm.bind_bo = brw_wm_get_binding_table(brw); + ret = brw_wm_get_binding_table(brw, &brw->wm.bind_bo); + if (ret) + return ret; - return 0; + return PIPE_OK; } const struct brw_tracked_state brw_wm_surfaces = { diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c index b1edca818a..fc465d7c14 100644 --- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c +++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c @@ -134,11 +134,12 @@ const char *data_types[BRW_DATA_MAX] = }; -static struct brw_winsys_buffer * +static enum pipe_error xlib_brw_bo_alloc( struct brw_winsys_screen *sws, - enum brw_buffer_type type, - unsigned size, - unsigned alignment ) + enum brw_buffer_type type, + unsigned size, + unsigned alignment, + struct brw_winsys_buffer **bo_out ) { struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws); struct xlib_brw_buffer *buf; @@ -148,12 +149,13 @@ xlib_brw_bo_alloc( struct brw_winsys_screen *sws, buf = CALLOC_STRUCT(xlib_brw_buffer); if (!buf) - return NULL; + return PIPE_ERROR_OUT_OF_MEMORY; + + pipe_reference_init(&buf->base.reference, 1); buf->offset = align(xbw->offset, alignment); buf->type = type; buf->virtual = MALLOC(size); - buf->cheesy_refcount = 1; buf->base.offset = &buf->offset; /* hmm, cheesy */ buf->base.size = size; @@ -161,36 +163,25 @@ xlib_brw_bo_alloc( struct brw_winsys_screen *sws, if (xbw->offset > MAX_VRAM) goto err; - return &buf->base; + /* XXX: possibly rentrant call to bo_destroy: + */ + bo_reference(bo_out, &buf->base); + return PIPE_OK; err: assert(0); + FREE(buf->virtual); FREE(buf); - return NULL; -} - -static void -xlib_brw_bo_reference( struct brw_winsys_buffer *buffer ) -{ - struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer); - - buf->cheesy_refcount++; + return PIPE_ERROR_OUT_OF_MEMORY; } static void -xlib_brw_bo_unreference( struct brw_winsys_buffer *buffer ) +xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer ) { struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer); - /* As a special favor in this call only, buffer is allowed to be - * NULL: - */ - if (buffer == NULL) - return; - - if (--buf->cheesy_refcount == 0) { - FREE(buffer); - } + FREE(buf->virtual); + FREE(buf); } static int @@ -378,8 +369,7 @@ xlib_create_brw_winsys_screen( void ) ws->base.destroy = xlib_brw_winsys_destroy; ws->base.bo_alloc = xlib_brw_bo_alloc; - ws->base.bo_reference = xlib_brw_bo_reference; - ws->base.bo_unreference = xlib_brw_bo_unreference; + ws->base.bo_destroy = xlib_brw_bo_destroy; ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc; ws->base.bo_exec = xlib_brw_bo_exec; ws->base.bo_subdata = xlib_brw_bo_subdata; -- cgit v1.2.3 From 3763457892c2d0c654c0eca7585e4d3a863f7714 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 5 Nov 2009 21:09:51 +0000 Subject: i965g: propogate map-buffer-range semantics down to winsys --- src/gallium/drivers/i965/brw_batchbuffer.c | 45 ++++++++--------------- src/gallium/drivers/i965/brw_batchbuffer.h | 9 ----- src/gallium/drivers/i965/brw_pipe_query.c | 2 +- src/gallium/drivers/i965/brw_screen_buffers.c | 51 ++++++++++++++++++++++++++- src/gallium/drivers/i965/brw_winsys.h | 18 +++++++++- src/gallium/winsys/drm/i965/xlib/xlib_i965.c | 19 ++++++++-- 6 files changed, 100 insertions(+), 44 deletions(-) (limited to 'src/gallium/drivers/i965/brw_batchbuffer.h') diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index a55be6faab..d725e8b27e 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -35,7 +35,6 @@ #include "brw_structs.h" #include "intel_decode.h" -#define USE_MALLOC_BUFFER 1 #define ALWAYS_EMIT_MI_FLUSH 1 enum pipe_error @@ -50,14 +49,18 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch) if (ret) return ret; - if (batch->malloc_buffer) - batch->map = batch->malloc_buffer; - else - batch->map = batch->sws->bo_map(batch->buf, - BRW_DATA_BATCH_BUFFER, - GL_TRUE); - batch->size = BRW_BATCH_SIZE; + + /* With map_range semantics, the winsys can decide whether to + * inject a malloc'ed bounce buffer instead of mapping directly. + */ + batch->map = batch->sws->bo_map(batch->buf, + BRW_DATA_BATCH_BUFFER, + 0, batch->size, + GL_TRUE, + GL_TRUE, + GL_TRUE); + batch->ptr = batch->map; return PIPE_OK; } @@ -68,11 +71,6 @@ brw_batchbuffer_alloc(struct brw_winsys_screen *sws, { struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer); - batch->use_malloc_buffer = USE_MALLOC_BUFFER; - if (batch->use_malloc_buffer) { - batch->malloc_buffer = MALLOC(BRW_BATCH_SIZE); - } - batch->sws = sws; batch->chipset = chipset; brw_batchbuffer_reset(batch); @@ -83,11 +81,7 @@ brw_batchbuffer_alloc(struct brw_winsys_screen *sws, void brw_batchbuffer_free(struct brw_batchbuffer *batch) { - if (batch->malloc_buffer) { - FREE(batch->malloc_buffer); - batch->map = NULL; - } - else if (batch->map) { + if (batch->map) { batch->sws->bo_unmap(batch->buf); batch->map = NULL; } @@ -134,18 +128,9 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, batch->ptr += 4; used = batch->ptr - batch->map; - if (batch->use_malloc_buffer) { - batch->sws->bo_subdata(batch->buf, - BRW_DATA_BATCH_BUFFER, - 0, used, - batch->map ); - batch->map = NULL; - } - else { - batch->sws->bo_unmap(batch->buf); - batch->map = NULL; - } - + batch->sws->bo_flush_range(batch->buf, 0, used); + batch->sws->bo_unmap(batch->buf); + batch->map = NULL; batch->ptr = NULL; batch->sws->bo_exec(batch->buf, used ); diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 288a9d2755..7473f5bea4 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -28,15 +28,6 @@ struct brw_batchbuffer { struct brw_winsys_buffer *buf; struct brw_chipset chipset; - /* Main-memory copy of the batch-buffer, built up incrementally & - * then copied as one to the true buffer. - * - * XXX: is this still necessary? - * XXX: if so, can this be hidden inside the GEM-specific winsys code? - */ - boolean use_malloc_buffer; - uint8_t *malloc_buffer; - /** * Values exported to speed up the writing the batchbuffer, * instead of having to go trough a accesor function for diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 6a01173787..2eb862635c 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -63,7 +63,7 @@ brw_query_get_result(struct pipe_context *pipe, if (brw->sws->bo_is_busy(query->bo) && !wait) return FALSE; - map = brw->sws->bo_map(query->bo, BRW_DATA_OTHER, GL_FALSE); + map = bo_map_read(brw->sws, query->bo); if (map == NULL) return FALSE; diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c index 7ae386ffb3..d8141a3f5b 100644 --- a/src/gallium/drivers/i965/brw_screen_buffers.c +++ b/src/gallium/drivers/i965/brw_screen_buffers.c @@ -11,6 +11,29 @@ +static void * +brw_buffer_map_range( struct pipe_screen *screen, + struct pipe_buffer *buffer, + unsigned offset, + unsigned length, + unsigned usage ) +{ + struct brw_screen *bscreen = brw_screen(screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer( buffer ); + + if (buf->user_buffer) + return buf->user_buffer; + + return sws->bo_map( buf->bo, + BRW_DATA_OTHER, + offset, + length, + (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE, + (usage & PIPE_BUFFER_USAGE_DISCARD) ? TRUE : FALSE, + (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) ? TRUE : FALSE); +} + static void * brw_buffer_map( struct pipe_screen *screen, struct pipe_buffer *buffer, @@ -25,9 +48,33 @@ brw_buffer_map( struct pipe_screen *screen, return sws->bo_map( buf->bo, BRW_DATA_OTHER, - (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE ); + 0, + buf->base.size, + (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE, + FALSE, + FALSE); } + +static void +brw_buffer_flush_mapped_range( struct pipe_screen *screen, + struct pipe_buffer *buffer, + unsigned offset, + unsigned length ) +{ + struct brw_screen *bscreen = brw_screen(screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer( buffer ); + + if (buf->user_buffer) + return; + + sws->bo_flush_range( buf->bo, + offset, + length ); +} + + static void brw_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *buffer ) @@ -148,6 +195,8 @@ void brw_screen_buffer_init(struct brw_screen *brw_screen) brw_screen->base.buffer_create = brw_buffer_create; brw_screen->base.user_buffer_create = brw_user_buffer_create; brw_screen->base.buffer_map = brw_buffer_map; + brw_screen->base.buffer_map_range = brw_buffer_map_range; + brw_screen->base.buffer_flush_mapped_range = brw_buffer_flush_mapped_range; brw_screen->base.buffer_unmap = brw_buffer_unmap; brw_screen->base.buffer_destroy = brw_buffer_destroy; } diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index f4a1e9d8ed..e72b928b06 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -169,7 +169,15 @@ struct brw_winsys_screen { */ void *(*bo_map)(struct brw_winsys_buffer *buffer, enum brw_buffer_data_type data_type, - boolean write); + unsigned offset, + unsigned length, + boolean write, + boolean discard, + boolean flush_explicit ); + + void (*bo_flush_range)( struct brw_winsys_buffer *buffer, + unsigned offset, + unsigned length ); /** * Unmap a buffer. @@ -189,6 +197,14 @@ struct brw_winsys_screen { void (*destroy)(struct brw_winsys_screen *iws); }; +static INLINE void * +bo_map_read( struct brw_winsys_screen *sws, struct brw_winsys_buffer *buf ) +{ + return sws->bo_map( buf, + BRW_DATA_OTHER, + 0, buf->size, + FALSE, FALSE, FALSE ); +} static INLINE void bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf) diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c index f46d9961c6..ab5df56bc0 100644 --- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c +++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c @@ -350,7 +350,11 @@ xlib_brw_check_aperture_space( struct brw_winsys_screen *iws, static void * xlib_brw_bo_map(struct brw_winsys_buffer *buffer, enum brw_buffer_data_type data_type, - boolean write) + unsigned offset, + unsigned length, + boolean write, + boolean discard, + boolean explicit) { struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer); @@ -365,6 +369,15 @@ xlib_brw_bo_map(struct brw_winsys_buffer *buffer, return buf->virtual; } + +static void +xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer, + unsigned offset, + unsigned length ) +{ +} + + static void xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer) { @@ -380,7 +393,8 @@ xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer) buf->modified = 0; - /* Consider dumping new buffer contents here. + /* Consider dumping new buffer contents here, using the + * flush-range info to minimize verbosity. */ } } @@ -421,6 +435,7 @@ xlib_create_brw_winsys_screen( void ) ws->base.bo_references = xlib_brw_bo_references; ws->base.check_aperture_space = xlib_brw_check_aperture_space; ws->base.bo_map = xlib_brw_bo_map; + ws->base.bo_flush_range = xlib_brw_bo_flush_range; ws->base.bo_unmap = xlib_brw_bo_unmap; ws->base.bo_wait_idle = xlib_brw_bo_wait_idle; -- cgit v1.2.3