summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-04-08 03:11:22 +0200
committerMarek Olšák <[email protected]>2011-04-08 04:38:36 +0200
commit10ea8567f49f4daaa654b6e4c365a816f855073b (patch)
treee6ac3732ad74783a716bde291211bb79e6b4bedd
parent9d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9 (diff)
r300g: fix texturing with sizes > 2048 on r500
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c1
-rw-r--r--src/gallium/drivers/r300/r300_chipset.h2
-rw-r--r--src/gallium/drivers/r300/r300_context.h3
-rw-r--r--src/gallium/drivers/r300/r300_emit.c6
-rw-r--r--src/gallium/drivers/r300/r300_screen.c3
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c5
-rw-r--r--src/gallium/drivers/r300/r300_texture.c40
7 files changed, 52 insertions, 8 deletions
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 990acea9f44..1068d357c94 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -419,4 +419,5 @@ void r300_parse_chipset(struct r300_capabilities* caps)
caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
caps->z_compress = caps->is_rv350 ? R300_ZCOMP_8X8 : R300_ZCOMP_4X4;
caps->dxtc_swizzle = caps->is_r400 || caps->is_r500;
+ caps->has_us_format = caps->is_r500;
}
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index 68943d561ba..3777f0cfae3 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -90,6 +90,8 @@ struct r300_capabilities {
boolean high_second_pipe;
/* DXTC texture swizzling. */
boolean dxtc_swizzle;
+ /* Whether R500_US_FORMAT0_0 is supported (depends on DRM). */
+ boolean has_us_format;
};
/* Enumerations for legibility and telling which card we're running on. */
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 550d3a75d27..c1f766f6180 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -190,6 +190,7 @@ struct r300_texture_format_state {
uint32_t format1; /* R300_TX_FORMAT1: 0x44c0 */
uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */
uint32_t tile_config; /* R300_TX_OFFSET (subset thereof) */
+ uint32_t us_format0; /* R500_US_FORMAT0_0: 0x4640 (through 15) */
};
struct r300_sampler_view {
@@ -211,7 +212,7 @@ struct r300_texture_sampler_state {
struct r300_texture_format_state format;
uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */
uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */
- uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
+ uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
};
struct r300_textures_state {
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 6b91f93e6d6..a21668a6fc5 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -775,6 +775,7 @@ void r300_emit_textures_state(struct r300_context *r300,
struct r300_texture_sampler_state *texstate;
struct r300_resource *tex;
unsigned i;
+ boolean has_us_format = r300->screen->caps.has_us_format;
CS_LOCALS(r300);
BEGIN_CS(size);
@@ -796,6 +797,11 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG(R300_TX_OFFSET_0 + (i * 4), texstate->format.tile_config);
OUT_CS_RELOC(tex);
+
+ if (has_us_format) {
+ OUT_CS_REG(R500_US_FORMAT0_0 + (i * 4),
+ texstate->format.us_format0);
+ }
}
}
END_CS;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 07d854d633c..eb1b4523533 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -482,6 +482,9 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
r300screen->caps.hiz_ram = 0;
+ if (!rws->get_value(rws, R300_VID_DRM_2_8_0))
+ r300screen->caps.has_us_format = FALSE;
+
pipe_mutex_init(r300screen->num_contexts_mutex);
util_slab_create(&r300screen->pool_buffers,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index e943f1a715f..c80cf7860cb 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -771,6 +771,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
unsigned min_level, max_level, i, j, size;
unsigned count = MIN2(state->sampler_view_count,
state->sampler_state_count);
+ boolean has_us_format = r300->screen->caps.has_us_format;
/* The KIL opcode fix, see below. */
if (!count && !r300->screen->caps.is_r500)
@@ -923,7 +924,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
texstate->filter0 |= i << 28;
- size += 16;
+ size += 16 + (has_us_format ? 2 : 0);
state->count = i+1;
} else {
/* For the KIL opcode to work on r3xx-r4xx, the texture unit
@@ -952,7 +953,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
texstate->border_color = 0;
texstate->filter0 |= i << 28;
- size += 16;
+ size += 16 + (has_us_format ? 2 : 0);
state->count = i+1;
}
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index ea6d9824030..47d1c3ef75e 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -751,6 +751,16 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
struct pipe_resource *pt = &tex->b.b.b;
struct r300_texture_desc *desc = &tex->tex;
boolean is_r500 = screen->caps.is_r500;
+ unsigned width, height, depth;
+ unsigned txwidth, txheight, txdepth;
+
+ width = u_minify(desc->width0, level);
+ height = u_minify(desc->height0, level);
+ depth = u_minify(desc->depth0, level);
+
+ txwidth = (width - 1) & 0x7ff;
+ txheight = (height - 1) & 0x7ff;
+ txdepth = util_logbase2(depth) & 0xf;
/* Mask out all the fields we change. */
out->format0 = 0;
@@ -760,9 +770,9 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
/* Set sampler state. */
out->format0 =
- R300_TX_WIDTH((u_minify(desc->width0, level) - 1) & 0x7ff) |
- R300_TX_HEIGHT((u_minify(desc->height0, level) - 1) & 0x7ff) |
- R300_TX_DEPTH(util_logbase2(u_minify(desc->depth0, level)) & 0xf);
+ R300_TX_WIDTH(txwidth) |
+ R300_TX_HEIGHT(txheight) |
+ R300_TX_DEPTH(txdepth);
if (desc->uses_stride_addressing) {
/* rectangles love this */
@@ -780,12 +790,32 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
/* large textures on r500 */
if (is_r500)
{
- if (desc->width0 > 2048) {
+ unsigned us_width = txwidth;
+ unsigned us_height = txheight;
+ unsigned us_depth = txdepth;
+
+ if (width > 2048) {
out->format2 |= R500_TXWIDTH_BIT11;
}
- if (desc->height0 > 2048) {
+ if (height > 2048) {
out->format2 |= R500_TXHEIGHT_BIT11;
}
+
+ /* The US_FORMAT register fixes an R500 TX addressing bug.
+ * Don't ask why it must be set like this. I don't know it either. */
+ if (width > 2048) {
+ us_width = (0x000007FF + us_width) >> 1;
+ us_depth |= 0x0000000D;
+ }
+ if (height > 2048) {
+ us_height = (0x000007FF + us_height) >> 1;
+ us_depth |= 0x0000000E;
+ }
+
+ out->us_format0 =
+ R300_TX_WIDTH(us_width) |
+ R300_TX_HEIGHT(us_height) |
+ R300_TX_DEPTH(us_depth);
}
out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |