[D3D12] Raw 32bpp resolve

This commit is contained in:
Triang3l
2018-08-23 13:25:36 +03:00
parent bc4125584c
commit ea1abdaa6e
8 changed files with 146 additions and 28 deletions

View File

@@ -1,12 +1,15 @@
#ifndef XENIA_GPU_D3D12_SHADERS_BYTE_SWAP_HLSLI_
#define XENIA_GPU_D3D12_SHADERS_BYTE_SWAP_HLSLI_
// These functions may accept endianness without it being masked with & 3 -
// don't use ==, <=, >= here!
#define XE_BYTE_SWAP_OVERLOAD(XeByteSwapType) \
XeByteSwapType XeByteSwap(XeByteSwapType v, uint endian) { \
[flatten] if (((endian ^ (endian >> 1u)) & 1u) != 0u) { \
if (((endian ^ (endian >> 1u)) & 1u) != 0u) { \
v = ((v & 0x00FF00FFu) << 8u) | ((v & 0xFF00FF00u) >> 8u); \
} \
[flatten] if ((endian & 2u) != 0u) { \
if ((endian & 2u) != 0u) { \
v = (v << 16u) | (v >> 16u); \
} \
return v; \
@@ -18,7 +21,7 @@ XE_BYTE_SWAP_OVERLOAD(uint4)
#define XE_BYTE_SWAP_16_OVERLOAD(XeByteSwapType) \
XeByteSwapType XeByteSwap16(XeByteSwapType v, uint endian) { \
[flatten] if (((endian ^ (endian >> 1u)) & 1u) != 0u) { \
if (((endian ^ (endian >> 1u)) & 1u) != 0u) { \
v = (v << 8u) | (v >> 8u); \
} \
return v; \
@@ -28,4 +31,19 @@ XE_BYTE_SWAP_16_OVERLOAD(uint2)
XE_BYTE_SWAP_16_OVERLOAD(uint3)
XE_BYTE_SWAP_16_OVERLOAD(uint4)
uint2 XeByteSwap64(uint2 v, uint endian) {
if (endian & 4u) {
v = v.yx;
endian = 2u;
}
return XeByteSwap(v, endian);
}
uint4 XeByteSwap64(uint4 v, uint endian) {
if (endian & 4u) {
v = v.yxwz;
endian = 2u;
}
return XeByteSwap(v, endian);
}
#endif // XENIA_GPU_D3D12_SHADERS_BYTE_SWAP_HLSLI_

View File

@@ -23,11 +23,11 @@ cbuffer XeEDRAMLoadStoreConstants : register(b0) {
// 14 - log2(vertical sample count), 0 for 1x AA, 1 for 2x/4x AA.
// 15 - log2(horizontal sample count), 0 for 1x/2x AA, 1 for 4x AA.
// 16:17 - sample to load (16 - vertical index, 17 - horizontal index).
// 18:19 - destination endianness.
// 20:31 - BPP-specific info for swapping red/blue, 0 if not swapping.
// 18:20 - destination endianness.
// 21:31 - BPP-specific info for swapping red/blue, 0 if not swapping.
// For 32 bits per pixel:
// 20:24 - red/blue bit depth.
// 25:29 - blue offset.
// 21:25 - red/blue bit depth.
// 26:30 - blue offset.
// For 64 bits per pixel, it's 1 if need to swap 0:15 and 32:47.
#define xe_edram_tile_sample_dest_info (xe_edram_load_store_constants.w)

View File

@@ -1,3 +1,4 @@
#include "byte_swap.hlsli"
#include "edram_load_store.hlsli"
#include "texture_address.hlsli"
@@ -6,8 +7,9 @@ void main(uint3 xe_group_id : SV_GroupID,
uint3 xe_group_thread_id : SV_GroupThreadID,
uint3 xe_thread_id : SV_DispatchThreadID) {
// Check if not outside of the destination texture completely.
uint4 copy_rect =
(xe_edram_tile_sample_rect.xyxy >> uint4(0u, 0u, 16u, 16u)) & 0xFFFFu;
uint4 copy_rect;
copy_rect.xz = xe_edram_tile_sample_rect & 0xFFFFu;
copy_rect.yw = xe_edram_tile_sample_rect >> 16u;
uint2 texel_index = xe_thread_id.xy;
texel_index.x *= 4u;
[branch] if (any(texel_index < copy_rect.xy) ||
@@ -19,9 +21,12 @@ void main(uint3 xe_group_id : SV_GroupID,
// XY - log2(pixel size), ZW - selected sample offset.
uint4 sample_info =
(xe_edram_tile_sample_dest_info.xxxx >> uint4(15u, 14u, 17u, 16u)) & 1u;
uint2 edram_tile_quarter =
uint2(uint2(10u, 8u) <= xe_group_thread_id) * sample_info.xy;
uint edram_offset = XeEDRAMOffset(
xe_group_id.xy << sample_info.xy,
xe_thread_id.xy << (sample_info.xy + uint2(2u, 0u)) + sample_info.zw);
(xe_group_id.xy << sample_info.xy) + edram_tile_quarter,
(xe_group_thread_id.xy - edram_tile_quarter * uint2(10u, 8u)) <<
(sample_info.xy + uint2(2u, 0u)) + sample_info.zw);
// At 1x and 2x, this contains samples of 4 pixels. At 4x, this contains
// samples of 2, need to load 2 more.
uint4 pixels = xe_edram_load_store_source.Load4(edram_offset);
@@ -30,7 +35,7 @@ void main(uint3 xe_group_id : SV_GroupID,
pixels.zw = xe_edram_load_store_source.Load3(edram_offset + 16u).xz;
}
uint red_blue_swap = xe_edram_tile_sample_dest_info >> 20u;
uint red_blue_swap = xe_edram_tile_sample_dest_info >> 21u;
if (red_blue_swap != 0u) {
uint red_mask = (1u << (red_blue_swap & 31u)) - 1u;
// No need to be ready for a long shift Barney, it's just 16 or 20.
@@ -42,16 +47,18 @@ void main(uint3 xe_group_id : SV_GroupID,
}
// Tile the pixels to the shared memory.
pixels = XeByteSwap(pixels, xe_edram_tile_sample_dest_info >> 18u);
uint4 texel_addresses =
xe_edram_tile_sample_dest_base +
XeTextureTiledOffset2D(texel_index - copy_rect.xy,
xe_edram_tile_sample_dest_info & 16383u, 2u);
xe_edram_load_store_dest.Store(texel_addresses.x, pixels.x);
[branch] if (texel_index.x + 1u < copy_rect.z) {
bool3 texels_in_rect = uint3(1u, 2u, 3u) + texel_index.x < copy_rect.z;
[branch] if (texels_in_rect.x) {
xe_edram_load_store_dest.Store(texel_addresses.y, pixels.y);
[branch] if (texel_index.x + 2u < copy_rect.z) {
[branch] if (texels_in_rect.y) {
xe_edram_load_store_dest.Store(texel_addresses.z, pixels.z);
[branch] if (texel_index.x + 3u < copy_rect.z) {
[branch] if (texels_in_rect.z) {
xe_edram_load_store_dest.Store(texel_addresses.w, pixels.w);
}
}

View File

@@ -57,7 +57,7 @@ uint4 XeFloat32To20e4(uint4 f32u32) {
}
uint4 XeFloat20e4To32(uint4 f24u32) {
uint4 mantissa = f24u32 & 0xF00000u;
uint4 mantissa = f24u32 & 0xFFFFFu;
uint4 exponent = f24u32 >> 20u;
// Normalize the values for the denormalized components.
// Exponent = 1;