summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c25
-rw-r--r--src/gallium/drivers/failover/fo_context.c23
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c26
-rw-r--r--src/gallium/drivers/i965simple/brw_context.c25
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c2
-rw-r--r--src/gallium/drivers/nv04/nv04_context.c27
-rw-r--r--src/gallium/drivers/nv04/nv04_transfer.c1
-rw-r--r--src/gallium/drivers/nv10/nv10_context.c26
-rw-r--r--src/gallium/drivers/nv10/nv10_transfer.c1
-rw-r--r--src/gallium/drivers/nv20/nv20_context.c27
-rw-r--r--src/gallium/drivers/nv20/nv20_transfer.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_context.c26
-rw-r--r--src/gallium/drivers/nv30/nv30_transfer.c1
-rw-r--r--src/gallium/drivers/nv40/nv40_context.c26
-rw-r--r--src/gallium/drivers/nv40/nv40_transfer.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c74
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c26
-rw-r--r--src/gallium/drivers/r300/r300_context.c26
-rw-r--r--src/gallium/drivers/r300/r300_context.h11
-rw-r--r--src/gallium/drivers/r300/r300_emit.c6
-rw-r--r--src/gallium/drivers/r300/r300_render.c16
-rw-r--r--src/gallium/drivers/r300/r300_state.c42
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c329
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.c36
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c23
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.h16
-rw-r--r--src/gallium/drivers/trace/tr_buffer.c9
-rw-r--r--src/gallium/drivers/trace/tr_buffer.h8
-rw-r--r--src/gallium/drivers/trace/tr_context.c67
-rw-r--r--src/gallium/drivers/trace/tr_context.h2
-rw-r--r--src/gallium/drivers/trace/tr_dump.c177
-rw-r--r--src/gallium/drivers/trace/tr_dump.h38
-rw-r--r--src/gallium/drivers/trace/tr_screen.c41
-rw-r--r--src/gallium/drivers/trace/tr_screen.h33
-rw-r--r--src/gallium/drivers/trace/tr_texture.c21
-rw-r--r--src/gallium/drivers/trace/tr_texture.h6
37 files changed, 1009 insertions, 237 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 808be589bd9..ebb7a7acc44 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -99,6 +99,28 @@ static const struct debug_named_value cell_debug_flags[] = {
{NULL, 0}
};
+static unsigned int
+cell_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+cell_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
struct pipe_context *
cell_create_context(struct pipe_screen *screen,
@@ -122,6 +144,9 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.clear = cell_clear;
cell->pipe.flush = cell_flush;
+ cell->pipe.is_texture_referenced = cell_is_texture_referenced;
+ cell->pipe.is_buffer_referenced = cell_is_buffer_referenced;
+
#if 0
cell->pipe.begin_query = cell_begin_query;
cell->pipe.end_query = cell_end_query;
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index fcad717cf83..37184eac7b1 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -105,7 +105,28 @@ static boolean failover_draw_arrays( struct pipe_context *pipe,
return failover_draw_elements(pipe, NULL, 0, prim, start, count);
}
+static unsigned int
+failover_is_texture_referenced( struct pipe_context *_pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ struct failover_context *failover = failover_context( _pipe );
+ struct pipe_context *pipe = (failover->mode == FO_HW) ?
+ failover->hw : failover->sw;
+
+ return pipe->is_texture_referenced(pipe, texture, face, level);
+}
+static unsigned int
+failover_is_buffer_referenced( struct pipe_context *_pipe,
+ struct pipe_buffer *buf)
+{
+ struct failover_context *failover = failover_context( _pipe );
+ struct pipe_context *pipe = (failover->mode == FO_HW) ?
+ failover->hw : failover->sw;
+
+ return pipe->is_buffer_referenced(pipe, buf);
+}
struct pipe_context *failover_create( struct pipe_context *hw,
struct pipe_context *sw )
@@ -151,6 +172,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
#endif
failover->pipe.flush = hw->flush;
+ failover->pipe.is_texture_referenced = failover_is_texture_referenced;
+ failover->pipe.is_buffer_referenced = failover_is_buffer_referenced;
failover->dirty = 0;
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index 3e3a5968849..ccf9bb31fb0 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -136,6 +136,29 @@ static boolean i915_draw_arrays( struct pipe_context *pipe,
}
+static unsigned int
+i915_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+i915_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *i915_create_context( struct pipe_screen *screen,
struct pipe_winsys *pipe_winsys,
@@ -160,6 +183,9 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
i915->pipe.draw_elements = i915_draw_elements;
i915->pipe.draw_range_elements = i915_draw_range_elements;
+ i915->pipe.is_texture_referenced = i915_is_texture_referenced;
+ i915->pipe.is_buffer_referenced = i915_is_buffer_referenced;
+
/*
* Create drawing context and plug our rendering stage into it.
*/
diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c
index c74cbf8d73e..9b33285bc73 100644
--- a/src/gallium/drivers/i965simple/brw_context.c
+++ b/src/gallium/drivers/i965simple/brw_context.c
@@ -73,6 +73,28 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps,
pipe->surface_fill(pipe, ps, x, y, w, h, clearValue);
}
+static unsigned int
+brw_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+brw_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
struct pipe_context *brw_create(struct pipe_screen *screen,
struct brw_winsys *brw_winsys,
@@ -94,6 +116,9 @@ struct pipe_context *brw_create(struct pipe_screen *screen,
brw->pipe.destroy = brw_destroy;
brw->pipe.clear = brw_clear;
+ brw->pipe.is_texture_referenced = brw_is_texture_referenced;
+ brw->pipe.is_buffer_referenced = brw_is_buffer_referenced;
+
brw_init_surface_functions(brw);
brw_init_texture_functions(brw);
brw_init_state_functions(brw);
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index f44bd17451b..8aea8c05581 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -240,7 +240,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
- if (pt->compressed) {
+ if (pf_is_compressed(pt->format)) {
pack_y_pitch = (height + 3) / 4;
if (pack_x_pitch > align(width, align_w)) {
diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c
index d6710cd8924..17166c9f51d 100644
--- a/src/gallium/drivers/nv04/nv04_context.c
+++ b/src/gallium/drivers/nv04/nv04_context.c
@@ -64,6 +64,30 @@ nv04_init_hwctx(struct nv04_context *nv04)
return TRUE;
}
+static unsigned int
+nv04_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv04_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+
struct pipe_context *
nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -89,6 +113,9 @@ nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv04->pipe.clear = nv04_clear;
nv04->pipe.flush = nv04_flush;
+ nv04->pipe.is_texture_referenced = nv04_is_texture_referenced;
+ nv04->pipe.is_buffer_referenced = nv04_is_buffer_referenced;
+
nv04_init_surface_functions(nv04);
nv04_init_state_functions(nv04);
diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c
index e925a44e298..854b855d64a 100644
--- a/src/gallium/drivers/nv04/nv04_transfer.c
+++ b/src/gallium/drivers/nv04/nv04_transfer.c
@@ -43,7 +43,6 @@ nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c
index ef2c0c5d9fd..3da8d2f568f 100644
--- a/src/gallium/drivers/nv10/nv10_context.c
+++ b/src/gallium/drivers/nv10/nv10_context.c
@@ -257,6 +257,29 @@ nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
{
}
+static unsigned int
+nv10_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv10_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -282,6 +305,9 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv10->pipe.clear = nv10_clear;
nv10->pipe.flush = nv10_flush;
+ nv10->pipe.is_texture_referenced = nv10_is_texture_referenced;
+ nv10->pipe.is_buffer_referenced = nv10_is_buffer_referenced;
+
nv10_init_surface_functions(nv10);
nv10_init_state_functions(nv10);
diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c
index 5a99225409c..c06b8d34c72 100644
--- a/src/gallium/drivers/nv10/nv10_transfer.c
+++ b/src/gallium/drivers/nv10/nv10_transfer.c
@@ -43,7 +43,6 @@ nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv20/nv20_context.c b/src/gallium/drivers/nv20/nv20_context.c
index 1659aec8fab..cbc41707d54 100644
--- a/src/gallium/drivers/nv20/nv20_context.c
+++ b/src/gallium/drivers/nv20/nv20_context.c
@@ -380,6 +380,30 @@ nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
{
}
+
+static unsigned int
+nv20_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv20_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -405,6 +429,9 @@ nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv20->pipe.clear = nv20_clear;
nv20->pipe.flush = nv20_flush;
+ nv20->pipe.is_texture_referenced = nv20_is_texture_referenced;
+ nv20->pipe.is_buffer_referenced = nv20_is_buffer_referenced;
+
nv20_init_surface_functions(nv20);
nv20_init_state_functions(nv20);
diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c
index e5255296aae..5018995596c 100644
--- a/src/gallium/drivers/nv20/nv20_transfer.c
+++ b/src/gallium/drivers/nv20/nv20_transfer.c
@@ -43,7 +43,6 @@ nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
index 61654f8756a..f827bdc78b1 100644
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ b/src/gallium/drivers/nv30/nv30_context.c
@@ -31,6 +31,29 @@ nv30_destroy(struct pipe_context *pipe)
FREE(nv30);
}
+static unsigned int
+nv30_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv30_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv30_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -55,6 +78,9 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv30->pipe.clear = nv30_clear;
nv30->pipe.flush = nv30_flush;
+ nv30->pipe.is_texture_referenced = nv30_is_texture_referenced;
+ nv30->pipe.is_buffer_referenced = nv30_is_buffer_referenced;
+
nv30_init_query_functions(nv30);
nv30_init_surface_functions(nv30);
nv30_init_state_functions(nv30);
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
index 8b915b35bd4..23675718781 100644
--- a/src/gallium/drivers/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nv30/nv30_transfer.c
@@ -43,7 +43,6 @@ nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c
index 5d325f5067f..8eba6a43ef9 100644
--- a/src/gallium/drivers/nv40/nv40_context.c
+++ b/src/gallium/drivers/nv40/nv40_context.c
@@ -31,6 +31,29 @@ nv40_destroy(struct pipe_context *pipe)
FREE(nv40);
}
+static unsigned int
+nv40_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv40_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -55,6 +78,9 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv40->pipe.clear = nv40_clear;
nv40->pipe.flush = nv40_flush;
+ nv40->pipe.is_texture_referenced = nv40_is_texture_referenced;
+ nv40->pipe.is_buffer_referenced = nv40_is_buffer_referenced;
+
nv40_init_query_functions(nv40);
nv40_init_surface_functions(nv40);
nv40_init_state_functions(nv40);
diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c
index 728e8b56745..ce45055fe82 100644
--- a/src/gallium/drivers/nv40/nv40_transfer.c
+++ b/src/gallium/drivers/nv40/nv40_transfer.c
@@ -43,7 +43,6 @@ nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index db44a9da0e3..33427a15a56 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -27,64 +27,42 @@
#include "nv50_context.h"
void
-nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps,
- unsigned clearValue)
+nv50_clear(struct pipe_context *pipe, unsigned buffers,
+ const float *rgba, double depth, unsigned stencil)
{
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->nvws->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_framebuffer_state fb, s_fb = nv50->framebuffer;
- struct pipe_scissor_state sc, s_sc = nv50->scissor;
- unsigned dirty = nv50->dirty;
+ struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+ unsigned mode = 0, i;
- nv50->dirty = 0;
+ if (!nv50_state_validate(nv50))
+ return;
- if (ps->format == PIPE_FORMAT_Z24S8_UNORM ||
- ps->format == PIPE_FORMAT_Z16_UNORM) {
- fb.nr_cbufs = 0;
- fb.zsbuf = ps;
- } else {
- fb.nr_cbufs = 1;
- fb.cbufs[0] = ps;
- fb.zsbuf = NULL;
+ if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4);
+ OUT_RING (chan, fui(rgba[0]));
+ OUT_RING (chan, fui(rgba[1]));
+ OUT_RING (chan, fui(rgba[2]));
+ OUT_RING (chan, fui(rgba[3]));
+ mode |= 0x3c;
}
- fb.width = ps->width;
- fb.height = ps->height;
- pipe->set_framebuffer_state(pipe, &fb);
- sc.minx = sc.miny = 0;
- sc.maxx = fb.width;
- sc.maxy = fb.height;
- pipe->set_scissor_state(pipe, &sc);
+ if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
+ OUT_RING (chan, fui(depth));
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
+ OUT_RING (chan, stencil & 0xff);
- nv50_state_validate(nv50);
-
- switch (ps->format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- BEGIN_RING(chan, tesla, 0x0d80, 4);
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 16) & 0xff));
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 8) & 0xff));
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 0) & 0xff));
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 24) & 0xff));
- BEGIN_RING(chan, tesla, 0x19d0, 1);
- OUT_RING (chan, 0x3c);
- break;
- case PIPE_FORMAT_Z24S8_UNORM:
- BEGIN_RING(chan, tesla, 0x0d90, 1);
- OUT_RINGf (chan, (float)(clearValue >> 8) * (1.0 / 16777215.0));
- BEGIN_RING(chan, tesla, 0x0da0, 1);
- OUT_RING (chan, clearValue & 0xff);
- BEGIN_RING(chan, tesla, 0x19d0, 1);
- OUT_RING (chan, 0x03);
- break;
- default:
- pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height,
- clearValue);
- break;
+ mode |= 0x03;
}
- pipe->set_framebuffer_state(pipe, &s_fb);
- pipe->set_scissor_state(pipe, &s_sc);
- nv50->dirty |= dirty;
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
+ OUT_RING (chan, mode);
+
+ for (i = 1; i < fb->nr_cbufs; i++) {
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
+ OUT_RING (chan, (i << 6) | 0x3c);
+ }
}
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 565a5da668c..a511f655c19 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -51,6 +51,29 @@ nv50_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
{
}
+static unsigned int
+nv50_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv50_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -76,6 +99,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv50->pipe.flush = nv50_flush;
+ nv50->pipe.is_texture_referenced = nv50_is_texture_referenced;
+ nv50->pipe.is_buffer_referenced = nv50_is_buffer_referenced;
+
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
nv50_init_query_functions(nv50);
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 31efe914171..6bdf544a05c 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -102,6 +102,29 @@ static void r300_destroy_context(struct pipe_context* context) {
FREE(r300);
}
+static unsigned int
+r300_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+r300_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct r300_winsys* r300_winsys)
{
@@ -124,6 +147,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_draw_range_elements;
+ r300->context.is_texture_referenced = r300_is_texture_referenced;
+ r300->context.is_buffer_referenced = r300_is_buffer_referenced;
+
r300->draw = draw_create();
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index fec2bad5461..4c695c1195a 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -60,7 +60,7 @@ struct r300_dsa_state {
};
struct r300_rs_state {
- /* XXX icky as fucking hell */
+ /* Draw-specific rasterizer state */
struct pipe_rasterizer_state rs;
uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */
@@ -225,10 +225,11 @@ struct r300_vertex_format {
uint32_t vap_prog_stream_cntl[8];
/* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
uint32_t vap_prog_stream_cntl_ext[8];
- /* This is a map of VAP/SW TCL outputs into the GA/RS.
- * tab[i] is the location of input i in GA/RS input memory.
- * Named tab for historical reasons. */
- int tab[16];
+ /* Map of vertex attributes into PVS memory for HW TCL,
+ * or GA memory for SW TCL. */
+ int vs_tab[16];
+ /* Map of rasterizer attributes from GB through RS to US. */
+ int fs_tab[16];
};
struct r300_vertex_shader {
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index a3d83376b66..417d5f6307d 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -340,7 +340,11 @@ void r300_emit_vertex_shader(struct r300_context* r300,
return;
}
- BEGIN_CS(13 + (vs->instruction_count * 4) + (constants->count * 4));
+ if (constants->count) {
+ BEGIN_CS(16 + (vs->instruction_count * 4) + (constants->count * 4));
+ } else {
+ 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));
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index b7ee8fb8a94..cbd84d7c569 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -234,6 +234,8 @@ static void r300_render_draw(struct vbuf_render* render,
struct pipe_screen* screen = r300->context.screen;
struct pipe_buffer* index_buffer;
void* index_map;
+ int i;
+ uint32_t index;
CS_LOCALS(r300);
@@ -252,14 +254,24 @@ static void r300_render_draw(struct vbuf_render* render,
pipe_buffer_unmap(screen, index_buffer);
debug_printf("r300: Doing indexbuf render, count %d\n", count);
-
- BEGIN_CS(6);
+/*
+ BEGIN_CS(8);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
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_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS; */
+
+ BEGIN_CS(2 + count);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
+ for (i = 0; i < count; i++) {
+ index = indices[i];
+ OUT_CS(index);
+ }
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 2a77fd17390..c9507ae1937 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -555,25 +555,41 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- r300->viewport_state->xscale = state->scale[0];
- r300->viewport_state->yscale = state->scale[1];
- r300->viewport_state->zscale = state->scale[2];
-
- r300->viewport_state->xoffset = state->translate[0];
- r300->viewport_state->yoffset = state->translate[1];
- r300->viewport_state->zoffset = state->translate[2];
-
- r300->viewport_state->vte_control = 0;
if (r300_screen(r300->context.screen)->caps->has_tcl) {
/* Do the transform in HW. */
- r300->viewport_state->vte_control |=
- R300_VPORT_X_SCALE_ENA | R300_VPORT_X_OFFSET_ENA |
- R300_VPORT_Y_SCALE_ENA | R300_VPORT_Y_OFFSET_ENA |
- R300_VPORT_Z_SCALE_ENA | R300_VPORT_Z_OFFSET_ENA;
+ r300->viewport_state->vte_control = R300_VTX_W0_FMT;
+
+ if (state->scale[0] != 1.0f) {
+ r300->viewport_state->xscale = state->scale[0];
+ r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA;
+ }
+ if (state->scale[1] != 1.0f) {
+ r300->viewport_state->yscale = state->scale[1];
+ r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA;
+ }
+ if (state->scale[2] != 1.0f) {
+ r300->viewport_state->zscale = state->scale[2];
+ r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA;
+ }
+ if (state->translate[0] != 0.0f) {
+ r300->viewport_state->xoffset = state->translate[0];
+ r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA;
+ }
+ if (state->translate[1] != 0.0f) {
+ r300->viewport_state->yoffset = state->translate[1];
+ r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA;
+ }
+ if (state->translate[2] != 0.0f) {
+ r300->viewport_state->zoffset = state->translate[2];
+ r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA;
+ }
} else {
+ r300->viewport_state->vte_control = 0;
/* Have Draw do the actual transform. */
draw_set_viewport_state(r300->draw, state);
}
+
+ r300->dirty_state |= R300_NEW_VIEWPORT;
}
static void r300_set_vertex_buffers(struct pipe_context* pipe,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index f1feafbcf91..c4c9784a00c 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -25,60 +25,82 @@
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
-/* Update the vertex_info struct in our r300_context.
- *
- * 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. */
-static void r300_update_vertex_layout(struct r300_context* r300)
+/* Set up the vs_tab and routes. */
+static void r300_vs_tab_routes(struct r300_context* r300,
+ struct r300_vertex_format* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_vertex_format vformat;
- struct vertex_info vinfo;
+ struct vertex_info* vinfo = &vformat->vinfo;
+ int* tab = vformat->vs_tab;
boolean pos = FALSE, psize = FALSE, fog = FALSE;
int i, texs = 0, cols = 0;
- int tab[16];
-
- struct tgsi_shader_info* info = &r300->fs->info;
+ struct tgsi_shader_info* info;
- memset(&vinfo, 0, sizeof(vinfo));
- for (i = 0; i < 16; i++) {
- tab[i] = -1;
+ if (r300screen->caps->has_tcl) {
+ /* Use vertex shader to determine required routes. */
+ info = &r300->vs->info;
+ } else {
+ /* Use fragment shader to determine required routes. */
+ info = &r300->fs->info;
}
assert(info->num_inputs <= 16);
- for (i = 0; i < info->num_inputs; i++) {
- switch (info->input_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- pos = TRUE;
- tab[i] = 0;
- break;
- case TGSI_SEMANTIC_COLOR:
- tab[i] = 2 + cols++;
- break;
- case TGSI_SEMANTIC_PSIZE:
- psize = TRUE;
- tab[i] = 1;
- break;
- case TGSI_SEMANTIC_FOG:
- fog = TRUE;
- /* Fall through... */
- case TGSI_SEMANTIC_GENERIC:
- tab[i] = 6 + texs++;
- break;
- default:
- debug_printf("r300: Unknown vertex input %d\n",
- info->input_semantic_name[i]);
- break;
- }
- }
-
if (r300screen->caps->has_tcl) {
+ /* Just copy vert attribs over as-is. */
for (i = 0; i < info->num_inputs; i++) {
- /* XXX should probably do real lookup with vert shader */
tab[i] = i;
}
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ pos = TRUE;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ cols++;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ psize = TRUE;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ fog = TRUE;
+ case TGSI_SEMANTIC_GENERIC:
+ texs++;
+ break;
+ default:
+ debug_printf("r300: Unknown vertex output %d\n",
+ info->output_semantic_name[i]);
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ pos = TRUE;
+ tab[i] = 0;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ tab[i] = 2 + cols;
+ cols++;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ psize = TRUE;
+ tab[i] = 15;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ fog = TRUE;
+ /* Fall through */
+ case TGSI_SEMANTIC_GENERIC:
+ tab[i] = 6 + texs;
+ texs++;
+ break;
+ default:
+ debug_printf("r300: Unknown vertex input %d\n",
+ info->input_semantic_name[i]);
+ break;
+ }
+ }
}
/* Do the actual vertex_info setup.
@@ -89,7 +111,7 @@ static void r300_update_vertex_layout(struct r300_context* r300)
* vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
* vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
- vinfo.hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+ vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
if (!pos) {
debug_printf("r300: Forcing vertex position attribute emit...\n");
@@ -99,109 +121,199 @@ static void r300_update_vertex_layout(struct r300_context* r300)
tab[i] = tab[i-1];
}
tab[0] = 0;
-
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_POS,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
- } else {
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
}
- vinfo.hwfmt[1] |= R300_INPUT_CNTL_POS;
- vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+ draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
+ vinfo->hwfmt[1] |= R300_INPUT_CNTL_POS;
+ vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
if (psize) {
- draw_emit_vertex_attr(&vinfo, EMIT_1F_PSIZE, INTERP_POS,
+ draw_emit_vertex_attr(vinfo, EMIT_1F_PSIZE, INTERP_POS,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_PSIZE, 0));
- vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+ vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
}
for (i = 0; i < cols; i++) {
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR,
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_COLOR, i));
- vinfo.hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- vinfo.hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
+ vinfo->hwfmt[1] |= R300_INPUT_CNTL_COLOR;
+ vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
}
for (i = 0; i < texs; i++) {
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
- vinfo.hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
- vinfo.hwfmt[3] |= (4 << (3 * i));
+ vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
+ vinfo->hwfmt[3] |= (4 << (3 * i));
}
if (fog) {
i++;
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
- vinfo.hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
- vinfo.hwfmt[3] |= (4 << (3 * i));
+ vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
+ vinfo->hwfmt[3] |= (4 << (3 * i));
+ }
+
+ draw_compute_vertex_size(vinfo);
+}
+
+/* Update the PSC tables. */
+static void r300_vertex_psc(struct r300_context* r300,
+ struct r300_vertex_format* vformat)
+{
+ struct vertex_info* vinfo = &vformat->vinfo;
+ int* tab = vformat->vs_tab;
+ uint32_t temp;
+ int i;
+
+ debug_printf("r300: attrib count: %d\n", vinfo->num_attribs);
+ for (i = 0; i < vinfo->num_attribs; i++) {
+ debug_printf("r300: attrib: offset %d, interp %d, size %d,"
+ " tab %d\n", vinfo->attrib[i].src_index,
+ vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
+ tab[i]);
}
- draw_compute_vertex_size(&vinfo);
-
- if (memcmp(&r300->vertex_info, &vinfo, sizeof(struct vertex_info))) {
- uint32_t temp;
- debug_printf("attrib count: %d, fp input count: %d\n",
- vinfo.num_attribs, info->num_inputs);
- for (i = 0; i < vinfo.num_attribs; i++) {
- debug_printf("attrib: offset %d, interp %d, size %d,"
- " tab %d\n", vinfo.attrib[i].src_index,
- vinfo.attrib[i].interp_mode, vinfo.attrib[i].emit,
- tab[i]);
+ for (i = 0; i < vinfo->num_attribs; i++) {
+ /* Make sure we have a proper destination for our attribute */
+ assert(tab[i] != -1);
+
+ /* Add the attribute to the PSC table. */
+ temp = translate_vertex_data_type(vinfo->attrib[i].emit) |
+ (tab[i] << R300_DST_VEC_LOC_SHIFT);
+ if (i & 1) {
+ vformat->vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;
+ vformat->vap_prog_stream_cntl[i >> 1] |= temp << 16;
+
+ vformat->vap_prog_stream_cntl_ext[i >> 1] |=
+ (R300_VAP_SWIZZLE_XYZW << 16);
+ } else {
+ vformat->vap_prog_stream_cntl[i >> 1] &= 0xffff0000;
+ vformat->vap_prog_stream_cntl[i >> 1] |= temp << 0;
+
+ vformat->vap_prog_stream_cntl_ext[i >> 1] |=
+ (R300_VAP_SWIZZLE_XYZW << 0);
}
+ }
- for (i = 0; i < vinfo.num_attribs; i++) {
- /* Make sure we have a proper destination for our attribute */
- assert(tab[i] != -1);
+ /* Set the last vector in the PSC. */
+ i--;
+ vformat->vap_prog_stream_cntl[i >> 1] |=
+ (R300_LAST_VEC << (i & 1 ? 16 : 0));
+}
- temp = translate_vertex_data_type(vinfo.attrib[i].emit) |
- (tab[i] << R300_DST_VEC_LOC_SHIFT);
- if (i & 1) {
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= temp << 16;
- } else {
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] &= 0xffff0000;
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= temp;
- }
+/* Update the vertex format. */
+static void r300_update_vertex_format(struct r300_context* r300)
+{
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct r300_vertex_format vformat;
+ int i;
- r300->vertex_info.vap_prog_stream_cntl_ext[i >> 1] |=
- (R300_VAP_SWIZZLE_XYZW << (i & 1 ? 16 : 0));
- }
- /* Set the last vector. */
- i--;
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC <<
- (i & 1 ? 16 : 0));
+ memset(&vformat, 0, sizeof(struct r300_vertex_format));
+ for (i = 0; i < 16; i++) {
+ vformat.vs_tab[i] = -1;
+ vformat.fs_tab[i] = -1;
+ }
- memcpy(r300->vertex_info.tab, tab, sizeof(tab));
- memcpy(&r300->vertex_info, &vinfo, sizeof(struct vertex_info));
+ r300_vs_tab_routes(r300, &vformat);
+
+ r300_vertex_psc(r300, &vformat);
+
+ if (memcmp(&r300->vertex_info, &vformat,
+ sizeof(struct r300_vertex_format))) {
+ memcpy(&r300->vertex_info, &vformat,
+ sizeof(struct r300_vertex_format));
r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
}
}
+/* Set up the mappings from GB to US, for RS block. */
+static void r300_update_fs_tab(struct r300_context* r300)
+{
+ struct r300_vertex_format* vformat = &r300->vertex_info;
+ struct tgsi_shader_info* info = &r300->fs->info;
+ int i, cols = 0, texs = 0, cols_emitted = 0;
+ int* tab = vformat->fs_tab;
+
+ for (i = 0; i < 16; i++) {
+ tab[i] = -1;
+ }
+
+ assert(info->num_inputs <= 16);
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ tab[i] = INTERP_LINEAR;
+ cols++;
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ case TGSI_SEMANTIC_PSIZE:
+ debug_printf("r300: Implementation error: Can't use "
+ "pos attribs in fragshader yet!\n");
+ /* Pass through for now */
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ tab[i] = INTERP_PERSPECTIVE;
+ break;
+ default:
+ debug_printf("r300: Unknown vertex input %d\n",
+ info->input_semantic_name[i]);
+ break;
+ }
+ }
+
+ /* Now that we know where everything is... */
+ debug_printf("r300: fp input count: %d\n", info->num_inputs);
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (tab[i]) {
+ case INTERP_LINEAR:
+ debug_printf("r300: attrib: "
+ "stack offset %d, color, tab %d\n",
+ i, cols_emitted);
+ tab[i] = cols_emitted;
+ cols_emitted++;
+ break;
+ case INTERP_PERSPECTIVE:
+ debug_printf("r300: attrib: "
+ "stack offset %d, texcoord, tab %d\n",
+ i, cols + texs);
+ tab[i] = cols + texs;
+ texs++;
+ break;
+ case -1:
+ debug_printf("r300: Implementation error: Bad fp interp!\n");
+ default:
+ break;
+ }
+ }
+
+}
+
/* Set up the RS block. This is the part of the chipset that actually does
* the rasterization of vertices into fragments. This is also the part of the
* chipset that locks up if any part of it is even slightly wrong. */
static void r300_update_rs_block(struct r300_context* r300)
{
struct r300_rs_block* rs = r300->rs_block;
- struct vertex_info* vinfo = &r300->vertex_info.vinfo;
- int* tab = r300->vertex_info.tab;
+ struct tgsi_shader_info* info = &r300->fs->info;
+ int* tab = r300->vertex_info.fs_tab;
int col_count = 0, fp_offset = 0, i, memory_pos, tex_count = 0;
memset(rs, 0, sizeof(struct r300_rs_block));
if (r300_screen(r300->context.screen)->caps->is_r500) {
- for (i = 0; i < vinfo->num_attribs; i++) {
- assert(tab[vinfo->attrib[i].src_index] != -1);
- memory_pos = tab[vinfo->attrib[i].src_index] * 4;
- switch (vinfo->attrib[i].interp_mode) {
- case INTERP_LINEAR:
+ for (i = 0; i < info->num_inputs; i++) {
+ assert(tab[i] != -1);
+ memory_pos = tab[i] * 4;
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
rs->ip[col_count] |=
R500_RS_COL_PTR(memory_pos) |
R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
col_count++;
break;
- case INTERP_PERSPECTIVE:
+ case TGSI_SEMANTIC_GENERIC:
rs->ip[tex_count] |=
R500_RS_SEL_S(memory_pos) |
R500_RS_SEL_T(memory_pos + 1) |
@@ -243,17 +355,17 @@ static void r300_update_rs_block(struct r300_context* r300)
fp_offset++;
}
} else {
- for (i = 0; i < vinfo->num_attribs; i++) {
- memory_pos = tab[vinfo->attrib[i].src_index] * 4;
- assert(tab[vinfo->attrib[i].src_index] != -1);
- switch (vinfo->attrib[i].interp_mode) {
- case INTERP_LINEAR:
+ for (i = 0; i < info->num_inputs; i++) {
+ assert(tab[i] != -1);
+ memory_pos = tab[i] * 4;
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
rs->ip[col_count] |=
R300_RS_COL_PTR(memory_pos) |
R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
col_count++;
break;
- case INTERP_PERSPECTIVE:
+ case TGSI_SEMANTIC_GENERIC:
rs->ip[tex_count] |=
R300_RS_TEX_PTR(memory_pos) |
R300_RS_SEL_S(R300_RS_SEL_C0) |
@@ -307,10 +419,11 @@ void r300_update_derived_state(struct r300_context* r300)
{
if (r300->dirty_state &
(R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) {
- r300_update_vertex_layout(r300);
+ r300_update_vertex_format(r300);
}
if (r300->dirty_state & R300_NEW_VERTEX_FORMAT) {
+ r300_update_fs_tab(r300);
r300_update_rs_block(r300);
}
}
diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c
index 47d6c6dfcdf..bb96e2ad67f 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.c
+++ b/src/gallium/drivers/r300/r300_state_tcl.c
@@ -40,6 +40,9 @@ static void r300_vs_declare(struct r300_vs_asm* assembler,
/* XXX multiple? */
assembler->tab[decl->DeclarationRange.First] = 6;
break;
+ case TGSI_SEMANTIC_PSIZE:
+ assembler->tab[decl->DeclarationRange.First] = 15;
+ break;
default:
debug_printf("r300: vs: Bad semantic declaration %d\n",
decl->Semantic.SemanticName);
@@ -117,6 +120,9 @@ static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
static uint32_t r300_vs_op(unsigned op)
{
switch (op) {
+ case TGSI_OPCODE_DP3:
+ case TGSI_OPCODE_DP4:
+ return R300_VE_DOT_PRODUCT;
case TGSI_OPCODE_MUL:
return R300_VE_MULTIPLY;
case TGSI_OPCODE_ADD:
@@ -195,6 +201,36 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
2);
break;
+ case TGSI_OPCODE_DP3:
+ /* Set alpha swizzle to zero for src0 and src1 */
+ if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
+ inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
+ }
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
+ TGSI_EXTSWIZZLE_ZERO;
+ if (!inst->FullSrcRegisters[1].SrcRegister.Extended) {
+ inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE;
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX =
+ inst->FullSrcRegisters[1].SrcRegister.SwizzleX;
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY =
+ inst->FullSrcRegisters[1].SrcRegister.SwizzleY;
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ =
+ inst->FullSrcRegisters[1].SrcRegister.SwizzleZ;
+ }
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW =
+ TGSI_EXTSWIZZLE_ZERO;
+ /* Fall through */
+ case TGSI_OPCODE_DP4:
+ 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;
diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h
index 3d10e248e15..de944028baa 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.h
+++ b/src/gallium/drivers/r300/r300_state_tcl.h
@@ -32,6 +32,7 @@
/* XXX get these to r300_reg */
#define R300_PVS_DST_OPCODE(x) ((x) << 0)
+# define R300_VE_DOT_PRODUCT 1
# define R300_VE_MULTIPLY 2
# define R300_VE_ADD 3
#define R300_PVS_DST_MACRO_INST (1 << 7)
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 06ace27d14b..11aff814791 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -121,11 +121,23 @@ static void softpipe_destroy( struct pipe_context *pipe )
FREE( softpipe );
}
+static unsigned int
+softpipe_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+softpipe_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
struct pipe_context *
-softpipe_create( struct pipe_screen *screen,
- struct pipe_winsys *pipe_winsys,
- void *unused )
+softpipe_create( struct pipe_screen *screen )
{
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
uint i;
@@ -140,7 +152,7 @@ softpipe_create( struct pipe_screen *screen,
softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
- softpipe->pipe.winsys = pipe_winsys;
+ softpipe->pipe.winsys = screen->winsys;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
@@ -190,6 +202,9 @@ softpipe_create( struct pipe_screen *screen,
softpipe->pipe.clear = softpipe_clear;
softpipe->pipe.flush = softpipe_flush;
+ softpipe->pipe.is_texture_referenced = softpipe_is_texture_referenced;
+ softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced;
+
softpipe_init_query_funcs( softpipe );
softpipe_init_texture_funcs( softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
index 4ab666486c4..cf91e7782bc 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_winsys.h
@@ -35,31 +35,17 @@
#define SP_WINSYS_H
-#include "pipe/p_compiler.h" /* for boolean */
-
-
#ifdef __cplusplus
extern "C" {
#endif
-enum pipe_format;
-
-struct softpipe_winsys {
- /** test if the given format is supported for front/back color bufs */
- boolean (*is_format_supported)( struct softpipe_winsys *sws,
- enum pipe_format format );
-
-};
-
struct pipe_screen;
struct pipe_winsys;
struct pipe_context;
-struct pipe_context *softpipe_create( struct pipe_screen *,
- struct pipe_winsys *,
- void *unused );
+struct pipe_context *softpipe_create( struct pipe_screen * );
struct pipe_screen *
diff --git a/src/gallium/drivers/trace/tr_buffer.c b/src/gallium/drivers/trace/tr_buffer.c
index 6ffce1660ec..4f0eff6a5a4 100644
--- a/src/gallium/drivers/trace/tr_buffer.c
+++ b/src/gallium/drivers/trace/tr_buffer.c
@@ -27,10 +27,10 @@
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "tr_buffer.h"
-
struct pipe_buffer *
trace_buffer_create(struct trace_screen *tr_scr,
struct pipe_buffer *buffer)
@@ -52,6 +52,8 @@ trace_buffer_create(struct trace_screen *tr_scr,
tr_buf->base.screen = &tr_scr->base;
tr_buf->buffer = buffer;
+ trace_screen_add_to_list(tr_scr, buffers, tr_buf);
+
return &tr_buf->base;
error:
@@ -64,7 +66,10 @@ void
trace_buffer_destroy(struct trace_screen *tr_scr,
struct pipe_buffer *buffer)
{
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, buffer);
+ struct trace_buffer *tr_buf = trace_buffer(buffer);
+
+ trace_screen_remove_from_list(tr_scr, buffers, tr_buf);
+
pipe_buffer_reference(&tr_buf->buffer, NULL);
FREE(tr_buf);
}
diff --git a/src/gallium/drivers/trace/tr_buffer.h b/src/gallium/drivers/trace/tr_buffer.h
index e9e4d354dad..1a2d0b9aeae 100644
--- a/src/gallium/drivers/trace/tr_buffer.h
+++ b/src/gallium/drivers/trace/tr_buffer.h
@@ -41,19 +41,19 @@ struct trace_buffer
struct pipe_buffer *buffer;
+ struct tr_list list;
+
void *map;
boolean range_flushed;
};
static INLINE struct trace_buffer *
-trace_buffer(struct trace_screen *tr_scr,
- struct pipe_buffer *buffer)
+trace_buffer(struct pipe_buffer *buffer)
{
if(!buffer)
return NULL;
- assert(tr_scr);
- assert(buffer->screen == &tr_scr->base);
+ (void)trace_screen(buffer->screen);
return (struct trace_buffer *)buffer;
}
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index d8d5821a1d1..47280459a75 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -26,6 +26,8 @@
**************************************************************************/
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+
#include "pipe/p_screen.h"
#include "tr_dump.h"
@@ -46,7 +48,7 @@ trace_buffer_unwrap(struct trace_context *tr_ctx,
if(!buffer)
return NULL;
- tr_buf = trace_buffer(tr_scr, buffer);
+ tr_buf = trace_buffer(buffer);
assert(tr_buf->buffer);
assert(tr_buf->buffer->screen == tr_scr->screen);
@@ -142,9 +144,8 @@ trace_context_draw_elements(struct pipe_context *_pipe,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
- struct trace_screen *tr_scr = trace_screen(_pipe->screen);
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _indexBuffer);
+ struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
struct pipe_context *pipe = tr_ctx->pipe;
struct pipe_buffer *indexBuffer = tr_buf->buffer;
boolean result;
@@ -180,9 +181,8 @@ trace_context_draw_range_elements(struct pipe_context *_pipe,
unsigned start,
unsigned count)
{
- struct trace_screen *tr_scr = trace_screen(_pipe->screen);
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _indexBuffer);
+ struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
struct pipe_context *pipe = tr_ctx->pipe;
struct pipe_buffer *indexBuffer = tr_buf->buffer;
boolean result;
@@ -1016,20 +1016,67 @@ trace_context_flush(struct pipe_context *_pipe,
static INLINE void
trace_context_destroy(struct pipe_context *_pipe)
{
+ struct trace_screen *tr_scr = trace_screen(_pipe->screen);
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
trace_dump_call_begin("pipe_context", "destroy");
-
trace_dump_arg(ptr, pipe);
+ trace_dump_call_end();
+
+ trace_screen_remove_from_list(tr_scr, contexts, tr_ctx);
pipe->destroy(pipe);
+ FREE(tr_ctx);
+}
+
+static unsigned int
+trace_is_texture_referenced( struct pipe_context *_pipe,
+ struct pipe_texture *_texture,
+ unsigned face, unsigned level)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_texture *tr_tex = trace_texture(_texture);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_texture *texture = tr_tex->texture;
+ unsigned int referenced;
+
+ trace_dump_call_begin("pipe_context", "is_texture_referenced");
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, texture);
+ trace_dump_arg(uint, face);
+ trace_dump_arg(uint, level);
+
+ referenced = pipe->is_texture_referenced(pipe, texture, face, level);
+
+ trace_dump_ret(uint, referenced);
trace_dump_call_end();
- FREE(tr_ctx);
+ return referenced;
}
+static unsigned int
+trace_is_buffer_referenced( struct pipe_context *_pipe,
+ struct pipe_buffer *_buf)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_buffer *tr_buf = trace_buffer(_buf);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_buffer *buf = tr_buf->buffer;
+ unsigned int referenced;
+
+ trace_dump_call_begin("pipe_context", "is_buffer_referenced");
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, buf);
+
+ referenced = pipe->is_buffer_referenced(pipe, buf);
+
+ trace_dump_ret(uint, referenced);
+ trace_dump_call_end();
+
+ return referenced;
+}
struct pipe_context *
trace_context_create(struct pipe_screen *_screen,
@@ -1042,7 +1089,7 @@ trace_context_create(struct pipe_screen *_screen,
if(!pipe)
goto error1;
- if(!trace_dump_enabled())
+ if(!trace_dump_trace_enabled())
goto error1;
tr_scr = trace_screen(_screen);
@@ -1096,6 +1143,8 @@ trace_context_create(struct pipe_screen *_screen,
tr_ctx->base.surface_fill = trace_context_surface_fill;
tr_ctx->base.clear = trace_context_clear;
tr_ctx->base.flush = trace_context_flush;
+ tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
+ tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
tr_ctx->pipe = pipe;
@@ -1104,6 +1153,8 @@ trace_context_create(struct pipe_screen *_screen,
trace_dump_ret(ptr, pipe);
trace_dump_call_end();
+ trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
+
return &tr_ctx->base;
error1:
diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h
index d02b22a069b..2512a0a2328 100644
--- a/src/gallium/drivers/trace/tr_context.h
+++ b/src/gallium/drivers/trace/tr_context.h
@@ -44,6 +44,8 @@ struct trace_context
struct pipe_context base;
struct pipe_context *pipe;
+
+ struct tr_list list;
};
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 2618883e70d..3a1409e95a7 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -61,6 +61,8 @@ static struct util_stream *stream = NULL;
static unsigned refcount = 0;
static pipe_mutex call_mutex;
static long unsigned call_no = 0;
+static boolean dumping = FALSE;
+static boolean initialized = FALSE;
static INLINE void
@@ -226,10 +228,22 @@ trace_dump_trace_close(void)
}
}
+void trace_dump_init()
+{
+ if (initialized)
+ return;
+
+ pipe_mutex_init(call_mutex);
+ dumping = FALSE;
+ initialized = TRUE;
+}
+
boolean trace_dump_trace_begin()
{
const char *filename;
+ assert(initialized);
+
filename = debug_get_option("GALLIUM_TRACE", NULL);
if(!filename)
return FALSE;
@@ -240,8 +254,6 @@ 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");
@@ -258,7 +270,7 @@ boolean trace_dump_trace_begin()
return TRUE;
}
-boolean trace_dump_enabled(void)
+boolean trace_dump_trace_enabled(void)
{
return stream ? TRUE : FALSE;
}
@@ -270,9 +282,71 @@ void trace_dump_trace_end(void)
trace_dump_trace_close();
}
-void trace_dump_call_begin(const char *klass, const char *method)
+/*
+ * Call lock
+ */
+
+void trace_dump_call_lock(void)
{
pipe_mutex_lock(call_mutex);
+}
+
+void trace_dump_call_unlock(void)
+{
+ pipe_mutex_unlock(call_mutex);
+}
+
+/*
+ * Dumping control
+ */
+
+void trace_dumping_start_locked(void)
+{
+ dumping = TRUE;
+}
+
+void trace_dumping_stop_locked(void)
+{
+ dumping = FALSE;
+}
+
+boolean trace_dumping_enabled_locked(void)
+{
+ return dumping;
+}
+
+void trace_dumping_start(void)
+{
+ pipe_mutex_lock(call_mutex);
+ trace_dumping_start_locked();
+ pipe_mutex_unlock(call_mutex);
+}
+
+void trace_dumping_stop(void)
+{
+ pipe_mutex_lock(call_mutex);
+ trace_dumping_stop_locked();
+ pipe_mutex_unlock(call_mutex);
+}
+
+boolean trace_dumping_enabled(void)
+{
+ boolean ret;
+ pipe_mutex_lock(call_mutex);
+ ret = trace_dumping_enabled_locked();
+ pipe_mutex_unlock(call_mutex);
+ return ret;
+}
+
+/*
+ * Dump functions
+ */
+
+void trace_dump_call_begin_locked(const char *klass, const char *method)
+{
+ if (!dumping)
+ return;
+
++call_no;
trace_dump_indent(1);
trace_dump_writes("<call no=\'");
@@ -285,56 +359,94 @@ void trace_dump_call_begin(const char *klass, const char *method)
trace_dump_newline();
}
-void trace_dump_call_end(void)
+void trace_dump_call_end_locked(void)
{
+ if (!dumping)
+ return;
+
trace_dump_indent(1);
trace_dump_tag_end("call");
trace_dump_newline();
util_stream_flush(stream);
+}
+
+void trace_dump_call_begin(const char *klass, const char *method)
+{
+ pipe_mutex_lock(call_mutex);
+ trace_dump_call_begin_locked(klass, method);
+}
+
+void trace_dump_call_end(void)
+{
+ trace_dump_call_end_locked();
pipe_mutex_unlock(call_mutex);
}
void trace_dump_arg_begin(const char *name)
{
+ if (!dumping)
+ return;
+
trace_dump_indent(2);
trace_dump_tag_begin1("arg", "name", name);
}
void trace_dump_arg_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_tag_end("arg");
trace_dump_newline();
}
void trace_dump_ret_begin(void)
{
+ if (!dumping)
+ return;
+
trace_dump_indent(2);
trace_dump_tag_begin("ret");
}
void trace_dump_ret_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_tag_end("ret");
trace_dump_newline();
}
void trace_dump_bool(int value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<bool>%c</bool>", value ? '1' : '0');
}
void trace_dump_int(long long int value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<int>%lli</int>", value);
}
void trace_dump_uint(long long unsigned value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<uint>%llu</uint>", value);
}
void trace_dump_float(double value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<float>%g</float>", value);
}
@@ -344,6 +456,10 @@ void trace_dump_bytes(const void *data,
static const char hex_table[16] = "0123456789ABCDEF";
const uint8_t *p = data;
long unsigned i;
+
+ if (!dumping)
+ return;
+
trace_dump_writes("<bytes>");
for(i = 0; i < size; ++i) {
uint8_t byte = *p++;
@@ -357,6 +473,9 @@ void trace_dump_bytes(const void *data,
void trace_dump_string(const char *str)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<string>");
trace_dump_escape(str);
trace_dump_writes("</string>");
@@ -364,6 +483,9 @@ void trace_dump_string(const char *str)
void trace_dump_enum(const char *value)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<enum>");
trace_dump_escape(value);
trace_dump_writes("</enum>");
@@ -371,51 +493,81 @@ void trace_dump_enum(const char *value)
void trace_dump_array_begin(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<array>");
}
void trace_dump_array_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</array>");
}
void trace_dump_elem_begin(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<elem>");
}
void trace_dump_elem_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</elem>");
}
void trace_dump_struct_begin(const char *name)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<struct name='%s'>", name);
}
void trace_dump_struct_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</struct>");
}
void trace_dump_member_begin(const char *name)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<member name='%s'>", name);
}
void trace_dump_member_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</member>");
}
void trace_dump_null(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<null/>");
}
void trace_dump_ptr(const void *value)
{
+ if (!dumping)
+ return;
+
if(value)
trace_dump_writef("<ptr>0x%08lx</ptr>", (unsigned long)(uintptr_t)value);
else
@@ -424,9 +576,11 @@ void trace_dump_ptr(const void *value)
void trace_dump_buffer_ptr(struct pipe_buffer *_buffer)
{
+ if (!dumping)
+ return;
+
if (_buffer) {
- struct trace_screen *tr_scr = trace_screen(_buffer->screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
trace_dump_ptr(tr_buf->buffer);
} else {
trace_dump_null();
@@ -435,6 +589,9 @@ void trace_dump_buffer_ptr(struct pipe_buffer *_buffer)
void trace_dump_texture_ptr(struct pipe_texture *_texture)
{
+ if (!dumping)
+ return;
+
if (_texture) {
struct trace_texture *tr_tex = trace_texture(_texture);
trace_dump_ptr(tr_tex->texture);
@@ -445,6 +602,9 @@ void trace_dump_texture_ptr(struct pipe_texture *_texture)
void trace_dump_surface_ptr(struct pipe_surface *_surface)
{
+ if (!dumping)
+ return;
+
if (_surface) {
struct trace_surface *tr_surf = trace_surface(_surface);
trace_dump_ptr(tr_surf->surface);
@@ -455,6 +615,9 @@ void trace_dump_surface_ptr(struct pipe_surface *_surface)
void trace_dump_transfer_ptr(struct pipe_transfer *_transfer)
{
+ if (!dumping)
+ return;
+
if (_transfer) {
struct trace_transfer *tr_tran = trace_transfer(_transfer);
trace_dump_ptr(tr_tran->transfer);
diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h
index 26409f26c66..31ac70802f0 100644
--- a/src/gallium/drivers/trace/tr_dump.h
+++ b/src/gallium/drivers/trace/tr_dump.h
@@ -42,11 +42,47 @@ struct pipe_texture;
struct pipe_surface;
struct pipe_transfer;
+/*
+ * Call before use.
+ */
+void trace_dump_init(void);
+
+/*
+ * Low level dumping controls.
+ *
+ * Opening the trace file and checking if that is opened.
+ */
boolean trace_dump_trace_begin(void);
-boolean trace_dump_enabled(void);
+boolean trace_dump_trace_enabled(void);
void trace_dump_trace_end(void);
+
+/*
+ * Lock and unlock the call mutex.
+ *
+ * It used by the none locked version of dumping control
+ * and begin/end call dump functions.
+ *
+ * Begin takes the lock while end unlocks it. Use the _locked
+ * version to avoid locking/unlocking it.
+ */
+void trace_dump_call_lock(void);
+void trace_dump_call_unlock(void);
+
+/*
+ * High level dumping control.
+ */
+void trace_dumping_start_locked(void);
+void trace_dumping_stop_locked(void);
+boolean trace_dumping_enabled_locked(void);
+void trace_dumping_start(void);
+void trace_dumping_stop(void);
+boolean trace_dumping_enabled(void);
+
+void trace_dump_call_begin_locked(const char *klass, const char *method);
+void trace_dump_call_end_locked(void);
void trace_dump_call_begin(const char *klass, const char *method);
void trace_dump_call_end(void);
+
void trace_dump_arg_begin(const char *name);
void trace_dump_arg_end(void);
void trace_dump_ret_begin(void);
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 67925053833..12a85353428 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -26,6 +26,7 @@
**************************************************************************/
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "tr_buffer.h"
#include "tr_dump.h"
@@ -603,7 +604,7 @@ trace_screen_buffer_map(struct pipe_screen *_screen,
unsigned usage)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
void *map;
@@ -628,7 +629,7 @@ trace_screen_buffer_map_range(struct pipe_screen *_screen,
unsigned usage)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
void *map;
@@ -680,7 +681,7 @@ trace_screen_buffer_flush_mapped_range(struct pipe_screen *_screen,
unsigned length)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
@@ -696,7 +697,7 @@ trace_screen_buffer_unmap(struct pipe_screen *_screen,
struct pipe_buffer *_buffer)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
@@ -712,7 +713,7 @@ static void
trace_screen_buffer_destroy(struct pipe_buffer *_buffer)
{
struct trace_screen *tr_scr = trace_screen(_buffer->screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
@@ -734,19 +735,23 @@ trace_screen_buffer_destroy(struct pipe_buffer *_buffer)
static void
trace_screen_fence_reference(struct pipe_screen *_screen,
- struct pipe_fence_handle **dst,
+ struct pipe_fence_handle **pdst,
struct pipe_fence_handle *src)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_fence_handle *dst;
+ assert(pdst);
+ dst = *pdst;
+
trace_dump_call_begin("pipe_screen", "fence_reference");
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, dst);
trace_dump_arg(ptr, src);
- screen->fence_reference(screen, dst, src);
+ screen->fence_reference(screen, pdst, src);
trace_dump_call_end();
}
@@ -755,7 +760,7 @@ trace_screen_fence_reference(struct pipe_screen *_screen,
static int
trace_screen_fence_signalled(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flag)
+ unsigned flags)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -765,9 +770,9 @@ trace_screen_fence_signalled(struct pipe_screen *_screen,
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
- trace_dump_arg(uint, flag);
+ trace_dump_arg(uint, flags);
- result = screen->fence_signalled(screen, fence, flag);
+ result = screen->fence_signalled(screen, fence, flags);
trace_dump_ret(int, result);
@@ -780,7 +785,7 @@ trace_screen_fence_signalled(struct pipe_screen *_screen,
static int
trace_screen_fence_finish(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flag)
+ unsigned flags)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -790,9 +795,9 @@ trace_screen_fence_finish(struct pipe_screen *_screen,
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
- trace_dump_arg(uint, flag);
+ trace_dump_arg(uint, flags);
- result = screen->fence_finish(screen, fence, flag);
+ result = screen->fence_finish(screen, fence, flags);
trace_dump_ret(int, result);
@@ -835,9 +840,13 @@ trace_screen_create(struct pipe_screen *screen)
if(!screen)
goto error1;
+ trace_dump_init();
+
if(!trace_dump_trace_begin())
goto error1;
+ trace_dumping_start();
+
trace_dump_call_begin("", "pipe_screen_create");
tr_scr = CALLOC_STRUCT(trace_screen);
@@ -851,6 +860,12 @@ trace_screen_create(struct pipe_screen *screen)
#else
winsys = screen->winsys;
#endif
+ pipe_mutex_init(tr_scr->list_mutex);
+ make_empty_list(&tr_scr->buffers);
+ make_empty_list(&tr_scr->contexts);
+ make_empty_list(&tr_scr->textures);
+ make_empty_list(&tr_scr->surfaces);
+ make_empty_list(&tr_scr->transfers);
tr_scr->base.winsys = winsys;
tr_scr->base.destroy = trace_screen_destroy;
diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h
index 8c65516b509..59f254166d4 100644
--- a/src/gallium/drivers/trace/tr_screen.h
+++ b/src/gallium/drivers/trace/tr_screen.h
@@ -30,6 +30,7 @@
#include "pipe/p_screen.h"
+#include "pipe/p_thread.h"
#ifdef __cplusplus
@@ -37,6 +38,11 @@ extern "C" {
#endif
+struct tr_list {
+ struct tr_list *next;
+ struct tr_list *prev;
+};
+
/**
* It often happens that new data is written directly to the user buffers
* without mapping/unmapping. This flag marks user buffers, so that their
@@ -50,6 +56,18 @@ struct trace_screen
struct pipe_screen base;
struct pipe_screen *screen;
+
+ pipe_mutex list_mutex;
+ int num_buffers;
+ int num_contexts;
+ int num_textures;
+ int num_surfaces;
+ int num_transfers;
+ struct tr_list buffers;
+ struct tr_list contexts;
+ struct tr_list textures;
+ struct tr_list surfaces;
+ struct tr_list transfers;
};
@@ -65,6 +83,21 @@ void
trace_screen_user_buffer_update(struct pipe_screen *screen,
struct pipe_buffer *buffer);
+#define trace_screen_add_to_list(tr_scr, name, obj) \
+ do { \
+ pipe_mutex_lock(tr_scr->list_mutex); \
+ insert_at_head(&tr_scr->name, &obj->list); \
+ tr_scr->num_##name++; \
+ pipe_mutex_unlock(tr_scr->list_mutex); \
+ } while (0)
+
+#define trace_screen_remove_from_list(tr_scr, name, obj) \
+ do { \
+ pipe_mutex_lock(tr_scr->list_mutex); \
+ remove_from_list(&obj->list); \
+ tr_scr->num_##name--; \
+ pipe_mutex_unlock(tr_scr->list_mutex); \
+ } while (0)
#ifdef __cplusplus
}
diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c
index f4e433792b1..1f25fe38d4c 100644
--- a/src/gallium/drivers/trace/tr_texture.c
+++ b/src/gallium/drivers/trace/tr_texture.c
@@ -27,6 +27,7 @@
#include "util/u_hash_table.h"
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "tr_screen.h"
#include "tr_texture.h"
@@ -53,6 +54,8 @@ trace_texture_create(struct trace_screen *tr_scr,
tr_tex->base.screen = &tr_scr->base;
tr_tex->texture = texture;
+ trace_screen_add_to_list(tr_scr, textures, tr_tex);
+
return &tr_tex->base;
error:
@@ -64,6 +67,10 @@ error:
void
trace_texture_destroy(struct trace_texture *tr_tex)
{
+ struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
+
+ trace_screen_remove_from_list(tr_scr, textures, tr_tex);
+
pipe_texture_reference(&tr_tex->texture, NULL);
FREE(tr_tex);
}
@@ -73,6 +80,7 @@ struct pipe_surface *
trace_surface_create(struct trace_texture *tr_tex,
struct pipe_surface *surface)
{
+ struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
struct trace_surface *tr_surf;
if(!surface)
@@ -91,6 +99,8 @@ trace_surface_create(struct trace_texture *tr_tex,
pipe_texture_reference(&tr_surf->base.texture, &tr_tex->base);
tr_surf->surface = surface;
+ trace_screen_add_to_list(tr_scr, surfaces, tr_surf);
+
return &tr_surf->base;
error:
@@ -102,6 +112,10 @@ error:
void
trace_surface_destroy(struct trace_surface *tr_surf)
{
+ struct trace_screen *tr_scr = trace_screen(tr_surf->base.texture->screen);
+
+ trace_screen_remove_from_list(tr_scr, surfaces, tr_surf);
+
pipe_texture_reference(&tr_surf->base.texture, NULL);
pipe_surface_reference(&tr_surf->surface, NULL);
FREE(tr_surf);
@@ -112,6 +126,7 @@ struct pipe_transfer *
trace_transfer_create(struct trace_texture *tr_tex,
struct pipe_transfer *transfer)
{
+ struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
struct trace_transfer *tr_trans;
if(!transfer)
@@ -130,6 +145,8 @@ trace_transfer_create(struct trace_texture *tr_tex,
tr_trans->transfer = transfer;
assert(tr_trans->base.texture == &tr_tex->base);
+ trace_screen_add_to_list(tr_scr, transfers, tr_trans);
+
return &tr_trans->base;
error:
@@ -141,7 +158,11 @@ error:
void
trace_transfer_destroy(struct trace_transfer *tr_trans)
{
+ struct trace_screen *tr_scr = trace_screen(tr_trans->base.texture->screen);
struct pipe_screen *screen = tr_trans->transfer->texture->screen;
+
+ trace_screen_remove_from_list(tr_scr, transfers, tr_trans);
+
pipe_texture_reference(&tr_trans->base.texture, NULL);
screen->tex_transfer_destroy(tr_trans->transfer);
FREE(tr_trans);
diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h
index 14dafd8b2c3..395e523e73a 100644
--- a/src/gallium/drivers/trace/tr_texture.h
+++ b/src/gallium/drivers/trace/tr_texture.h
@@ -40,6 +40,8 @@ struct trace_texture
struct pipe_texture base;
struct pipe_texture *texture;
+
+ struct tr_list list;
};
@@ -48,6 +50,8 @@ struct trace_surface
struct pipe_surface base;
struct pipe_surface *surface;
+
+ struct tr_list list;
};
@@ -57,6 +61,8 @@ struct trace_transfer
struct pipe_transfer *transfer;
+ struct tr_list list;
+
void *map;
};