summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_context.c16
-rw-r--r--src/gallium/drivers/r300/r300_context.h20
-rw-r--r--src/gallium/drivers/r300/r300_debug.c82
-rw-r--r--src/gallium/drivers/r300/r300_emit.c27
-rw-r--r--src/gallium/drivers/r300/r300_flush.c42
-rw-r--r--src/gallium/drivers/r300/r300_query.c18
-rw-r--r--src/gallium/drivers/r300/r300_render.c37
-rw-r--r--src/gallium/drivers/r300/r300_screen.c1
-rw-r--r--src/gallium/drivers/r300/r300_screen.h30
-rw-r--r--src/gallium/drivers/r300/r300_state.c84
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c15
-rw-r--r--src/gallium/drivers/r300/r300_vs.c20
-rw-r--r--src/gallium/drivers/r300/r300_vs.h6
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h9
14 files changed, 303 insertions, 104 deletions
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 0444fdac7d..9837deaa5e 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -80,6 +80,9 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300->ztop_state.state);
FREE(r300->fs_constants.state);
FREE(r300->vs_constants.state);
+ if (!r300->screen->caps.has_tcl) {
+ FREE(r300->vertex_stream_state.state);
+ }
FREE(r300);
}
@@ -151,6 +154,16 @@ static void r300_setup_atoms(struct r300_context* r300)
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
r300->vs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
+ if (!r300->screen->caps.has_tcl) {
+ r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
+ }
+
+ /* Some non-CSO atoms don't use the state pointer. */
+ r300->invariant_state.allow_null_state = TRUE;
+ r300->fs_rc_constant_state.allow_null_state = TRUE;
+ r300->pvs_flush.allow_null_state = TRUE;
+ r300->query_start.allow_null_state = TRUE;
+ r300->texture_cache_inval.allow_null_state = TRUE;
}
struct pipe_context* r300_create_context(struct pipe_screen* screen,
@@ -201,6 +214,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
/* Enable Draw's clipping. */
draw_set_driver_clipping(r300->draw, FALSE);
+ /* Disable converting points/lines to triangles. */
+ draw_wide_line_threshold(r300->draw, 10000000.f);
+ draw_wide_point_threshold(r300->draw, 10000000.f);
}
r300_setup_atoms(r300);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 5ad448978b..e44906d009 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -55,6 +55,8 @@ struct r300_atom {
unsigned size;
/* Whether this atom should be emitted. */
boolean dirty;
+ /* Whether this atom may be emitted with state == NULL. */
+ boolean allow_null_state;
};
struct r300_blend_state {
@@ -88,8 +90,10 @@ struct r300_dsa_state {
};
struct r300_rs_state {
- /* Draw-specific rasterizer state */
+ /* Original rasterizer state. */
struct pipe_rasterizer_state rs;
+ /* Draw-specific rasterizer state. */
+ struct pipe_rasterizer_state rs_draw;
uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */
uint32_t antialiasing_config; /* R300_GB_AA_CONFIG: 0x4020 */
@@ -235,10 +239,6 @@ struct r300_constant_buffer {
struct r300_query {
/* The kind of query. Currently only OQ is supported. */
unsigned type;
- /* Whether this query is currently active. Only active queries will
- * get emitted into the command stream, and only active queries get
- * tallied. */
- boolean active;
/* The current count of this query. Required to be at least 32 bits. */
unsigned int count;
/* The offset of this query into the query buffer, in bytes. */
@@ -304,16 +304,6 @@ struct r300_texture {
enum r300_buffer_tiling microtile, macrotile;
};
-struct r300_vertex_info {
- /* Parent class */
- struct vertex_info vinfo;
-
- /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
- uint32_t vap_prog_stream_cntl[8];
- /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
- uint32_t vap_prog_stream_cntl_ext[8];
-};
-
struct r300_vertex_element_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index 8eb321fa08..85a1aa7b06 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -40,6 +40,7 @@ static struct debug_option debug_options[] = {
{ "texalloc", DBG_TEXALLOC, "Texture allocation (for debugging)" },
{ "fall", DBG_FALL, "Fallbacks (for debugging)" },
{ "rs", DBG_RS, "Rasterizer (for debugging)" },
+ { "fb", DBG_FB, "Framebuffer (for debugging)" },
{ "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" },
{ "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" },
{ "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" },
@@ -97,3 +98,84 @@ void r300_init_debug(struct r300_screen * screen)
}
}
}
+
+void r500_dump_rs_block(struct r300_rs_block *rs)
+{
+ unsigned count, ip, it_count, ic_count, i, j;
+ unsigned tex_ptr;
+ unsigned col_ptr, col_fmt;
+
+ count = rs->inst_count & 0xf;
+ count++;
+
+ it_count = rs->count & 0x7f;
+ ic_count = (rs->count >> 7) & 0xf;
+
+ fprintf(stderr, "RS Block: %d texcoords (linear), %d colors (perspective)\n",
+ it_count, ic_count);
+ fprintf(stderr, "%d instructions\n", count);
+
+ for (i = 0; i < count; i++) {
+ if (rs->inst[i] & 0x10) {
+ ip = rs->inst[i] & 0xf;
+ fprintf(stderr, "texture: ip %d to psf %d\n",
+ ip, (rs->inst[i] >> 5) & 0x7f);
+
+ tex_ptr = rs->ip[ip] & 0xffffff;
+ fprintf(stderr, " : ");
+
+ j = 3;
+ do {
+ if (tex_ptr & 0x3f == 63) {
+ fprintf(stderr, "1.0");
+ } else if (tex_ptr & 0x3f == 62) {
+ fprintf(stderr, "0.0");
+ } else {
+ fprintf(stderr, "[%d]", tex_ptr & 0x3f);
+ }
+ } while (j-- && fprintf(stderr, "/"));
+ fprintf(stderr, "\n");
+ }
+
+ if (rs->inst[i] & 0x10000) {
+ ip = (rs->inst[i] >> 12) & 0xf;
+ fprintf(stderr, "color: ip %d to psf %d\n",
+ ip, (rs->inst[i] >> 18) & 0x7f);
+
+ col_ptr = (rs->ip[ip] >> 24) & 0x7;
+ col_fmt = (rs->ip[ip] >> 27) & 0xf;
+ fprintf(stderr, " : offset %d ", col_ptr);
+
+ switch (col_fmt) {
+ case 0:
+ fprintf(stderr, "(R/G/B/A)");
+ break;
+ case 1:
+ fprintf(stderr, "(R/G/B/0)");
+ break;
+ case 2:
+ fprintf(stderr, "(R/G/B/1)");
+ break;
+ case 4:
+ fprintf(stderr, "(0/0/0/A)");
+ break;
+ case 5:
+ fprintf(stderr, "(0/0/0/0)");
+ break;
+ case 6:
+ fprintf(stderr, "(0/0/0/1)");
+ break;
+ case 8:
+ fprintf(stderr, "(1/1/1/A)");
+ break;
+ case 9:
+ fprintf(stderr, "(1/1/1/0)");
+ break;
+ case 10:
+ fprintf(stderr, "(1/1/1/1)");
+ break;
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+}
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 568109cf96..7f7f2929cc 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -548,8 +548,8 @@ void r300_emit_query_start(struct r300_context *r300, unsigned size, void*state)
}
-static void r300_emit_query_finish(struct r300_context *r300,
- struct r300_query *query)
+static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
+ struct r300_query *query)
{
struct r300_capabilities* caps = &r300->screen->caps;
CS_LOCALS(r300);
@@ -604,8 +604,8 @@ static void r300_emit_query_finish(struct r300_context *r300,
END_CS;
}
-static void rv530_emit_query_single(struct r300_context *r300,
- struct r300_query *query)
+static void rv530_emit_query_end_single_z(struct r300_context *r300,
+ struct r300_query *query)
{
CS_LOCALS(r300);
@@ -617,8 +617,8 @@ static void rv530_emit_query_single(struct r300_context *r300,
END_CS;
}
-static void rv530_emit_query_double(struct r300_context *r300,
- struct r300_query *query)
+static void rv530_emit_query_end_double_z(struct r300_context *r300,
+ struct r300_query *query)
{
CS_LOCALS(r300);
@@ -646,11 +646,13 @@ void r300_emit_query_end(struct r300_context* r300)
if (caps->family == CHIP_FAMILY_RV530) {
if (caps->num_z_pipes == 2)
- rv530_emit_query_double(r300, query);
+ rv530_emit_query_end_double_z(r300, query);
else
- rv530_emit_query_single(r300, query);
+ rv530_emit_query_end_single_z(r300, query);
} else
- r300_emit_query_finish(r300, query);
+ r300_emit_query_end_frag_pipes(r300, query);
+
+ query->begin_emitted = FALSE;
}
void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state)
@@ -714,6 +716,10 @@ void r300_emit_rs_block_state(struct r300_context* r300,
unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1;
CS_LOCALS(r300);
+ if (SCREEN_DBG_ON(r300->screen, DBG_DRAW)) {
+ r500_dump_rs_block(rs);
+ }
+
DBG(r300, DBG_DRAW, "r300: RS emit:\n");
BEGIN_CS(size);
@@ -1094,7 +1100,8 @@ validate:
}
}
/* ...occlusion query buffer... */
- if (r300->query_start.dirty) {
+ if (r300->query_start.dirty ||
+ (r300->query_current && r300->query_current->begin_emitted)) {
if (!r300_add_buffer(r300->rws, r300->oqbo,
0, RADEON_GEM_DOMAIN_GTT)) {
r300->context.flush(&r300->context, 0, NULL);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index e78c6a3624..d6876c1903 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -37,6 +38,8 @@ static void r300_flush(struct pipe_context* pipe,
struct r300_context *r300 = r300_context(pipe);
struct r300_query *query;
struct r300_atom *atom;
+ struct pipe_framebuffer_state *fb;
+ unsigned i;
CS_LOCALS(r300);
(void) cs_count;
@@ -48,15 +51,15 @@ static void r300_flush(struct pipe_context* pipe,
draw_flush(r300->draw);
}
- r300_emit_query_end(r300);
-
if (r300->dirty_hw) {
+ r300_emit_query_end(r300);
+
FLUSH_CS;
r300->dirty_hw = 0;
/* New kitchen sink, baby. */
foreach(atom, &r300->atom_list) {
- if (atom->state) {
+ if (atom->state || atom->allow_null_state) {
atom->dirty = TRUE;
}
}
@@ -72,6 +75,39 @@ static void r300_flush(struct pipe_context* pipe,
foreach(query, &r300->query_list) {
query->flushed = TRUE;
}
+
+ /* XXX
+ *
+ * This is a preliminary implementation of glFinish. Note that st/mesa
+ * uses a non-null fence when glFinish is called and then waits for
+ * the fence. Instead of returning the actual fence, we do the sync
+ * directly.
+ *
+ * The ideal implementation should use something like EmitIrqLocked and
+ * WaitIrq, or better, real fences.
+ *
+ * This feature degrades performance to the level of r300c for games that
+ * use glFinish a lot, even openarena does. Ideally we wouldn't need
+ * glFinish at all if we had proper throttling in swapbuffers so that
+ * the CPU wouldn't outrun the GPU by several frames, so this is basically
+ * a temporary fix for the input lag. Once swap&sync works with DRI2,
+ * I'll be happy to remove this code.
+ *
+ * - M. */
+ if (fence && r300->fb_state.state) {
+ fb = r300->fb_state.state;
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ if (fb->cbufs[i]->texture) {
+ r300->rws->buffer_wait(r300->rws,
+ r300_texture(fb->cbufs[i]->texture)->buffer);
+ }
+ if (fb->zsbuf) {
+ r300->rws->buffer_wait(r300->rws,
+ r300_texture(fb->zsbuf->texture)->buffer);
+ }
+ }
+ }
}
void r300_init_flush_functions(struct r300_context* r300)
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 5c27796e89..6acbac2219 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -43,8 +43,6 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
q->type = query_type;
assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
- q->active = FALSE;
-
if (r300screen->caps.family == CHIP_FAMILY_RV530)
query_size = r300screen->caps.num_z_pipes * sizeof(uint32_t);
else
@@ -59,6 +57,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
/* XXX */
if (q->offset >= 4096) {
q->offset = 0;
+ fprintf(stderr, "r300: Rewinding OQBO...\n");
}
return (struct pipe_query*)q;
@@ -80,7 +79,12 @@ static void r300_begin_query(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct r300_query* q = (struct r300_query*)query;
- assert(r300->query_current == NULL);
+ if (r300->query_current != NULL) {
+ fprintf(stderr, "r300: begin_query: "
+ "Some other query has already been started.\n");
+ assert(0);
+ return;
+ }
pipe_buffer_write(pipe,
r300->oqbo,
@@ -97,10 +101,14 @@ static void r300_end_query(struct pipe_context* pipe,
struct pipe_query* query)
{
struct r300_context* r300 = r300_context(pipe);
- struct r300_query* q = (struct r300_query*)query;
+
+ if ((struct r300_query*)query != r300->query_current) {
+ fprintf(stderr, "r300: end_query: Got invalid query.\n");
+ assert(0);
+ return;
+ }
r300_emit_query_end(r300);
- q->begin_emitted = false;
r300->query_current = NULL;
}
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 8795410efd..e1f61982be 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -735,6 +735,8 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
return;
}
+ r300_update_derived_state(r300);
+
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe,
r300->vertex_buffer[i].buffer,
@@ -747,6 +749,10 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
draw_arrays(r300->draw, mode, start, count);
+ /* XXX Not sure whether this is the best fix.
+ * It prevents CS from being rejected and weird assertion failures. */
+ draw_flush(r300->draw);
+
for (i = 0; i < r300->vertex_buffer_count; i++) {
pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
vb_transfer[i]);
@@ -779,6 +785,8 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
return;
}
+ r300_update_derived_state(r300);
+
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe,
r300->vertex_buffer[i].buffer,
@@ -794,6 +802,10 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
draw_arrays(r300->draw, mode, start, count);
+ /* XXX Not sure whether this is the best fix.
+ * It prevents CS from being rejected and weird assertion failures. */
+ draw_flush(r300->draw);
+
for (i = 0; i < r300->vertex_buffer_count; i++) {
pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
vb_transfer[i]);
@@ -827,7 +839,7 @@ struct r300_render {
size_t vbo_max_used;
void * vbo_ptr;
- struct pipe_transfer *vbo_transfer;
+ struct pipe_transfer *vbo_transfer;
};
static INLINE struct r300_render*
@@ -842,8 +854,6 @@ r300_render_get_vertex_info(struct vbuf_render* render)
struct r300_render* r300render = r300_render(render);
struct r300_context* r300 = r300render->r300;
- r300_update_derived_state(r300);
-
return &r300->vertex_info;
}
@@ -891,10 +901,6 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
{
struct r300_render* r300render = r300_render(render);
struct pipe_context* context = &r300render->r300->context;
- CS_LOCALS(r300render->r300);
- BEGIN_CS(2);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max);
- END_CS;
r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
r300render->vertex_size * (max + 1));
@@ -928,10 +934,13 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
struct r300_context* r300 = r300render->r300;
uint8_t* ptr;
unsigned i;
+ unsigned dwords = 6;
CS_LOCALS(r300);
- r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, 2, 0, 0);
+ (void) i; (void) ptr;
+
+ r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
@@ -952,7 +961,10 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
r300render->vbo_transfer);
*/
- BEGIN_CS(2);
+ BEGIN_CS(dwords);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, r300render->prim));
+ OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300render->hwprim);
@@ -966,13 +978,18 @@ static void r500_render_draw_elements(struct vbuf_render* render,
struct r300_render* r300render = r300_render(render);
struct r300_context* r300 = r300render->r300;
int i;
- unsigned dwords = 2 + (count+1)/2;
+ unsigned dwords = 6 + (count+1)/2;
+ unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) /
+ (r300render->r300->vertex_info.size * 4) - 1;
CS_LOCALS(r300);
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
BEGIN_CS(dwords);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, r300render->prim));
+ OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300render->hwprim);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 8399f5df8e..640b3d3468 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -115,6 +115,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
return 1;
/* Unsupported features (boolean caps). */
+ case PIPE_CAP_TIMER_QUERY:
case PIPE_CAP_DUAL_SOURCE_BLEND:
case PIPE_CAP_TGSI_CONT_SUPPORTED:
case PIPE_CAP_INDEP_BLEND_ENABLE:
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index d58aa138a7..29492024fe 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -61,19 +61,23 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
* those changes.
*/
/*@{*/
-#define DBG_HELP 0x0000001
-#define DBG_FP 0x0000002
-#define DBG_VP 0x0000004
-#define DBG_CS 0x0000008
-#define DBG_DRAW 0x0000010
-#define DBG_TEX 0x0000020
-#define DBG_FALL 0x0000040
-#define DBG_ANISOHQ 0x0000080
-#define DBG_NO_TILING 0x0000100
-#define DBG_NO_IMMD 0x0000200
-#define DBG_STATS 0x0000400
-#define DBG_RS 0x0000800
-#define DBG_TEXALLOC 0x0001000
+#define DBG_HELP (1 << 0)
+/* Logging. */
+#define DBG_FP (1 << 1)
+#define DBG_VP (1 << 2)
+#define DBG_CS (1 << 3)
+#define DBG_DRAW (1 << 4)
+#define DBG_TEX (1 << 5)
+#define DBG_TEXALLOC (1 << 6)
+#define DBG_RS (1 << 7)
+#define DBG_FALL (1 << 8)
+#define DBG_FB (1 << 9)
+/* Features. */
+#define DBG_ANISOHQ (1 << 16)
+#define DBG_NO_TILING (1 << 17)
+#define DBG_NO_IMMD (1 << 18)
+/* Statistics. */
+#define DBG_STATS (1 << 24)
/*@}*/
static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 006a34119b..11c10e2f2a 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -566,13 +566,35 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300,
}
}
+static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
+ const char *binding)
+{
+ struct pipe_resource *tex = surf->texture;
+ struct r300_texture *rtex = r300_texture(tex);
+
+ fprintf(stderr,
+ "r300: %s[%i] Dim: %ix%i, Offset: %i, ZSlice: %i, "
+ "Face: %i, Level: %i, Format: %s\n"
+
+ "r300: TEX: Macro: %s, Micro: %s, Pitch: %i, "
+ "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
+
+ binding, index, surf->width, surf->height, surf->offset,
+ surf->zslice, surf->face, surf->level,
+ util_format_short_name(surf->format),
+
+ rtex->macrotile ? "YES" : " NO", rtex->microtile ? "YES" : " NO",
+ rtex->hwpitch[0], tex->width0, tex->height0, tex->depth0,
+ tex->last_level, util_format_short_name(tex->format));
+}
+
static void
r300_set_framebuffer_state(struct pipe_context* pipe,
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
struct pipe_framebuffer_state *old_state = r300->fb_state.state;
- unsigned max_width, max_height;
+ unsigned max_width, max_height, i;
uint32_t zbuffer_bpp = 0;
if (state->nr_cbufs > 4) {
@@ -634,6 +656,16 @@ static void
r300->rs_state.dirty = TRUE;
}
}
+
+ if (DBG_ON(r300, DBG_FB)) {
+ fprintf(stderr, "r300: set_framebuffer_state:\n");
+ for (i = 0; i < state->nr_cbufs; i++) {
+ r300_print_fb_surf_info(state->cbufs[i], i, "CB");
+ }
+ if (state->zsbuf) {
+ r300_print_fb_surf_info(state->zsbuf, 0, "ZB");
+ }
+ }
}
/* Create fragment shader state. */
@@ -724,8 +756,12 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
int i;
float psiz;
- /* Copy rasterizer state for Draw. */
+ /* Copy rasterizer state. */
rs->rs = *state;
+ rs->rs_draw = *state;
+
+ /* Override some states for Draw. */
+ rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */
#ifdef PIPE_ARCH_LITTLE_ENDIAN
rs->vap_control_status = R300_VC_NO_SWAP;
@@ -856,9 +892,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
int last_sprite_coord_enable = r300->sprite_coord_enable;
boolean last_two_sided_color = r300->two_sided_color;
- if (r300->draw) {
+ if (r300->draw && rs) {
draw_flush(r300->draw);
- draw_set_rasterizer_state(r300->draw, &rs->rs, state);
+ draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);
}
if (rs) {
@@ -1200,7 +1236,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
}
}
-/* Update the PSC tables. */
+/* Initialize the PSC tables. */
static void r300_vertex_psc(struct r300_vertex_element_state *velems)
{
struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
@@ -1339,7 +1375,6 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
abort();
}
}
-
}
}
return velems;
@@ -1360,6 +1395,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
if (r300->draw) {
draw_flush(r300->draw);
draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
+ return;
}
UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
@@ -1382,8 +1418,10 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
vs->state = *shader;
vs->state.tokens = tgsi_dup_tokens(shader->tokens);
+ r300_init_vs_outputs(vs);
+
if (r300->screen->caps.has_tcl) {
- r300_translate_vertex_shader(r300, vs, vs->state.tokens);
+ r300_translate_vertex_shader(r300, vs);
} else {
vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
}
@@ -1453,7 +1491,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
struct r300_constant_buffer *cbuf;
struct pipe_transfer *tr;
void *mapped;
- int max_size = 0;
+ int max_size = 0, max_size_bytes = 0, clamped_size = 0;
switch (shader) {
case PIPE_SHADER_VERTEX:
@@ -1472,6 +1510,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
assert(0);
return;
}
+ max_size_bytes = max_size * 4 * sizeof(float);
if (buf == NULL || buf->width0 == 0 ||
(mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
@@ -1480,19 +1519,21 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
return;
}
- assert((buf->width0 % 4 * sizeof(float)) == 0);
+ if (shader == PIPE_SHADER_FRAGMENT ||
+ (shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) {
+ assert((buf->width0 % (4 * sizeof(float))) == 0);
- /* Check the size of the constant buffer. */
- /* XXX Subtract immediates and RC_STATE_* variables. */
- if (buf->width0 > (sizeof(float) * 4 * max_size)) {
- fprintf(stderr, "r300: Max size of the constant buffer is "
- "%i*4 floats.\n", max_size);
- abort();
- }
+ /* Check the size of the constant buffer. */
+ /* XXX Subtract immediates and RC_STATE_* variables. */
+ if (buf->width0 > max_size_bytes) {
+ fprintf(stderr, "r300: Max size of the constant buffer is "
+ "%i*4 floats.\n", max_size);
+ }
+ clamped_size = MIN2(buf->width0, max_size_bytes);
- memcpy(cbuf->constants, mapped, buf->width0);
- cbuf->count = buf->width0 / (4 * sizeof(float));
- pipe_buffer_unmap(pipe, buf, tr);
+ memcpy(cbuf->constants, mapped, clamped_size);
+ cbuf->count = clamped_size / (4 * sizeof(float));
+ }
if (shader == PIPE_SHADER_VERTEX) {
if (r300->screen->caps.has_tcl) {
@@ -1502,12 +1543,13 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
r300->pvs_flush.dirty = TRUE;
} else if (r300->draw) {
draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
- 0, cbuf->constants,
- buf->width0);
+ 0, mapped, buf->width0);
}
} else if (shader == PIPE_SHADER_FRAGMENT) {
r300->fs_constants.dirty = TRUE;
}
+
+ pipe_buffer_unmap(pipe, buf, tr);
}
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 c738899827..7583862a1a 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -116,13 +116,12 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
static void r300_swtcl_vertex_psc(struct r300_context *r300)
{
struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state;
- struct vertex_info* vinfo = &r300->vertex_info;
+ struct vertex_info *vinfo = &r300->vertex_info;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
int* vs_output_tab = r300->stream_loc_notcl;
- /* XXX hax */
memset(vstream, 0, sizeof(struct r300_vertex_stream_state));
/* For each Draw attribute, route it to the fragment shader according
@@ -615,13 +614,13 @@ void r300_update_derived_state(struct r300_context* r300)
if (r300->rs_block_state.dirty) {
r300_update_rs_block(r300);
- }
- if (r300->draw) {
- memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
- r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(&r300->vertex_info);
- r300_swtcl_vertex_psc(r300);
+ if (r300->draw) {
+ memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+ r300_draw_emit_all_attribs(r300);
+ draw_compute_vertex_size(&r300->vertex_info);
+ r300_swtcl_vertex_psc(r300);
+ }
}
r300_update_hyperz_state(r300);
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index f3186431e1..59f89b3482 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -181,21 +181,23 @@ static void r300_dummy_vertex_shader(
state.tokens = ureg_finalize(ureg);
shader->dummy = TRUE;
- r300_translate_vertex_shader(r300, shader, state.tokens);
+ r300_translate_vertex_shader(r300, shader);
ureg_destroy(ureg);
}
-void r300_translate_vertex_shader(struct r300_context* r300,
- struct r300_vertex_shader* vs,
- const struct tgsi_token *tokens)
+void r300_init_vs_outputs(struct r300_vertex_shader *vs)
+{
+ tgsi_scan_shader(vs->state.tokens, &vs->info);
+ r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
+}
+
+void r300_translate_vertex_shader(struct r300_context *r300,
+ struct r300_vertex_shader *vs)
{
struct r300_vertex_program_compiler compiler;
struct tgsi_to_rc ttr;
- tgsi_scan_shader(tokens, &vs->info);
- r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
-
/* Setup the compiler */
rc_init(&compiler.Base);
@@ -205,7 +207,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
if (compiler.Base.Debug) {
debug_printf("r300: Initial vertex program\n");
- tgsi_dump(tokens, 0);
+ tgsi_dump(vs->state.tokens, 0);
}
/* Translate TGSI to our internal representation */
@@ -213,7 +215,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
ttr.info = &vs->info;
ttr.use_half_swizzles = FALSE;
- r300_tgsi_to_rc(&ttr, tokens);
+ r300_tgsi_to_rc(&ttr, vs->state.tokens);
compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 57b3fbca0b..31890d78ca 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -56,8 +56,8 @@ struct r300_vertex_shader {
void *draw_vs;
};
-void r300_translate_vertex_shader(struct r300_context* r300,
- struct r300_vertex_shader* vs,
- const struct tgsi_token *tokens);
+void r300_init_vs_outputs(struct r300_vertex_shader *vs);
+void r300_translate_vertex_shader(struct r300_context *r300,
+ struct r300_vertex_shader *vs);
#endif /* R300_VS_H */
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 1642981eaa..3d0413f90a 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -87,13 +87,8 @@ struct r300_winsys_screen {
struct r300_winsys_buffer **pdst,
struct r300_winsys_buffer *src);
- boolean (*buffer_references)(struct r300_winsys_buffer *a,
- struct r300_winsys_buffer *b);
-
- void (*buffer_flush_range)(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf,
- unsigned offset,
- unsigned length);
+ void (*buffer_wait)(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf);
/* Add a pipe_resource to the list of buffer objects to validate. */
boolean (*add_buffer)(struct r300_winsys_screen *winsys,