r300g: implement D24X8 texture sampling for r3xx-r4xx
Because the hw can't sample it, I reinterpret the format as G16R16 and sample the G component. This gives 16 bits of precision, which should be enough for depth texturing (surprisingly, the sampled values are exactly the same as in D16 textures). This also enables EXT_packed_depth_stencil on those old chipsets, finally.
This commit is contained in:
parent
451a0ddb19
commit
6f2936c654
|
@ -257,8 +257,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
|||
uint32_t retval = 0;
|
||||
boolean is_r500 = r300_screen(screen)->caps.is_r500;
|
||||
boolean is_r400 = r300_screen(screen)->caps.is_r400;
|
||||
boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM ||
|
||||
format == PIPE_FORMAT_S8_USCALED_Z24_UNORM;
|
||||
boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
|
||||
format == PIPE_FORMAT_R10G10B10X2_SNORM ||
|
||||
format == PIPE_FORMAT_B10G10R10A2_UNORM ||
|
||||
|
@ -293,8 +291,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
|||
|
||||
/* Check sampler format support. */
|
||||
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
|
||||
/* Z24 cannot be sampled from on non-r5xx. */
|
||||
(is_r500 || !is_z24) &&
|
||||
/* ATI1N is r5xx-only. */
|
||||
(is_r500 || !is_ati1n) &&
|
||||
/* ATI2N is supported on r4xx-r5xx. */
|
||||
|
|
|
@ -1330,6 +1330,7 @@ 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);
|
||||
boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
|
||||
|
||||
if (view) {
|
||||
view->base = *templ;
|
||||
|
@ -1345,8 +1346,9 @@ r300_create_sampler_view(struct pipe_context *pipe,
|
|||
|
||||
view->format = tex->tx_format;
|
||||
view->format.format1 |= r300_translate_texformat(templ->format,
|
||||
view->swizzle);
|
||||
if (r300_screen(pipe->screen)->caps.is_r500) {
|
||||
view->swizzle,
|
||||
is_r500);
|
||||
if (is_r500) {
|
||||
view->format.format2 |= r500_tx_format_msb_bit(templ->format);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,15 +528,9 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
|
|||
struct r300_sampler_state *sampler;
|
||||
struct r300_sampler_view *view;
|
||||
struct r300_texture *tex;
|
||||
unsigned min_level, max_level, i, size;
|
||||
unsigned min_level, max_level, i, j, 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
|
||||
};
|
||||
|
||||
/* The KIL opcode fix, see below. */
|
||||
if (!count && !r300->screen->caps.is_r500)
|
||||
|
@ -563,14 +557,29 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
|
|||
/* Assign a texture cache region. */
|
||||
texstate->format.format1 |= view->texcache_region;
|
||||
|
||||
/* 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. */
|
||||
/* Depth textures are kinda special. */
|
||||
if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
|
||||
unsigned char depth_swizzle[4];
|
||||
|
||||
if (!r300->screen->caps.is_r500 &&
|
||||
util_format_get_blocksizebits(tex->desc.b.b.format) == 32) {
|
||||
/* X24x8 is sampled as Y16X16 on r3xx-r4xx.
|
||||
* The depth here is at the Y component. */
|
||||
for (j = 0; j < 4; j++)
|
||||
depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_Y;
|
||||
} else {
|
||||
for (j = 0; j < 4; j++)
|
||||
depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_X;
|
||||
}
|
||||
|
||||
/* If compare mode is disabled, sampler view swizzles
|
||||
* are stored in the format.
|
||||
* Otherwise, the swizzles must be applied after the compare
|
||||
* mode in the fragment shader. */
|
||||
if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {
|
||||
texstate->format.format1 |=
|
||||
r300_get_swizzle_combined(depth_swizzle, view->swizzle);
|
||||
r300_get_swizzle_combined(depth_swizzle,
|
||||
view->swizzle);
|
||||
} else {
|
||||
texstate->format.format1 |=
|
||||
r300_get_swizzle_combined(depth_swizzle, 0);
|
||||
|
|
|
@ -105,7 +105,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
|
|||
* The FORMAT specifies how the texture sampler will treat the texture, and
|
||||
* makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
|
||||
uint32_t r300_translate_texformat(enum pipe_format format,
|
||||
const unsigned char *swizzle_view)
|
||||
const unsigned char *swizzle_view,
|
||||
boolean is_r500)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
const struct util_format_description *desc;
|
||||
|
@ -130,7 +131,10 @@ uint32_t r300_translate_texformat(enum pipe_format format,
|
|||
return R300_TX_FORMAT_X16;
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
return R500_TX_FORMAT_Y8X24;
|
||||
if (is_r500)
|
||||
return R500_TX_FORMAT_Y8X24;
|
||||
else
|
||||
return R300_TX_FORMAT_Y16X16;
|
||||
default:
|
||||
return ~0; /* Unsupported. */
|
||||
}
|
||||
|
@ -533,7 +537,7 @@ boolean r300_is_zs_format_supported(enum pipe_format format)
|
|||
|
||||
boolean r300_is_sampler_format_supported(enum pipe_format format)
|
||||
{
|
||||
return r300_translate_texformat(format, 0) != ~0;
|
||||
return r300_translate_texformat(format, 0, TRUE) != ~0;
|
||||
}
|
||||
|
||||
static void r300_texture_setup_immutable_state(struct r300_screen* screen,
|
||||
|
|
|
@ -35,7 +35,8 @@ 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);
|
||||
const unsigned char *swizzle_view,
|
||||
boolean is_r500);
|
||||
|
||||
uint32_t r500_tx_format_msb_bit(enum pipe_format format);
|
||||
|
||||
|
|
Loading…
Reference in New Issue