diff options
author | Roland Scheidegger <[email protected]> | 2013-05-17 23:13:51 +0200 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2013-05-18 00:31:49 +0200 |
commit | d7e811c0b0f51df85a624a5784518e274a1db173 (patch) | |
tree | 532c8950c62d22d970078ca2db5faab838a3e743 /src/gallium/auxiliary/gallivm/lp_bld_format_soa.c | |
parent | 0346e9b3bb24cf79c182a86fd8445251dfaa64ca (diff) |
gallivm: handle z32s8x24 format for sampling
Since we can only sample either depth or stencil but not both only load
the required bits which makes things a bit easier (it requires special
handling since the format doesn't fit into 32bit).
The logic for deciding if depth or stencil should be sampled is a bit odd,
but seems to be what other drivers and statetrackers do: if it's a format with
both depth and stencil (or just with depth) then sample depth, for sampling
stencil a sampler view format with only stencil is required.
Also while here fix up stencil sampling for other formats as well, though
this isn't supported by mesa (ARB_stencil_texturing), and while blits would
use it they don't work neither since they'd also need stencil export.
Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/gallivm/lp_bld_format_soa.c')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_format_soa.c | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index 54ca61a0c38..edc24424289 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -51,16 +51,25 @@ lp_build_format_swizzle_soa(const struct util_format_description *format_desc, assert(UTIL_FORMAT_SWIZZLE_1 == PIPE_SWIZZLE_ONE); if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + enum util_format_swizzle swizzle; + LLVMValueRef depth_or_stencil; + + if (util_format_has_stencil(format_desc) && + !util_format_has_depth(format_desc)) { + assert(!bld->type.floating); + swizzle = format_desc->swizzle[1]; + } + else { + assert(bld->type.floating); + swizzle = format_desc->swizzle[0]; + } /* - * Return zzz1 for depth-stencil formats. - * - * XXX: Allow to control the depth swizzle with an additional parameter, - * as the caller may wish another depth swizzle, or retain the stencil - * value. + * Return zzz1 or sss1 for depth-stencil formats here. + * Correct swizzling will be handled by apply_sampler_swizzle() later. */ - enum util_format_swizzle swizzle = format_desc->swizzle[0]; - LLVMValueRef depth = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle); - swizzled_out[2] = swizzled_out[1] = swizzled_out[0] = depth; + depth_or_stencil = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle); + + swizzled_out[2] = swizzled_out[1] = swizzled_out[0] = depth_or_stencil; swizzled_out[3] = bld->one; } else { @@ -392,6 +401,40 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm, return; } + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && + format_desc->block.bits == 64) { + /* + * special case the format is 64 bits but we only require + * 32bit (or 8bit) from each block. + */ + LLVMValueRef packed; + + if (format_desc->format == PIPE_FORMAT_X32_S8X24_UINT) { + /* + * for stencil simply fix up offsets - could in fact change + * base_ptr instead even outside the shader. + */ + unsigned mask = (1 << 8) - 1; + LLVMValueRef s_offset = lp_build_const_int_vec(gallivm, type, 4); + offset = LLVMBuildAdd(builder, offset, s_offset, ""); + packed = lp_build_gather(gallivm, type.length, + 32, type.width, base_ptr, offset); + packed = LLVMBuildAnd(builder, packed, + lp_build_const_int_vec(gallivm, type, mask), ""); + } + else { + assert (format_desc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT); + packed = lp_build_gather(gallivm, type.length, + 32, type.width, base_ptr, offset); + packed = LLVMBuildBitCast(builder, packed, + lp_build_vec_type(gallivm, type), ""); + } + /* for consistency with lp_build_unpack_rgba_soa() return sss1 or zzz1 */ + rgba_out[0] = rgba_out[1] = rgba_out[2] = packed; + rgba_out[3] = lp_build_const_vec(gallivm, type, 1.0f); + return; + } + /* * Try calling lp_build_fetch_rgba_aos for all pixels. */ |