diff options
author | Dave Airlie <airlied@redhat.com> | 2009-04-09 10:14:35 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-04-09 10:31:08 +1000 |
commit | d1a9b1f513109c975a5a7ed5a2d0c329b280afe4 (patch) | |
tree | 5c85af47b4f5af0661acf129e3ce3f59e43cbfd9 /src/gallium/drivers | |
parent | 90ffce497395d8c02fee2ea4ee4c025eede3d876 (diff) | |
parent | 8648c2685870174cf620ef15de70ef030a8d5a20 (diff) |
Merge remote branch 'origin/master' into radeon-rewrite
Conflicts:
src/mesa/drivers/dri/r200/r200_tex.c
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_swtcl.c
src/mesa/drivers/dri/r300/r300_tex.c
src/mesa/drivers/dri/r300/r300_texmem.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/radeon/radeon_tex.c
Diffstat (limited to 'src/gallium/drivers')
75 files changed, 1373 insertions, 570 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index edc06747ac..79ad687ea9 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -46,53 +46,41 @@ /** - * Convert packed pixel from one format to another. - */ -static unsigned -convert_color(enum pipe_format srcFormat, unsigned srcColor, - enum pipe_format dstFormat) -{ - ubyte r, g, b, a; - unsigned dstColor; - - util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a); - util_pack_color_ub(r, g, b, a, dstFormat, &dstColor); - - return dstColor; -} - - - -/** * Called via pipe->clear() */ void -cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { struct cell_context *cell = cell_context(pipe); - uint surfIndex; if (cell->dirty) cell_update_derived(cell); - if (ps == cell->framebuffer.zsbuf) { - /* clear z/stencil buffer */ - surfIndex = 1; - } - else { - /* clear color buffer */ - surfIndex = 0; + if (buffers & PIPE_CLEAR_COLOR) { + uint surfIndex = 0; + uint clearValue; - if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) { - clearValue = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue, - ps->format); - } + util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &clearValue); + + /* Build a CLEAR command and place it in the current batch buffer */ + STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0); + struct cell_command_clear_surface *clr + = (struct cell_command_clear_surface *) + cell_batch_alloc16(cell, sizeof(*clr)); + clr->opcode[0] = CELL_CMD_CLEAR_SURFACE; + clr->surface = surfIndex; + clr->value = clearValue; } + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + uint surfIndex = 1; + uint clearValue; - /* Build a CLEAR command and place it in the current batch buffer */ - { + clearValue = util_pack_z_stencil(cell->framebuffer.zsbuf->format, + depth, stencil); + + /* Build a CLEAR command and place it in the current batch buffer */ STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0); struct cell_command_clear_surface *clr = (struct cell_command_clear_surface *) @@ -101,17 +89,4 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, clr->surface = surfIndex; clr->value = clearValue; } - - /* Technically, the surface's contents are now known and cleared, - * so we could set the status to PIPE_SURFACE_STATUS_CLEAR. But - * it turns out it's quite painful to recognize when any particular - * surface goes from PIPE_SURFACE_STATUS_CLEAR to - * PIPE_SURFACE_STATUS_DEFINED (i.e. with known contents), because - * the drawing commands could be operating on numerous draw buffers, - * which we'd have to iterate through to set all their stati... - * For now, we cheat a bit and set the surface's status to DEFINED - * right here. Later we should revisit this and set the status to - * CLEAR here, and find a better place to set the status to DEFINED. - */ - ps->status = PIPE_SURFACE_STATUS_DEFINED; } diff --git a/src/gallium/drivers/cell/ppu/cell_clear.h b/src/gallium/drivers/cell/ppu/cell_clear.h index ff47d43f4c..08e091adfd 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.h +++ b/src/gallium/drivers/cell/ppu/cell_clear.h @@ -31,13 +31,11 @@ struct pipe_context; -struct pipe_surface; extern void -cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); - +cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); #endif /* CELL_CLEAR_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index ae82ded334..808be589bd 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -119,7 +119,7 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.screen = screen; cell->pipe.destroy = cell_destroy_context; - cell->pipe.clear = cell_clear_surface; + cell->pipe.clear = cell_clear; cell->pipe.flush = cell_flush; #if 0 diff --git a/src/gallium/drivers/i915simple/i915_clear.c b/src/gallium/drivers/i915simple/i915_clear.c index 8a2d3ca43f..90530f2826 100644 --- a/src/gallium/drivers/i915simple/i915_clear.c +++ b/src/gallium/drivers/i915simple/i915_clear.c @@ -25,24 +25,24 @@ * **************************************************************************/ -/* Author: +/* Authors: * Brian Paul */ -#include "pipe/p_defines.h" +#include "util/u_clear.h" #include "i915_context.h" #include "i915_state.h" /** - * Clear the given surface to the specified value. + * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). */ void -i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_DEFINED; + util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 3cdabe45f9..b6983ba86e 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -314,8 +314,8 @@ void i915_emit_hardware_state(struct i915_context *i915 ); /*********************************************************************** * i915_clear.c: */ -void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); /*********************************************************************** diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 39aca9f817..ca8e87af8d 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -677,7 +677,6 @@ i915_get_tex_surface(struct pipe_screen *screen, ps->height = pt->height[level]; ps->offset = offset; ps->usage = flags; - ps->status = PIPE_SURFACE_STATUS_DEFINED; } return ps; } @@ -725,14 +724,6 @@ i915_init_texture_functions(struct i915_context *i915) static void i915_tex_surface_destroy(struct pipe_surface *surf) { - /* This really should not be possible, but it's actually - * happening quite a bit... Will fix. - */ - if (surf->status == PIPE_SURFACE_STATUS_CLEAR) { - debug_printf("XXX destroying a surface with pending clears...\n"); - assert(0); - } - pipe_texture_reference(&surf->texture, NULL); FREE(surf); } diff --git a/src/gallium/drivers/i965simple/brw_defines.h b/src/gallium/drivers/i965simple/brw_defines.h index 9379a397f6..715d2d2d01 100644 --- a/src/gallium/drivers/i965simple/brw_defines.h +++ b/src/gallium/drivers/i965simple/brw_defines.h @@ -289,6 +289,24 @@ #define BRW_RASTRULE_UPPER_LEFT 0 #define BRW_RASTRULE_UPPER_RIGHT 1 +/* These are listed as "Reserved, but not seen as useful" + * in Intel documentation (page 212, "Point Rasterization Rule", + * section 7.4 "SF Pipeline State Summary", of document + * "Intel® 965 Express Chipset Family and Intel® G35 Express + * Chipset Graphics Controller Programmer's Reference Manual, + * Volume 2: 3D/Media", Revision 1.0b as of January 2008, + * available at + * http://intellinuxgraphics.org/documentation.html + * at the time of this writing). + * + * These appear to be supported on at least some + * i965-family devices, and the BRW_RASTRULE_LOWER_RIGHT + * is useful when using OpenGL to render to a FBO + * (which has the pixel coordinate Y orientation inverted + * with respect to the normal OpenGL pixel coordinate system). + */ +#define BRW_RASTRULE_LOWER_LEFT 2 +#define BRW_RASTRULE_LOWER_RIGHT 3 #define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0 #define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1 diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index c921c0d38b..f44bd17451 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -363,7 +363,6 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, ps->nblocksy = pt->nblocksy[level]; ps->stride = tex->stride; ps->offset = offset; - ps->status = PIPE_SURFACE_STATUS_DEFINED; } return ps; } diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 97859110b5..a54820e851 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -46,9 +46,12 @@ static INLINE void so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso) { struct nouveau_stateobj *so = *pso; + int i; if (pipe_reference((struct pipe_reference**)pso, &ref->reference)) { free(so->push); + for (i = 0; i < so->cur_reloc; i++) + pipe_buffer_reference(&so->reloc[i].bo, NULL); free(so->reloc); free(so); } @@ -83,7 +86,8 @@ so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo, { struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++]; - r->bo = bo; + r->bo = NULL; + pipe_buffer_reference(&r->bo, bo); r->offset = so->cur - so->push; r->packet = so->cur_packet; r->data = data; diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 85dc017fbc..4da833c25e 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -122,7 +122,6 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c index be7e09cf4b..a39a2b5f52 100644 --- a/src/gallium/drivers/nv10/nv10_clear.c +++ b/src/gallium/drivers/nv10/nv10_clear.c @@ -1,12 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv10_context.h" void -nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv10_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index f3b56de25a..f1e003c953 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -118,8 +118,9 @@ extern void nv10_init_surface_functions(struct nv10_context *nv10); extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv10_clear.c */ -extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv10_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); + /* nv10_draw.c */ extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index bb3a1c0f19..34e3c2ebd7 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -136,7 +136,6 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c index 29f4afd87c..2b4490fa5e 100644 --- a/src/gallium/drivers/nv20/nv20_clear.c +++ b/src/gallium/drivers/nv20/nv20_clear.c @@ -1,13 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv20_context.h" void -nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv20_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_CLEAR; + util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h index 8ad926db20..fc932f1f90 100644 --- a/src/gallium/drivers/nv20/nv20_context.h +++ b/src/gallium/drivers/nv20/nv20_context.h @@ -118,8 +118,8 @@ extern void nv20_init_surface_functions(struct nv20_context *nv20); extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv20_clear.c */ -extern void nv20_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv20_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); /* nv20_draw.c */ extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20); diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c index b2f29aff8d..185fbf53e0 100644 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -170,7 +170,6 @@ nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c index 8c3ca204d5..c4ba926664 100644 --- a/src/gallium/drivers/nv30/nv30_clear.c +++ b/src/gallium/drivers/nv30/nv30_clear.c @@ -1,13 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv30_context.h" void -nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv30_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_CLEAR; + util_clear(pipe, &nv30_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index b933769700..4229c0a0e1 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -206,7 +206,7 @@ extern boolean nv30_draw_elements(struct pipe_context *pipe, unsigned count); /* nv30_clear.c */ -extern void nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv30_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); #endif diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index d6dc621c9e..7f8054de73 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -177,7 +177,6 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index f77b08ff69..c18be20a32 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -21,14 +21,6 @@ static void nv30_state_do_validate(struct nv30_context *nv30, struct nv30_state_entry **states) { - const struct pipe_framebuffer_state *fb = &nv30->framebuffer; - unsigned i; - - for (i = 0; i < fb->nr_cbufs; i++) - fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - if (fb->zsbuf) - fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - while (*states) { struct nv30_state_entry *e = *states; diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c index 59efd620e3..ddf13addf3 100644 --- a/src/gallium/drivers/nv40/nv40_clear.c +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -1,13 +1,14 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "util/u_clear.h" #include "nv40_context.h" void -nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +nv40_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); - ps->status = PIPE_SURFACE_STATUS_CLEAR; + util_clear(pipe, &nv40_context(pipe)->framebuffer, buffers, rgba, depth, + stencil); } diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index adcfbdd85a..97bc83292d 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -227,7 +227,7 @@ extern boolean nv40_draw_elements(struct pipe_context *pipe, unsigned count); /* nv40_clear.c */ -extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv40_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); #endif diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index abadca8c93..5a201ccf45 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -176,7 +176,6 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ns->base.width = pt->width[level]; ns->base.height = pt->height[level]; ns->base.usage = flags; - ns->base.status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; ns->base.level = level; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index ce859def10..10aae29832 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -38,14 +38,6 @@ static void nv40_state_do_validate(struct nv40_context *nv40, struct nv40_state_entry **states) { - const struct pipe_framebuffer_state *fb = &nv40->framebuffer; - unsigned i; - - for (i = 0; i < fb->nr_cbufs; i++) - fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - if (fb->zsbuf) - fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - while (*states) { struct nv40_state_entry *e = *states; diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c index f9bc3b53ca..db44a9da0e 100644 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -86,7 +86,5 @@ nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, pipe->set_framebuffer_state(pipe, &s_fb); pipe->set_scissor_state(pipe, &s_sc); nv50->dirty |= dirty; - - ps->status = PIPE_SURFACE_STATUS_CLEAR; } diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 313e435e7a..7b67a75439 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -184,8 +184,8 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe, extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ -extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, + const float *rgba, double depth, unsigned stencil); /* nv50_program.c */ extern void nv50_vertprog_validate(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index dc4688ccdc..f79a7ca86c 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -163,7 +163,6 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->width = pt->width[level]; ps->height = pt->height[level]; ps->usage = flags; - ps->status = PIPE_SURFACE_STATUS_DEFINED; pipe_reference_init(&ps->reference, 1); ps->face = face; ps->level = level; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index a2c56f99a8..35cebdbdc3 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -41,7 +41,7 @@ nv50_query(struct pipe_query *pipe) static struct pipe_query * nv50_query_create(struct pipe_context *pipe, unsigned type) { - struct pipe_screen *screen = pipe->winsys; + struct pipe_screen *screen = pipe->screen; struct nv50_query *q = CALLOC_STRUCT(nv50_query); assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 85098a78a2..c13d3de1cb 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -178,17 +178,10 @@ nv50_state_emit(struct nv50_context *nv50) boolean nv50_state_validate(struct nv50_context *nv50) { - const struct pipe_framebuffer_state *fb = &nv50->framebuffer; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_stateobj *so; unsigned i; - for (i = 0; i < fb->nr_cbufs; i++) - fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - - if (fb->zsbuf) - fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - if (nv50->dirty & NV50_NEW_FRAMEBUFFER) nv50_state_validate_fb(nv50); @@ -251,7 +244,7 @@ nv50_state_validate(struct nv50_context *nv50) } scissor_uptodate: - if (nv50->dirty & NV50_NEW_VIEWPORT) { + if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) { unsigned bypass; if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport) @@ -288,6 +281,7 @@ scissor_uptodate: so_ref(so, &nv50->state.viewport); so_ref(NULL, &so); + nv50->state.dirty |= NV50_NEW_VIEWPORT; } viewport_uptodate: diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 0e4e115532..e44f9b9dfc 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -11,13 +11,14 @@ C_SOURCES = \ r300_emit.c \ r300_flush.c \ r300_query.c \ + r300_render.c \ r300_screen.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ r300_state_shader.c \ + r300_state_tcl.c \ r300_surface.c \ - r300_swtcl_emit.c \ r300_texture.c include ../../Makefile.template diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 18684c3e7f..182ed2d459 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -3,15 +3,25 @@ Import('*') env = env.Clone() r300 = env.ConvenienceLibrary( - target = 'r300', - source = [ - 'r300_blit.c', - 'r300_clear.c', - 'r300_context.c', - 'r300_screen.c', - 'r300_state.c', - 'r300_surface.c', - ]) + target = 'r300', + source = [ + 'r300_chipset.c', + 'r300_clear.c', + 'r300_context.c', + 'r300_debug.c', + 'r300_emit.c', + 'r300_flush.c', + 'r300_query.c', + 'r300_render.c', + 'r300_screen.c', + 'r300_state.c', + 'r300_state_derived.c', + 'r300_state_invariant.c', + 'r300_state_shader.c', + 'r300_state_tcl.c', + 'r300_surface.c', + 'r300_texture.c', + ]) Export('r300') diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index e01a0546b2..9d95ad918c 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -30,7 +30,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) { /* Reasonable defaults */ - caps->has_tcl = getenv("RADEON_NO_TCL") ? TRUE : FALSE; + caps->has_tcl = getenv("RADEON_NO_TCL") ? FALSE : TRUE; caps->is_r500 = FALSE; caps->num_vert_fpus = 4; diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c index fd28437aaa..8b9cb819ae 100644 --- a/src/gallium/drivers/r300/r300_clear.c +++ b/src/gallium/drivers/r300/r300_clear.c @@ -22,12 +22,14 @@ #include "r300_clear.h" -/* This gets its own file because Intel's is in its own file. - * I assume there's a good reason. */ +/* Clears currently bound buffers. */ void r300_clear(struct pipe_context* pipe, - struct pipe_surface* ps, - unsigned color) + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); - ps->status = PIPE_SURFACE_STATUS_DEFINED; -}
\ No newline at end of file + /* XXX we can and should do one clear if both color and zs are set */ + util_clear(pipe, &r300_context(pipe)->framebuffer_state, + buffers, rgba, depth, stencil); +} diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_clear.h index e24a0690c9..cd5900565e 100644 --- a/src/gallium/drivers/r300/r300_clear.h +++ b/src/gallium/drivers/r300/r300_clear.h @@ -20,8 +20,17 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "pipe/p_context.h" +#ifndef R300_CLEAR_H +#define R300_CLEAR_H + +#include "util/u_clear.h" + +#include "r300_context.h" void r300_clear(struct pipe_context* pipe, - struct pipe_surface* ps, - unsigned color); + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil); + +#endif /* R300_CLEAR_H */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index b8584702aa..31efe91417 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -125,7 +125,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.draw_range_elements = r300_draw_range_elements; r300->draw = draw_create(); - draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300)); + draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state); r300->rs_block = CALLOC_STRUCT(r300_rs_block); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 0e5e471d11..fec2bad546 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -169,10 +169,7 @@ struct r300_fragment_shader { int indirections; /* Indirection node offsets */ - int offset0; - int offset1; - int offset2; - int offset3; + int alu_offset[4]; /* Machine instructions */ struct { @@ -234,6 +231,29 @@ struct r300_vertex_format { int tab[16]; }; +struct r300_vertex_shader { + /* Parent class */ + struct pipe_shader_state state; + struct tgsi_shader_info info; + + /* Fallback shader, because Draw has issues */ + struct draw_vertex_shader* draw; + + /* Has this shader been translated yet? */ + boolean translated; + + /* Number of used instructions */ + int instruction_count; + + /* Machine instructions */ + struct { + uint32_t inst0; + uint32_t inst1; + uint32_t inst2; + uint32_t inst3; + } instructions[128]; /*< XXX magic number */ +}; + struct r300_context { /* Parent class */ struct pipe_context context; @@ -273,6 +293,8 @@ struct r300_context { int vertex_buffer_count; /* Vertex information. */ struct r300_vertex_format vertex_info; + /* Vertex shader. */ + struct r300_vertex_shader* vs; /* Viewport state. */ struct r300_viewport_state* viewport_state; /* Bitmask of dirty state objects. */ @@ -287,7 +309,7 @@ static struct r300_context* r300_context(struct pipe_context* context) { } /* Context initialization. */ -struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300); +struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_surface_functions(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 9913678d27..5d9799dd72 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -132,4 +132,14 @@ OUT_CS(CP_PACKET3(op, count)); \ } while (0) +#define OUT_CS_INDEX_RELOC(bo, offset, count, rd, wd, flags) do { \ + debug_printf("r300: writing relocation for index buffer %p," \ + "offset %d\n", bo, offset); \ + assert(bo); \ + OUT_CS(offset); \ + OUT_CS(count); \ + cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \ + cs_count -= 2; \ +} while (0) + #endif /* R300_CS_H */ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index f657588c72..dd63136c9d 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -22,6 +22,14 @@ #include "r300_debug.h" +static void r300_dump_fs(struct r300_fragment_shader* fs) +{ + int i; + + for (i = 0; i < fs->alu_instruction_count; i++) { + } +} + static char* r500_fs_swiz[] = { " R", " G", @@ -216,3 +224,15 @@ void r500_fs_dump(struct r500_fragment_shader* fs) } } } + +void r300_vs_dump(struct r300_vertex_shader* vs) +{ + int i; + + for (i = 0; i < vs->instruction_count; i++) { + debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0); + debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1); + debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2); + debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3); + } +} diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h index de5d701ed9..a1f873656d 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r300_debug.h @@ -25,7 +25,10 @@ #include "r300_reg.h" #include "r300_state_shader.h" +#include "r300_state_tcl.h" void r500_fs_dump(struct r500_fragment_shader* fs); +void r300_vs_dump(struct r300_vertex_shader* vs); + #endif /* R300_DEBUG_H */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 9bfb89626c..a3d83376b6 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -82,20 +82,20 @@ void r300_emit_dsa_state(struct r300_context* r300, void r300_emit_fragment_shader(struct r300_context* r300, struct r300_fragment_shader* fs) { - CS_LOCALS(r300); int i; + CS_LOCALS(r300); BEGIN_CS(22); - OUT_CS_REG(R300_US_CONFIG, MAX2(fs->indirections - 1, 0)); + OUT_CS_REG(R300_US_CONFIG, fs->indirections); OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size); /* XXX figure out exactly how big the sizes are on this reg */ - OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); + OUT_CS_REG(R300_US_CODE_OFFSET, 0x40); /* XXX figure these ones out a bit better kthnx */ OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); - OUT_CS_REG(R300_US_CODE_ADDR_3, R300_RGBA_OUT); + OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT); for (i = 0; i < fs->alu_instruction_count; i++) { OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i), @@ -114,10 +114,10 @@ void r300_emit_fragment_shader(struct r300_context* r300, void r500_emit_fragment_shader(struct r300_context* r300, struct r500_fragment_shader* fs) { - CS_LOCALS(r300); + int i; struct r300_constant_buffer* constants = &r300->shader_constants[PIPE_SHADER_FRAGMENT]; - int i; + CS_LOCALS(r300); BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) + (constants->count * 4)); @@ -156,9 +156,9 @@ void r500_emit_fragment_shader(struct r300_context* r300, void r300_emit_fb_state(struct r300_context* r300, struct pipe_framebuffer_state* fb) { - CS_LOCALS(r300); - struct r300_texture* tex; int i; + struct r300_texture* tex; + CS_LOCALS(r300); BEGIN_CS((6 * fb->nr_cbufs) + (fb->zsbuf ? 6 : 0) + 4); for (i = 0; i < fb->nr_cbufs; i++) { @@ -217,9 +217,9 @@ void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs) void r300_emit_rs_block_state(struct r300_context* r300, struct r300_rs_block* rs) { + int i; struct r300_screen* r300screen = r300_screen(r300->context.screen); CS_LOCALS(r300); - int i; BEGIN_CS(21); if (r300screen->caps->is_r500) { @@ -293,8 +293,8 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_format_state(struct r300_context* r300) { - CS_LOCALS(r300); int i; + CS_LOCALS(r300); BEGIN_CS(26); OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info.vinfo.size); @@ -325,25 +325,80 @@ void r300_emit_vertex_format_state(struct r300_context* r300) END_CS; } +void r300_emit_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs) +{ + int i; + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_constant_buffer* constants = + &r300->shader_constants[PIPE_SHADER_VERTEX]; + CS_LOCALS(r300); + + if (!r300screen->caps->has_tcl) { + debug_printf("r300: Implementation error: emit_vertex_shader called," + " but has_tcl is FALSE!\n"); + return; + } + + BEGIN_CS(13 + (vs->instruction_count * 4) + (constants->count * 4)); + + OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) | + R300_PVS_LAST_INST(vs->instruction_count - 1)); + OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, vs->instruction_count - 1); + + /* XXX */ + OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x0); + + OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4); + for (i = 0; i < vs->instruction_count; i++) { + OUT_CS(vs->instructions[i].inst0); + OUT_CS(vs->instructions[i].inst1); + OUT_CS(vs->instructions[i].inst2); + OUT_CS(vs->instructions[i].inst3); + } + + if (constants->count) { + OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, + (r300screen->caps->is_r500 ? + R500_PVS_CONST_START : R300_PVS_CONST_START)); + OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->count * 4); + for (i = 0; i < constants->count; i++) { + OUT_CS_32F(constants->constants[i][0]); + OUT_CS_32F(constants->constants[i][1]); + OUT_CS_32F(constants->constants[i][2]); + OUT_CS_32F(constants->constants[i][3]); + } + } + + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); + END_CS; + +} + void r300_emit_viewport_state(struct r300_context* r300, struct r300_viewport_state* viewport) { - return; CS_LOCALS(r300); - BEGIN_CS(7); - OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 7); + BEGIN_CS(9); + OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); OUT_CS_32F(viewport->xscale); OUT_CS_32F(viewport->xoffset); OUT_CS_32F(viewport->yscale); OUT_CS_32F(viewport->yoffset); OUT_CS_32F(viewport->zscale); OUT_CS_32F(viewport->zoffset); - OUT_CS(viewport->vte_control); + + OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); END_CS; } -static void r300_flush_textures(struct r300_context* r300) +void r300_flush_textures(struct r300_context* r300) { CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 0bc1f90e6a..31dbc7ab85 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -64,9 +64,14 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_format_state(struct r300_context* r300); +void r300_emit_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs); + void r300_emit_viewport_state(struct r300_context* r300, struct r300_viewport_state* viewport); +void r300_flush_textures(struct r300_context* r300); + /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index 5f5f4c4dbd..8fc61c2dec 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -46,12 +46,12 @@ static void r300_destroy_query(struct pipe_context* pipe, static void r300_begin_query(struct pipe_context* pipe, struct pipe_query* query) { + uint32_t* map; struct r300_context* r300 = r300_context(pipe); struct r300_query* q = (struct r300_query*)query; CS_LOCALS(r300); - uint32_t* map = pipe_buffer_map(pipe->screen, q->buf, - PIPE_BUFFER_USAGE_CPU_WRITE); + map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_WRITE); *map = ~0; pipe_buffer_unmap(pipe->screen, q->buf); @@ -79,6 +79,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe, uint64_t* result) { struct r300_query* q = (struct r300_query*)query; + uint32_t* map; uint32_t temp; if (wait) { @@ -88,8 +89,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe, pipe->flush(pipe, 0, NULL); } - uint32_t* map = pipe_buffer_map(pipe->screen, q->buf, - PIPE_BUFFER_USAGE_CPU_READ); + map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_READ); temp = *map; pipe_buffer_unmap(pipe->screen, q->buf); diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 3fe45e1393..660816e1da 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -73,6 +73,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_PVS_NUM_CNTLRS_SHIFT 4 # define R300_PVS_NUM_FPUS_SHIFT 8 # define R300_VF_MAX_VTX_NUM_SHIFT 18 +# define R300_PVS_NUM_SLOTS(x) ((x) << 0) +# define R300_PVS_NUM_CNTLRS(x) ((x) << 4) +# define R300_PVS_NUM_FPUS(x) ((x) << 8) +# define R300_PVS_VF_MAX_VTX_NUM(x) ((x) << 18) # define R300_GL_CLIP_SPACE_DEF (0 << 22) # define R300_DX_CLIP_SPACE_DEF (1 << 22) # define R500_TCL_STATE_OPTIMIZATION (1 << 23) @@ -506,6 +510,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_PVS_FIRST_INST_SHIFT 0 # define R300_PVS_XYZW_VALID_INST_SHIFT 10 # define R300_PVS_LAST_INST_SHIFT 20 +# define R300_PVS_FIRST_INST(x) ((x) << 0) +# define R300_PVS_LAST_INST(x) ((x) << 20) /* Addresses are relative the the vertex program parameters area. */ #define R300_VAP_PVS_CONST_CNTL 0x22D4 # define R300_PVS_CONST_BASE_OFFSET_SHIFT 0 @@ -1191,6 +1197,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_RS_INST_COUNT_MASK 0x0000000f # define R300_RS_TX_OFFSET_SHIFT 5 # define R300_RS_TX_OFFSET_MASK 0x000000e0 +# define R300_RS_TX_OFFSET(x) ((x) << 5) /* gap */ @@ -1434,6 +1441,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_MAX_ANISO_8_TO_1 (3 << 21) # define R300_TX_MAX_ANISO_16_TO_1 (4 << 21) # define R300_TX_MAX_ANISO_MASK (7 << 21) +# define R300_TX_WRAP_S(x) ((x) << 0) +# define R300_TX_WRAP_T(x) ((x) << 3) #define R300_TX_FILTER1_0 0x4440 # define R300_CHROMA_KEY_MODE_DISABLE 0 diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_render.c index 83c25f496b..b7ee8fb8a9 100644 --- a/src/gallium/drivers/r300/r300_swtcl_emit.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,9 +29,9 @@ #include "r300_reg.h" #include "r300_state_derived.h" -/* r300_swtcl_emit: Vertex and index buffer primitive emission. No HW TCL. */ +/* r300_render: Vertex and index buffer primitive emission. */ -struct r300_swtcl_render { +struct r300_render { /* Parent class */ struct vbuf_render base; @@ -52,16 +52,16 @@ struct r300_swtcl_render { size_t vbo_max_used; }; -static INLINE struct r300_swtcl_render* -r300_swtcl_render(struct vbuf_render* render) +static INLINE struct r300_render* +r300_render(struct vbuf_render* render) { - return (struct r300_swtcl_render*)render; + return (struct r300_render*)render; } static const struct vertex_info* -r300_swtcl_render_get_vertex_info(struct vbuf_render* render) +r300_render_get_vertex_info(struct vbuf_render* render) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; r300_update_derived_state(r300); @@ -69,11 +69,11 @@ r300_swtcl_render_get_vertex_info(struct vbuf_render* render) return &r300->vertex_info.vinfo; } -static boolean r300_swtcl_render_allocate_vertices(struct vbuf_render* render, +static boolean r300_render_allocate_vertices(struct vbuf_render* render, ushort vertex_size, ushort count) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; struct pipe_screen* screen = r300->context.screen; size_t size = (size_t)vertex_size * (size_t)count; @@ -98,9 +98,9 @@ static boolean r300_swtcl_render_allocate_vertices(struct vbuf_render* render, } } -static void* r300_swtcl_render_map_vertices(struct vbuf_render* render) +static void* r300_render_map_vertices(struct vbuf_render* render) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct pipe_screen* screen = r300render->r300->context.screen; r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo, @@ -109,11 +109,11 @@ static void* r300_swtcl_render_map_vertices(struct vbuf_render* render) return (unsigned char*)r300render->vbo_map + r300render->vbo_offset; } -static void r300_swtcl_render_unmap_vertices(struct vbuf_render* render, +static void r300_render_unmap_vertices(struct vbuf_render* render, ushort min, ushort max) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct pipe_screen* screen = r300render->r300->context.screen; r300render->vbo_max_used = MAX2(r300render->vbo_max_used, @@ -122,17 +122,17 @@ static void r300_swtcl_render_unmap_vertices(struct vbuf_render* render, pipe_buffer_unmap(screen, r300render->vbo); } -static void r300_swtcl_render_release_vertices(struct vbuf_render* render) +static void r300_render_release_vertices(struct vbuf_render* render) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); pipe_buffer_reference(&r300render->vbo, NULL); } -static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render, +static boolean r300_render_set_primitive(struct vbuf_render* render, unsigned prim) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); r300render->prim = prim; switch (prim) { @@ -174,7 +174,7 @@ static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render, return TRUE; } -static void prepare_render(struct r300_swtcl_render* render, unsigned count) +static void prepare_render(struct r300_render* render, unsigned count) { struct r300_context* r300 = render->r300; @@ -203,11 +203,11 @@ static void prepare_render(struct r300_swtcl_render* render, unsigned count) END_CS; } -static void r300_swtcl_render_draw_arrays(struct vbuf_render* render, +static void r300_render_draw_arrays(struct vbuf_render* render, unsigned start, unsigned count) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; CS_LOCALS(r300); @@ -225,11 +225,11 @@ static void r300_swtcl_render_draw_arrays(struct vbuf_render* render, END_CS; } -static void r300_swtcl_render_draw(struct vbuf_render* render, +static void r300_render_draw(struct vbuf_render* render, const ushort* indices, uint count) { - struct r300_swtcl_render* r300render = r300_swtcl_render(render); + struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; struct pipe_screen* screen = r300->context.screen; struct pipe_buffer* index_buffer; @@ -241,7 +241,7 @@ static void r300_swtcl_render_draw(struct vbuf_render* render, /* Send our indices into an index buffer. */ index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, - count); + count * 2); if (!index_buffer) { return; } @@ -253,25 +253,24 @@ static void r300_swtcl_render_draw(struct vbuf_render* render, debug_printf("r300: Doing indexbuf render, count %d\n", count); - BEGIN_CS(5); + BEGIN_CS(6); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | - r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); - + r300render->hwprim); OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2); OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2)); - OUT_CS_RELOC(index_buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); + OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0); END_CS; } -static void r300_swtcl_render_destroy(struct vbuf_render* render) +static void r300_render_destroy(struct vbuf_render* render) { FREE(render); } -static struct vbuf_render* r300_swtcl_render_create(struct r300_context* r300) +static struct vbuf_render* r300_render_create(struct r300_context* r300) { - struct r300_swtcl_render* r300render = CALLOC_STRUCT(r300_swtcl_render); + struct r300_render* r300render = CALLOC_STRUCT(r300_render); r300render->r300 = r300; @@ -279,25 +278,25 @@ static struct vbuf_render* r300_swtcl_render_create(struct r300_context* r300) r300render->base.max_vertex_buffer_bytes = 128 * 1024; r300render->base.max_indices = 16 * 1024; - r300render->base.get_vertex_info = r300_swtcl_render_get_vertex_info; - r300render->base.allocate_vertices = r300_swtcl_render_allocate_vertices; - r300render->base.map_vertices = r300_swtcl_render_map_vertices; - r300render->base.unmap_vertices = r300_swtcl_render_unmap_vertices; - r300render->base.set_primitive = r300_swtcl_render_set_primitive; - r300render->base.draw = r300_swtcl_render_draw; - r300render->base.draw_arrays = r300_swtcl_render_draw_arrays; - r300render->base.release_vertices = r300_swtcl_render_release_vertices; - r300render->base.destroy = r300_swtcl_render_destroy; + r300render->base.get_vertex_info = r300_render_get_vertex_info; + r300render->base.allocate_vertices = r300_render_allocate_vertices; + r300render->base.map_vertices = r300_render_map_vertices; + r300render->base.unmap_vertices = r300_render_unmap_vertices; + r300render->base.set_primitive = r300_render_set_primitive; + r300render->base.draw = r300_render_draw; + r300render->base.draw_arrays = r300_render_draw_arrays; + r300render->base.release_vertices = r300_render_release_vertices; + r300render->base.destroy = r300_render_destroy; return &r300render->base; } -struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300) +struct draw_stage* r300_draw_stage(struct r300_context* r300) { struct vbuf_render* render; struct draw_stage* stage; - render = r300_swtcl_render_create(r300); + render = r300_render_create(r300); if (!render) { return NULL; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 2a026e7fca..2a77fd1739 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -132,6 +132,7 @@ static void const struct pipe_constant_buffer* buffer) { struct r300_context* r300 = r300_context(pipe); + int i = r300->shader_constants[shader].user_count; /* This entire chunk of code seems ever-so-slightly baked. * It's as if I've got pipe_buffer* matryoshkas... */ @@ -149,6 +150,17 @@ static void } r300->dirty_state |= R300_NEW_CONSTANTS; + + /* If the number of constants have changed, invalidate the shader. */ + if (r300->shader_constants[shader].user_count != i) { + if (shader == PIPE_SHADER_FRAGMENT && r300->fs) { + r300->fs->translated = FALSE; + r300_translate_fragment_shader(r300, r300->fs); + } else if (shader == PIPE_SHADER_VERTEX && r300->vs) { + r300->vs->translated = FALSE; + r300_translate_vertex_shader(r300, r300->vs); + } + } } /* Create a new depth, stencil, and alpha state based on the CSO dsa state. @@ -293,11 +305,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300->fs = NULL; return; } else if (!fs->translated) { - if (r300_screen(r300->context.screen)->caps->is_r500) { - r500_translate_fragment_shader(r300, (struct r500_fragment_shader*)fs); - } else { - r300_translate_fragment_shader(r300, (struct r300_fragment_shader*)fs); - } + r300_translate_fragment_shader(r300, fs); } fs->translated = TRUE; @@ -330,9 +338,18 @@ static void* r300_create_rs_state(struct pipe_context* pipe, { struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); - /* XXX this is part of HW TCL */ - /* XXX endian control */ - rs->vap_control_status = R300_VAP_TCL_BYPASS; + /* Copy rasterizer state for Draw. */ + rs->rs = *state; + + /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL. + * Else, enable HW TCL and force Draw's TCL off. */ + if (state->bypass_vs_clip_and_viewport || + !r300_screen(pipe->screen)->caps->has_tcl) { + rs->vap_control_status = R300_VAP_TCL_BYPASS; + } else { + rs->rs.bypass_vs_clip_and_viewport = TRUE; + rs->vap_control_status = 0; + } rs->point_size = pack_float_16_6x(state->point_size) | (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); @@ -395,8 +412,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->color_control = R300_SHADE_MODEL_SMOOTH; } - rs->rs = *state; - return (void*)rs; } @@ -581,30 +596,68 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, const struct pipe_vertex_element* elements) { struct r300_context* r300 = r300_context(pipe); - /* XXX Draw */ + draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, count, elements); } static void* r300_create_vs_state(struct pipe_context* pipe, - const struct pipe_shader_state* state) + const struct pipe_shader_state* shader) { - struct r300_context* context = r300_context(pipe); - /* XXX handing this off to Draw for now */ - return draw_create_vertex_shader(context->draw, state); + struct r300_context* r300 = r300_context(pipe); + + if (r300_screen(pipe->screen)->caps->has_tcl) { + struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); + /* Copy state directly into shader. */ + vs->state = *shader; + + tgsi_scan_shader(shader->tokens, &vs->info); + + /* Appease Draw. */ + vs->draw = draw_create_vertex_shader(r300->draw, shader); + + return (void*)vs; + } else { + return draw_create_vertex_shader(r300->draw, shader); + } } -static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { - struct r300_context* context = r300_context(pipe); - /* XXX handing this off to Draw for now */ - draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); +static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) +{ + struct r300_context* r300 = r300_context(pipe); + + if (r300_screen(pipe->screen)->caps->has_tcl) { + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; + + if (vs == NULL) { + r300->vs = NULL; + return; + } else if (!vs->translated) { + r300_translate_vertex_shader(r300, vs); + } + + draw_bind_vertex_shader(r300->draw, vs->draw); + r300->vs = vs; + r300->dirty_state |= R300_NEW_VERTEX_SHADER; + } else { + draw_bind_vertex_shader(r300->draw, + (struct draw_vertex_shader*)shader); + } } -static void r300_delete_vs_state(struct pipe_context* pipe, void* state) +static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) { - struct r300_context* context = r300_context(pipe); - /* XXX handing this off to Draw for now */ - draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); + struct r300_context* r300 = r300_context(pipe); + + if (r300_screen(pipe->screen)->caps->has_tcl) { + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; + + draw_delete_vertex_shader(r300->draw, vs->draw); + FREE(shader); + } else { + draw_delete_vertex_shader(r300->draw, + (struct draw_vertex_shader*)shader); + } } void r300_init_state_functions(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index d761a0302f..f1feafbcf9 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -30,9 +30,9 @@ * The vertex_info struct describes the post-TCL format of vertices. It is * required for Draw when doing SW TCL, and also for describing the * dreaded RS block on R300 chipsets. */ -/* XXX this function should be able to handle vert shaders as well as draw */ static void r300_update_vertex_layout(struct r300_context* r300) { + struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_vertex_format vformat; struct vertex_info vinfo; boolean pos = FALSE, psize = FALSE, fog = FALSE; @@ -74,6 +74,13 @@ static void r300_update_vertex_layout(struct r300_context* r300) } } + if (r300screen->caps->has_tcl) { + for (i = 0; i < info->num_inputs; i++) { + /* XXX should probably do real lookup with vert shader */ + tab[i] = i; + } + } + /* Do the actual vertex_info setup. * * vertex_info has four uints of hardware-specific data in it. @@ -211,7 +218,6 @@ static void r300_update_rs_block(struct r300_context* r300) rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); } - /* Set up at least one texture pointer or RS will not be happy. */ if (tex_count == 0) { rs->ip[0] |= R500_RS_SEL_S(R500_RS_IP_PTR_K0) | @@ -220,15 +226,20 @@ static void r300_update_rs_block(struct r300_context* r300) R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } + /* Rasterize at least one color, or bad things happen. */ + if ((col_count == 0) && (tex_count == 0)) { + col_count++; + } + for (i = 0; i < tex_count; i++) { - rs->inst[i] |= R500_RS_INST_TEX_ID(i) | R500_RS_INST_TEX_CN_WRITE | - R500_RS_INST_TEX_ADDR(fp_offset); + rs->inst[i] |= R500_RS_INST_TEX_ID(i) | + R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_offset); fp_offset++; } for (i = 0; i < col_count; i++) { - rs->inst[i] |= R500_RS_INST_COL_ID(i) | R500_RS_INST_COL_CN_WRITE | - R500_RS_INST_COL_ADDR(fp_offset); + rs->inst[i] |= R500_RS_INST_COL_ID(i) | + R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(fp_offset); fp_offset++; } } else { @@ -268,15 +279,20 @@ static void r300_update_rs_block(struct r300_context* r300) R300_RS_SEL_Q(R300_RS_SEL_K1); } + /* Rasterize at least one color, or bad things happen. */ + if ((col_count == 0) && (tex_count == 0)) { + col_count++; + } + for (i = 0; i < tex_count; i++) { - rs->inst[i] |= R300_RS_INST_TEX_ID(i) | R300_RS_INST_TEX_CN_WRITE | - R300_RS_INST_TEX_ADDR(fp_offset); + rs->inst[i] |= R300_RS_INST_TEX_ID(i) | + R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_offset); fp_offset++; } for (i = 0; i < col_count; i++) { - rs->inst[i] |= R300_RS_INST_COL_ID(i) | R300_RS_INST_COL_CN_WRITE | - R300_RS_INST_COL_ADDR(fp_offset); + rs->inst[i] |= R300_RS_INST_COL_ID(i) | + R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_offset); fp_offset++; } } @@ -289,7 +305,8 @@ static void r300_update_rs_block(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) { + if (r300->dirty_state & + (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) { r300_update_vertex_layout(r300); } diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index b80ff1c1ab..91b93fc367 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -292,6 +292,7 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) return R300_COLOR_FORMAT_ARGB4444; /* 32-bit buffers */ case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: return R300_COLOR_FORMAT_ARGB8888; /* XXX Not in pipe_format case PIPE_FORMAT_A32R32G32B32: @@ -337,6 +338,7 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: return R300_US_OUT_FMT_C4_8 | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index e1837b6380..8bd9b41bd7 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -86,7 +86,7 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(91 + (caps->has_tcl ? 26 : 0)); + BEGIN_CS(79 + (caps->has_tcl ? 7 : 0)); /* Flush PVS. */ OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -141,28 +141,11 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000); - if (caps->has_tcl) { - OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, - (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | - ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | - R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); - } else { - OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, - (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | - ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | - R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); - } - OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, - (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | - (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1); OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405); OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F); /* Vertex size. */ OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8); - OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, 0x00000003); - OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x00000000); - OUT_CS_REG(R300_TX_ENABLE, 0x0); /* XXX */ OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa); @@ -173,33 +156,5 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS(R300_US_OUT_FMT_UNUSED); OUT_CS(R300_US_OUT_FMT_UNUSED); OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0); - /* XXX these magic numbers should be explained when - * this becomes a cached state object */ - if (caps->has_tcl) { - OUT_CS_REG(R300_VAP_CNTL, 0xA | - (0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | - (0xB << R300_VF_MAX_VTX_NUM_SHIFT) | - (caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); - OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, 0x00100000); - OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x00000000); - OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, 0x00000001); - /* XXX translate these back into normal instructions */ - OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x1); - OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0x0); - OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 8); - OUT_CS(0x00F00203); - OUT_CS(0x00D10001); - OUT_CS(0x01248001); - OUT_CS(0x00000000); - OUT_CS(0x00F02203); - OUT_CS(0x00D10021); - OUT_CS(0x01248021); - OUT_CS(0x00000000); - } else { - OUT_CS_REG(R300_VAP_CNTL, 0xA | - (0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | - (0x5 << R300_VF_MAX_VTX_NUM_SHIFT) | - (caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); - } END_CS; } diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h index 8204bf9588..5bea6779fe 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.h +++ b/src/gallium/drivers/r300/r300_state_invariant.h @@ -23,6 +23,7 @@ #ifndef R300_STATE_INVARIANT_H #define R300_STATE_INVARIANT_H +#include "r300_chipset.h" #include "r300_context.h" #include "r300_cs.h" #include "r300_reg.h" diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c index 20b83bd15b..1b02239ee7 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -171,6 +171,26 @@ static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg) (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); } +static INLINE uint32_t r300_rgb_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MOV: + return R300_ALU_OUTC_CMP; + default: + return 0; + } +} + +static INLINE uint32_t r300_alpha_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MOV: + return R300_ALU_OUTA_CMP; + default: + return 0; + } +} + static INLINE uint32_t r500_rgba_op(unsigned op) { switch (op) { @@ -249,6 +269,31 @@ static INLINE uint32_t r500_tex_op(unsigned op) } } +static INLINE void r300_emit_maths(struct r300_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_src_register* src, + struct tgsi_full_dst_register* dst, + unsigned op, + unsigned count) +{ + int i = fs->alu_instruction_count; + + fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + r300_rgb_op(op); + fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; + fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + r300_alpha_op(op); + fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; + + fs->alu_instruction_count++; +} + /* Setup an ALU operation. */ static INLINE void r500_emit_alu(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, @@ -367,11 +412,31 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, } } +static void r300_fs_instruction(struct r300_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_instruction* inst) +{ + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_MOV: + /* src0 -> src1 and src2 forced to zero */ + inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; + inst->FullSrcRegisters[2] = r500_constant_zero; + r300_emit_maths(fs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); + break; + case TGSI_OPCODE_END: + break; + default: + debug_printf("r300: fs: Bad opcode %d\n", + inst->Instruction.Opcode); + break; + } +} + static void r500_fs_instruction(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, struct tgsi_full_instruction* inst) { - int i; /* Switch between opcodes. When possible, prefer using the official * AMD/ATI names for opcodes, please, as it facilitates using the * documentation. */ @@ -487,35 +552,26 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, } } -static void r500_fs_finalize(struct r500_fragment_shader* fs, +static void r300_fs_finalize(struct r3xx_fragment_shader* fs, struct r300_fs_asm* assembler) { - fs->shader.stack_size = assembler->temp_count + assembler->temp_offset; + fs->stack_size = assembler->temp_count + assembler->temp_offset; +} +static void r500_fs_finalize(struct r500_fragment_shader* fs, + struct r300_fs_asm* assembler) +{ /* XXX should this just go with OPCODE_END? */ fs->instructions[fs->instruction_count - 1].inst0 |= R500_INST_LAST; } void r300_translate_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs) -{ - struct tgsi_parse_context parser; - - tgsi_parse_init(&parser, fs->shader.state.tokens); - - while (!tgsi_parse_end_of_tokens(&parser)) { - tgsi_parse_token(&parser); - } - - r300_copy_passthrough_shader(fs); -} - -void r500_translate_fragment_shader(struct r300_context* r300, - struct r500_fragment_shader* fs) + struct r3xx_fragment_shader* fs) { struct tgsi_parse_context parser; int i; + boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; struct r300_constant_buffer* consts = &r300->shader_constants[PIPE_SHADER_FRAGMENT]; @@ -526,7 +582,12 @@ void r500_translate_fragment_shader(struct r300_context* r300, /* Setup starting offset for immediates. */ assembler->imm_offset = consts->user_count; - tgsi_parse_init(&parser, fs->shader.state.tokens); + /* Make sure we start at the beginning of the shader. */ + if (is_r500) { + ((struct r500_fragment_shader*)fs)->instruction_count = 0; + } + + tgsi_parse_init(&parser, fs->state.tokens); while (!tgsi_parse_end_of_tokens(&parser)) { tgsi_parse_token(&parser); @@ -553,25 +614,35 @@ void r500_translate_fragment_shader(struct r300_context* r300, assembler->imm_count++; break; case TGSI_TOKEN_TYPE_INSTRUCTION: - r500_fs_instruction(fs, assembler, - &parser.FullToken.FullInstruction); + if (is_r500) { + r500_fs_instruction((struct r500_fragment_shader*)fs, + assembler, &parser.FullToken.FullInstruction); + } else { + r300_fs_instruction((struct r300_fragment_shader*)fs, + assembler, &parser.FullToken.FullInstruction); + } break; } - } - debug_printf("r300: %d texs and %d colors, first free reg is %d\n", + debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", assembler->tex_count, assembler->color_count, assembler->tex_count + assembler->color_count); consts->count = consts->user_count + assembler->imm_count; - debug_printf("r300: %d total constants, " + debug_printf("r300: fs: %d total constants, " "%d from user and %d from immediates\n", consts->count, consts->user_count, assembler->imm_count); - r500_fs_finalize(fs, assembler); + r300_fs_finalize(fs, assembler); + if (is_r500) { + r500_fs_finalize((struct r500_fragment_shader*)fs, assembler); + } - tgsi_dump(fs->shader.state.tokens); - r500_fs_dump(fs); + tgsi_dump(fs->state.tokens); + /* XXX finish r300 dumper too */ + if (is_r500) { + r500_fs_dump((struct r500_fragment_shader*)fs); + } tgsi_parse_free(&parser); FREE(assembler); diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h index 06c0bb7378..185fdd90f0 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r300_state_shader.h @@ -102,12 +102,9 @@ struct r300_fs_asm { }; void r300_translate_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs); + struct r3xx_fragment_shader* fs); -void r500_translate_fragment_shader(struct r300_context* r300, - struct r500_fragment_shader* fs); - -static const struct r300_fragment_shader r300_passthrough_fragment_shader = { +static struct r300_fragment_shader r300_passthrough_fragment_shader = { /* XXX This is the emission code. TODO: decode OUT_CS_REG(R300_US_CONFIG, 0); OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); @@ -118,24 +115,24 @@ static const struct r300_fragment_shader r300_passthrough_fragment_shader = { */ .alu_instruction_count = 1, .tex_instruction_count = 0, - .indirections = 1, - .shader.stack_size = 2, + .indirections = 0, + .shader.stack_size = 1, .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_ONE) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - R300_ALU_OUTC_MAD, + R300_ALU_OUTC_CMP, .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_ONE) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - R300_ALU_OUTA_MAD, + R300_ALU_OUTA_CMP, .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, }; -static const struct r500_fragment_shader r500_passthrough_fragment_shader = { +static struct r500_fragment_shader r500_passthrough_fragment_shader = { .shader.stack_size = 0, .instruction_count = 1, .instructions[0].inst0 = R500_INST_TYPE_OUT | @@ -161,4 +158,73 @@ static const struct r500_fragment_shader r500_passthrough_fragment_shader = { R500_ALU_RGBA_A_SWIZ_0, }; +static struct r300_fragment_shader r300_texture_fragment_shader = { + /* XXX This is the emission code. TODO: decode + OUT_CS_REG(R300_US_CONFIG, 0); + OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000); +*/ + .alu_instruction_count = 1, + .tex_instruction_count = 0, + .indirections = 0, + .shader.stack_size = 1, + + .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + R300_ALU_OUTC_CMP, + .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, + .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + R300_ALU_OUTA_CMP, + .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +static struct r500_fragment_shader r500_texture_fragment_shader = { + .shader.stack_size = 1, + .instruction_count = 2, + .instructions[0].inst0 = R500_INST_TYPE_TEX | + R500_INST_TEX_SEM_WAIT | + R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | + R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, + .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) | + R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | + R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | + R500_TEX_DST_ADDR(0) | + R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | + R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, + .instructions[0].inst3 = 0x0, + .instructions[0].inst4 = 0x0, + .instructions[0].inst5 = 0x0, + .instructions[1].inst0 = R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | R500_INST_LAST | + R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, + .instructions[1].inst1 = + R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, + .instructions[1].inst2 = + R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, + .instructions[1].inst3 = + R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | + R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, + .instructions[1].inst4 = + R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, + .instructions[1].inst5 = + R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0, +}; + #endif /* R300_STATE_SHADER_H */ diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c new file mode 100644 index 0000000000..47d6c6dfcd --- /dev/null +++ b/src/gallium/drivers/r300/r300_state_tcl.c @@ -0,0 +1,285 @@ +/* + * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_state_tcl.h" + +static void r300_vs_declare(struct r300_vs_asm* assembler, + struct tgsi_full_declaration* decl) +{ + switch (decl->Declaration.File) { + case TGSI_FILE_INPUT: + break; + case TGSI_FILE_OUTPUT: + switch (decl->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + assembler->tab[decl->DeclarationRange.First] = 0; + break; + case TGSI_SEMANTIC_COLOR: + assembler->tab[decl->DeclarationRange.First] = 2; + break; + case TGSI_SEMANTIC_GENERIC: + /* XXX multiple? */ + assembler->tab[decl->DeclarationRange.First] = 6; + break; + default: + debug_printf("r300: vs: Bad semantic declaration %d\n", + decl->Semantic.SemanticName); + break; + } + break; + case TGSI_FILE_CONSTANT: + break; + case TGSI_FILE_TEMPORARY: + assembler->temp_count++; + break; + default: + debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File); + break; + } +} + +static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler, + struct tgsi_src_register* src) +{ + switch (src->File) { + case TGSI_FILE_NULL: + /* Probably a zero or one swizzle */ + return R300_PVS_SRC_REG_INPUT; + break; + case TGSI_FILE_INPUT: + return R300_PVS_SRC_REG_INPUT; + break; + case TGSI_FILE_TEMPORARY: + return R300_PVS_SRC_REG_TEMPORARY; + break; + case TGSI_FILE_CONSTANT: + return R300_PVS_SRC_REG_CONSTANT; + default: + debug_printf("r300: vs: Unimplemented src type %d\n", src->File); + break; + } + return 0; +} + +static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler, + struct tgsi_dst_register* dst) +{ + switch (dst->File) { + case TGSI_FILE_TEMPORARY: + return R300_PVS_DST_REG_TEMPORARY; + break; + case TGSI_FILE_OUTPUT: + return R300_PVS_DST_REG_OUT; + break; + default: + debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File); + break; + } + return 0; +} + +static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler, + struct tgsi_dst_register* dst) +{ + switch (dst->File) { + case TGSI_FILE_TEMPORARY: + return dst->Index; + break; + case TGSI_FILE_OUTPUT: + return assembler->tab[dst->Index]; + break; + default: + debug_printf("r300: vs: Unimplemented dst %d\n", dst->File); + break; + } + return 0; +} + +static uint32_t r300_vs_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MUL: + return R300_VE_MULTIPLY; + case TGSI_OPCODE_ADD: + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_SWZ: + return R300_VE_ADD; + case TGSI_OPCODE_MAD: + return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD; + default: + break; + } + return 0; +} + +static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg) +{ + if (reg->SrcRegister.Extended) { + return reg->SrcRegisterExtSwz.ExtSwizzleX | + (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) | + (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) | + (reg->SrcRegisterExtSwz.ExtSwizzleW << 9); + } else { + return reg->SrcRegister.SwizzleX | + (reg->SrcRegister.SwizzleY << 3) | + (reg->SrcRegister.SwizzleZ << 6) | + (reg->SrcRegister.SwizzleW << 9); + } +} + +static void r300_vs_emit_inst(struct r300_vertex_shader* vs, + struct r300_vs_asm* assembler, + struct tgsi_full_src_register* src, + struct tgsi_full_dst_register* dst, + unsigned op, + unsigned count) +{ + int i = vs->instruction_count; + vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) | + R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) | + R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) | + R300_PVS_DST_WE_XYZW; + switch (count) { + case 3: + vs->instructions[i].inst3 = + R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, + &src[2].SrcRegister)) | + R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) | + R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2])); + /* Fall through */ + case 2: + vs->instructions[i].inst2 = + R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, + &src[1].SrcRegister)) | + R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) | + R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1])); + /* Fall through */ + case 1: + vs->instructions[i].inst1 = + R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, + &src[0].SrcRegister)) | + R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) | + R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0])); + break; + } + vs->instruction_count++; +} + +static void r300_vs_instruction(struct r300_vertex_shader* vs, + struct r300_vs_asm* assembler, + struct tgsi_full_instruction* inst) +{ + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ADD: + case TGSI_OPCODE_MUL: + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 2); + break; + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_SWZ: + inst->FullSrcRegisters[1] = r300_constant_zero; + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 2); + break; + case TGSI_OPCODE_MAD: + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 3); + break; + case TGSI_OPCODE_END: + break; + default: + debug_printf("r300: vs: Bad opcode %d\n", + inst->Instruction.Opcode); + break; + } +} + +void r300_translate_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs) +{ + struct tgsi_parse_context parser; + int i; + struct r300_constant_buffer* consts = + &r300->shader_constants[PIPE_SHADER_VERTEX]; + + struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm); + if (assembler == NULL) { + return; + } + /* Setup starting offset for immediates. */ + assembler->imm_offset = consts->user_count; + + tgsi_parse_init(&parser, vs->state.tokens); + + while (!tgsi_parse_end_of_tokens(&parser)) { + tgsi_parse_token(&parser); + + /* This is seriously the lamest way to create fragment programs ever. + * I blame TGSI. */ + switch (parser.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* Allocated registers sitting at the beginning + * of the program. */ + r300_vs_declare(assembler, &parser.FullToken.FullDeclaration); + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + debug_printf("r300: Emitting immediate to constant buffer, " + "position %d\n", + assembler->imm_offset + assembler->imm_count); + /* I am not amused by the length of these. */ + for (i = 0; i < 4; i++) { + consts->constants[assembler->imm_offset + + assembler->imm_count][i] = + parser.FullToken.FullImmediate.u.ImmediateFloat32[i] + .Float; + } + assembler->imm_count++; + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + r300_vs_instruction(vs, assembler, + &parser.FullToken.FullInstruction); + break; + } + } + + debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n", + assembler->tex_count, assembler->color_count, + assembler->tex_count + assembler->color_count); + + consts->count = consts->user_count + assembler->imm_count; + debug_printf("r300: vs: %d total constants, " + "%d from user and %d from immediates\n", consts->count, + consts->user_count, assembler->imm_count); + + debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0], + assembler->tab[1], assembler->tab[2], assembler->tab[3]); + + tgsi_dump(vs->state.tokens); + /* XXX finish r300 vertex shader dumper */ + r300_vs_dump(vs); + + tgsi_parse_free(&parser); + FREE(assembler); +} diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h new file mode 100644 index 0000000000..3d10e248e1 --- /dev/null +++ b/src/gallium/drivers/r300/r300_state_tcl.h @@ -0,0 +1,146 @@ +/* + * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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. */ + +#ifndef R300_STATE_TCL_H +#define R300_STATE_TCL_H + +#include "tgsi/tgsi_parse.h" + +#include "r300_context.h" +#include "r300_debug.h" +#include "r300_reg.h" +#include "r300_screen.h" + +/* XXX get these to r300_reg */ +#define R300_PVS_DST_OPCODE(x) ((x) << 0) +# define R300_VE_MULTIPLY 2 +# define R300_VE_ADD 3 +#define R300_PVS_DST_MACRO_INST (1 << 7) +# define R300_PVS_MACRO_OP_2CLK_MADD 0 +#define R300_PVS_DST_REG_TYPE(x) ((x) << 8) +# define R300_PVS_DST_REG_TEMPORARY 0 +# define R300_PVS_DST_REG_A0 1 +# define R300_PVS_DST_REG_OUT 2 +# define R300_PVS_DST_REG_OUT_REPL_X 3 +# define R300_PVS_DST_REG_ALT_TEMPORARY 4 +# define R300_PVS_DST_REG_INPUT 5 +#define R300_PVS_DST_OFFSET(x) ((x) << 13) +#define R300_PVS_DST_WE(x) ((x) << 20) +#define R300_PVS_DST_WE_XYZW (0xf << 20) + +#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0) +# define R300_PVS_SRC_REG_TEMPORARY 0 +# define R300_PVS_SRC_REG_INPUT 1 +# define R300_PVS_SRC_REG_CONSTANT 2 +# define R300_PVS_SRC_REG_ALT_TEMPORARY 3 +#define R300_PVS_SRC_OFFSET(x) ((x) << 5) +#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13) +# define R300_PVS_SRC_SELECT_X 0 +# define R300_PVS_SRC_SELECT_Y 1 +# define R300_PVS_SRC_SELECT_Z 2 +# define R300_PVS_SRC_SELECT_W 3 +# define R300_PVS_SRC_SELECT_FORCE_0 4 +# define R300_PVS_SRC_SELECT_FORCE_1 5 +# define R300_PVS_SRC_SWIZZLE_XYZW \ + ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \ + (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13) +# define R300_PVS_SRC_SWIZZLE_ZERO \ + ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \ + (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \ + (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13) +# define R300_PVS_SRC_SWIZZLE_ONE \ + ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \ + (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \ + (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13) + +static const struct tgsi_full_src_register r300_constant_zero = { + .SrcRegister.Extended = TRUE, + .SrcRegister.File = TGSI_FILE_NULL, + .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, +}; + +/* Temporary struct used to hold assembly state while putting together + * fragment programs. */ +struct r300_vs_asm { + /* Pipe context. */ + struct r300_context* r300; + /* Number of colors. */ + unsigned color_count; + /* Number of texcoords. */ + unsigned tex_count; + /* Number of requested temporary registers. */ + unsigned temp_count; + /* Offset for immediate constants. Neither R300 nor R500 can do four + * inline constants per source, so instead we copy immediates into the + * constant buffer. */ + unsigned imm_offset; + /* Number of immediate constants. */ + unsigned imm_count; + /* Offsets into vertex output memory. */ + unsigned tab[16]; +}; + +static struct r300_vertex_shader r300_passthrough_vertex_shader = { + /* XXX translate these back into normal instructions */ + .instruction_count = 2, + .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, + .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[0].inst3 = 0x0, + .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(2) | R300_PVS_DST_WE_XYZW, + .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[1].inst3 = 0x0, +}; + +static struct r300_vertex_shader r300_texture_vertex_shader = { + /* XXX translate these back into normal instructions */ + .instruction_count = 2, + .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, + .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[0].inst3 = 0x0, + .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | + R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | + R300_PVS_DST_OFFSET(6) | R300_PVS_DST_WE_XYZW, + .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | + R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, + .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, + .instructions[1].inst3 = 0x0, +}; + +void r300_translate_vertex_shader(struct r300_context* r300, + struct r300_vertex_shader* vs); + +#endif /* R300_STATE_TCL_H */ diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index db18975a10..79bed03253 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -29,10 +29,10 @@ static void r300_surface_setup(struct pipe_context* pipe, unsigned w, unsigned h) { struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* tex = (struct r300_texture*)dest->texture; unsigned pixpitch = tex->stride / tex->tex.block.size; + CS_LOCALS(r300); r300_emit_blend_state(r300, &blend_clear_state); r300_emit_blend_color_state(r300, &blend_color_clear_state); @@ -80,14 +80,15 @@ static void r300_surface_fill(struct pipe_context* pipe, unsigned w, unsigned h, unsigned color) { + int i; + float r, g, b, a, depth; struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* tex = (struct r300_texture*)dest->texture; - int i; - float r, g, b, a, depth; unsigned pixpitch = tex->stride / tex->tex.block.size; + CS_LOCALS(r300); + a = (float)((color >> 24) & 0xff) / 255.0f; r = (float)((color >> 16) & 0xff) / 255.0f; g = (float)((color >> 8) & 0xff) / 255.0f; b = (float)((color >> 0) & 0xff) / 255.0f; @@ -96,7 +97,7 @@ static void r300_surface_fill(struct pipe_context* pipe, dest, x, y, w, h, pixpitch, color); /* Fallback? */ - if (tex->tex.format != PIPE_FORMAT_A8R8G8B8_UNORM) { + if (FALSE) { debug_printf("r300: Falling back on surface clear..."); util_surface_fill(pipe, dest, x, y, w, h, color); return; @@ -104,6 +105,19 @@ static void r300_surface_fill(struct pipe_context* pipe, r300_surface_setup(r300, dest, x, y, w, h); + /* Vertex shader setup */ + if (caps->has_tcl) { + r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader); + } else { + BEGIN_CS(4); + OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + END_CS; + } + /* Fragment shader setup */ if (caps->is_r500) { r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader); @@ -113,7 +127,32 @@ static void r300_surface_fill(struct pipe_context* pipe, r300_emit_rs_block_state(r300, &r300_rs_block_clear_state); } - BEGIN_CS(21); + BEGIN_CS(31); + + /* VAP stream control, mapping from input memory to PVS/RS memory */ + if (caps->has_tcl) { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); + } else { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); + } + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); + + /* VAP format controls */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT); + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x0); + + /* Disable textures */ + OUT_CS_REG(R300_TX_ENABLE, 0x0); /* Viewport setup */ OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); @@ -132,16 +171,17 @@ static void r300_surface_fill(struct pipe_context* pipe, /* Packet3 with our point vertex */ OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | - (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + /* Position */ OUT_CS_32F(w / 2.0); OUT_CS_32F(h / 2.0); - /* XXX this should be the depth value to clear to */ OUT_CS_32F(1.0); OUT_CS_32F(1.0); + /* Color */ OUT_CS_32F(r); OUT_CS_32F(g); OUT_CS_32F(b); - OUT_CS_32F(1.0); + OUT_CS_32F(a); /* XXX figure out why this is 0xA and not 0x2 */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); @@ -162,23 +202,100 @@ static void r300_surface_copy(struct pipe_context* pipe, unsigned w, unsigned h) { struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); + struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* srctex = (struct r300_texture*)src->texture; struct r300_texture* desttex = (struct r300_texture*)dest->texture; - unsigned pixpitch = srctex->stride / srctex->tex.block.size; + CS_LOCALS(r300); + debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d)," " dimensions %dx%d (pixel pitch %d)\n", src, srcx, srcy, dest, destx, desty, w, h, pixpitch); - /* if ((srctex == desttex) && + if ((srctex == desttex) && ((destx < srcx + w) || (srcx < destx + w)) && - ((desty < srcy + h) || (srcy < destx + h))) { */ - if (TRUE) { + ((desty < srcy + h) || (srcy < desty + h))) { debug_printf("r300: Falling back on surface_copy\n"); - return util_surface_copy(pipe, FALSE, dest, destx, desty, src, + util_surface_copy(pipe, FALSE, dest, destx, desty, src, srcx, srcy, w, h); } + + r300_emit_sampler(r300, &r300_sampler_copy_state, 0); + r300_emit_texture(r300, srctex, 0); + r300_flush_textures(r300); + + /* Vertex shader setup */ + if (caps->has_tcl) { + r300_emit_vertex_shader(r300, &r300_texture_vertex_shader); + } else { + BEGIN_CS(4); + OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + END_CS; + } + + /* Fragment shader setup */ + if (caps->is_r500) { + r500_emit_fragment_shader(r300, &r500_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r500_rs_block_copy_state); + } else { + r300_emit_fragment_shader(r300, &r300_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r300_rs_block_copy_state); + } + + /* VAP stream control, mapping from input memory to PVS/RS memory */ + if (caps->has_tcl) { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT)); + } else { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (6 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT)); + } + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); + + /* VAP format controls */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT); + /* Two components of texture 0 */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2); + + /* Packet3 with our texcoords */ + OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); + OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING | + (4 << R300_PRIM_NUM_VERTICES_SHIFT)); + /* (x , y ) */ + OUT_CS_32F((float)destx); + OUT_CS_32F((float)desty); + OUT_CS_32F((float)srcx); + OUT_CS_32F((float)srcy); + /* (x , y + h) */ + OUT_CS_32F((float)destx); + OUT_CS_32F((float)(desty + h)); + OUT_CS_32F((float)srcx); + OUT_CS_32F((float)(srcy + h)); + /* (x + w, y + h) */ + OUT_CS_32F((float)(destx + w)); + OUT_CS_32F((float)(desty + h)); + OUT_CS_32F((float)(srcx + w)); + OUT_CS_32F((float)(srcy + h)); + /* (x + w, y ) */ + OUT_CS_32F((float)(destx + w)); + OUT_CS_32F((float)desty); + OUT_CS_32F((float)(srcx + w)); + OUT_CS_32F((float)srcy); + + OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); + + r300->dirty_hw++; } void r300_init_surface_functions(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h index b75b3ab84c..894def07aa 100644 --- a/src/gallium/drivers/r300/r300_surface.h +++ b/src/gallium/drivers/r300/r300_surface.h @@ -32,22 +32,23 @@ #include "r300_cs.h" #include "r300_emit.h" #include "r300_state_shader.h" +#include "r300_state_tcl.h" #include "r300_state_inlines.h" -const struct r300_blend_state blend_clear_state = { +static struct r300_blend_state blend_clear_state = { .blend_control = 0x0, .alpha_blend_control = 0x0, .rop = 0x0, .dither = 0x0, }; -const struct r300_blend_color_state blend_color_clear_state = { +static struct r300_blend_color_state blend_color_clear_state = { .blend_color = 0x0, .blend_color_red_alpha = 0x0, .blend_color_green_blue = 0x0, }; -const struct r300_dsa_state dsa_clear_state = { +static struct r300_dsa_state dsa_clear_state = { .alpha_function = 0x0, .alpha_reference = 0x0, .z_buffer_control = 0x0, @@ -57,7 +58,7 @@ const struct r300_dsa_state dsa_clear_state = { .stencil_ref_bf = 0x0, }; -const struct r300_rs_state rs_clear_state = { +static struct r300_rs_state rs_clear_state = { .point_minmax = 0x36000006, .line_control = 0x00030006, .depth_scale_front = 0x0, @@ -71,7 +72,7 @@ const struct r300_rs_state rs_clear_state = { .color_control = R300_SHADE_MODEL_FLAT, }; -const struct r300_rs_block r300_rs_block_clear_state = { +static struct r300_rs_block r300_rs_block_clear_state = { .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | R500_RS_SEL_T(R300_RS_SEL_K0) | R500_RS_SEL_R(R300_RS_SEL_K0) | @@ -81,7 +82,7 @@ const struct r300_rs_block r300_rs_block_clear_state = { .inst_count = 0, }; -const struct r300_rs_block r500_rs_block_clear_state = { +static struct r300_rs_block r500_rs_block_clear_state = { .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) | R500_RS_SEL_T(R500_RS_IP_PTR_K0) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | @@ -91,4 +92,33 @@ const struct r300_rs_block r500_rs_block_clear_state = { .inst_count = 0, }; +/* The following state is used for surface_copy only. */ + +static struct r300_rs_block r300_rs_block_copy_state = { + .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | + R500_RS_SEL_T(R300_RS_SEL_K0) | + R500_RS_SEL_R(R300_RS_SEL_K0) | + R500_RS_SEL_Q(R300_RS_SEL_K1), + .inst[0] = R300_RS_INST_COL_CN_WRITE, + .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, + .inst_count = R300_RS_TX_OFFSET(6), +}; + +static struct r300_rs_block r500_rs_block_copy_state = { + .ip[0] = R500_RS_SEL_S(0) | + R500_RS_SEL_T(1) | + R500_RS_SEL_R(R500_RS_IP_PTR_K0) | + R500_RS_SEL_Q(R500_RS_IP_PTR_K1), + .inst[0] = R500_RS_INST_TEX_CN_WRITE, + .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, + .inst_count = R300_RS_TX_OFFSET(6), +}; + +static struct r300_sampler_state r300_sampler_copy_state = { + .filter0 = R300_TX_WRAP_S(R300_TX_CLAMP) | + R300_TX_WRAP_T(R300_TX_CLAMP) | + R300_TX_MAG_FILTER_NEAREST | + R300_TX_MIN_FILTER_NEAREST, +}; + #endif /* R300_SURFACE_H */ diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 6cdea3d285..fe91f4e184 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -147,7 +147,6 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, surface->height = texture->height[level]; surface->offset = offset; surface->usage = flags; - surface->status = PIPE_SURFACE_STATUS_DEFINED; } return surface; diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index ad108ec446..fa59277438 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -2,6 +2,7 @@ * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. + * Copyright 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -27,6 +28,7 @@ /* Author: * Brian Paul + * Michel Dänzer */ @@ -40,34 +42,15 @@ /** - * Convert packed pixel from one format to another. - */ -static unsigned -convert_color(enum pipe_format srcFormat, unsigned srcColor, - enum pipe_format dstFormat) -{ - ubyte r, g, b, a; - unsigned dstColor; - - util_unpack_color_ub(srcFormat, &srcColor, &r, &g, &b, &a); - util_pack_color_ub(r, g, b, a, dstFormat, &dstColor); - - return dstColor; -} - - - -/** - * Clear the given surface to the specified value. + * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). - * Note: when clearing a color buffer, the clearValue is always - * encoded as PIPE_FORMAT_A8R8G8B8_UNORM. */ void -softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned cv; uint i; if (softpipe->no_rast) @@ -77,31 +60,30 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, softpipe_update_derived(softpipe); /* not needed?? */ #endif - if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { - sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); - softpipe->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_CLEAR; -#if TILE_CLEAR_OPTIMIZATION - return; -#endif - } + if (buffers & PIPE_CLEAR_COLOR) { + for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { + struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; - for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { - if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { - unsigned cv; - if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) { - cv = convert_color(PIPE_FORMAT_A8R8G8B8_UNORM, clearValue, - ps->format); - } - else { - cv = clearValue; - } - sp_tile_cache_clear(softpipe->cbuf_cache[i], cv); - softpipe->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_CLEAR; + util_pack_color(rgba, ps->format, &cv); + sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, cv); + +#if !TILE_CLEAR_OPTIMIZATION + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); +#endif } } + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + static const float zero[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; + + cv = util_pack_z_stencil(ps->format, depth, stencil); + sp_tile_cache_clear(softpipe->zsbuf_cache, zero, cv); + #if !TILE_CLEAR_OPTIMIZATION - /* non-cached surface */ - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); #endif + } } diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h index a8ed1c4ecc..2e450672f5 100644 --- a/src/gallium/drivers/softpipe/sp_clear.h +++ b/src/gallium/drivers/softpipe/sp_clear.h @@ -36,8 +36,8 @@ struct pipe_context; extern void -softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); +softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); #endif /* SP_CLEAR_H */ diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 0c14d92864..9ee86fe787 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -25,22 +25,29 @@ * **************************************************************************/ +/** + * Execute fragment shader using the TGSI interpreter. + */ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" #include "sp_quad.h" - #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_parse.h" + +/** + * Subclass of sp_fragment_shader + */ struct sp_exec_fragment_shader { struct sp_fragment_shader base; + /* No other members for now */ }; @@ -106,8 +113,6 @@ exec_prepare( const struct sp_fragment_shader *base, } - - /* TODO: hide the machine struct in here somewhere, remove from this * interface: */ @@ -116,7 +121,6 @@ exec_run( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct quad_header *quad ) { - /* Compute X, Y, Z, W vals for this quad */ sp_setup_pos_vector(quad->posCoef, (float)quad->input.x0, (float)quad->input.y0, @@ -126,7 +130,6 @@ exec_run( const struct sp_fragment_shader *base, } - static void exec_delete( struct sp_fragment_shader *base ) { @@ -135,9 +138,6 @@ exec_delete( struct sp_fragment_shader *base ) } - - - struct sp_fragment_shader * softpipe_create_fs_exec(struct softpipe_context *softpipe, const struct pipe_shader_state *templ) @@ -160,4 +160,3 @@ softpipe_create_fs_exec(struct softpipe_context *softpipe, return &shader->base; } - diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index f33b3e3285..95c0d982d1 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -25,7 +25,9 @@ * **************************************************************************/ -/* Authors: +/** + * Execute fragment shader using LLVM code generation. + * Authors: * Zack Rusin */ @@ -33,7 +35,6 @@ #include "sp_state.h" #include "sp_fs.h" - #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_memory.h" @@ -41,11 +42,16 @@ #if 0 -struct sp_llvm_fragment_shader { +/** + * Subclass of sp_fragment_shader + */ +struct sp_llvm_fragment_shader +{ struct sp_fragment_shader base; struct gallivm_prog *llvm_prog; }; + static void shade_quad_llvm(struct quad_stage *qs, struct quad_header *quad) @@ -160,7 +166,7 @@ delete_llvm_fs( struct sp_fragment_shader *base ) struct sp_fragment_shader * softpipe_create_fs_llvm(struct softpipe_context *softpipe, - const struct pipe_shader_state *templ) + const struct pipe_shader_state *templ) { struct sp_llvm_fragment_shader *shader = NULL; diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 366abe2ed4..31c3ca21c5 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -25,13 +25,15 @@ * **************************************************************************/ +/** + * Execute fragment shader using runtime SSE code generation. + */ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" #include "sp_quad.h" - #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_memory.h" @@ -56,14 +58,25 @@ typedef void (PIPE_CDECL *codegen_function)( ); -struct sp_sse_fragment_shader { +/** + * Subclass of sp_fragment_shader + */ +struct sp_sse_fragment_shader +{ struct sp_fragment_shader base; - struct x86_function sse2_program; + struct x86_function sse2_program; codegen_function func; float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; +/** cast wrapper */ +static INLINE struct sp_sse_fragment_shader * +sp_sse_fragment_shader(const struct sp_fragment_shader *base) +{ + return (struct sp_sse_fragment_shader *) base; +} + static void fs_sse_prepare( const struct sp_fragment_shader *base, @@ -83,7 +96,7 @@ fs_sse_run( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct quad_header *quad ) { - struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; + struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base); /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */ sp_setup_pos_vector(quad->posCoef, @@ -110,7 +123,7 @@ fs_sse_run( const struct sp_fragment_shader *base, static void fs_sse_delete( struct sp_fragment_shader *base ) { - struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; + struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base); x86_release_func( &shader->sse2_program ); FREE(shader); @@ -156,7 +169,7 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, #else -/* Maybe put this varient in the header file. +/* Maybe put this variant in the header file. */ struct sp_fragment_shader * softpipe_create_fs_sse(struct softpipe_context *softpipe, diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index adca5df73d..ca637a1d6a 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -65,14 +65,11 @@ quad_shade_stage(struct quad_stage *qs) } - /** * Execute fragment shader for the four fragments in the quad. */ static void -shade_quad( - struct quad_stage *qs, - struct quad_header *quad ) +shade_quad(struct quad_stage *qs, struct quad_header *quad) { struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; @@ -85,9 +82,7 @@ shade_quad( machine->InterpCoefs = quad->coef; /* run shader */ - quad->inout.mask &= softpipe->fs->run( softpipe->fs, - &qss->machine, - quad ); + quad->inout.mask &= softpipe->fs->run( softpipe->fs, machine, quad ); /* store outputs */ z_written = FALSE; @@ -135,15 +130,17 @@ shade_quad( } /* shader may cull fragments */ - if( quad->inout.mask ) { + if (quad->inout.mask) { qs->next->run( qs->next, quad ); } } + /** * Per-primitive (or per-begin?) setup */ -static void shade_begin(struct quad_stage *qs) +static void +shade_begin(struct quad_stage *qs) { struct quad_shade_stage *qss = quad_shade_stage(qs); struct softpipe_context *softpipe = qs->softpipe; @@ -157,7 +154,8 @@ static void shade_begin(struct quad_stage *qs) } -static void shade_destroy(struct quad_stage *qs) +static void +shade_destroy(struct quad_stage *qs) { struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; @@ -168,7 +166,8 @@ static void shade_destroy(struct quad_stage *qs) } -struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +struct quad_stage * +sp_quad_shade_stage( struct softpipe_context *softpipe ) { struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 96cb09b905..accc692b66 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -252,16 +252,6 @@ static PIPE_THREAD_ROUTINE( quad_thread, param ) #endif -/** - * Test if x is NaN or +/- infinity. - */ -static INLINE boolean -is_inf_or_nan(float x) -{ - union fi tmp; - tmp.f = x; - return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31); -} /** @@ -506,6 +496,9 @@ static void print_vertex(const struct setup_context *setup, for (i = 0; i < setup->quad.nr_attrs; i++) { debug_printf(" %d: %f %f %f %f\n", i, v[i][0], v[i][1], v[i][2], v[i][3]); + if (util_is_inf_or_nan(v[i][0])) { + debug_printf(" NaN!\n"); + } } } #endif @@ -595,7 +588,7 @@ static boolean setup_sort_vertices( struct setup_context *setup, debug_printf("%s one-over-area %f area %f det %f\n", __FUNCTION__, setup->oneoverarea, area, det ); */ - if (is_inf_or_nan(setup->oneoverarea)) + if (util_is_inf_or_nan(setup->oneoverarea)) return FALSE; } @@ -1065,7 +1058,7 @@ setup_line_coefficients(struct setup_context *setup, /* NOTE: this is not really area but something proportional to it */ area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; - if (area == 0.0f || is_inf_or_nan(area)) + if (area == 0.0f || util_is_inf_or_nan(area)) return FALSE; setup->oneoverarea = 1.0f / area; @@ -1489,16 +1482,6 @@ void setup_prepare( struct setup_context *setup ) softpipe_update_derived(sp); } - /* Mark surfaces as defined now */ - for (i = 0; i < sp->framebuffer.nr_cbufs; i++){ - if (sp->framebuffer.cbufs[i]) { - sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - } - } - if (sp->framebuffer.zsbuf) { - sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - } - /* Note: nr_attrs is only used for debugging (vertex printing) */ setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw); diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index ef04843f17..b04c2a63ad 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -27,6 +27,7 @@ #include "util/u_rect.h" #include "sp_context.h" +#include "sp_surface.h" static void diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 48b2c22af4..c0113c47ad 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -138,7 +138,6 @@ softpipe_texture_create(struct pipe_screen *screen, goto fail; } - assert(p_atomic_read(&spt->base.reference.count) == 1); return &spt->base; fail: @@ -328,7 +327,7 @@ static void * softpipe_transfer_map( struct pipe_screen *screen, struct pipe_transfer *transfer ) { - ubyte *map; + ubyte *map, *xfer_map; struct softpipe_texture *spt; unsigned flags = 0; @@ -358,9 +357,11 @@ softpipe_transfer_map( struct pipe_screen *screen, softpipe_screen(screen)->timestamp++; } - return map + softpipe_transfer(transfer)->offset + + xfer_map = map + softpipe_transfer(transfer)->offset + transfer->y / transfer->block.height * transfer->stride + transfer->x / transfer->block.width * transfer->block.size; + /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ + return xfer_map; } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 69292753f1..1f9b8f1f4f 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -57,9 +57,9 @@ struct softpipe_tile_cache struct pipe_texture *texture; /**< if caching a texture */ struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; - float clear_color[4]; - uint clear_val; - boolean depth_stencil; /** Is the surface a depth/stencil format? */ + float clear_color[4]; /**< for color bufs */ + uint clear_val; /**< for z+stencil, or packed color clear value */ + boolean depth_stencil; /**< Is the surface a depth/stencil format? */ struct pipe_transfer *tex_trans; void *tex_trans_map; @@ -599,40 +599,17 @@ sp_get_cached_tile_tex(struct softpipe_context *sp, * Save the color and set a 'clearflag' for each tile of the screen. */ void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue) +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, + uint clearValue) { - uint r, g, b, a; uint pos; - tc->clear_val = clearValue; - - switch (tc->transfer->format) { - case PIPE_FORMAT_R8G8B8A8_UNORM: - r = (clearValue >> 24) & 0xff; - g = (clearValue >> 16) & 0xff; - b = (clearValue >> 8) & 0xff; - a = (clearValue ) & 0xff; - break; - case PIPE_FORMAT_A8R8G8B8_UNORM: - r = (clearValue >> 16) & 0xff; - g = (clearValue >> 8) & 0xff; - b = (clearValue ) & 0xff; - a = (clearValue >> 24) & 0xff; - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - r = (clearValue >> 8) & 0xff; - g = (clearValue >> 16) & 0xff; - b = (clearValue >> 24) & 0xff; - a = (clearValue ) & 0xff; - break; - default: - r = g = b = a = 0; - } + tc->clear_color[0] = rgba[0]; + tc->clear_color[1] = rgba[1]; + tc->clear_color[2] = rgba[2]; + tc->clear_color[3] = rgba[3]; - tc->clear_color[0] = r / 255.0f; - tc->clear_color[1] = g / 255.0f; - tc->clear_color[2] = b / 255.0f; - tc->clear_color[3] = a / 255.0f; + tc->clear_val = clearValue; #if TILE_CLEAR_OPTIMIZATION /* set flags to indicate all the tiles are cleared */ diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 9ac3fdda94..8f247d0e58 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -89,7 +89,8 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc); extern void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue); +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, + uint clearValue); extern struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_context *softpipe, diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index f0e1cd596d..73dce20372 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -10,15 +10,14 @@ This directory contains a Gallium3D pipe driver which traces all incoming calls. To build, invoke scons on the top dir as - scons statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib + scons dri=no statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib = Usage = To use do - ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib ensure the right libGL.so is being picked by doing @@ -26,6 +25,7 @@ ensure the right libGL.so is being picked by doing and then try running + export XMESA_TRACE=y GALLIUM_TRACE=tri.trace progs/trivial/tri which should create a tri.trace file, which is an XML file. You can view copying diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index c894972904..d8d5821a1d 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -58,16 +58,14 @@ static INLINE struct pipe_texture * trace_texture_unwrap(struct trace_context *tr_ctx, struct pipe_texture *texture) { - struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); struct trace_texture *tr_tex; if(!texture) return NULL; - tr_tex = trace_texture(tr_scr, texture); + tr_tex = trace_texture(texture); assert(tr_tex->texture); - assert(tr_tex->texture->screen == tr_scr->screen); return tr_tex->texture; } @@ -77,7 +75,6 @@ trace_surface_unwrap(struct trace_context *tr_ctx, struct pipe_surface *surface) { struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); - struct trace_texture *tr_tex; struct trace_surface *tr_surf; if(!surface) @@ -87,8 +84,7 @@ trace_surface_unwrap(struct trace_context *tr_ctx, if(!surface->texture) return surface; - tr_tex = trace_texture(tr_scr, surface->texture); - tr_surf = trace_surface(tr_tex, surface); + tr_surf = trace_surface(surface); assert(tr_surf->surface); assert(tr_surf->surface->texture->screen == tr_scr->screen); @@ -973,21 +969,23 @@ trace_context_surface_fill(struct pipe_context *_pipe, static INLINE void trace_context_clear(struct pipe_context *_pipe, - struct pipe_surface *surface, - unsigned clearValue) + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - surface = trace_surface_unwrap(tr_ctx, surface); - trace_dump_call_begin("pipe_context", "clear"); trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, surface); - trace_dump_arg(uint, clearValue); + trace_dump_arg(uint, buffers); + trace_dump_arg_array(float, rgba, 4); + trace_dump_arg(float, depth); + trace_dump_arg(uint, stencil); - pipe->clear(pipe, surface, clearValue);; + pipe->clear(pipe, buffers, rgba, depth, stencil); trace_dump_call_end(); } @@ -1037,9 +1035,9 @@ struct pipe_context * trace_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) { - struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_screen *tr_scr; struct trace_context *tr_ctx; - struct pipe_screen *screen = tr_scr->screen; + struct pipe_screen *screen; if(!pipe) goto error1; @@ -1047,6 +1045,9 @@ trace_context_create(struct pipe_screen *_screen, if(!trace_dump_enabled()) goto error1; + tr_scr = trace_screen(_screen); + screen = tr_scr->screen; + tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) goto error1; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 6837c94542..2618883e70 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -40,11 +40,12 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) #include <stdlib.h> #endif #include "pipe/p_compiler.h" +#include "pipe/p_thread.h" #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -58,6 +59,8 @@ static struct util_stream *stream = NULL; static unsigned refcount = 0; +static pipe_mutex call_mutex; +static long unsigned call_no = 0; static INLINE void @@ -218,6 +221,8 @@ trace_dump_trace_close(void) util_stream_close(stream); stream = NULL; refcount = 0; + call_no = 0; + pipe_mutex_destroy(call_mutex); } } @@ -235,11 +240,13 @@ boolean trace_dump_trace_begin() if(!stream) return FALSE; + pipe_mutex_init(call_mutex); + trace_dump_writes("<?xml version='1.0' encoding='UTF-8'?>\n"); trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n"); trace_dump_writes("<trace version='0.1'>\n"); -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) /* Linux applications rarely cleanup GL / Gallium resources so catch * application exit here */ atexit(trace_dump_trace_close); @@ -265,8 +272,16 @@ void trace_dump_trace_end(void) void trace_dump_call_begin(const char *klass, const char *method) { + pipe_mutex_lock(call_mutex); + ++call_no; trace_dump_indent(1); - trace_dump_tag_begin2("call", "class", klass, "method", method); + trace_dump_writes("<call no=\'"); + trace_dump_writef("%lu", call_no); + trace_dump_writes("\' class =\'"); + trace_dump_escape(klass); + trace_dump_writes("\' method=\'"); + trace_dump_escape(method); + trace_dump_writes("\'>"); trace_dump_newline(); } @@ -276,6 +291,7 @@ void trace_dump_call_end(void) trace_dump_tag_end("call"); trace_dump_newline(); util_stream_flush(stream); + pipe_mutex_unlock(call_mutex); } void trace_dump_arg_begin(const char *name) @@ -420,8 +436,7 @@ void trace_dump_buffer_ptr(struct pipe_buffer *_buffer) void trace_dump_texture_ptr(struct pipe_texture *_texture) { if (_texture) { - struct trace_screen *tr_scr = trace_screen(_texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); trace_dump_ptr(tr_tex->texture); } else { trace_dump_null(); @@ -431,9 +446,7 @@ void trace_dump_texture_ptr(struct pipe_texture *_texture) void trace_dump_surface_ptr(struct pipe_surface *_surface) { if (_surface) { - struct trace_screen *tr_scr = trace_screen(_surface->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _surface->texture); - struct trace_surface *tr_surf = trace_surface(tr_tex, _surface); + struct trace_surface *tr_surf = trace_surface(_surface); trace_dump_ptr(tr_surf->surface); } else { trace_dump_null(); @@ -443,9 +456,7 @@ void trace_dump_surface_ptr(struct pipe_surface *_surface) void trace_dump_transfer_ptr(struct pipe_transfer *_transfer) { if (_transfer) { - struct trace_screen *tr_scr = trace_screen(_transfer->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_tran = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_tran = trace_transfer(_transfer); trace_dump_ptr(tr_tran->transfer); } else { trace_dump_null(); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 954576d721..6792505383 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -159,8 +159,7 @@ trace_screen_flush_frontbuffer(struct pipe_screen *_screen, void *context_private) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _surface->texture); - struct trace_surface *tr_surf = trace_surface(tr_tex, _surface); + struct trace_surface *tr_surf = trace_surface(_surface); struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *surface = tr_surf->surface; @@ -242,7 +241,7 @@ static void trace_screen_texture_destroy(struct pipe_texture *_texture) { struct trace_screen *tr_scr = trace_screen(_texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = tr_tex->texture; @@ -255,7 +254,7 @@ trace_screen_texture_destroy(struct pipe_texture *_texture) trace_dump_call_end(); - trace_texture_destroy(tr_scr, _texture); + trace_texture_destroy(tr_tex); } @@ -272,7 +271,7 @@ trace_screen_get_tex_surface(struct pipe_screen *_screen, unsigned usage) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = tr_tex->texture; struct pipe_surface *result = NULL; @@ -304,8 +303,7 @@ static void trace_screen_tex_surface_destroy(struct pipe_surface *_surface) { struct trace_screen *tr_scr = trace_screen(_surface->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _surface->texture); - struct trace_surface *tr_surf = trace_surface(tr_tex, _surface); + struct trace_surface *tr_surf = trace_surface(_surface); struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *surface = tr_surf->surface; @@ -316,7 +314,7 @@ trace_screen_tex_surface_destroy(struct pipe_surface *_surface) trace_dump_call_end(); - trace_surface_destroy(tr_tex, _surface); + trace_surface_destroy(tr_surf); } @@ -334,7 +332,7 @@ trace_screen_get_tex_transfer(struct pipe_screen *_screen, unsigned x, unsigned y, unsigned w, unsigned h) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _texture); + struct trace_texture *tr_tex = trace_texture(_texture); struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = tr_tex->texture; struct pipe_transfer *result = NULL; @@ -372,10 +370,9 @@ static void trace_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) { struct trace_screen *tr_scr = trace_screen(_transfer->texture->screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_tran = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_trans = trace_transfer(_transfer); struct pipe_screen *screen = tr_scr->screen; - struct pipe_transfer *transfer = tr_tran->transfer; + struct pipe_transfer *transfer = tr_trans->transfer; trace_dump_call_begin("pipe_screen", "tex_transfer_destroy"); @@ -384,7 +381,7 @@ trace_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) trace_dump_call_end(); - trace_transfer_destroy(tr_tex, _transfer); + trace_transfer_destroy(tr_trans); } @@ -393,8 +390,7 @@ trace_screen_transfer_map(struct pipe_screen *_screen, struct pipe_transfer *_transfer) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_trans = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_trans = trace_transfer(_transfer); struct pipe_screen *screen = tr_scr->screen; struct pipe_transfer *transfer = tr_trans->transfer; void *map; @@ -416,8 +412,7 @@ trace_screen_transfer_unmap(struct pipe_screen *_screen, struct pipe_transfer *_transfer) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_texture *tr_tex = trace_texture(tr_scr, _transfer->texture); - struct trace_transfer *tr_trans = trace_transfer(tr_tex, _transfer); + struct trace_transfer *tr_trans = trace_transfer(_transfer); struct pipe_screen *screen = tr_scr->screen; struct pipe_transfer *transfer = tr_trans->transfer; @@ -706,7 +701,7 @@ trace_screen_buffer_unmap(struct pipe_screen *_screen, struct pipe_buffer *buffer = tr_buf->buffer; if (tr_buf->map && !tr_buf->range_flushed) - buffer_write(screen, buffer, tr_buf->map, 0, buffer->size); + buffer_write(screen, buffer, 0, tr_buf->map, buffer->size); tr_buf->map = NULL; tr_buf->range_flushed = FALSE; screen->buffer_unmap(screen, buffer); diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index f9fbe9aee7..a9570c1aeb 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -406,8 +406,6 @@ void trace_dump_surface(const struct pipe_surface *state) trace_dump_reference(&state->reference); trace_dump_member(format, state, format); - trace_dump_member(uint, state, status); - trace_dump_member(uint, state, clear_value); trace_dump_member(uint, state, width); trace_dump_member(uint, state, height); diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c index 7b392f0728..f4e433792b 100644 --- a/src/gallium/drivers/trace/tr_texture.c +++ b/src/gallium/drivers/trace/tr_texture.c @@ -62,10 +62,8 @@ error: void -trace_texture_destroy(struct trace_screen *tr_scr, - struct pipe_texture *texture) +trace_texture_destroy(struct trace_texture *tr_tex) { - struct trace_texture *tr_tex = trace_texture(tr_scr, texture); pipe_texture_reference(&tr_tex->texture, NULL); FREE(tr_tex); } @@ -102,10 +100,8 @@ error: void -trace_surface_destroy(struct trace_texture *tr_tex, - struct pipe_surface *surface) +trace_surface_destroy(struct trace_surface *tr_surf) { - struct trace_surface *tr_surf = trace_surface(tr_tex, surface); pipe_texture_reference(&tr_surf->base.texture, NULL); pipe_surface_reference(&tr_surf->surface, NULL); FREE(tr_surf); @@ -143,10 +139,8 @@ error: void -trace_transfer_destroy(struct trace_texture *tr_tex, - struct pipe_transfer *transfer) +trace_transfer_destroy(struct trace_transfer *tr_trans) { - struct trace_transfer *tr_trans = trace_transfer(tr_tex, transfer); struct pipe_screen *screen = tr_trans->transfer->texture->screen; pipe_texture_reference(&tr_trans->base.texture, NULL); screen->tex_transfer_destroy(tr_trans->transfer); diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h index 9c21bc7d27..14dafd8b2c 100644 --- a/src/gallium/drivers/trace/tr_texture.h +++ b/src/gallium/drivers/trace/tr_texture.h @@ -62,37 +62,31 @@ struct trace_transfer static INLINE struct trace_texture * -trace_texture(struct trace_screen *tr_scr, - struct pipe_texture *texture) +trace_texture(struct pipe_texture *texture) { if(!texture) return NULL; - assert(tr_scr); - assert(texture->screen == &tr_scr->base); + (void)trace_screen(texture->screen); return (struct trace_texture *)texture; } static INLINE struct trace_surface * -trace_surface(struct trace_texture *tr_tex, - struct pipe_surface *surface) +trace_surface(struct pipe_surface *surface) { if(!surface) return NULL; - assert(tr_tex); - assert(surface->texture == &tr_tex->base); + (void)trace_texture(surface->texture); return (struct trace_surface *)surface; } static INLINE struct trace_transfer * -trace_transfer(struct trace_texture *tr_tex, - struct pipe_transfer *transfer) +trace_transfer(struct pipe_transfer *transfer) { if(!transfer) return NULL; - assert(tr_tex); - assert(transfer->texture == &tr_tex->base); + (void)trace_texture(transfer->texture); return (struct trace_transfer *)transfer; } @@ -102,24 +96,21 @@ trace_texture_create(struct trace_screen *tr_scr, struct pipe_texture *texture); void -trace_texture_destroy(struct trace_screen *tr_scr, - struct pipe_texture *texture); +trace_texture_destroy(struct trace_texture *tr_tex); struct pipe_surface * trace_surface_create(struct trace_texture *tr_tex, struct pipe_surface *surface); void -trace_surface_destroy(struct trace_texture *tr_tex, - struct pipe_surface *surface); +trace_surface_destroy(struct trace_surface *tr_surf); struct pipe_transfer * trace_transfer_create(struct trace_texture *tr_tex, struct pipe_transfer *transfer); void -trace_transfer_destroy(struct trace_texture *tr_tex, - struct pipe_transfer *transfer); +trace_transfer_destroy(struct trace_transfer *tr_trans); #endif /* TR_TEXTURE_H_ */ diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 9cd621e7ab..7be95e0e75 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -68,6 +68,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. <xsl:template match="call"> <li> + <xsl:attribute name="value"> + <xsl:apply-templates select="@no"/> + </xsl:attribute> <span class="fun"> <xsl:value-of select="@class"/> <xsl:text>::</xsl:text> |