[D3D12] 32bpp tiling shader

This commit is contained in:
Triang3l
2018-08-25 01:16:35 +03:00
parent 4a747b3b81
commit 2c6224ad37
9 changed files with 492 additions and 150 deletions

View File

@@ -32,18 +32,26 @@ XE_BYTE_SWAP_16_OVERLOAD(uint3)
XE_BYTE_SWAP_16_OVERLOAD(uint4)
uint2 XeByteSwap64(uint2 v, uint endian) {
if (endian & 4u) {
if ((endian & 4u) != 0u) {
v = v.yx;
endian = 2u;
}
return XeByteSwap(v, endian);
}
uint4 XeByteSwap64(uint4 v, uint endian) {
if (endian & 4u) {
if ((endian & 4u) != 0u) {
v = v.yxwz;
endian = 2u;
}
return XeByteSwap(v, endian);
}
uint4 XeByteSwap128(uint4 v, uint endian) {
if ((endian & 4u) != 0u) {
v = ((endian & 1u) != 0u) ? v.wzyx /* 8in128 */ : v.yxwz /* 8in64 */;
endian = 2u;
}
return XeByteSwap(v, endian);
}
#endif // XENIA_GPU_D3D12_SHADERS_BYTE_SWAP_HLSLI_

View File

@@ -1,4 +1,4 @@
cbuffer XeResolveCbuffer : register(b0) {
cbuffer XeResolveConstants : register(b0) {
// In samples.
// Left and top in the lower 16 bits, width and height in the upper.
uint2 xe_resolve_rect_samples;

View File

@@ -4,7 +4,7 @@
#include "byte_swap.hlsli"
#include "texture_address.hlsli"
cbuffer xe_texture_copy_constants : register(b0) {
cbuffer XeTextureCopyConstants : register(b0) {
uint xe_texture_copy_guest_base;
// For linear textures - row byte pitch.
uint xe_texture_copy_guest_pitch;

View File

@@ -0,0 +1,26 @@
#ifndef XENIA_GPU_D3D12_SHADERS_TEXTURE_TILE_HLSLI_
#define XENIA_GPU_D3D12_SHADERS_TEXTURE_TILE_HLSLI_
#include "byte_swap.hlsli"
#include "texture_address.hlsli"
cbuffer XeTextureTileConstants : register(b0) {
// Either from the start of the shared memory or from the start of the typed
// UAV, in bytes.
uint xe_texture_tile_guest_base;
// 0:2 - endianness (up to Xin128).
// 3:31 - actual guest texture width.
uint xe_texture_tile_endian_guest_pitch;
// Size to copy, texels with index bigger than this won't be written.
// Width in the lower 16 bits, height in the upper.
uint xe_texture_tile_size;
// Byte offset to the first texel from the beginning of the source buffer.
uint xe_texture_tile_host_base;
// Row pitch of the source buffer.
uint xe_texture_tile_host_pitch;
}
ByteAddressBuffer xe_texture_tile_source : register(t0);
// The target is u0, may be a raw UAV or a typed UAV depending on the format.
#endif // XENIA_GPU_D3D12_SHADERS_TEXTURE_TILE_HLSLI_

View File

@@ -0,0 +1,31 @@
#include "texture_tile.hlsli"
RWByteAddressBuffer xe_texture_tile_dest : register(u0);
[numthreads(8, 32, 1)]
void main(uint3 xe_thread_id : SV_DispatchThreadID) {
// 1 thread = 4 texels.
uint2 texture_size = (xe_texture_tile_size >> uint2(0u, 16u)) & 0xFFFFu;
uint2 texel_index = xe_thread_id.xy;
texel_index.x <<= 2u;
[branch] if (any(texel_index >= texture_size)) {
return;
}
uint4 texels = xe_texture_tile_source.Load4(
xe_texture_tile_host_base + texel_index.y * xe_texture_tile_host_pitch +
texel_index.x * 4u);
texels = XeByteSwap(texels, xe_texture_tile_endian_guest_pitch & 7u);
uint4 texel_addresses = xe_texture_tile_guest_base + XeTextureTiledOffset2D(
texel_index, xe_texture_tile_endian_guest_pitch >> 3u, 2u);
xe_texture_tile_dest.Store(texel_addresses.x, texels.x);
bool3 texels_inside = uint3(1u, 2u, 3u) + texel_index.x < texture_size.x;
[branch] if (texels_inside.x) {
xe_texture_tile_dest.Store(texel_addresses.y, texels.y);
[branch] if (texels_inside.y) {
xe_texture_tile_dest.Store(texel_addresses.z, texels.z);
[branch] if (texels_inside.z) {
xe_texture_tile_dest.Store(texel_addresses.w, texels.w);
}
}
}
}