summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
authorNicolai Hähnle <nhaehnle@gmail.com>2009-10-03 19:30:48 +0200
committerNicolai Hähnle <nhaehnle@gmail.com>2009-10-03 19:30:48 +0200
commit6d25b9125ec1e66e0e255b0ee20fe18dfe1076fa (patch)
treec376951940eac2875567979a81e6a03a019942b7 /src/gallium/drivers/r300
parent81c7561d9d3faf70ac22c6a5f3fbea18f53eed92 (diff)
parent7d2699aedc084d9cb9c2bd2f8bdb5f038271ac1e (diff)
Merge branch 'master' into r300-compiler
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_cs.h30
-rw-r--r--src/gallium/drivers/r300/r300_emit.c1
-rw-r--r--src/gallium/drivers/r300/r300_fs.c11
-rw-r--r--src/gallium/drivers/r300/r300_fs.h2
-rw-r--r--src/gallium/drivers/r300/r300_reg.h1
-rw-r--r--src/gallium/drivers/r300/r300_render.c14
-rw-r--r--src/gallium/drivers/r300/r300_screen.c17
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c47
-rw-r--r--src/gallium/drivers/r300/r300_texture.c38
-rw-r--r--src/gallium/drivers/r300/r300_texture.h5
10 files changed, 85 insertions, 81 deletions
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 0a7e470363..883f0a02dc 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -68,11 +68,17 @@
} while (0)
#define OUT_CS(value) do { \
+ if (VERY_VERBOSE_CS || VERY_VERBOSE_REGISTERS) { \
+ DBG(cs_context_copy, DBG_CS, "r300: writing %08x\n", value); \
+ } \
cs_winsys->write_cs_dword(cs_winsys, (value)); \
cs_count--; \
} while (0)
#define OUT_CS_32F(value) do { \
+ if (VERY_VERBOSE_CS || VERY_VERBOSE_REGISTERS) { \
+ DBG(cs_context_copy, DBG_CS, "r300: writing %f\n", value); \
+ } \
cs_winsys->write_cs_dword(cs_winsys, fui(value)); \
cs_count--; \
} while (0)
@@ -82,8 +88,9 @@
DBG(cs_context_copy, DBG_CS, "r300: writing 0x%08X to register 0x%04X\n", \
value, register); \
assert(register); \
- OUT_CS(CP_PACKET0(register, 0)); \
- OUT_CS(value); \
+ cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0(register, 0)); \
+ cs_winsys->write_cs_dword(cs_winsys, value); \
+ cs_count -= 2; \
} while (0)
/* Note: This expects count to be the number of registers,
@@ -93,7 +100,8 @@
DBG(cs_context_copy, DBG_CS, "r300: writing register sequence of %d to 0x%04X\n", \
count, register); \
assert(register); \
- OUT_CS(CP_PACKET0(register, ((count) - 1))); \
+ cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1))); \
+ cs_count--; \
} while (0)
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
@@ -101,9 +109,9 @@
"domains (%d, %d, %d)\n", \
bo, offset, rd, wd, flags); \
assert(bo); \
- OUT_CS(offset); \
+ cs_winsys->write_cs_dword(cs_winsys, offset); \
cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
- cs_count -= 2; \
+ cs_count -= 3; \
} while (0)
#define END_CS do { \
@@ -131,24 +139,26 @@
DBG(cs_context_copy, DBG_CS, "r300: writing data sequence of %d to 0x%04X\n", \
count, register); \
assert(register); \
- OUT_CS(CP_PACKET0(register, ((count) - 1)) | RADEON_ONE_REG_WR); \
+ cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR); \
+ cs_count--; \
} while (0)
#define CP_PACKET3(op, count) \
(RADEON_CP_PACKET3 | (op) | ((count) << 16))
#define OUT_CS_PKT3(op, count) do { \
- OUT_CS(CP_PACKET3(op, count)); \
+ cs_winsys->write_cs_dword(cs_winsys, CP_PACKET3(op, count)); \
+ cs_count--; \
} while (0)
#define OUT_CS_INDEX_RELOC(bo, offset, count, rd, wd, flags) do { \
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for index buffer %p," \
"offset %d\n", bo, offset); \
assert(bo); \
- OUT_CS(offset); \
- OUT_CS(count); \
+ cs_winsys->write_cs_dword(cs_winsys, offset); \
+ cs_winsys->write_cs_dword(cs_winsys, count); \
cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
- cs_count -= 2; \
+ cs_count -= 4; \
} while (0)
#endif /* R300_CS_H */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index a1b36ba2ed..77ce431cdc 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -381,6 +381,7 @@ void r300_emit_query_end(struct r300_context* r300,
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
0, RADEON_GEM_DOMAIN_GTT, 0);
+ break;
default:
debug_printf("r300: Implementation error: Chipset reports %d"
" pixel pipes!\n", caps->num_frag_pipes);
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index a0e848a59a..546ad545a5 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -126,9 +126,14 @@ void r300_translate_fragment_shader(struct r300_context* r300,
/* Invoke the compiler */
r3xx_compile_fragment_program(&compiler);
if (compiler.Base.Error) {
- /* Todo: Fail gracefully */
- fprintf(stderr, "r300 FP: Compiler error\n");
- abort();
+ /* Todo: Fallback to software rendering gracefully? */
+ fprintf(stderr, "r300 FP: Compiler error: %s\n", compiler.Base.ErrorMsg);
+
+ if (compiler.is_r500) {
+ memcpy(compiler.code, &r5xx_passthrough_fragment_shader, sizeof(r5xx_passthrough_fragment_shader));
+ } else {
+ memcpy(compiler.code, &r3xx_passthrough_fragment_shader, sizeof(r3xx_passthrough_fragment_shader));
+ }
}
/* And, finally... */
diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h
index 9fab789402..967e9f697e 100644
--- a/src/gallium/drivers/r300/r300_fs.h
+++ b/src/gallium/drivers/r300/r300_fs.h
@@ -48,4 +48,4 @@ struct r300_fragment_shader {
void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs);
- #endif /* R300_FS_H */
+#endif /* R300_FS_H */
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 03cd219cde..3abff5db62 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -1478,6 +1478,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_TX_PITCH_EN (1 << 31)
# define R300_TX_WIDTH(x) ((x) << 0)
# define R300_TX_HEIGHT(x) ((x) << 11)
+# define R300_TX_DEPTH(x) ((x) << 22)
# define R300_TX_NUM_LEVELS(x) ((x) << 26)
#define R300_TX_FORMAT1_0 0x44C0
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 737396d8d9..ca44e0f661 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -79,12 +79,14 @@ 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 (size + r300render->vbo_offset > r300render->vbo_size)
+ if (size + r300render->vbo_offset > r300render->vbo_size)
{
+ pipe_buffer_reference(&r300->vbo, NULL);
r300render->vbo = pipe_buffer_create(screen,
64,
PIPE_BUFFER_USAGE_VERTEX,
R300_MAX_VBO_SIZE);
+ r300render->vbo_offset = 0;
r300render->vbo_size = R300_MAX_VBO_SIZE;
}
@@ -117,7 +119,7 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max);
END_CS;
- r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
+ r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
r300render->vertex_size * (max + 1));
pipe_buffer_unmap(screen, r300render->vbo);
}
@@ -129,7 +131,6 @@ static void r300_render_release_vertices(struct vbuf_render* render)
r300render->vbo_offset += r300render->vbo_max_used;
r300render->vbo_max_used = 0;
- r300->vbo = NULL;
}
static boolean r300_render_set_primitive(struct vbuf_render* render,
@@ -222,13 +223,6 @@ static void r300_render_draw(struct vbuf_render* render,
r300_prepare_render(r300render, count);
- /* Send our indices into an index buffer. */
- index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX,
- count * 2);
- if (!index_buffer) {
- return;
- }
-
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) |
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 3b5b1bbd37..f2659ca61f 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -101,11 +101,9 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
case PIPE_CAP_MAX_RENDER_TARGETS:
return 4;
case PIPE_CAP_OCCLUSION_QUERY:
- /* IN THEORY */
- return 0;
+ return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
- /* IN THEORY */
- return 0;
+ return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
if (r300screen->caps->is_r500) {
/* 13 == 4096x4096 */
@@ -347,16 +345,9 @@ static void* r300_transfer_map(struct pipe_screen* screen,
{
struct r300_texture* tex = (struct r300_texture*)transfer->texture;
char* map;
- unsigned flags = 0;
-
- if (transfer->usage != PIPE_TRANSFER_WRITE) {
- flags |= PIPE_BUFFER_USAGE_CPU_READ;
- }
- if (transfer->usage != PIPE_TRANSFER_READ) {
- flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
- }
- map = pipe_buffer_map(screen, tex->buffer, flags);
+ map = pipe_buffer_map(screen, tex->buffer,
+ pipe_transfer_buffer_flags(transfer));
if (!map) {
return NULL;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 5f6b225d34..02b7ab9107 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -53,7 +53,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,
if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte)
{
for (i = 0; i < info->num_inputs; i++) {
- switch (info->input_semantic_name[i]) {
+ switch (r300->vs->code.inputs[i]) {
case TGSI_SEMANTIC_POSITION:
pos = TRUE;
tab[i] = 0;
@@ -63,10 +63,12 @@ static void r300_vs_tab_routes(struct r300_context* r300,
cols++;
break;
case TGSI_SEMANTIC_PSIZE:
+ assert(psize == FALSE);
psize = TRUE;
tab[i] = 15;
break;
case TGSI_SEMANTIC_FOG:
+ assert(fog == FALSE);
fog = TRUE;
/* Fall through */
case TGSI_SEMANTIC_GENERIC:
@@ -125,7 +127,9 @@ static void r300_vs_tab_routes(struct r300_context* r300,
vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
- if (!pos) {
+ /* We need to add vertex position attribute only for SW TCL case,
+ * for HW TCL case it could be generated by vertex shader */
+ if (!pos && !r300screen->caps->has_tcl) {
debug_printf("r300: Forcing vertex position attribute emit...\n");
/* Make room for the position attribute
* at the beginning of the tab. */
@@ -164,7 +168,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,
vinfo->hwfmt[3] |= (4 << (3 * i));
}
- for (i; i < texs; i++) {
+ for (; i < texs; i++) {
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
@@ -334,48 +338,37 @@ static void r300_update_rs_block(struct r300_context* r300)
struct r300_rs_block* rs = r300->rs_block;
struct tgsi_shader_info* info = &r300->fs->info;
int* tab = r300->vertex_info.fs_tab;
- int col_count = 0, fp_offset = 0, i, memory_pos, tex_count = 0;
-
+ int col_count = 0, fp_offset = 0, i, tex_count = 0;
+ int rs_tex_comp = 0;
memset(rs, 0, sizeof(struct r300_rs_block));
if (r300_screen(r300->context.screen)->caps->is_r500) {
for (i = 0; i < info->num_inputs; i++) {
assert(tab[i] != -1);
- memory_pos = tab[i] * 4;
switch (info->input_semantic_name[i]) {
case TGSI_SEMANTIC_COLOR:
rs->ip[col_count] |=
- R500_RS_COL_PTR(memory_pos) |
+ R500_RS_COL_PTR(col_count) |
R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
col_count++;
break;
case TGSI_SEMANTIC_GENERIC:
rs->ip[tex_count] |=
- R500_RS_SEL_S(memory_pos) |
- R500_RS_SEL_T(memory_pos + 1) |
- R500_RS_SEL_R(memory_pos + 2) |
- R500_RS_SEL_Q(memory_pos + 3);
+ R500_RS_SEL_S(rs_tex_comp) |
+ R500_RS_SEL_T(rs_tex_comp + 1) |
+ R500_RS_SEL_R(rs_tex_comp + 2) |
+ R500_RS_SEL_Q(rs_tex_comp + 3);
tex_count++;
+ rs_tex_comp += 4;
break;
default:
break;
}
}
- if (col_count == 0) {
- rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
- }
-
- if (tex_count == 0) {
- rs->ip[0] |=
- R500_RS_SEL_S(R500_RS_IP_PTR_K0) |
- R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
- R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
- R500_RS_SEL_Q(R500_RS_IP_PTR_K1);
- }
-
/* Rasterize at least one color, or bad things happen. */
if ((col_count == 0) && (tex_count == 0)) {
+ rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
col_count++;
}
@@ -393,22 +386,22 @@ static void r300_update_rs_block(struct r300_context* r300)
} else {
for (i = 0; i < info->num_inputs; i++) {
assert(tab[i] != -1);
- memory_pos = tab[i] * 4;
switch (info->input_semantic_name[i]) {
case TGSI_SEMANTIC_COLOR:
rs->ip[col_count] |=
- R300_RS_COL_PTR(memory_pos) |
+ R300_RS_COL_PTR(col_count) |
R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
col_count++;
break;
case TGSI_SEMANTIC_GENERIC:
rs->ip[tex_count] |=
- R300_RS_TEX_PTR(memory_pos) |
+ R300_RS_TEX_PTR(rs_tex_comp) |
R300_RS_SEL_S(R300_RS_SEL_C0) |
R300_RS_SEL_T(R300_RS_SEL_C1) |
R300_RS_SEL_R(R300_RS_SEL_C2) |
R300_RS_SEL_Q(R300_RS_SEL_C3);
tex_count++;
+ rs_tex_comp+=4;
break;
default:
break;
@@ -445,7 +438,7 @@ static void r300_update_rs_block(struct r300_context* r300)
}
}
- rs->count = (tex_count * 4) | (col_count << R300_IC_COUNT_SHIFT) |
+ rs->count = (rs_tex_comp) | (col_count << R300_IC_COUNT_SHIFT) |
R300_HIRES_EN;
rs->inst_count = MAX2(MAX2(col_count - 1, tex_count - 1), 0);
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 6e8c368320..ce60ded7ca 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -22,34 +22,39 @@
#include "r300_texture.h"
-static void r300_setup_texture_state(struct r300_texture* tex,
- unsigned width,
- unsigned height,
- unsigned levels)
+static void r300_setup_texture_state(struct r300_texture* tex)
{
struct r300_texture_state* state = &tex->state;
+ struct pipe_texture *pt = &tex->tex;
- state->format0 = R300_TX_WIDTH((width - 1) & 0x7ff) |
- R300_TX_HEIGHT((height - 1) & 0x7ff) |
- R300_TX_NUM_LEVELS(levels) |
+ state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) |
+ R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff) |
+ R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf) |
+ R300_TX_NUM_LEVELS(pt->last_level) |
R300_TX_PITCH_EN;
/* XXX */
- state->format1 = r300_translate_texformat(tex->tex.format);
+ state->format1 = r300_translate_texformat(pt->format);
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ state->format1 |= R300_TX_FORMAT_CUBIC_MAP;
+ }
+ if (pt->target == PIPE_TEXTURE_3D) {
+ state->format1 |= R300_TX_FORMAT_3D;
+ }
- state->format2 = r300_texture_get_stride(tex, 0);
+ state->format2 = (r300_texture_get_stride(tex, 0) / pt->block.size) - 1;
/* Assume (somewhat foolishly) that oversized textures will
* not be permitted by the state tracker. */
- if (width > 2048) {
+ if (pt->width[0] > 2048) {
state->format2 |= R500_TXWIDTH_BIT11;
}
- if (height > 2048) {
+ if (pt->height[0] > 2048) {
state->format2 |= R500_TXHEIGHT_BIT11;
}
- debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n",
- width, height, levels);
+ debug_printf("r300: Set texture state (%dx%d, %d levels)\n",
+ pt->width[0], pt->height[0], pt->last_level);
}
/**
@@ -62,7 +67,7 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level)
return tex->stride_override;
if (level > tex->tex.last_level) {
- debug_printf("%s: level (%u) > last_level (%u)\n", level, tex->tex.last_level);
+ debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, level, tex->tex.last_level);
return 0;
}
@@ -120,8 +125,7 @@ static struct pipe_texture*
r300_setup_miptree(tex);
- r300_setup_texture_state(tex, template->width[0], template->height[0],
- template->last_level);
+ r300_setup_texture_state(tex);
tex->buffer = screen->buffer_create(screen, 1024,
PIPE_BUFFER_USAGE_PIXEL,
@@ -204,7 +208,7 @@ static struct pipe_texture*
tex->stride_override = *stride;
/* XXX */
- r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], 0);
+ r300_setup_texture_state(tex);
pipe_buffer_reference(&tex->buffer, buffer);
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 3109af5bac..78ee0f1611 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -72,6 +72,11 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
/* W24_FP */
case PIPE_FORMAT_Z24S8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
+ /* Z5_Y6_X5 */
+ case PIPE_FORMAT_R16_SNORM:
+ return R300_EASY_TX_FORMAT(X, X, X, X, Z5Y6X5);
+ case PIPE_FORMAT_Z16_UNORM:
+ return R300_EASY_TX_FORMAT(X, X, X, X, X16);
default:
debug_printf("r300: Implementation error: "
"Got unsupported texture format %s in %s\n",