Merge branch 'master' of https://github.com/xenia-project/xenia into canary_experimental

This commit is contained in:
Gliniak
2022-07-23 13:26:31 +02:00
66 changed files with 44142 additions and 43718 deletions

View File

@@ -3287,13 +3287,19 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
// Apply the source 32bpp tile index.
// r1.w = destination to source EDRAM tile adjustment
a.OpIBFE(dxbc::Dest::R(1, 0b1000), dxbc::Src::LU(xenos::kEdramBaseTilesBits),
a.OpIBFE(dxbc::Dest::R(1, 0b1000),
dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1),
dxbc::Src::LU(xenos::kEdramPitchTilesBits * 2),
dxbc::Src::CB(cbuffer_index_address, kTransferCBVRegisterAddress, 0,
dxbc::Src::kXXXX));
// r1.w = 32bpp tile index within the source
// r1.w = 32bpp tile index within the source, or the tile index within the
// source minus the EDRAM tile count if transferring across addressing
// wrapping (if negative)
a.OpIAdd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::R(1, dxbc::Src::kWWWW));
// r1.w = 32bpp tile index within the source
a.OpAnd(dxbc::Dest::R(1, 0b1000), dxbc::Src::R(1, dxbc::Src::kWWWW),
dxbc::Src::LU(xenos::kEdramTileCount - 1));
// r2.x = source pitch in 32bpp tiles
a.OpUBFE(dxbc::Dest::R(2, 0b0001), dxbc::Src::LU(xenos::kEdramPitchTilesBits),
dxbc::Src::LU(xenos::kEdramPitchTilesBits),
@@ -3887,6 +3893,9 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
}
// Combine the tile sample index and the tile index into buffer
// address to r0.x.
// The tile index doesn't need to be wrapped, as the host depth is
// written to the beginning of the buffer, without the base
// offset.
a.OpUMAd(dxbc::Dest::R(0, 0b0001),
dxbc::Src::LU(tile_width_samples),
dxbc::Src::R(0, dxbc::Src::kYYYY),
@@ -3906,16 +3915,23 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
// source.
// r0.w = destination to host depth source EDRAM tile adjustment
a.OpIBFE(dxbc::Dest::R(0, 0b1000),
dxbc::Src::LU(xenos::kEdramBaseTilesBits),
dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1),
dxbc::Src::LU(xenos::kEdramPitchTilesBits * 2),
dxbc::Src::CB(cbuffer_index_host_depth_address,
kTransferCBVRegisterHostDepthAddress, 0,
dxbc::Src::kXXXX));
// r0.z = tile index relative to the host depth source base
// r0.z = tile index relative to the host depth source base, or
// the tile index within the host depth source minus the
// EDRAM tile count if transferring across addressing
// wrapping (if negative)
// r0.w = free
a.OpIAdd(dxbc::Dest::R(0, 0b0100),
dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::R(0, dxbc::Src::kWWWW));
// r0.z = tile index relative to the host depth source base
a.OpAnd(dxbc::Dest::R(0, 0b0100),
dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::LU(xenos::kEdramTileCount - 1));
// Convert position and sample index from within the destination
// tile to within the host depth source tile, like for the guest
// render target, but for 32bpp -> 32bpp only.
@@ -5943,28 +5959,38 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
dxbc::Src::R(1, dxbc::Src::kXXXX),
dxbc::Src::R(0, dxbc::Src::kZZZZ));
// Extract the index of the first tile of the dispatch in the EDRAM to r0.z.
// Extract the index of the first tile (taking EDRAM addressing wrapping into
// account) of the dispatch in the EDRAM to r0.z.
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = first EDRAM tile index in the dispatch
// r0.w = tile index relative to the dump rectangle base
a.OpUBFE(dxbc::Dest::R(0, 0b0100), dxbc::Src::LU(xenos::kEdramBaseTilesBits),
dxbc::Src::LU(0),
a.OpUBFE(dxbc::Dest::R(0, 0b0100),
dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1), dxbc::Src::LU(0),
dxbc::Src::CB(kDumpCbufferOffsets, kDumpCbufferOffsets, 0,
dxbc::Src::kXXXX));
// Add the base tile in the dispatch to the dispatch-local tile index to r0.w.
// Add the base tile in the dispatch to the dispatch-local tile index to r0.w,
// not wrapping yet so in case of a wraparound, the address relative to the
// base in the texture after subtraction of the base won't be negative.
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = free
// r0.w = tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
a.OpIAdd(dxbc::Dest::R(0, 0b1000), dxbc::Src::R(0, dxbc::Src::kWWWW),
dxbc::Src::R(0, dxbc::Src::kZZZZ));
// Wrap the address of the tile in the EDRAM to r0.z.
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = wrapped tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
a.OpAnd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kWWWW),
dxbc::Src::LU(xenos::kEdramTileCount - 1));
// Convert the tile index to samples and add the X sample index to it to r0.z.
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = tile sample offset in the EDRAM plus X sample offset
// r0.w = tile index in the EDRAM
a.OpUMAd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kWWWW),
// r0.w = non-wrapped tile index in the EDRAM
a.OpUMAd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::LU(
draw_resolution_scale_x * draw_resolution_scale_y *
(xenos::kEdramTileWidthSamples >> uint32_t(format_is_64bpp)) *
@@ -5975,7 +6001,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = sample offset in the EDRAM without the depth column swapping
// r0.w = tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
a.OpUMAd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kYYYY),
dxbc::Src::LU(tile_width), dxbc::Src::R(0, dxbc::Src::kZZZZ));
if (key.is_depth) {
@@ -5984,7 +6010,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = sample offset in the EDRAM without the depth column swapping
// r0.w = tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
// r1.x = 0xFFFFFFFF if in the right 40-sample half, 0 otherwise
a.OpUGE(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(0, dxbc::Src::kXXXX),
dxbc::Src::LU(tile_width_half));
@@ -5992,7 +6018,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = sample offset in the EDRAM without the depth column swapping
// r0.w = tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
// r1.x = depth half-tile flipping offset
a.OpMovC(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX),
dxbc::Src::LI(-int32_t(tile_width_half)),
@@ -6002,7 +6028,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = sample offset in the EDRAM
// r0.w = tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
// r1.x = free
a.OpIAdd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::R(1, dxbc::Src::kXXXX));
@@ -6012,10 +6038,10 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
// r0.x = X sample position within the tile
// r0.y = Y sample position within the tile
// r0.z = sample offset in the EDRAM
// r0.w = tile index in the EDRAM
// r0.w = non-wrapped tile index in the EDRAM
// r1.x = source texture base tile index
a.OpUBFE(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(xenos::kEdramBaseTilesBits),
dxbc::Src::LU(xenos::kEdramBaseTilesBits),
dxbc::Src::LU(xenos::kEdramBaseTilesBits + 1),
dxbc::Src::CB(kDumpCbufferOffsets, kDumpCbufferOffsets, 0,
dxbc::Src::kXXXX));
// Get the linear tile index within the source texture to r0.w.

