summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-06-07 16:51:32 +1000
committerDave Airlie <airlied@redhat.com>2009-06-07 16:51:32 +1000
commit545e574cd9a2a659cd9a93879dff8884bd247558 (patch)
treef56d65eaa851edfb1248a6fc8ac0bae4cc98eff5 /src/gallium/drivers/r300
parente2aedfa62079ff1a333e1f4e56faea303cc36edb (diff)
parentf1edfa09ea50e8833ddbf241da4d36fd38685e9d (diff)
Merge remote branch 'origin/master' into radeon-rewrite
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c1
-rw-r--r--src/gallium/drivers/r300/r300_context.h51
-rw-r--r--src/gallium/drivers/r300/r300_cs.h24
-rw-r--r--src/gallium/drivers/r300/r300_debug.c26
-rw-r--r--src/gallium/drivers/r300/r300_debug.h30
-rw-r--r--src/gallium/drivers/r300/r300_emit.c90
-rw-r--r--src/gallium/drivers/r300/r300_emit.h3
-rw-r--r--src/gallium/drivers/r300/r300_reg.h3
-rw-r--r--src/gallium/drivers/r300/r300_render.c56
-rw-r--r--src/gallium/drivers/r300/r300_state.c13
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c25
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c4
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.c105
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.h2
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.c18
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.h7
-rw-r--r--src/gallium/drivers/r300/r300_surface.c63
-rw-r--r--src/gallium/drivers/r300/r300_surface.h4
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h8
19 files changed, 372 insertions, 161 deletions
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 758f706c51..00fae8d26f 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -149,6 +149,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
caps->num_vert_fpus = 6;
break;
+ case 0x4B48:
case 0x4B49:
case 0x4B4A:
case 0x4B4B:
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 58f1fa0e2e..27bc7fd1a9 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -117,23 +117,24 @@ struct r300_viewport_state {
uint32_t vte_control; /* R300_VAP_VTE_CNTL: 0x20b0 */
};
-#define R300_NEW_BLEND 0x0000001
-#define R300_NEW_BLEND_COLOR 0x0000002
-#define R300_NEW_CONSTANTS 0x0000004
-#define R300_NEW_DSA 0x0000008
-#define R300_NEW_FRAMEBUFFERS 0x0000010
-#define R300_NEW_FRAGMENT_SHADER 0x0000020
-#define R300_NEW_RASTERIZER 0x0000040
-#define R300_NEW_RS_BLOCK 0x0000080
-#define R300_NEW_SAMPLER 0x0000100
-#define R300_ANY_NEW_SAMPLERS 0x000ff00
-#define R300_NEW_SCISSOR 0x0010000
-#define R300_NEW_TEXTURE 0x0020000
-#define R300_ANY_NEW_TEXTURES 0x1fe0000
-#define R300_NEW_VERTEX_FORMAT 0x2000000
-#define R300_NEW_VERTEX_SHADER 0x4000000
-#define R300_NEW_VIEWPORT 0x8000000
-#define R300_NEW_KITCHEN_SINK 0xfffffff
+#define R300_NEW_BLEND 0x00000001
+#define R300_NEW_BLEND_COLOR 0x00000002
+#define R300_NEW_CLIP 0x00000004
+#define R300_NEW_CONSTANTS 0x00000008
+#define R300_NEW_DSA 0x00000010
+#define R300_NEW_FRAMEBUFFERS 0x00000020
+#define R300_NEW_FRAGMENT_SHADER 0x00000040
+#define R300_NEW_RASTERIZER 0x00000080
+#define R300_NEW_RS_BLOCK 0x00000100
+#define R300_NEW_SAMPLER 0x00000200
+#define R300_ANY_NEW_SAMPLERS 0x0001fe00
+#define R300_NEW_SCISSOR 0x00020000
+#define R300_NEW_TEXTURE 0x00040000
+#define R300_ANY_NEW_TEXTURES 0x03fc0000
+#define R300_NEW_VERTEX_FORMAT 0x04000000
+#define R300_NEW_VERTEX_SHADER 0x08000000
+#define R300_NEW_VIEWPORT 0x10000000
+#define R300_NEW_KITCHEN_SINK 0x1fffffff
/* The next several objects are not pure Radeon state; they inherit from
* various Gallium classes. */
@@ -141,11 +142,11 @@ struct r300_viewport_state {
struct r300_constant_buffer {
/* Buffer of constants */
/* XXX first number should be raised */
- float constants[8][4];
+ float constants[32][4];
/* Number of user-defined constants */
- int user_count;
+ unsigned user_count;
/* Total number of constants */
- int count;
+ unsigned count;
};
struct r3xx_fragment_shader {
@@ -158,6 +159,10 @@ struct r3xx_fragment_shader {
/* Pixel stack size */
int stack_size;
+
+ /* Are there immediates in this shader?
+ * If not, we can heavily optimize recompilation. */
+ boolean uses_imms;
};
struct r300_fragment_shader {
@@ -248,6 +253,10 @@ struct r300_vertex_shader {
/* Has this shader been translated yet? */
boolean translated;
+ /* Are there immediates in this shader?
+ * If not, we can heavily optimize recompilation. */
+ boolean uses_imms;
+
/* Number of used instructions */
int instruction_count;
@@ -284,6 +293,8 @@ struct r300_context {
struct r300_blend_state* blend_state;
/* Blend color state. */
struct r300_blend_color_state* blend_color_state;
+ /* User clip planes. */
+ struct pipe_clip_state clip_state;
/* Shader constants. */
struct r300_constant_buffer shader_constants[PIPE_SHADER_TYPES];
/* Depth, stencil, and alpha state. */
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 82a3942248..71b142c0db 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -34,6 +34,7 @@
#define MAX_CS_SIZE 64 * 1024 / 4
+#define VERY_VERBOSE_CS 0
#define VERY_VERBOSE_REGISTERS 0
/* XXX stolen from radeon_drm.h */
@@ -56,8 +57,10 @@
#define BEGIN_CS(size) do { \
CHECK_CS(size); \
- debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
- size, __FUNCTION__, __FILE__, __LINE__); \
+ if (VERY_VERBOSE_CS) { \
+ debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
+ size, __FUNCTION__, __FILE__, __LINE__); \
+ } \
cs_winsys->begin_cs(cs_winsys, (size), \
__FILE__, __FUNCTION__, __LINE__); \
cs_count = size; \
@@ -93,8 +96,9 @@
} while (0)
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
- debug_printf("r300: writing relocation for buffer %p, offset %d\n", \
- bo, offset); \
+ debug_printf("r300: writing relocation for buffer %p, offset %d, " \
+ "domains (%d, %d, %d)\n", \
+ bo, offset, rd, wd, flags); \
assert(bo); \
OUT_CS(offset); \
cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
@@ -102,16 +106,20 @@
} while (0)
#define END_CS do { \
- debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \
- __LINE__); \
+ if (VERY_VERBOSE_CS) { \
+ debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \
+ __FILE__, __LINE__); \
+ } \
if (cs_count != 0) \
debug_printf("r300: Warning: cs_count off by %d\n", cs_count); \
cs_winsys->end_cs(cs_winsys, __FILE__, __FUNCTION__, __LINE__); \
} while (0)
#define FLUSH_CS do { \
- debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, __FILE__, \
- __LINE__); \
+ if (VERY_VERBOSE_CS) { \
+ debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \
+ __FILE__, __LINE__); \
+ } \
cs_winsys->flush_cs(cs_winsys); \
} while (0)
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index ffc93eb591..678cd2b812 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -152,6 +152,8 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
static void r300_vs_op_dump(uint32_t op)
{
+ debug_printf(" dst: %d%s op: ",
+ (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
if (op & 0x80) {
if (op & 0x1) {
debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
@@ -165,14 +167,32 @@ static void r300_vs_op_dump(uint32_t op)
}
}
+void r300_vs_src_dump(uint32_t src)
+{
+ debug_printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
+ (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
+ src & (1 << 25) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 13) & 0x7],
+ src & (1 << 26) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 16) & 0x7],
+ src & (1 << 27) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 19) & 0x7],
+ src & (1 << 28) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 22) & 0x7]);
+}
+
void r300_vs_dump(struct r300_vertex_shader* vs)
{
int i;
for (i = 0; i < vs->instruction_count; i++) {
+ debug_printf("%d: op: 0x%08x", i, vs->instructions[i].inst0);
r300_vs_op_dump(vs->instructions[i].inst0);
- debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1);
- debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2);
- debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3);
+ debug_printf(" src0: 0x%08x", vs->instructions[i].inst1);
+ r300_vs_src_dump(vs->instructions[i].inst1);
+ debug_printf(" src1: 0x%08x", vs->instructions[i].inst2);
+ r300_vs_src_dump(vs->instructions[i].inst2);
+ debug_printf(" src2: 0x%08x", vs->instructions[i].inst3);
+ r300_vs_src_dump(vs->instructions[i].inst3);
}
}
diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h
index 6306594099..c86410ec0a 100644
--- a/src/gallium/drivers/r300/r300_debug.h
+++ b/src/gallium/drivers/r300/r300_debug.h
@@ -173,6 +173,36 @@ static char* r300_vs_me_ops[] = {
" (reserved)",
};
+/* XXX refactor to avoid clashing symbols */
+static char* r300_vs_src_debug[] = {
+ "t",
+ "i",
+ "c",
+ "a",
+};
+
+static char* r300_vs_dst_debug[] = {
+ "t",
+ "a0",
+ "o",
+ "ox",
+ "a",
+ "i",
+ "u",
+ "u",
+};
+
+static char* r300_vs_swiz_debug[] = {
+ "X",
+ "Y",
+ "Z",
+ "W",
+ "0",
+ "1",
+ "U",
+ "U",
+};
+
void r500_fs_dump(struct r500_fragment_shader* fs);
void r300_vs_dump(struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 0cb0507fc8..d81abe4d0b 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -56,6 +56,30 @@ void r300_emit_blend_color_state(struct r300_context* r300,
}
}
+void r300_emit_clip_state(struct r300_context* r300,
+ struct pipe_clip_state* clip)
+{
+ int i;
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ CS_LOCALS(r300);
+
+ BEGIN_CS(5 + (6 * 4));
+ OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+ (r300screen->caps->is_r500 ?
+ R500_PVS_UCP_START : R300_PVS_UCP_START));
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4);
+ for (i = 0; i < 6; i++) {
+ OUT_CS_32F(clip->ucp[i][0]);
+ OUT_CS_32F(clip->ucp[i][1]);
+ OUT_CS_32F(clip->ucp[i][2]);
+ OUT_CS_32F(clip->ucp[i][3]);
+ }
+
+ OUT_CS_REG(R300_VAP_CLIP_CNTL, ((1 << clip->nr) - 1) |
+ R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
+ END_CS;
+}
+
void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa)
{
@@ -372,17 +396,22 @@ void r300_emit_vertex_shader(struct r300_context* r300,
}
if (constants->count) {
- BEGIN_CS(16 + (vs->instruction_count * 4) + (constants->count * 4));
+ BEGIN_CS(14 + (vs->instruction_count * 4) + (constants->count * 4));
} else {
- BEGIN_CS(13 + (vs->instruction_count * 4) + (constants->count * 4));
+ BEGIN_CS(11 + (vs->instruction_count * 4));
}
- OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) |
+ /* R300_VAP_PVS_CODE_CNTL_0
+ * R300_VAP_PVS_CONST_CNTL
+ * R300_VAP_PVS_CODE_CNTL_1
+ * See the r5xx docs for instructions on how to use these.
+ * XXX these could be optimized to select better values... */
+ OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
+ OUT_CS(R300_PVS_FIRST_INST(0) |
+ R300_PVS_XYZW_VALID_INST(vs->instruction_count - 1) |
R300_PVS_LAST_INST(vs->instruction_count - 1));
- OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, vs->instruction_count - 1);
-
- /* XXX */
- OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x0);
+ OUT_CS(R300_PVS_MAX_CONST_ADDR(constants->count - 1));
+ OUT_CS(vs->instruction_count - 1);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4);
@@ -412,7 +441,6 @@ void r300_emit_vertex_shader(struct r300_context* r300,
R300_PVS_VF_MAX_VTX_NUM(12));
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
END_CS;
-
}
void r300_emit_viewport_state(struct r300_context* r300,
@@ -452,8 +480,8 @@ void r300_emit_dirty_state(struct r300_context* r300)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct r300_texture* tex;
- int i;
- int dirty_tex = 0;
+ int i, dirty_tex = 0;
+ boolean invalid = FALSE;
if (!(r300->dirty_state)) {
return;
@@ -462,38 +490,55 @@ void r300_emit_dirty_state(struct r300_context* r300)
r300_update_derived_state(r300);
/* XXX check size */
+validate:
/* Color buffers... */
for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture;
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- r300->winsys->add_buffer(r300->winsys, tex->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
}
/* ...depth buffer... */
if (r300->framebuffer_state.zsbuf) {
tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture;
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
- r300->winsys->add_buffer(r300->winsys, tex->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
}
/* ...textures... */
for (i = 0; i < r300->texture_count; i++) {
tex = r300->textures[i];
assert(tex && tex->buffer && "texture is marked, but NULL!");
- r300->winsys->add_buffer(r300->winsys, tex->buffer,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
}
/* ...and vertex buffer. */
if (r300->vbo) {
- r300->winsys->add_buffer(r300->winsys, r300->vbo,
- RADEON_GEM_DOMAIN_GTT, 0);
+ if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
} else {
debug_printf("No VBO while emitting dirty state!\n");
}
-
if (r300->winsys->validate(r300->winsys)) {
- /* XXX */
r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ /* Well, hell. */
+ exit(1);
+ }
+ invalid = TRUE;
+ goto validate;
}
if (r300->dirty_state & R300_NEW_BLEND) {
@@ -506,6 +551,11 @@ void r300_emit_dirty_state(struct r300_context* r300)
r300->dirty_state &= ~R300_NEW_BLEND_COLOR;
}
+ if (r300->dirty_state & R300_NEW_CLIP) {
+ r300_emit_clip_state(r300, &r300->clip_state);
+ r300->dirty_state &= ~R300_NEW_CLIP;
+ }
+
if (r300->dirty_state & R300_NEW_DSA) {
r300_emit_dsa_state(r300, r300->dsa_state);
r300->dirty_state &= ~R300_NEW_DSA;
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 36e14f69f7..946f625bd8 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -36,6 +36,9 @@ void r300_emit_blend_state(struct r300_context* r300,
void r300_emit_blend_color_state(struct r300_context* r300,
struct r300_blend_color_state* bc);
+void r300_emit_clip_state(struct r300_context* r300,
+ struct pipe_clip_state* clip);
+
void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa);
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 660816e1da..3bb9bc47b5 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -511,11 +511,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_PVS_XYZW_VALID_INST_SHIFT 10
# define R300_PVS_LAST_INST_SHIFT 20
# define R300_PVS_FIRST_INST(x) ((x) << 0)
+# define R300_PVS_XYZW_VALID_INST(x) ((x) << 10)
# define R300_PVS_LAST_INST(x) ((x) << 20)
/* Addresses are relative the the vertex program parameters area. */
#define R300_VAP_PVS_CONST_CNTL 0x22D4
# define R300_PVS_CONST_BASE_OFFSET_SHIFT 0
# define R300_PVS_MAX_CONST_ADDR_SHIFT 16
+# define R300_PVS_MAX_CONST_ADDR(x) ((x) << 16)
#define R300_VAP_PVS_CODE_CNTL_1 0x22D8
# define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0
#define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC
@@ -3040,6 +3042,7 @@ enum {
# define R500_INST_RGB_WMASK_R (1 << 11)
# define R500_INST_RGB_WMASK_G (1 << 12)
# define R500_INST_RGB_WMASK_B (1 << 13)
+# define R500_INST_RGB_WMASK_RGB (7 << 11)
# define R500_INST_ALPHA_WMASK (1 << 14)
# define R500_INST_RGB_OMASK_R (1 << 15)
# define R500_INST_RGB_OMASK_G (1 << 16)
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 29b66cee7e..cd458d019a 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -45,11 +45,7 @@ struct r300_render {
/* VBO */
struct pipe_buffer* vbo;
- size_t vbo_size;
- size_t vbo_offset;
- void* vbo_map;
size_t vbo_alloc_size;
- size_t vbo_max_used;
};
static INLINE struct r300_render*
@@ -78,24 +74,21 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
struct pipe_screen* screen = r300->context.screen;
size_t size = (size_t)vertex_size * (size_t)count;
- if (r300render->vbo) {
+ if (r300render->vbo && (size > r300render->vbo_alloc_size)) {
pipe_buffer_reference(&r300render->vbo, NULL);
}
+
+ if (!r300render->vbo) {
+ r300render->vbo = pipe_buffer_create(screen,
+ 64,
+ PIPE_BUFFER_USAGE_VERTEX,
+ size);
+ }
- r300render->vbo_size = MAX2(size, r300render->vbo_alloc_size);
- r300render->vbo_offset = 0;
- r300render->vbo = pipe_buffer_create(screen,
- 64,
- PIPE_BUFFER_USAGE_VERTEX,
- r300render->vbo_size);
-
+ r300render->vbo_alloc_size = MAX2(size, r300render->vbo_alloc_size);
r300render->vertex_size = vertex_size;
- if (r300render->vbo) {
- return TRUE;
- } else {
- return FALSE;
- }
+ return (r300render->vbo) ? TRUE : FALSE;
}
static void* r300_render_map_vertices(struct vbuf_render* render)
@@ -103,10 +96,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render)
struct r300_render* r300render = r300_render(render);
struct pipe_screen* screen = r300render->r300->context.screen;
- r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- return (unsigned char*)r300render->vbo_map + r300render->vbo_offset;
+ return (unsigned char*)pipe_buffer_map(screen, r300render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
}
static void r300_render_unmap_vertices(struct vbuf_render* render,
@@ -116,9 +107,6 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
struct r300_render* r300render = r300_render(render);
struct pipe_screen* screen = r300render->r300->context.screen;
- r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
- r300render->vertex_size * (max + 1));
-
pipe_buffer_unmap(screen, r300render->vbo);
}
@@ -181,7 +169,6 @@ static void prepare_render(struct r300_render* render, unsigned count)
CS_LOCALS(r300);
r300->vbo = render->vbo;
- r300->vbo_offset = render->vbo_offset;
r300_emit_dirty_state(r300);
}
@@ -195,8 +182,6 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
- r300render->vbo_offset = start;
-
prepare_render(r300render, count);
debug_printf("r300: Doing vbuf render, count %d\n", count);
@@ -231,13 +216,14 @@ static void r300_render_draw(struct vbuf_render* render,
return;
}
+/*
index_map = pipe_buffer_map(screen, index_buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(index_map, indices, count);
pipe_buffer_unmap(screen, index_buffer);
debug_printf("r300: Doing indexbuf render, count %d\n", count);
-/*
+
BEGIN_CS(8);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
@@ -247,13 +233,15 @@ static void r300_render_draw(struct vbuf_render* render,
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);
+ BEGIN_CS(2 + (count+1)/2);
+ 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 | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
- for (i = 0; i < count; i++) {
- index = indices[i];
- OUT_CS(index);
+ r300render->hwprim);
+ for (i = 0; i < count-1; i += 2) {
+ OUT_CS(indices[i+1] << 16 | indices[i]);
+ }
+ if (count % 2) {
+ OUT_CS(indices[count-1]);
}
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 4e65fbbabe..29e721984f 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -119,9 +119,10 @@ static void r300_set_clip_state(struct pipe_context* pipe,
const struct pipe_clip_state* state)
{
struct r300_context* r300 = r300_context(pipe);
- /* XXX add HW TCL clipping setup */
- draw_flush(r300->draw);
- draw_set_clip_state(r300->draw, state);
+
+ r300->clip_state = *state;
+
+ r300->dirty_state |= R300_NEW_CLIP;
}
static void
@@ -151,10 +152,12 @@ static void
/* If the number of constants have changed, invalidate the shader. */
if (r300->shader_constants[shader].user_count != i) {
- if (shader == PIPE_SHADER_FRAGMENT && r300->fs) {
+ if (shader == PIPE_SHADER_FRAGMENT && r300->fs &&
+ r300->fs->uses_imms) {
r300->fs->translated = FALSE;
r300_translate_fragment_shader(r300, r300->fs);
- } else if (shader == PIPE_SHADER_VERTEX && r300->vs) {
+ } else if (shader == PIPE_SHADER_VERTEX && r300->vs &&
+ r300->vs->uses_imms) {
r300->vs->translated = FALSE;
r300_translate_vertex_shader(r300, r300->vs);
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index caa5f3b543..2477b30822 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -64,6 +64,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,
break;
case TGSI_SEMANTIC_FOG:
fog = TRUE;
+ /* Fall through */
case TGSI_SEMANTIC_GENERIC:
texs++;
break;
@@ -103,6 +104,9 @@ static void r300_vs_tab_routes(struct r300_context* r300,
}
}
+ /* XXX magic */
+ assert(texs <= 8);
+
/* Do the actual vertex_info setup.
*
* vertex_info has four uints of hardware-specific data in it.
@@ -140,21 +144,32 @@ static void r300_vs_tab_routes(struct r300_context* r300,
vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
}
- for (i = 0; i < texs; i++) {
+ /* Init i right here, increment it if fog is enabled.
+ * This gets around a double-increment problem. */
+ i = 0;
+
+ if (fog) {
+ i++;
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
+ draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
vinfo->hwfmt[3] |= (4 << (3 * i));
}
- if (fog) {
- i++;
+ for (i; i < texs; i++) {
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
+ draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
vinfo->hwfmt[3] |= (4 << (3 * i));
}
+ /* Handle the case where the vertex shader will be generating some of
+ * the attribs based on its inputs. */
+ if (r300screen->caps->has_tcl &&
+ info->num_inputs < info->num_outputs) {
+ vinfo->num_attribs = info->num_inputs;
+ }
+
draw_compute_vertex_size(vinfo);
}
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 9dde662802..60eff08f2e 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -69,7 +69,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(77 + (caps->has_tcl ? 7 : 0));
+ BEGIN_CS(75 + (caps->has_tcl ? 7 : 0));
/* Flush PVS. */
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
@@ -80,8 +80,6 @@ void r300_emit_invariant_state(struct r300_context* r300)
/* XXX endian */
if (caps->has_tcl) {
OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP);
- OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE |
- R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
OUT_CS_32F(1.0);
OUT_CS_32F(1.0);
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c
index ed99c76c15..cc7f6a7c4b 100644
--- a/src/gallium/drivers/r300/r300_state_shader.c
+++ b/src/gallium/drivers/r300/r300_state_shader.c
@@ -22,24 +22,6 @@
#include "r300_state_shader.h"
-static void r300_copy_passthrough_shader(struct r300_fragment_shader* fs)
-{
- struct r300_fragment_shader* pt = &r300_passthrough_fragment_shader;
- fs->shader.stack_size = pt->shader.stack_size;
- fs->alu_instruction_count = pt->alu_instruction_count;
- fs->tex_instruction_count = pt->tex_instruction_count;
- fs->indirections = pt->indirections;
- fs->instructions[0] = pt->instructions[0];
-}
-
-static void r500_copy_passthrough_shader(struct r500_fragment_shader* fs)
-{
- struct r500_fragment_shader* pt = &r500_passthrough_fragment_shader;
- fs->shader.stack_size = pt->shader.stack_size;
- fs->instruction_count = pt->instruction_count;
- fs->instructions[0] = pt->instructions[0];
-}
-
static void r300_fs_declare(struct r300_fs_asm* assembler,
struct tgsi_full_declaration* decl)
{
@@ -49,6 +31,7 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,
case TGSI_SEMANTIC_COLOR:
assembler->color_count++;
break;
+ case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
assembler->tex_count++;
break;
@@ -323,9 +306,12 @@ static INLINE void r300_emit_maths(struct r300_fragment_shader* fs,
}
/* Setup an ALU operation. */
-static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_dst_register* dst)
+static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
+ struct r300_fs_asm* assembler,
+ struct tgsi_full_src_register* src,
+ struct tgsi_full_dst_register* dst,
+ unsigned op,
+ unsigned count)
{
int i = fs->instruction_count;
@@ -348,18 +334,6 @@ static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,
R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
fs->instructions[i].inst5 =
R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
-}
-
-static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count)
-{
- int i = fs->instruction_count;
-
- r500_emit_alu(fs, assembler, dst);
switch (count) {
case 3:
@@ -381,8 +355,8 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALU_RGB_SEL_B_SRC1 |
R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1]));
fs->instructions[i].inst4 |=
- R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])) |
- R500_ALPHA_SEL_B_SRC1;
+ R500_ALPHA_SEL_B_SRC1 |
+ R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1]));
case 1:
case 0:
default:
@@ -394,8 +368,8 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALU_RGB_SEL_A_SRC0 |
R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0]));
fs->instructions[i].inst4 |=
- R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])) |
- R500_ALPHA_SEL_A_SRC0;
+ R500_ALPHA_SEL_A_SRC0 |
+ R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0]));
break;
}
@@ -565,6 +539,60 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
+ /* The compound and hybrid insts. */
+ case TGSI_OPCODE_LRP:
+ /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */
+ inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1];
+ inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2];
+ inst->FullSrcRegisters[0].SrcRegister.Negate =
+ !(inst->FullSrcRegisters[0].SrcRegister.Negate);
+ inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
+ inst->FullDstRegisters[0].DstRegister.Index =
+ assembler->temp_count;
+ inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
+ inst->FullSrcRegisters[2].SrcRegister.Index =
+ assembler->temp_count;
+ inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+ inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3];
+ inst->FullSrcRegisters[0].SrcRegister.Negate =
+ !(inst->FullSrcRegisters[0].SrcRegister.Negate);
+ inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
+ break;
+ case TGSI_OPCODE_POW:
+ /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
+ inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
+ inst->FullDstRegisters[0].DstRegister.Index =
+ assembler->temp_count;
+ inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);
+ inst->FullSrcRegisters[0].SrcRegister.Index =
+ assembler->temp_count;
+ inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+ inst->FullSrcRegisters[2] = r500_constant_zero;
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
+ inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);
+ break;
+
/* The texture instruction set. */
case TGSI_OPCODE_KIL:
case TGSI_OPCODE_TEX:
@@ -593,7 +621,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
static void r300_fs_finalize(struct r3xx_fragment_shader* fs,
struct r300_fs_asm* assembler)
{
- fs->stack_size = assembler->temp_count + assembler->temp_offset;
+ fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
}
static void r500_fs_finalize(struct r500_fragment_shader* fs,
@@ -670,6 +698,7 @@ void r300_translate_fragment_shader(struct r300_context* r300,
assembler->tex_count + assembler->color_count);
consts->count = consts->user_count + assembler->imm_count;
+ fs->uses_imms = assembler->imm_count;
debug_printf("r300: fs: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h
index 06260e61fe..b6087404ce 100644
--- a/src/gallium/drivers/r300/r300_state_shader.h
+++ b/src/gallium/drivers/r300/r300_state_shader.h
@@ -181,7 +181,7 @@ static struct r500_fragment_shader r500_texture_fragment_shader = {
.instruction_count = 2,
.instructions[0].inst0 = R500_INST_TYPE_TEX |
R500_INST_TEX_SEM_WAIT |
- R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
.instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c
index fdbcbf3db8..8cf8250425 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.c
+++ b/src/gallium/drivers/r300/r300_state_tcl.c
@@ -144,6 +144,7 @@ static uint32_t r300_vs_op(unsigned op)
return R300_VE_MULTIPLY;
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_MOV:
+ case TGSI_OPCODE_SUB:
case TGSI_OPCODE_SWZ:
return R300_VE_ADD;
case TGSI_OPCODE_MAX:
@@ -163,12 +164,14 @@ static uint32_t r300_vs_op(unsigned op)
static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
{
if (reg->SrcRegister.Extended) {
- return reg->SrcRegisterExtSwz.ExtSwizzleX |
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegisterExtSwz.ExtSwizzleX |
(reg->SrcRegisterExtSwz.ExtSwizzleY << 3) |
(reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) |
(reg->SrcRegisterExtSwz.ExtSwizzleW << 9);
} else {
- return reg->SrcRegister.SwizzleX |
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegister.SwizzleX |
(reg->SrcRegister.SwizzleY << 3) |
(reg->SrcRegister.SwizzleZ << 6) |
(reg->SrcRegister.SwizzleW << 9);
@@ -179,12 +182,14 @@ static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg)
{
if (reg->SrcRegister.Extended) {
- return reg->SrcRegisterExtSwz.ExtSwizzleX |
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegisterExtSwz.ExtSwizzleX |
(reg->SrcRegisterExtSwz.ExtSwizzleX << 3) |
(reg->SrcRegisterExtSwz.ExtSwizzleX << 6) |
(reg->SrcRegisterExtSwz.ExtSwizzleX << 9);
} else {
- return reg->SrcRegister.SwizzleX |
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegister.SwizzleX |
(reg->SrcRegister.SwizzleX << 3) |
(reg->SrcRegister.SwizzleX << 6) |
(reg->SrcRegister.SwizzleX << 9);
@@ -246,6 +251,10 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
1, TRUE);
break;
+ case TGSI_OPCODE_SUB:
+ inst->FullSrcRegisters[1].SrcRegister.Negate =
+ !inst->FullSrcRegisters[1].SrcRegister.Negate;
+ /* Fall through */
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_MUL:
case TGSI_OPCODE_MAX:
@@ -386,6 +395,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
assembler->tex_count + assembler->color_count);
consts->count = consts->user_count + assembler->imm_count;
+ vs->uses_imms = assembler->imm_count;
debug_printf("r300: vs: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h
index d5d425e9d6..2c8b586c2f 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.h
+++ b/src/gallium/drivers/r300/r300_state_tcl.h
@@ -76,6 +76,13 @@
((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
(R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
(R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
+#define R300_PVS_MODIFIER_X (1 << 25)
+#define R300_PVS_MODIFIER_Y (1 << 26)
+#define R300_PVS_MODIFIER_Z (1 << 27)
+#define R300_PVS_MODIFIER_W (1 << 28)
+#define R300_PVS_NEGATE_XYZW \
+ (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
+ R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
static const struct tgsi_full_src_register r300_constant_zero = {
.SrcRegister.Extended = TRUE,
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index acb6192492..c9e2dff14e 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -32,13 +32,6 @@ static void r300_surface_setup(struct r300_context* r300,
unsigned pixpitch = dest->stride / dest->tex.block.size;
CS_LOCALS(r300);
- /* Make sure our target BO is okay. */
- r300->winsys->add_buffer(r300->winsys, dest->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM);
- if (r300->winsys->validate(r300->winsys)) {
- r300->context.flush(&r300->context, 0, NULL);
- }
-
r300_emit_blend_state(r300, &blend_clear_state);
r300_emit_blend_color_state(r300, &blend_color_clear_state);
r300_emit_dsa_state(r300, &dsa_clear_state);
@@ -106,6 +99,7 @@ static void r300_surface_fill(struct pipe_context* pipe,
struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
struct r300_texture* tex = (struct r300_texture*)dest->texture;
unsigned pixpitch = tex->stride / tex->tex.block.size;
+ boolean invalid = FALSE;
CS_LOCALS(r300);
a = (float)((color >> 24) & 0xff) / 255.0f;
@@ -118,11 +112,28 @@ static void r300_surface_fill(struct pipe_context* pipe,
/* Fallback? */
if (FALSE) {
+fallback:
debug_printf("r300: Falling back on surface clear...");
util_surface_fill(pipe, dest, x, y, w, h, color);
return;
}
+ /* Make sure our target BO is okay. */
+validate:
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ if (r300->winsys->validate(r300->winsys)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ goto fallback;
+ }
+ invalid = TRUE;
+ goto validate;
+ }
+
r300_surface_setup(r300, tex, x, y, w, h);
/* Vertex shader setup */
@@ -216,6 +227,7 @@ static void r300_surface_copy(struct pipe_context* pipe,
struct r300_texture* srctex = (struct r300_texture*)src->texture;
struct r300_texture* desttex = (struct r300_texture*)dest->texture;
unsigned pixpitch = srctex->stride / srctex->tex.block.size;
+ boolean invalid = FALSE;
CS_LOCALS(r300);
debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d),"
@@ -225,21 +237,44 @@ static void r300_surface_copy(struct pipe_context* pipe,
if ((srctex == desttex) &&
((destx < srcx + w) || (srcx < destx + w)) &&
((desty < srcy + h) || (srcy < desty + h))) {
+fallback:
debug_printf("r300: Falling back on surface_copy\n");
util_surface_copy(pipe, FALSE, dest, destx, desty, src,
srcx, srcy, w, h);
}
- /* Add our source texture to the BO list before emitting anything.
- * r300_surface_setup will flush if needed for us. */
- r300->winsys->add_buffer(r300->winsys, srctex->buffer,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ /* Add our target BOs to the list. */
+validate:
+ if (!r300->winsys->add_buffer(r300->winsys, srctex->buffer,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ if (!r300->winsys->add_buffer(r300->winsys, desttex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ if (r300->winsys->validate(r300->winsys)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ goto fallback;
+ }
+ invalid = TRUE;
+ goto validate;
+ }
r300_surface_setup(r300, desttex, destx, desty, w, h);
+ /* Setup the texture. */
r300_emit_sampler(r300, &r300_sampler_copy_state, 0);
r300_emit_texture(r300, srctex, 0);
- r300_flush_textures(r300);
+
+ /* Flush and enable. */
+ BEGIN_CS(4);
+ OUT_CS_REG(R300_TX_INVALTAGS, 0);
+ OUT_CS_REG(R300_TX_ENABLE, 0x1);
+ END_CS;
/* Vertex shader setup */
if (caps->has_tcl) {
@@ -263,7 +298,7 @@ static void r300_surface_copy(struct pipe_context* pipe,
r300_emit_rs_block_state(r300, &r300_rs_block_copy_state);
}
- BEGIN_CS(28);
+ BEGIN_CS(30);
/* VAP stream control, mapping from input memory to PVS/RS memory */
if (caps->has_tcl) {
OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
@@ -287,7 +322,7 @@ static void r300_surface_copy(struct pipe_context* pipe,
OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2);
/* Vertex size. */
- OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
+ OUT_CS_REG(R300_VAP_VTX_SIZE, 0x4);
/* Packet3 with our texcoords */
OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 16);
diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h
index 894def07aa..9a4c39f58b 100644
--- a/src/gallium/drivers/r300/r300_surface.h
+++ b/src/gallium/drivers/r300/r300_surface.h
@@ -101,7 +101,7 @@ static struct r300_rs_block r300_rs_block_copy_state = {
R500_RS_SEL_Q(R300_RS_SEL_K1),
.inst[0] = R300_RS_INST_COL_CN_WRITE,
.count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN,
- .inst_count = R300_RS_TX_OFFSET(6),
+ .inst_count = R300_RS_TX_OFFSET(0),
};
static struct r300_rs_block r500_rs_block_copy_state = {
@@ -111,7 +111,7 @@ static struct r300_rs_block r500_rs_block_copy_state = {
R500_RS_SEL_Q(R500_RS_IP_PTR_K1),
.inst[0] = R500_RS_INST_TEX_CN_WRITE,
.count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN,
- .inst_count = R300_RS_TX_OFFSET(6),
+ .inst_count = R300_RS_TX_OFFSET(0),
};
static struct r300_sampler_state r300_sampler_copy_state = {
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index a5ced8041c..d2893c3b9d 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -52,10 +52,10 @@ struct r300_winsys {
uint32_t vram_size;
/* Add a pipe_buffer to the list of buffer objects to validate. */
- void (*add_buffer)(struct r300_winsys* winsys,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd);
+ boolean (*add_buffer)(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd);
/* Revalidate all currently setup pipe_buffers.
* Returns TRUE if a flush is required. */