summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-05-08 18:51:03 +0200
committerMarek Olšák <[email protected]>2010-05-08 23:03:45 +0200
commit71584d0cc75dda3c579a2a0cb6c1ac9591f7d5c9 (patch)
treeee6ae2d414a69c87dfbded303b002bf7adad5ae6
parent78e881368b392d8a6945990c20493560fcd73231 (diff)
r300g: pass depth texture swizzle to the compiler if compare mode is enabled
-rw-r--r--src/gallium/drivers/r300/r300_context.h18
-rw-r--r--src/gallium/drivers/r300/r300_fs.c14
-rw-r--r--src/gallium/drivers/r300/r300_state.c11
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c21
-rw-r--r--src/gallium/drivers/r300/r300_texture.c112
-rw-r--r--src/gallium/drivers/r300/r300_texture.h3
6 files changed, 111 insertions, 68 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 2e91a5b2659..b3c54595941 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -151,6 +151,10 @@ struct r300_texture_format_state {
struct r300_sampler_view {
struct pipe_sampler_view base;
+ /* Swizzles in the UTIL_FORMAT_SWIZZLE_* representation,
+ * derived from base. */
+ unsigned char swizzle[4];
+
/* Copy of r300_texture::texture_format_state with format-specific bits
* added. */
struct r300_texture_format_state format;
@@ -166,6 +170,13 @@ struct r300_texture_fb_state {
uint32_t zb_format; /* R300_ZB_FORMAT */
};
+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 */
+};
+
struct r300_textures_state {
/* Textures. */
struct r300_sampler_view *sampler_views[16];
@@ -177,12 +188,7 @@ struct r300_textures_state {
/* This is the merge of the texture and sampler states. */
unsigned count;
uint32_t tx_enable; /* R300_TX_ENABLE: 0x4101 */
- 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 */
- } regs[16];
+ struct r300_texture_sampler_state regs[16];
};
struct r300_vertex_stream_state {
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 19023457bf3..30aa0651399 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -137,6 +137,7 @@ static void get_external_state(
{
struct r300_textures_state *texstate = r300->textures_state.state;
unsigned i;
+ unsigned char *swizzle;
for (i = 0; i < texstate->sampler_state_count; i++) {
struct r300_sampler_state* s = texstate->sampler_states[i];
@@ -148,9 +149,16 @@ static void get_external_state(
if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
state->unit[i].compare_mode_enabled = 1;
- /* XXX Gallium doesn't provide us with any information regarding
- * this mode, so we are screwed. Let's set INTENSITY for now. */
- state->unit[i].depth_texture_swizzle = RC_SWIZZLE_XYZW;
+ /* Pass depth texture swizzling to the compiler. */
+ if (texstate->sampler_views[i]) {
+ swizzle = texstate->sampler_views[i]->swizzle;
+
+ state->unit[i].depth_texture_swizzle =
+ RC_MAKE_SWIZZLE(swizzle[0], swizzle[1],
+ swizzle[2], swizzle[3]);
+ } else {
+ state->unit[i].depth_texture_swizzle = RC_SWIZZLE_XYZW;
+ }
/* Fortunately, no need to translate this. */
state->unit[i].texture_compare_func = s->state.compare_func;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 446422ca0f0..fe3eae9805f 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1021,7 +1021,6 @@ r300_create_sampler_view(struct pipe_context *pipe,
{
struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
struct r300_texture *tex = r300_texture(texture);
- unsigned char swizzle[4];
if (view) {
view->base = *templ;
@@ -1030,14 +1029,14 @@ r300_create_sampler_view(struct pipe_context *pipe,
view->base.texture = NULL;
pipe_resource_reference(&view->base.texture, texture);
- swizzle[0] = templ->swizzle_r;
- swizzle[1] = templ->swizzle_g;
- swizzle[2] = templ->swizzle_b;
- swizzle[3] = templ->swizzle_a;
+ view->swizzle[0] = templ->swizzle_r;
+ view->swizzle[1] = templ->swizzle_g;
+ view->swizzle[2] = templ->swizzle_b;
+ view->swizzle[3] = templ->swizzle_a;
view->format = tex->tx_format;
view->format.format1 |= r300_translate_texformat(templ->format,
- swizzle);
+ view->swizzle);
if (r300_screen(pipe->screen)->caps.is_r500) {
view->format.format2 |= r500_tx_format_msb_bit(templ->format);
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index e3adace0faa..193a60c034f 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -34,6 +34,7 @@
#include "r300_state.h"
#include "r300_state_derived.h"
#include "r300_state_inlines.h"
+#include "r300_texture.h"
#include "r300_vs.h"
/* r300_state_derived: Various bits of state which are dependent upon
@@ -493,6 +494,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
unsigned min_level, max_level, i, size;
unsigned count = MIN2(state->sampler_view_count,
state->sampler_state_count);
+ unsigned char depth_swizzle[4] = {
+ UTIL_FORMAT_SWIZZLE_X,
+ UTIL_FORMAT_SWIZZLE_X,
+ UTIL_FORMAT_SWIZZLE_X,
+ UTIL_FORMAT_SWIZZLE_X
+ };
state->tx_enable = 0;
state->count = 0;
@@ -512,6 +519,20 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
texstate->filter1 = sampler->filter1;
texstate->border_color = sampler->border_color;
+ /* If compare mode is disabled, the sampler view swizzles
+ * are stored in the format.
+ * Otherwise, swizzles must be applied after the compare mode
+ * in the fragment shader. */
+ if (util_format_is_depth_or_stencil(tex->b.b.format)) {
+ if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {
+ texstate->format.format1 |=
+ r300_get_swizzle_combined(depth_swizzle, view->swizzle);
+ } else {
+ texstate->format.format1 |=
+ r300_get_swizzle_combined(depth_swizzle, 0);
+ }
+ }
+
/* to emulate 1D textures through 2D ones correctly */
if (tex->b.b.target == PIPE_TEXTURE_1D) {
texstate->filter0 &= ~R300_TX_WRAP_T_MASK;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index a2fefde3529..c0911aef385 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -47,6 +47,60 @@ static const unsigned microblock_table[5][3][2] = {
{{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
};
+unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
+ const unsigned char *swizzle_view)
+{
+ unsigned i;
+ unsigned char swizzle[4];
+ unsigned result = 0;
+ const uint32_t swizzle_shift[4] = {
+ R300_TX_FORMAT_R_SHIFT,
+ R300_TX_FORMAT_G_SHIFT,
+ R300_TX_FORMAT_B_SHIFT,
+ R300_TX_FORMAT_A_SHIFT
+ };
+ const uint32_t swizzle_bit[4] = {
+ R300_TX_FORMAT_X,
+ R300_TX_FORMAT_Y,
+ R300_TX_FORMAT_Z,
+ R300_TX_FORMAT_W
+ };
+
+ if (swizzle_view) {
+ /* Combine two sets of swizzles. */
+ for (i = 0; i < 4; i++) {
+ swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
+ swizzle_format[swizzle_view[i]] : swizzle_view[i];
+ }
+ } else {
+ memcpy(swizzle, swizzle_format, 4);
+ }
+
+ /* Get swizzle. */
+ for (i = 0; i < 4; i++) {
+ switch (swizzle[i]) {
+ case UTIL_FORMAT_SWIZZLE_Y:
+ result |= swizzle_bit[1] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_Z:
+ result |= swizzle_bit[2] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_W:
+ result |= swizzle_bit[3] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_0:
+ result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_1:
+ result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
+ break;
+ default: /* UTIL_FORMAT_SWIZZLE_X */
+ result |= swizzle_bit[0] << swizzle_shift[i];
+ }
+ }
+ return result;
+}
+
/* Translate a pipe_format into a useful texture format for sampling.
*
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
@@ -66,38 +120,26 @@ uint32_t r300_translate_texformat(enum pipe_format format,
const struct util_format_description *desc;
unsigned i;
boolean uniform = TRUE;
- const uint32_t swizzle_shift[4] = {
- R300_TX_FORMAT_R_SHIFT,
- R300_TX_FORMAT_G_SHIFT,
- R300_TX_FORMAT_B_SHIFT,
- R300_TX_FORMAT_A_SHIFT
- };
- const uint32_t swizzle_bit[4] = {
- R300_TX_FORMAT_X,
- R300_TX_FORMAT_Y,
- R300_TX_FORMAT_Z,
- R300_TX_FORMAT_W
- };
const uint32_t sign_bit[4] = {
R300_TX_FORMAT_SIGNED_X,
R300_TX_FORMAT_SIGNED_Y,
R300_TX_FORMAT_SIGNED_Z,
R300_TX_FORMAT_SIGNED_W,
};
- unsigned char swizzle[4];
desc = util_format_description(format);
/* Colorspace (return non-RGB formats directly). */
switch (desc->colorspace) {
- /* Depth stencil formats. */
+ /* Depth stencil formats.
+ * Swizzles are added in r300_merge_textures_and_samplers. */
case UTIL_FORMAT_COLORSPACE_ZS:
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
- return R300_EASY_TX_FORMAT(X, X, X, X, X16);
+ return R300_TX_FORMAT_X16;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
- return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
+ return R300_TX_FORMAT_W24_FP;
default:
return ~0; /* Unsupported. */
}
@@ -131,43 +173,7 @@ uint32_t r300_translate_texformat(enum pipe_format format,
}
}
- /* Get swizzle. */
- if (swizzle_view) {
- /* Compose two sets of swizzles. */
- for (i = 0; i < 4; i++) {
- swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
- desc->swizzle[swizzle_view[i]] : swizzle_view[i];
- }
- } else {
- memcpy(swizzle, desc->swizzle, sizeof(swizzle));
- }
-
- /* Add swizzle. */
- for (i = 0; i < 4; i++) {
- switch (swizzle[i]) {
- case UTIL_FORMAT_SWIZZLE_X:
- case UTIL_FORMAT_SWIZZLE_NONE:
- result |= swizzle_bit[0] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_Y:
- result |= swizzle_bit[1] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_Z:
- result |= swizzle_bit[2] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_W:
- result |= swizzle_bit[3] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_0:
- result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_1:
- result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
- break;
- default:
- return ~0; /* Unsupported. */
- }
- }
+ result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view);
/* S3TC formats. */
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index ba79ec068a1..2d8f0e14393 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -27,6 +27,9 @@
struct r300_texture;
+unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
+ const unsigned char *swizzle_view);
+
uint32_t r300_translate_texformat(enum pipe_format format,
const unsigned char *swizzle_view);