View File

@@ -469,16 +469,13 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
// All in tiles.
uint32_t dest_pitch : xenos::kEdramPitchTilesBits;
uint32_t source_pitch : xenos::kEdramPitchTilesBits;
// Safe to use 12 bits for signed difference - no ownership transfer can
// ever occur between render targets with EDRAM base >= 2048 as this would
// result in 0-length spans. 10 + 10 + 12 is exactly 32, any more bits,
// and more root 32-bit constants will be used.
// Destination base in tiles minus source base in tiles (not vice versa
// because this is a transform of the coordinate system, not addresses
// themselves).
// + 1 bit because this is a signed difference between two EDRAM bases.
// 0 for host_depth_source_is_copy (ignored in this case anyway as
// destination == source anyway).
int32_t source_to_dest : xenos::kEdramBaseTilesBits;
int32_t source_to_dest : xenos::kEdramBaseTilesBits + 1;
};
TransferAddressConstant() : constant(0) {
static_assert_size(*this, sizeof(constant));
@@ -576,7 +573,9 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
union DumpOffsets {
uint32_t offsets;
struct {
uint32_t dispatch_first_tile : xenos::kEdramBaseTilesBits;
// May be beyond the EDRAM tile count in case of EDRAM addressing
// wrapping, thus + 1 bit.
uint32_t dispatch_first_tile : xenos::kEdramBaseTilesBits + 1;
uint32_t source_base_tiles : xenos::kEdramBaseTilesBits;
};
DumpOffsets() : offsets(0) { static_assert_size(*this, sizeof(offsets)); }