shader_recompiler: Better branch detection + more opcodes

This commit is contained in:
raphaelthegreat 2024-06-01 20:25:31 +03:00
parent f624f7749c
commit 02a50265f8
31 changed files with 772 additions and 120 deletions

View file

@ -39,7 +39,9 @@ using Libraries::VideoOut::TilingMode;
if (false /*&& IsDepthStencilFormat(format)*/) {
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
} else {
usage |= vk::ImageUsageFlagBits::eColorAttachment;
if (format != vk::Format::eBc3SrgbBlock) {
usage |= vk::ImageUsageFlagBits::eColorAttachment;
}
}
return usage;
}
@ -101,8 +103,10 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept {
size.width = image.width + 1;
size.height = image.height + 1;
size.depth = 1;
pitch = image.Pitch();
resources.levels = image.NumLevels();
resources.layers = image.NumLayers();
// TODO: Derive this properly from tiling params
pitch = size.width;
guest_size_bytes = size.width * size.height * 4;
}
@ -183,7 +187,7 @@ void Image::Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> ds
.subresourceRange{
.aspectMask = aspect_mask,
.baseMipLevel = 0,
.levelCount = 1,
.levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0,
.layerCount = VK_REMAINING_ARRAY_LAYERS,
}};

View file

@ -14,8 +14,9 @@ vk::ImageViewType ConvertImageViewType(AmdGpu::ImageType type) {
case AmdGpu::ImageType::Color1DArray:
return vk::ImageViewType::e1DArray;
case AmdGpu::ImageType::Color2D:
case AmdGpu::ImageType::Cube:
return vk::ImageViewType::e2D;
case AmdGpu::ImageType::Cube:
return vk::ImageViewType::eCube;
case AmdGpu::ImageType::Color2DArray:
return vk::ImageViewType::e2DArray;
case AmdGpu::ImageType::Color3D:
@ -47,10 +48,10 @@ vk::ComponentSwizzle ConvertComponentSwizzle(u32 dst_sel) {
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image) noexcept {
type = ConvertImageViewType(image.type);
format = Vulkan::LiverpoolToVK::SurfaceFormat(image.GetDataFmt(), image.GetNumberFmt());
range.base.level = image.base_level;
range.base.level = 0;
range.base.layer = 0;
range.extent.levels = 1;
range.extent.layers = 1;
range.extent.levels = image.NumLevels();
range.extent.layers = image.NumLayers();
mapping.r = ConvertComponentSwizzle(image.dst_sel_x);
mapping.g = ConvertComponentSwizzle(image.dst_sel_y);
mapping.b = ConvertComponentSwizzle(image.dst_sel_z);

View file

@ -175,48 +175,94 @@ void TextureCache::RefreshImage(Image& image) {
// Mark image as validated.
image.flags &= ~ImageFlagBits::CpuModified;
// Upload data to the staging buffer.
const auto [data, offset, _] = staging.Map(image.info.guest_size_bytes, 4);
const u8* image_data = reinterpret_cast<const u8*>(image.cpu_addr);
if (image.info.is_tiled) {
ConvertTileToLinear(data, image_data, image.info.size.width, image.info.size.height,
Config::isNeoMode());
} else {
std::memcpy(data, image_data, image.info.guest_size_bytes);
}
staging.Commit(image.info.guest_size_bytes);
{
// Copy to the image.
const vk::BufferImageCopy image_copy = {
.bufferOffset = offset,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource{
// Upload data to the staging buffer.
const auto [data, offset, _] = staging.Map(image.info.guest_size_bytes, 4);
const u8* image_data = reinterpret_cast<const u8*>(image.cpu_addr);
if (image.info.is_tiled) {
ConvertTileToLinear(data, image_data, image.info.size.width, image.info.size.height,
Config::isNeoMode());
} else {
std::memcpy(data, image_data, image.info.guest_size_bytes);
}
staging.Commit(image.info.guest_size_bytes);
// Copy to the image.
const vk::BufferImageCopy image_copy = {
.bufferOffset = offset,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.imageOffset = {0, 0, 0},
.imageExtent = {image.info.size.width, image.info.size.height, 1},
};
const auto cmdbuf = scheduler.CommandBuffer();
const vk::ImageSubresourceRange range = {
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
.imageOffset = {0, 0, 0},
.imageExtent = {image.info.size.width, image.info.size.height, 1},
};
.layerCount = VK_REMAINING_ARRAY_LAYERS,
};
const auto cmdbuf = scheduler.CommandBuffer();
const vk::ImageSubresourceRange range = {
.aspectMask = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = VK_REMAINING_ARRAY_LAYERS,
};
image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits::eTransferWrite);
image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits::eTransferWrite);
cmdbuf.copyBufferToImage(staging.Handle(), image.image,
vk::ImageLayout::eTransferDstOptimal, image_copy);
cmdbuf.copyBufferToImage(staging.Handle(), image.image, vk::ImageLayout::eTransferDstOptimal,
image_copy);
image.Transit(vk::ImageLayout::eGeneral,
vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eTransferRead);
return;
}
image.Transit(vk::ImageLayout::eGeneral,
vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eTransferRead);
const u8* image_data = reinterpret_cast<const u8*>(image.cpu_addr);
for (u32 l = 0; l < image.info.resources.layers; l++) {
// Upload data to the staging buffer.
for (u32 m = 0; m < image.info.resources.levels; m++) {
const u32 width = image.info.size.width >> m;
const u32 height = image.info.size.height >> m;
const u32 map_size = width * height;
const auto [data, offset, _] = staging.Map(map_size, 16);
if (image.info.is_tiled) {
ConvertTileToLinear(data, image_data, width, height, Config::isNeoMode());
} else {
std::memcpy(data, image_data, map_size);
}
staging.Commit(map_size);
image_data += map_size;
// Copy to the image.
const vk::BufferImageCopy image_copy = {
.bufferOffset = offset,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = m,
.baseArrayLayer = l,
.layerCount = 1,
},
.imageOffset = {0, 0, 0},
.imageExtent = {width, height, 1},
};
const auto cmdbuf = scheduler.CommandBuffer();
image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits::eTransferWrite);
cmdbuf.copyBufferToImage(staging.Handle(), image.image,
vk::ImageLayout::eTransferDstOptimal, image_copy);
image.Transit(vk::ImageLayout::eGeneral,
vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eTransferRead);
}
}
}
vk::Sampler TextureCache::GetSampler(const AmdGpu::Sampler& sampler) {