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.c4
-rw-r--r--src/gallium/drivers/r300/r300_context.h14
-rw-r--r--src/gallium/drivers/r300/r300_cs.h18
-rw-r--r--src/gallium/drivers/r300/r300_debug.c90
-rw-r--r--src/gallium/drivers/r300/r300_debug.h146
-rw-r--r--src/gallium/drivers/r300/r300_emit.c83
-rw-r--r--src/gallium/drivers/r300/r300_emit.h2
-rw-r--r--src/gallium/drivers/r300/r300_flush.c2
-rw-r--r--src/gallium/drivers/r300/r300_render.c23
-rw-r--r--src/gallium/drivers/r300/r300_state.c9
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.c123
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.h16
-rw-r--r--src/gallium/drivers/r300/r300_surface.c7
-rw-r--r--src/gallium/drivers/r300/r300_texture.c2
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h55
15 files changed, 416 insertions, 178 deletions
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 6bdf544a05..a4e89c37d1 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -34,10 +34,6 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
int i;
- if (r300->dirty_state) {
- r300_emit_dirty_state(r300);
- }
-
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe->screen,
r300->vertex_buffers[i].buffer,
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 4c695c1195..96f1f11246 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -264,6 +264,11 @@ struct r300_context {
/* Draw module. Used mostly for SW TCL. */
struct draw_context* draw;
+ /* Vertex buffer for rendering. */
+ struct pipe_buffer* vbo;
+ /* Offset into the VBO. */
+ size_t vbo_offset;
+
/* Various CSO state objects. */
/* Blend state. */
struct r300_blend_state* blend_state;
@@ -289,7 +294,7 @@ struct r300_context {
/* Texture states. */
struct r300_texture* textures[8];
int texture_count;
- /* Vertex buffers. */
+ /* Vertex buffers for Gallium. */
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
int vertex_buffer_count;
/* Vertex information. */
@@ -314,11 +319,4 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300);
void r300_init_state_functions(struct r300_context* r300);
void r300_init_surface_functions(struct r300_context* r300);
-/* Fun with includes: r300_winsys also declares this prototype.
- * We'll just step out in that case... */
-#ifndef R300_WINSYS_H
-struct pipe_context* r300_create_context(struct pipe_screen* screen,
- struct r300_winsys* r300_winsys);
-#endif
-
#endif /* R300_CONTEXT_H */
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 5d9799dd72..82a3942248 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -49,27 +49,27 @@
#define CS_LOCALS(context) \
struct r300_winsys* cs_winsys = context->winsys; \
- struct radeon_cs* cs = cs_winsys->cs; \
int cs_count = 0;
#define CHECK_CS(size) \
- cs_winsys->check_cs(cs, (size))
+ cs_winsys->check_cs(cs_winsys, (size))
#define BEGIN_CS(size) do { \
CHECK_CS(size); \
debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
size, __FUNCTION__, __FILE__, __LINE__); \
- cs_winsys->begin_cs(cs, (size), __FILE__, __FUNCTION__, __LINE__); \
+ cs_winsys->begin_cs(cs_winsys, (size), \
+ __FILE__, __FUNCTION__, __LINE__); \
cs_count = size; \
} while (0)
#define OUT_CS(value) do { \
- cs_winsys->write_cs_dword(cs, (value)); \
+ cs_winsys->write_cs_dword(cs_winsys, (value)); \
cs_count--; \
} while (0)
#define OUT_CS_32F(value) do { \
- cs_winsys->write_cs_dword(cs, fui(value)); \
+ cs_winsys->write_cs_dword(cs_winsys, fui(value)); \
cs_count--; \
} while (0)
@@ -97,7 +97,7 @@
bo, offset); \
assert(bo); \
OUT_CS(offset); \
- cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \
+ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
cs_count -= 2; \
} while (0)
@@ -106,13 +106,13 @@
__LINE__); \
if (cs_count != 0) \
debug_printf("r300: Warning: cs_count off by %d\n", cs_count); \
- cs_winsys->end_cs(cs, __FILE__, __FUNCTION__, __LINE__); \
+ 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__); \
- cs_winsys->flush_cs(cs); \
+ cs_winsys->flush_cs(cs_winsys); \
} while (0)
#define RADEON_ONE_REG_WR (1 << 15)
@@ -138,7 +138,7 @@
assert(bo); \
OUT_CS(offset); \
OUT_CS(count); \
- cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \
+ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
cs_count -= 2; \
} while (0)
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index dd63136c9d..1ff72172eb 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -30,81 +30,6 @@ static void r300_dump_fs(struct r300_fragment_shader* fs)
}
}
-static char* r500_fs_swiz[] = {
- " R",
- " G",
- " B",
- " A",
- " 0",
- ".5",
- " 1",
- " U",
-};
-
-static char* r500_fs_op_rgb[] = {
- "MAD",
- "DP3",
- "DP4",
- "D2A",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "SOP",
- "MDH",
- "MDV",
-};
-
-static char* r500_fs_op_alpha[] = {
- "MAD",
- " DP",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "EX2",
- "LN2",
- "RCP",
- "RSQ",
- "SIN",
- "COS",
- "MDH",
- "MDV",
-};
-
-static char* r500_fs_mask[] = {
- "NONE",
- "R ",
- " G ",
- "RG ",
- " B ",
- "R B ",
- " GB ",
- "RGB ",
- " A",
- "R A",
- " G A",
- "RG A",
- " BA",
- "R BA",
- " GBA",
- "RGBA",
-};
-
-static char* r500_fs_tex[] = {
- " NOP",
- " LD",
- "TEXKILL",
- " PROJ",
- "LODBIAS",
- " LOD",
- " DXDY",
-};
-
void r500_fs_dump(struct r500_fragment_shader* fs)
{
int i;
@@ -225,12 +150,25 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
}
}
+static void r300_vs_op_dump(uint32_t op)
+{
+ if (op & 0x81) {
+ debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
+ } else if (op & 0x80) {
+ debug_printf(" PVS_MACRO_OP_2CLK_MADD\n");
+ } else if (op & 0x40) {
+ debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]);
+ } else {
+ debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]);
+ }
+}
+
void r300_vs_dump(struct r300_vertex_shader* vs)
{
int i;
for (i = 0; i < vs->instruction_count; i++) {
- debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0);
+ 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);
diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h
index a1f873656d..6306594099 100644
--- a/src/gallium/drivers/r300/r300_debug.h
+++ b/src/gallium/drivers/r300/r300_debug.h
@@ -27,6 +27,152 @@
#include "r300_state_shader.h"
#include "r300_state_tcl.h"
+static char* r500_fs_swiz[] = {
+ " R",
+ " G",
+ " B",
+ " A",
+ " 0",
+ ".5",
+ " 1",
+ " U",
+};
+
+static char* r500_fs_op_rgb[] = {
+ "MAD",
+ "DP3",
+ "DP4",
+ "D2A",
+ "MIN",
+ "MAX",
+ "---",
+ "CND",
+ "CMP",
+ "FRC",
+ "SOP",
+ "MDH",
+ "MDV",
+};
+
+static char* r500_fs_op_alpha[] = {
+ "MAD",
+ " DP",
+ "MIN",
+ "MAX",
+ "---",
+ "CND",
+ "CMP",
+ "FRC",
+ "EX2",
+ "LN2",
+ "RCP",
+ "RSQ",
+ "SIN",
+ "COS",
+ "MDH",
+ "MDV",
+};
+
+static char* r500_fs_mask[] = {
+ "NONE",
+ "R ",
+ " G ",
+ "RG ",
+ " B ",
+ "R B ",
+ " GB ",
+ "RGB ",
+ " A",
+ "R A",
+ " G A",
+ "RG A",
+ " BA",
+ "R BA",
+ " GBA",
+ "RGBA",
+};
+
+static char* r500_fs_tex[] = {
+ " NOP",
+ " LD",
+ "TEXKILL",
+ " PROJ",
+ "LODBIAS",
+ " LOD",
+ " DXDY",
+};
+
+static char* r300_vs_ve_ops[] = {
+ /* R300 vector ops */
+ " VE_NO_OP",
+ " VE_DOT_PRODUCT",
+ " VE_MULTIPLY",
+ " VE_ADD",
+ " VE_MULTIPLY_ADD",
+ " VE_DISTANCE_FACTOR",
+ " VE_FRACTION",
+ " VE_MAXIMUM",
+ " VE_MINIMUM",
+ "VE_SET_GREATER_THAN_EQUAL",
+ " VE_SET_LESS_THAN",
+ " VE_MULTIPLYX2_ADD",
+ " VE_MULTIPLY_CLAMP",
+ " VE_FLT2FIX_DX",
+ " VE_FLT2FIX_DX_RND",
+ /* R500 vector ops */
+ " VE_PRED_SET_EQ_PUSH",
+ " VE_PRED_SET_GT_PUSH",
+ " VE_PRED_SET_GTE_PUSH",
+ " VE_PRED_SET_NEQ_PUSH",
+ " VE_COND_WRITE_EQ",
+ " VE_COND_WRITE_GT",
+ " VE_COND_WRITE_GTE",
+ " VE_COND_WRITE_NEQ",
+ " VE_SET_GREATER_THAN",
+ " VE_SET_EQUAL",
+ " VE_SET_NOT_EQUAL",
+ " (reserved)",
+ " (reserved)",
+ " (reserved)",
+};
+
+static char* r300_vs_me_ops[] = {
+ /* R300 math ops */
+ " ME_NO_OP",
+ " ME_EXP_BASE2_DX",
+ " ME_LOG_BASE2_DX",
+ " ME_EXP_BASEE_FF",
+ " ME_LIGHT_COEFF_DX",
+ " ME_POWER_FUNC_FF",
+ " ME_RECIP_DX",
+ " ME_RECIP_FF",
+ " ME_RECIP_SQRT_DX",
+ " ME_RECIP_SQRT_FF",
+ " ME_MULTIPLY",
+ " ME_EXP_BASE2_FULL_DX",
+ " ME_LOG_BASE2_FULL_DX",
+ " ME_POWER_FUNC_FF_CLAMP_B",
+ "ME_POWER_FUNC_FF_CLAMP_B1",
+ "ME_POWER_FUNC_FF_CLAMP_01",
+ " ME_SIN",
+ " ME_COS",
+ /* R500 math ops */
+ " ME_LOG_BASE2_IEEE",
+ " ME_RECIP_IEEE",
+ " ME_RECIP_SQRT_IEEE",
+ " ME_PRED_SET_EQ",
+ " ME_PRED_SET_GT",
+ " ME_PRED_SET_GTE",
+ " ME_PRED_SET_NEQ",
+ " ME_PRED_SET_CLR",
+ " ME_PRED_SET_INV",
+ " ME_PRED_SET_POP",
+ " ME_PRED_SET_RESTORE",
+ " (reserved)",
+ " (reserved)",
+ " (reserved)",
+};
+
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 417d5f6307..c73d5a0b44 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -152,34 +152,39 @@ void r500_emit_fragment_shader(struct r300_context* r300,
END_CS;
}
-/* XXX add pitch, stride, clean up */
void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb)
{
- int i;
struct r300_texture* tex;
+ unsigned pixpitch;
+ int i;
CS_LOCALS(r300);
- BEGIN_CS((6 * fb->nr_cbufs) + (fb->zsbuf ? 6 : 0) + 4);
+ BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4);
for (i = 0; i < fb->nr_cbufs; i++) {
tex = (struct r300_texture*)fb->cbufs[i]->texture;
+ pixpitch = tex->stride / tex->tex.block.size;
+
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pixpitch |
+ r300_translate_colorformat(tex->tex.format));
+
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),
r300_translate_out_fmt(fb->cbufs[i]->format));
}
if (fb->zsbuf) {
tex = (struct r300_texture*)fb->zsbuf->texture;
+ pixpitch = (tex->stride / tex->tex.block.size);
+
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- if (fb->zsbuf->format == PIPE_FORMAT_Z24S8_UNORM) {
- OUT_CS_REG(R300_ZB_FORMAT,
- R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL);
- } else {
- OUT_CS_REG(R300_ZB_FORMAT, 0x0);
- }
+
+ OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));
+
+ OUT_CS_REG(R300_ZB_DEPTHPITCH, pixpitch);
}
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
@@ -291,6 +296,30 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
+void r300_emit_vertex_buffer(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ debug_printf("r300: Preparing vertex buffer %p for render, "
+ "vertex size %d\n", r300->vbo,
+ r300->vertex_info.vinfo.size);
+ /* Set the pointer to our vertex buffer. The emitted values are this:
+ * PACKET3 [3D_LOAD_VBPNTR]
+ * COUNT [1]
+ * FORMAT [size | stride << 8]
+ * OFFSET [offset into BO]
+ * VBPNTR [relocated BO]
+ */
+ BEGIN_CS(7);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
+ OUT_CS(1);
+ OUT_CS(r300->vertex_info.vinfo.size |
+ (r300->vertex_info.vinfo.size << 8));
+ OUT_CS(r300->vbo_offset);
+ OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
+}
+
void r300_emit_vertex_format_state(struct r300_context* r300)
{
int i;
@@ -416,16 +445,45 @@ void r300_flush_textures(struct r300_context* r300)
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;
- if (!(r300->dirty_state) && !(r300->dirty_hw)) {
+ if (!(r300->dirty_state)) {
return;
}
r300_update_derived_state(r300);
/* XXX check size */
+ /* 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!");
+ if (!tex->buffer) return;
+ r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+ /* ...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!");
+ if (!tex->buffer) return;
+ r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+ /* ...and vertex buffer. */
+ if (r300->vbo) {
+ r300->winsys->add_buffer(r300->winsys, r300->vbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ } 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 (r300->dirty_state & R300_NEW_BLEND) {
r300_emit_blend_state(r300, r300->blend_state);
@@ -506,4 +564,9 @@ void r300_emit_dirty_state(struct r300_context* r300)
r300_emit_vertex_format_state(r300);
r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;
}
+
+ /* Finally, emit the VBO. */
+ r300_emit_vertex_buffer(r300);
+
+ r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 31dbc7ab85..36e14f69f7 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -62,6 +62,8 @@ void r300_emit_scissor_state(struct r300_context* r300,
void r300_emit_texture(struct r300_context* r300,
struct r300_texture* tex, unsigned offset);
+void r300_emit_vertex_buffer(struct r300_context* r300);
+
void r300_emit_vertex_format_state(struct r300_context* r300);
void r300_emit_vertex_shader(struct r300_context* r300,
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 20ca6905ad..89a5f2b20c 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -29,6 +29,8 @@ static void r300_flush(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
CS_LOCALS(r300);
+ draw_flush(r300->draw);
+
if (r300->dirty_hw) {
FLUSH_CS;
r300_emit_invariant_state(r300);
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index cbd84d7c56..29b66cee7e 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -180,27 +180,10 @@ static void prepare_render(struct r300_render* render, unsigned count)
CS_LOCALS(r300);
- /* Make sure that all possible state is emitted. */
- r300_emit_dirty_state(r300);
+ r300->vbo = render->vbo;
+ r300->vbo_offset = render->vbo_offset;
- debug_printf("r300: Preparing vertex buffer %p for render, "
- "vertex size %d, vertex count %d\n", render->vbo,
- r300->vertex_info.vinfo.size, count);
- /* Set the pointer to our vertex buffer. The emitted values are this:
- * PACKET3 [3D_LOAD_VBPNTR]
- * COUNT [1]
- * FORMAT [size | stride << 8]
- * OFFSET [0]
- * VBPNTR [relocated BO]
- */
- BEGIN_CS(7);
- OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
- OUT_CS(1);
- OUT_CS(r300->vertex_info.vinfo.size |
- (r300->vertex_info.vinfo.size << 8));
- OUT_CS(render->vbo_offset);
- OUT_CS_RELOC(render->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
- END_CS;
+ r300_emit_dirty_state(r300);
}
static void r300_render_draw_arrays(struct vbuf_render* render,
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index c9507ae193..0143e228c4 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -421,6 +421,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ draw_flush(r300->draw);
draw_set_rasterizer_state(r300->draw, &rs->rs);
r300->rs_state = rs;
@@ -528,7 +529,6 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
const struct pipe_scissor_state* state)
{
struct r300_context* r300 = r300_context(pipe);
- draw_flush(r300->draw);
if (r300_screen(r300->context.screen)->caps->is_r500) {
r300->scissor_state->scissor_top_left =
@@ -555,19 +555,24 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
+ draw_flush(r300->draw);
+
if (r300_screen(r300->context.screen)->caps->has_tcl) {
/* Do the transform in HW. */
r300->viewport_state->vte_control = R300_VTX_W0_FMT;
if (state->scale[0] != 1.0f) {
+ assert(state->scale[0] != 0.0f);
r300->viewport_state->xscale = state->scale[0];
r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA;
}
if (state->scale[1] != 1.0f) {
+ assert(state->scale[1] != 0.0f);
r300->viewport_state->yscale = state->scale[1];
r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA;
}
if (state->scale[2] != 1.0f) {
+ assert(state->scale[2] != 0.0f);
r300->viewport_state->zscale = state->scale[2];
r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA;
}
@@ -642,6 +647,8 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ draw_flush(r300->draw);
+
if (r300_screen(pipe->screen)->caps->has_tcl) {
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c
index bb96e2ad67..ed9164db49 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.c
+++ b/src/gallium/drivers/r300/r300_state_tcl.c
@@ -34,14 +34,20 @@ static void r300_vs_declare(struct r300_vs_asm* assembler,
assembler->tab[decl->DeclarationRange.First] = 0;
break;
case TGSI_SEMANTIC_COLOR:
- assembler->tab[decl->DeclarationRange.First] = 2;
+ assembler->tab[decl->DeclarationRange.First] =
+ (assembler->point_size ? 1 : 0) +
+ assembler->out_colors;
break;
+ case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
/* XXX multiple? */
- assembler->tab[decl->DeclarationRange.First] = 6;
+ assembler->tab[decl->DeclarationRange.First] =
+ (assembler->point_size ? 1 : 0) +
+ assembler->out_colors +
+ assembler->out_texcoords;
break;
case TGSI_SEMANTIC_PSIZE:
- assembler->tab[decl->DeclarationRange.First] = 15;
+ assembler->tab[decl->DeclarationRange.First] = 1;
break;
default:
debug_printf("r300: vs: Bad semantic declaration %d\n",
@@ -65,16 +71,13 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
{
switch (src->File) {
case TGSI_FILE_NULL:
- /* Probably a zero or one swizzle */
- return R300_PVS_SRC_REG_INPUT;
- break;
case TGSI_FILE_INPUT:
+ /* Probably a zero or one swizzle */
return R300_PVS_SRC_REG_INPUT;
- break;
case TGSI_FILE_TEMPORARY:
return R300_PVS_SRC_REG_TEMPORARY;
- break;
case TGSI_FILE_CONSTANT:
+ case TGSI_FILE_IMMEDIATE:
return R300_PVS_SRC_REG_CONSTANT;
default:
debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
@@ -83,16 +86,32 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
return 0;
}
+static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler,
+ struct tgsi_src_register* src)
+{
+ switch (src->File) {
+ case TGSI_FILE_NULL:
+ case TGSI_FILE_INPUT:
+ case TGSI_FILE_TEMPORARY:
+ case TGSI_FILE_CONSTANT:
+ return src->Index;
+ case TGSI_FILE_IMMEDIATE:
+ return src->Index + assembler->imm_offset;
+ default:
+ debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
+ break;
+ }
+ return 0;
+}
+
static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler,
struct tgsi_dst_register* dst)
{
switch (dst->File) {
case TGSI_FILE_TEMPORARY:
return R300_PVS_DST_REG_TEMPORARY;
- break;
case TGSI_FILE_OUTPUT:
return R300_PVS_DST_REG_OUT;
- break;
default:
debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File);
break;
@@ -106,10 +125,8 @@ static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
switch (dst->File) {
case TGSI_FILE_TEMPORARY:
return dst->Index;
- break;
case TGSI_FILE_OUTPUT:
return assembler->tab[dst->Index];
- break;
default:
debug_printf("r300: vs: Unimplemented dst %d\n", dst->File);
break;
@@ -129,6 +146,12 @@ static uint32_t r300_vs_op(unsigned op)
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
return R300_VE_ADD;
+ case TGSI_OPCODE_MAX:
+ return R300_VE_MAXIMUM;
+ case TGSI_OPCODE_SLT:
+ return R300_VE_SET_LESS_THAN;
+ case TGSI_OPCODE_RSQ:
+ return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX;
case TGSI_OPCODE_MAD:
return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD;
default:
@@ -152,39 +175,62 @@ static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
}
}
+/* XXX icky icky icky icky */
+static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg)
+{
+ if (reg->SrcRegister.Extended) {
+ return reg->SrcRegisterExtSwz.ExtSwizzleX |
+ (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) |
+ (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) |
+ (reg->SrcRegisterExtSwz.ExtSwizzleX << 9);
+ } else {
+ return reg->SrcRegister.SwizzleX |
+ (reg->SrcRegister.SwizzleX << 3) |
+ (reg->SrcRegister.SwizzleX << 6) |
+ (reg->SrcRegister.SwizzleX << 9);
+ }
+}
+
+/* XXX scalar stupidity */
static void r300_vs_emit_inst(struct r300_vertex_shader* vs,
struct r300_vs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst,
unsigned op,
- unsigned count)
+ unsigned count,
+ boolean is_scalar)
{
int i = vs->instruction_count;
vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) |
R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) |
R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) |
- R300_PVS_DST_WE_XYZW;
+ R300_PVS_DST_WE(dst->DstRegister.WriteMask);
switch (count) {
case 3:
vs->instructions[i].inst3 =
R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
&src[2].SrcRegister)) |
- R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) |
+ R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
+ &src[2].SrcRegister)) |
R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2]));
/* Fall through */
case 2:
vs->instructions[i].inst2 =
R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
&src[1].SrcRegister)) |
- R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) |
+ R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
+ &src[1].SrcRegister)) |
R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1]));
/* Fall through */
case 1:
vs->instructions[i].inst1 =
R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
&src[0].SrcRegister)) |
- R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) |
- R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0]));
+ R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
+ &src[0].SrcRegister)) |
+ /* XXX the icky, it burns */
+ R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0])
+ : r300_vs_swiz(&src[0]));
break;
}
vs->instruction_count++;
@@ -195,11 +241,18 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
struct tgsi_full_instruction* inst)
{
switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_RSQ:
+ r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], inst->Instruction.Opcode,
+ 1, TRUE);
+ break;
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_MUL:
+ case TGSI_OPCODE_MAX:
+ case TGSI_OPCODE_SLT:
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2);
+ 2, FALSE);
break;
case TGSI_OPCODE_DP3:
/* Set alpha swizzle to zero for src0 and src1 */
@@ -229,19 +282,19 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
case TGSI_OPCODE_DP4:
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2);
+ 2, FALSE);
break;
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
inst->FullSrcRegisters[1] = r300_constant_zero;
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2);
+ 2, FALSE);
break;
case TGSI_OPCODE_MAD:
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 3);
+ 3, FALSE);
break;
case TGSI_OPCODE_END:
break;
@@ -252,6 +305,28 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
}
}
+static void r300_vs_init(struct r300_vertex_shader* vs,
+ struct r300_vs_asm* assembler)
+{
+ struct tgsi_shader_info* info = &vs->info;
+ int i;
+
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
+ case TGSI_SEMANTIC_PSIZE:
+ assembler->point_size = TRUE;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ assembler->out_colors++;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ assembler->out_texcoords++;
+ break;
+ }
+ }
+}
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs)
{
@@ -264,6 +339,10 @@ void r300_translate_vertex_shader(struct r300_context* r300,
if (assembler == NULL) {
return;
}
+
+ /* Init assembler. */
+ r300_vs_init(vs, assembler);
+
/* Setup starting offset for immediates. */
assembler->imm_offset = consts->user_count;
diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h
index de944028ba..d5d425e9d6 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.h
+++ b/src/gallium/drivers/r300/r300_state_tcl.h
@@ -35,6 +35,10 @@
# define R300_VE_DOT_PRODUCT 1
# define R300_VE_MULTIPLY 2
# define R300_VE_ADD 3
+# define R300_VE_MAXIMUM 7
+# define R300_VE_SET_LESS_THAN 10
+#define R300_PVS_DST_MATH_INST (1 << 6)
+# define R300_ME_RECIP_DX 6
#define R300_PVS_DST_MACRO_INST (1 << 7)
# define R300_PVS_MACRO_OP_2CLK_MADD 0
#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
@@ -99,7 +103,13 @@ struct r300_vs_asm {
unsigned imm_offset;
/* Number of immediate constants. */
unsigned imm_count;
- /* Offsets into vertex output memory. */
+ /* Number of colors to write. */
+ unsigned out_colors;
+ /* Number of texcoords to write. */
+ unsigned out_texcoords;
+ /* Whether to emit point size. */
+ boolean point_size;
+ /* Tab of declared outputs to OVM outputs. */
unsigned tab[16];
};
@@ -115,7 +125,7 @@ static struct r300_vertex_shader r300_passthrough_vertex_shader = {
.instructions[0].inst3 = 0x0,
.instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(2) | R300_PVS_DST_WE_XYZW,
+ R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
.instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
.instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
@@ -134,7 +144,7 @@ static struct r300_vertex_shader r300_texture_vertex_shader = {
.instructions[0].inst3 = 0x0,
.instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(6) | R300_PVS_DST_WE_XYZW,
+ R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
.instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
.instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index 79bed03253..4dd5b8af99 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -34,6 +34,13 @@ static void r300_surface_setup(struct pipe_context* pipe,
unsigned pixpitch = tex->stride / tex->tex.block.size;
CS_LOCALS(r300);
+ /* Make sure our target BO is okay. */
+ r300->winsys->add_buffer(r300->winsys, tex->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);
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index fe91f4e184..5ea9f56247 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -86,8 +86,6 @@ static struct pipe_texture*
r300_texture_create(struct pipe_screen* screen,
const struct pipe_texture* template)
{
- /* XXX struct r300_screen* r300screen = r300_screen(screen); */
-
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
if (!tex) {
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index baa95282c3..a833bb0399 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -35,8 +35,6 @@ extern "C" {
#include "pipe/p_state.h"
#include "pipe/internal/p_winsys_screen.h"
-struct radeon_cs;
-
struct r300_winsys {
/* Parent class */
struct pipe_winsys base;
@@ -50,39 +48,50 @@ struct r300_winsys {
/* GB pipe count */
uint32_t gb_pipes;
- /* CS object. This is very much like Intel's batchbuffer.
- * Fill it full of dwords and relocs and then submit.
- * Repeat as needed. */
- struct radeon_cs* cs;
+ /* GART size. */
+ uint32_t gart_size;
+
+ /* VRAM size. */
+ 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);
+
+ /* Revalidate all currently setup pipe_buffers.
+ * Returns TRUE if a flush is required. */
+ boolean (*validate)(struct r300_winsys* winsys);
/* Check to see if there's room for commands. */
- boolean (*check_cs)(struct radeon_cs* cs, int size);
+ boolean (*check_cs)(struct r300_winsys* winsys, int size);
/* Start a command emit. */
- void (*begin_cs)(struct radeon_cs* cs,
- int size,
- const char* file,
- const char* function,
- int line);
+ void (*begin_cs)(struct r300_winsys* winsys,
+ int size,
+ const char* file,
+ const char* function,
+ int line);
/* Write a dword to the command buffer. */
- void (*write_cs_dword)(struct radeon_cs* cs, uint32_t dword);
+ void (*write_cs_dword)(struct r300_winsys* winsys, uint32_t dword);
/* Write a relocated dword to the command buffer. */
- void (*write_cs_reloc)(struct radeon_cs* cs,
- struct pipe_buffer* bo,
- uint32_t rd,
- uint32_t wd,
- uint32_t flags);
+ void (*write_cs_reloc)(struct r300_winsys* winsys,
+ struct pipe_buffer* bo,
+ uint32_t rd,
+ uint32_t wd,
+ uint32_t flags);
/* Finish a command emit. */
- void (*end_cs)(struct radeon_cs* cs,
- const char* file,
- const char* function,
- int line);
+ void (*end_cs)(struct r300_winsys* winsys,
+ const char* file,
+ const char* function,
+ int line);
/* Flush the CS. */
- void (*flush_cs)(struct radeon_cs* cs);
+ void (*flush_cs)(struct r300_winsys* winsys);
};
struct pipe_context* r300_create_context(struct pipe_screen* screen,