mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-07 11:13:15 +00:00
shader_recompiler: Improvements to array and cube handling. (#2083)
* shader_recompiler: Account for instruction array flag in image type. * shader_recompiler: Check da flag for all mimg instructions. * shader_recompiler: Convert cube images into 2D arrays. * shader_recompiler: Move image resource functions into sharp type. * shader_recompiler: Use native AMD cube instructions when possible. * specialization: Fix buffer storage mistake.
This commit is contained in:
parent
93402620de
commit
725814ce01
28 changed files with 217 additions and 144 deletions
|
@ -153,13 +153,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
|
|||
// the texture cache should re-create the resource with the usage requested
|
||||
vk::ImageCreateFlags flags{vk::ImageCreateFlagBits::eMutableFormat |
|
||||
vk::ImageCreateFlagBits::eExtendedUsage};
|
||||
const bool can_be_cube =
|
||||
(info.type == vk::ImageType::e2D) &&
|
||||
((info.props.is_pow2 ? (info.resources.layers % 8) : (info.resources.layers % 6)) == 0) &&
|
||||
(info.size.width == info.size.height);
|
||||
if (info.props.is_cube || can_be_cube) {
|
||||
flags |= vk::ImageCreateFlagBits::eCubeCompatible;
|
||||
} else if (info.props.is_volume) {
|
||||
if (info.props.is_volume) {
|
||||
flags |= vk::ImageCreateFlagBits::e2DArrayCompatible;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ static vk::ImageType ConvertImageType(AmdGpu::ImageType type) noexcept {
|
|||
return vk::ImageType::e1D;
|
||||
case AmdGpu::ImageType::Color2D:
|
||||
case AmdGpu::ImageType::Color2DMsaa:
|
||||
case AmdGpu::ImageType::Cube:
|
||||
case AmdGpu::ImageType::Color2DArray:
|
||||
return vk::ImageType::e2D;
|
||||
case AmdGpu::ImageType::Color3D:
|
||||
|
@ -130,7 +129,6 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image, const Shader::ImageResource& de
|
|||
}
|
||||
type = ConvertImageType(image.GetType());
|
||||
props.is_tiled = image.IsTiled();
|
||||
props.is_cube = image.GetType() == AmdGpu::ImageType::Cube;
|
||||
props.is_volume = image.GetType() == AmdGpu::ImageType::Color3D;
|
||||
props.is_pow2 = image.pow2pad;
|
||||
props.is_block = IsBlockCoded();
|
||||
|
@ -139,7 +137,7 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image, const Shader::ImageResource& de
|
|||
size.depth = props.is_volume ? image.depth + 1 : 1;
|
||||
pitch = image.Pitch();
|
||||
resources.levels = image.NumLevels();
|
||||
resources.layers = image.NumLayers(desc.is_array);
|
||||
resources.layers = image.NumLayers();
|
||||
num_samples = image.NumSamples();
|
||||
num_bits = NumBits(image.GetDataFmt());
|
||||
|
||||
|
|
|
@ -61,7 +61,6 @@ struct ImageInfo {
|
|||
} meta_info{};
|
||||
|
||||
struct {
|
||||
u32 is_cube : 1;
|
||||
u32 is_volume : 1;
|
||||
u32 is_tiled : 1;
|
||||
u32 is_pow2 : 1;
|
||||
|
|
|
@ -20,8 +20,6 @@ vk::ImageViewType ConvertImageViewType(AmdGpu::ImageType type) {
|
|||
case AmdGpu::ImageType::Color2D:
|
||||
case AmdGpu::ImageType::Color2DMsaa:
|
||||
return vk::ImageViewType::e2D;
|
||||
case AmdGpu::ImageType::Cube:
|
||||
return vk::ImageViewType::eCube;
|
||||
case AmdGpu::ImageType::Color2DArray:
|
||||
return vk::ImageViewType::e2DArray;
|
||||
case AmdGpu::ImageType::Color3D:
|
||||
|
@ -32,7 +30,7 @@ vk::ImageViewType ConvertImageViewType(AmdGpu::ImageType type) {
|
|||
}
|
||||
|
||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept
|
||||
: is_storage{desc.IsStorage(image)} {
|
||||
: is_storage{desc.is_written} {
|
||||
const auto dfmt = image.GetDataFmt();
|
||||
auto nfmt = image.GetNumberFmt();
|
||||
if (is_storage && nfmt == AmdGpu::NumberFormat::Srgb) {
|
||||
|
@ -42,30 +40,12 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso
|
|||
if (desc.is_depth) {
|
||||
format = Vulkan::LiverpoolToVK::PromoteFormatToDepth(format);
|
||||
}
|
||||
|
||||
range.base.level = image.base_level;
|
||||
range.base.layer = image.base_array;
|
||||
if (image.GetType() == AmdGpu::ImageType::Color2DMsaa ||
|
||||
image.GetType() == AmdGpu::ImageType::Color2DMsaaArray) {
|
||||
range.extent.levels = 1;
|
||||
} else {
|
||||
range.extent.levels = image.last_level - image.base_level + 1;
|
||||
}
|
||||
range.extent.layers = image.last_array - image.base_array + 1;
|
||||
type = ConvertImageViewType(image.GetBoundType());
|
||||
|
||||
// Adjust view type for arrays
|
||||
if (type == vk::ImageViewType::eCube) {
|
||||
if (desc.is_array) {
|
||||
type = vk::ImageViewType::eCubeArray;
|
||||
} else {
|
||||
// Some games try to bind an array of cubemaps while shader reads only single one.
|
||||
range.extent.layers = std::min(range.extent.layers, 6u);
|
||||
}
|
||||
}
|
||||
if (type == vk::ImageViewType::e3D && range.extent.layers > 1) {
|
||||
// Some games pass incorrect layer count for 3D textures so we need to fixup it.
|
||||
range.extent.layers = 1;
|
||||
}
|
||||
range.extent.levels = image.NumViewLevels(desc.is_array);
|
||||
range.extent.layers = image.NumViewLayers(desc.is_array);
|
||||
type = ConvertImageViewType(image.GetBoundType(desc.is_array));
|
||||
|
||||
if (!is_storage) {
|
||||
mapping = Vulkan::LiverpoolToVK::ComponentMapping(image.DstSelect());
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
struct TextureDesc : public BaseDesc {
|
||||
TextureDesc() = default;
|
||||
TextureDesc(const AmdGpu::Image& image, const Shader::ImageResource& desc)
|
||||
: BaseDesc{desc.IsStorage(image) ? BindingType::Storage : BindingType::Texture,
|
||||
: BaseDesc{desc.is_written ? BindingType::Storage : BindingType::Texture,
|
||||
ImageInfo{image, desc}, ImageViewInfo{image, desc}} {}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue