Merge branch 'master' of https://github.com/xenia-project/xenia into canary_experimental
This commit is contained in:
@@ -2657,17 +2657,24 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader(
|
||||
-int32_t(source_32bpp_tile_half_pixels)))));
|
||||
}
|
||||
|
||||
// Transform the destination 32bpp tile index into the source.
|
||||
spv::Id source_tile_index = builder.createUnaryOp(
|
||||
spv::OpBitcast, type_uint,
|
||||
builder.createBinOp(
|
||||
spv::OpIAdd, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int, dest_tile_index),
|
||||
builder.createTriOp(
|
||||
spv::OpBitFieldSExtract, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int, address_constant),
|
||||
builder.makeUintConstant(xenos::kEdramPitchTilesBits * 2),
|
||||
builder.makeUintConstant(xenos::kEdramBaseTilesBits))));
|
||||
// Transform the destination 32bpp tile index into the source. After the
|
||||
// addition, it may be negative - in which case, the transfer is done across
|
||||
// EDRAM addressing wrapping, and xenos::kEdramTileCount must be added to it,
|
||||
// but `& (xenos::kEdramTileCount - 1)` handles that regardless of the sign.
|
||||
spv::Id source_tile_index = builder.createBinOp(
|
||||
spv::OpBitwiseAnd, type_uint,
|
||||
builder.createUnaryOp(
|
||||
spv::OpBitcast, type_uint,
|
||||
builder.createBinOp(
|
||||
spv::OpIAdd, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int, dest_tile_index),
|
||||
builder.createTriOp(
|
||||
spv::OpBitFieldSExtract, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int,
|
||||
address_constant),
|
||||
builder.makeUintConstant(xenos::kEdramPitchTilesBits * 2),
|
||||
builder.makeUintConstant(xenos::kEdramBaseTilesBits + 1)))),
|
||||
builder.makeUintConstant(xenos::kEdramTileCount - 1));
|
||||
// Split the source 32bpp tile index into X and Y tile index within the source
|
||||
// image.
|
||||
spv::Id source_pitch_tiles = builder.createTriOp(
|
||||
@@ -3724,19 +3731,28 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader(
|
||||
push_constants, id_vector_temp),
|
||||
spv::NoPrecision);
|
||||
// Transform the destination tile index into the host depth source.
|
||||
spv::Id host_depth_source_tile_index = builder.createUnaryOp(
|
||||
spv::OpBitcast, type_uint,
|
||||
builder.createBinOp(
|
||||
spv::OpIAdd, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int,
|
||||
dest_tile_index),
|
||||
builder.createTriOp(
|
||||
spv::OpBitFieldSExtract, type_int,
|
||||
// After the addition, it may be negative - in which case, the
|
||||
// transfer is done across EDRAM addressing wrapping, and
|
||||
// xenos::kEdramTileCount must be added to it, but
|
||||
// `& (xenos::kEdramTileCount - 1)` handles that regardless of the
|
||||
// sign.
|
||||
spv::Id host_depth_source_tile_index = builder.createBinOp(
|
||||
spv::OpBitwiseAnd, type_uint,
|
||||
builder.createUnaryOp(
|
||||
spv::OpBitcast, type_uint,
|
||||
builder.createBinOp(
|
||||
spv::OpIAdd, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int,
|
||||
host_depth_address_constant),
|
||||
builder.makeUintConstant(xenos::kEdramPitchTilesBits *
|
||||
2),
|
||||
builder.makeUintConstant(xenos::kEdramBaseTilesBits))));
|
||||
dest_tile_index),
|
||||
builder.createTriOp(
|
||||
spv::OpBitFieldSExtract, type_int,
|
||||
builder.createUnaryOp(spv::OpBitcast, type_int,
|
||||
host_depth_address_constant),
|
||||
builder.makeUintConstant(
|
||||
xenos::kEdramPitchTilesBits * 2),
|
||||
builder.makeUintConstant(
|
||||
xenos::kEdramBaseTilesBits + 1)))),
|
||||
builder.makeUintConstant(xenos::kEdramTileCount - 1));
|
||||
// Split the host depth source tile index into X and Y tile index
|
||||
// within the source image.
|
||||
spv::Id host_depth_source_pitch_tiles = builder.createTriOp(
|
||||
@@ -3837,6 +3853,8 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader(
|
||||
type_uint, id_vector_temp);
|
||||
}
|
||||
// Combine the tile sample index and the tile index.
|
||||
// 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.
|
||||
spv::Id host_depth_offset = builder.createBinOp(
|
||||
spv::OpIAdd, type_uint,
|
||||
builder.createBinOp(
|
||||
@@ -5427,28 +5445,33 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) {
|
||||
const_edram_pitch_tiles_bits),
|
||||
rectangle_tile_index_y),
|
||||
rectangle_tile_index_x);
|
||||
// Add the base tile in the dispatch to the dispatch-local tile index.
|
||||
// Add the base tile in the dispatch to the dispatch-local tile index, not
|
||||
// wrapping yet so in case of a wraparound, the address relative to the base
|
||||
// in the image after subtraction of the base won't be negative.
|
||||
id_vector_temp.clear();
|
||||
id_vector_temp.push_back(builder.makeIntConstant(kDumpPushConstantOffsets));
|
||||
spv::Id offsets_constant = builder.createLoad(
|
||||
builder.createAccessChain(spv::StorageClassPushConstant, push_constants,
|
||||
id_vector_temp),
|
||||
spv::NoPrecision);
|
||||
spv::Id const_edram_base_tiles_bits =
|
||||
builder.makeUintConstant(xenos::kEdramBaseTilesBits);
|
||||
spv::Id edram_tile_index = builder.createBinOp(
|
||||
spv::Id const_edram_base_tiles_bits_plus_1 =
|
||||
builder.makeUintConstant(xenos::kEdramBaseTilesBits + 1);
|
||||
spv::Id edram_tile_index_non_wrapped = builder.createBinOp(
|
||||
spv::OpIAdd, type_uint,
|
||||
builder.createTriOp(spv::OpBitFieldUExtract, type_uint, offsets_constant,
|
||||
const_uint_0, const_edram_base_tiles_bits),
|
||||
const_uint_0, const_edram_base_tiles_bits_plus_1),
|
||||
rectangle_tile_index);
|
||||
|
||||
// Combine the tile sample index and the tile index into the EDRAM sample
|
||||
// index.
|
||||
// Combine the tile sample index and the tile index, wrapping the tile
|
||||
// addressing, into the EDRAM sample index.
|
||||
spv::Id edram_sample_address = builder.createBinOp(
|
||||
spv::OpIAdd, type_uint,
|
||||
builder.createBinOp(spv::OpIMul, type_uint,
|
||||
builder.makeUintConstant(tile_width * tile_height),
|
||||
edram_tile_index),
|
||||
builder.createBinOp(
|
||||
spv::OpIMul, type_uint,
|
||||
builder.makeUintConstant(tile_width * tile_height),
|
||||
builder.createBinOp(
|
||||
spv::OpBitwiseAnd, type_uint, edram_tile_index_non_wrapped,
|
||||
builder.makeUintConstant(xenos::kEdramTileCount - 1))),
|
||||
builder.createBinOp(spv::OpIAdd, type_uint,
|
||||
builder.createBinOp(spv::OpIMul, type_uint,
|
||||
const_tile_width, tile_sample_y),
|
||||
@@ -5474,10 +5497,11 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) {
|
||||
|
||||
// Get the linear tile index within the source texture.
|
||||
spv::Id source_tile_index = builder.createBinOp(
|
||||
spv::OpISub, type_uint, edram_tile_index,
|
||||
builder.createTriOp(spv::OpBitFieldUExtract, type_uint, offsets_constant,
|
||||
const_edram_base_tiles_bits,
|
||||
const_edram_base_tiles_bits));
|
||||
spv::OpISub, type_uint, edram_tile_index_non_wrapped,
|
||||
builder.createTriOp(
|
||||
spv::OpBitFieldUExtract, type_uint, offsets_constant,
|
||||
const_edram_base_tiles_bits_plus_1,
|
||||
builder.makeUintConstant(xenos::kEdramBaseTilesBits)));
|
||||
// Split the linear tile index in the source texture into X and Y in tiles.
|
||||
spv::Id source_pitch_tiles = builder.createTriOp(
|
||||
spv::OpBitFieldUExtract, type_uint, pitches_constant,
|
||||
|
||||
@@ -412,13 +412,13 @@ class VulkanRenderTargetCache final : public RenderTargetCache {
|
||||
// Same as RenderTargetKey::pitch_tiles_at_32bpp.
|
||||
uint32_t pitch_tiles_at_32bpp : 8; // 8
|
||||
// [0, 2047].
|
||||
uint32_t depth_base_tiles : xenos::kEdramBaseTilesBits - 1; // 19
|
||||
uint32_t color_0_base_tiles : xenos::kEdramBaseTilesBits - 1; // 30
|
||||
uint32_t depth_base_tiles : xenos::kEdramBaseTilesBits; // 19
|
||||
uint32_t color_0_base_tiles : xenos::kEdramBaseTilesBits; // 30
|
||||
|
||||
uint32_t color_1_base_tiles : xenos::kEdramBaseTilesBits - 1; // 43
|
||||
uint32_t color_2_base_tiles : xenos::kEdramBaseTilesBits - 1; // 54
|
||||
uint32_t color_1_base_tiles : xenos::kEdramBaseTilesBits; // 43
|
||||
uint32_t color_2_base_tiles : xenos::kEdramBaseTilesBits; // 54
|
||||
|
||||
uint32_t color_3_base_tiles : xenos::kEdramBaseTilesBits - 1; // 75
|
||||
uint32_t color_3_base_tiles : xenos::kEdramBaseTilesBits; // 75
|
||||
|
||||
// Including all the padding, for a stable hash.
|
||||
FramebufferKey() { Reset(); }
|
||||
@@ -619,16 +619,13 @@ class VulkanRenderTargetCache 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));
|
||||
@@ -746,7 +743,9 @@ class VulkanRenderTargetCache 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)); }
|
||||
|
||||
Reference in New Issue
Block a user