summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/nv04/nv04_miptree.c3
-rw-r--r--src/gallium/drivers/nv04/nv04_state.h2
-rw-r--r--src/gallium/drivers/r300/r300_context.c4
-rw-r--r--src/gallium/drivers/r300/r300_context.h7
-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.c60
-rw-r--r--src/gallium/drivers/r300/r300_emit.h2
-rw-r--r--src/gallium/drivers/r300/r300_render.c23
-rw-r--r--src/gallium/drivers/r300/r300_state.c6
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c35
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.c85
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.h4
-rw-r--r--src/gallium/drivers/r300/r300_surface.c20
-rw-r--r--src/gallium/drivers/r300/r300_texture.c2
15 files changed, 339 insertions, 150 deletions
diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c
index 4da833c25e..93f752faec 100644
--- a/src/gallium/drivers/nv04/nv04_miptree.c
+++ b/src/gallium/drivers/nv04/nv04_miptree.c
@@ -31,7 +31,8 @@ nv04_miptree_layout(struct nv04_miptree *nv04mt)
for (l = 0; l <= pt->last_level; l++) {
- nv04mt->level[l].image_offset = offset;
+ nv04mt->level[l].image_offset =
+ CALLOC(nr_faces, sizeof(unsigned));
offset += nv04mt->level[l].pitch * pt->height[l];
}
diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h
index 0d51439e3f..399f750dbe 100644
--- a/src/gallium/drivers/nv04/nv04_state.h
+++ b/src/gallium/drivers/nv04/nv04_state.h
@@ -37,7 +37,7 @@ struct nv04_miptree {
struct {
uint pitch;
- uint image_offset;
+ uint *image_offset;
} level[PIPE_MAX_TEXTURE_LEVELS];
};
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 6f62998b35..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. */
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 01bac5f759..c73d5a0b44 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -296,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;
@@ -421,20 +445,41 @@ 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_hw)) {
+ if (!(r300->dirty_state)) {
return;
}
r300_update_derived_state(r300);
/* XXX check size */
- struct r300_texture* fb_tex =
- (struct r300_texture*)r300->framebuffer_state.cbufs[0];
- r300->winsys->add_buffer(r300->winsys, fb_tex->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ /* 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);
@@ -519,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_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 184a23c9e6..2118f7706f 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -289,6 +289,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
/* Copy state directly into shader. */
fs->state = *shader;
+ fs->state.tokens = tgsi_dup_tokens(shader->tokens);
tgsi_scan_shader(shader->tokens, &fs->info);
@@ -317,6 +318,8 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
/* Delete fragment shader state. */
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
{
+ struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
+ FREE(fs->state.tokens);
FREE(shader);
}
@@ -562,14 +565,17 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
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;
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index c4c9784a00..caa5f3b543 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -162,26 +162,40 @@ static void r300_vs_tab_routes(struct r300_context* r300,
static void r300_vertex_psc(struct r300_context* r300,
struct r300_vertex_format* vformat)
{
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct vertex_info* vinfo = &vformat->vinfo;
int* tab = vformat->vs_tab;
uint32_t temp;
- int i;
+ int i, attrib_count;
- debug_printf("r300: attrib count: %d\n", vinfo->num_attribs);
- for (i = 0; i < vinfo->num_attribs; i++) {
- debug_printf("r300: attrib: offset %d, interp %d, size %d,"
- " tab %d\n", vinfo->attrib[i].src_index,
- vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
- tab[i]);
+ /* Vertex shaders have no semantics on their inputs,
+ * so PSC should just route stuff based on their info,
+ * and not on attrib information. */
+ if (r300screen->caps->has_tcl) {
+ attrib_count = r300->vs->info.num_inputs;
+ debug_printf("r300: routing %d attribs in psc for vs\n",
+ attrib_count);
+ } else {
+ attrib_count = vinfo->num_attribs;
+ debug_printf("r300: attrib count: %d\n", attrib_count);
+ for (i = 0; i < attrib_count; i++) {
+ debug_printf("r300: attrib: offset %d, interp %d, size %d,"
+ " tab %d\n", vinfo->attrib[i].src_index,
+ vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
+ tab[i]);
+ }
}
- for (i = 0; i < vinfo->num_attribs; i++) {
+ for (i = 0; i < attrib_count; i++) {
/* Make sure we have a proper destination for our attribute */
assert(tab[i] != -1);
/* Add the attribute to the PSC table. */
- temp = translate_vertex_data_type(vinfo->attrib[i].emit) |
- (tab[i] << R300_DST_VEC_LOC_SHIFT);
+ temp = r300screen->caps->has_tcl ?
+ R300_DATA_TYPE_FLOAT_4 :
+ translate_vertex_data_type(vinfo->attrib[i].emit);
+ temp |= tab[i] << R300_DST_VEC_LOC_SHIFT;
+
if (i & 1) {
vformat->vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;
vformat->vap_prog_stream_cntl[i >> 1] |= temp << 16;
@@ -206,7 +220,6 @@ static void r300_vertex_psc(struct r300_context* r300,
/* Update the vertex format. */
static void r300_update_vertex_format(struct r300_context* r300)
{
- struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct r300_vertex_format vformat;
int i;
diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c
index d84912de48..ed9164db49 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.c
+++ b/src/gallium/drivers/r300/r300_state_tcl.c
@@ -71,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);
@@ -89,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;
@@ -112,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;
@@ -135,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:
@@ -158,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++;
@@ -201,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 */
@@ -235,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;
diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h
index e2e1357d43..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)
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index 4dd5b8af99..3198c97378 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -23,19 +23,17 @@
#include "r300_surface.h"
-static void r300_surface_setup(struct pipe_context* pipe,
- struct pipe_surface* dest,
+static void r300_surface_setup(struct r300_context* r300,
+ struct r300_texture* dest,
unsigned x, unsigned y,
unsigned w, unsigned h)
{
- struct r300_context* r300 = r300_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;
+ struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
+ unsigned pixpitch = dest->stride / dest->tex.block.size;
CS_LOCALS(r300);
/* Make sure our target BO is okay. */
- r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 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);
@@ -71,9 +69,9 @@ static void r300_surface_setup(struct pipe_context* pipe,
/* Setup colorbuffer. */
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
- OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch |
- r300_translate_colorformat(tex->tex.format));
+ r300_translate_colorformat(dest->tex.format));
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);
END_CS;
@@ -110,7 +108,7 @@ static void r300_surface_fill(struct pipe_context* pipe,
return;
}
- r300_surface_setup(r300, dest, x, y, w, h);
+ r300_surface_setup(r300, tex, x, y, w, h);
/* Vertex shader setup */
if (caps->has_tcl) {
@@ -227,6 +225,8 @@ static void r300_surface_copy(struct pipe_context* pipe,
srcx, srcy, w, h);
}
+ r300_surface_setup(r300, desttex, destx, desty, w, h);
+
r300_emit_sampler(r300, &r300_sampler_copy_state, 0);
r300_emit_texture(r300, srctex, 0);
r300_flush_textures(r300);
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) {