mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-06 01:12:33 +00:00
shader_recompiler: Move image resource functions into sharp type.
This commit is contained in:
parent
501b921e49
commit
40d35211a3
@ -773,8 +773,8 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) {
|
|||||||
Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
|
Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
|
||||||
const auto image = desc.GetSharp(ctx.info);
|
const auto image = desc.GetSharp(ctx.info);
|
||||||
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown;
|
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown;
|
||||||
const auto type = desc.GetBoundType(image);
|
const auto type = image.GetBoundType(desc.is_array);
|
||||||
const u32 sampled = desc.IsStorage(image) ? 2 : 1;
|
const u32 sampled = desc.is_written ? 2 : 1;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AmdGpu::ImageType::Color1D:
|
case AmdGpu::ImageType::Color1D:
|
||||||
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format);
|
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format);
|
||||||
@ -799,7 +799,7 @@ void EmitContext::DefineImagesAndSamplers() {
|
|||||||
const auto sharp = image_desc.GetSharp(info);
|
const auto sharp = image_desc.GetSharp(info);
|
||||||
const auto nfmt = sharp.GetNumberFmt();
|
const auto nfmt = sharp.GetNumberFmt();
|
||||||
const bool is_integer = AmdGpu::IsInteger(nfmt);
|
const bool is_integer = AmdGpu::IsInteger(nfmt);
|
||||||
const bool is_storage = image_desc.IsStorage(sharp);
|
const bool is_storage = image_desc.is_written;
|
||||||
const VectorIds& data_types = GetAttributeType(*this, nfmt);
|
const VectorIds& data_types = GetAttributeType(*this, nfmt);
|
||||||
const Id sampled_type = data_types[1];
|
const Id sampled_type = data_types[1];
|
||||||
const Id image_type{ImageType(*this, image_desc, sampled_type)};
|
const Id image_type{ImageType(*this, image_desc, sampled_type)};
|
||||||
@ -814,7 +814,7 @@ void EmitContext::DefineImagesAndSamplers() {
|
|||||||
.sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type),
|
.sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type),
|
||||||
.pointer_type = pointer_type,
|
.pointer_type = pointer_type,
|
||||||
.image_type = image_type,
|
.image_type = image_type,
|
||||||
.bound_type = image_desc.GetBoundType(sharp),
|
.bound_type = sharp.GetBoundType(image_desc.is_array),
|
||||||
.is_integer = is_integer,
|
.is_integer = is_integer,
|
||||||
.is_storage = is_storage,
|
.is_storage = is_storage,
|
||||||
});
|
});
|
||||||
|
@ -70,49 +70,8 @@ struct ImageResource {
|
|||||||
bool is_depth{};
|
bool is_depth{};
|
||||||
bool is_atomic{};
|
bool is_atomic{};
|
||||||
bool is_array{};
|
bool is_array{};
|
||||||
bool is_read{};
|
|
||||||
bool is_written{};
|
bool is_written{};
|
||||||
|
|
||||||
[[nodiscard]] AmdGpu::ImageType GetBoundType(const AmdGpu::Image& image) const noexcept {
|
|
||||||
const auto base_type = image.GetType();
|
|
||||||
if (base_type == AmdGpu::ImageType::Color1DArray && !is_array) {
|
|
||||||
return AmdGpu::ImageType::Color1D;
|
|
||||||
}
|
|
||||||
if (base_type == AmdGpu::ImageType::Color2DArray && !is_array) {
|
|
||||||
return AmdGpu::ImageType::Color2D;
|
|
||||||
}
|
|
||||||
if (base_type == AmdGpu::ImageType::Color2DMsaaArray && !is_array) {
|
|
||||||
return AmdGpu::ImageType::Color2DMsaa;
|
|
||||||
}
|
|
||||||
return base_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] u32 NumViewLevels(const AmdGpu::Image& image) const noexcept {
|
|
||||||
switch (GetBoundType(image)) {
|
|
||||||
case AmdGpu::ImageType::Color2DMsaa:
|
|
||||||
case AmdGpu::ImageType::Color2DMsaaArray:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return image.last_level - image.base_level + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] u32 NumViewLayers(const AmdGpu::Image image) const noexcept {
|
|
||||||
switch (GetBoundType(image)) {
|
|
||||||
case AmdGpu::ImageType::Color1D:
|
|
||||||
case AmdGpu::ImageType::Color2D:
|
|
||||||
case AmdGpu::ImageType::Color2DMsaa:
|
|
||||||
case AmdGpu::ImageType::Color3D:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return image.last_array - image.base_array + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept {
|
|
||||||
return is_written;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
|
[[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
|
||||||
};
|
};
|
||||||
using ImageResourceList = boost::container::small_vector<ImageResource, 16>;
|
using ImageResourceList = boost::container::small_vector<ImageResource, 16>;
|
||||||
|
@ -164,7 +164,6 @@ public:
|
|||||||
return desc.sharp_idx == existing.sharp_idx && desc.is_array == existing.is_array;
|
return desc.sharp_idx == existing.sharp_idx && desc.is_array == existing.is_array;
|
||||||
})};
|
})};
|
||||||
auto& image = image_resources[index];
|
auto& image = image_resources[index];
|
||||||
image.is_read |= desc.is_read;
|
|
||||||
image.is_written |= desc.is_written;
|
image.is_written |= desc.is_written;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@ -361,7 +360,6 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||||||
image = AmdGpu::Image::Null();
|
image = AmdGpu::Image::Null();
|
||||||
}
|
}
|
||||||
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
|
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
|
||||||
const bool is_read = inst.GetOpcode() == IR::Opcode::ImageRead;
|
|
||||||
const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite;
|
const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite;
|
||||||
|
|
||||||
// Patch image instruction if image is FMask.
|
// Patch image instruction if image is FMask.
|
||||||
@ -402,7 +400,6 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||||||
.is_depth = bool(inst_info.is_depth),
|
.is_depth = bool(inst_info.is_depth),
|
||||||
.is_atomic = IsImageAtomicInstruction(inst),
|
.is_atomic = IsImageAtomicInstruction(inst),
|
||||||
.is_array = bool(inst_info.is_array),
|
.is_array = bool(inst_info.is_array),
|
||||||
.is_read = is_read,
|
|
||||||
.is_written = is_written,
|
.is_written = is_written,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -785,7 +782,7 @@ void PatchImageArgs(IR::Block& block, IR::Inst& inst, Info& info) {
|
|||||||
const auto lod = inst_info.has_lod ? IR::U32{arg} : IR::U32{};
|
const auto lod = inst_info.has_lod ? IR::U32{arg} : IR::U32{};
|
||||||
const auto ms = has_ms ? IR::U32{arg} : IR::U32{};
|
const auto ms = has_ms ? IR::U32{arg} : IR::U32{};
|
||||||
|
|
||||||
const auto is_storage = image_res.IsStorage(image);
|
const auto is_storage = image_res.is_written;
|
||||||
if (inst.GetOpcode() == IR::Opcode::ImageRead) {
|
if (inst.GetOpcode() == IR::Opcode::ImageRead) {
|
||||||
auto texel = ir.ImageRead(handle, coords, lod, ms, inst_info);
|
auto texel = ir.ImageRead(handle, coords, lod, ms, inst_info);
|
||||||
if (is_storage) {
|
if (is_storage) {
|
||||||
|
@ -100,7 +100,7 @@ struct StageSpecialization {
|
|||||||
ForEachSharp(binding, buffers, info->buffers,
|
ForEachSharp(binding, buffers, info->buffers,
|
||||||
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {
|
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {
|
||||||
spec.stride = sharp.GetStride();
|
spec.stride = sharp.GetStride();
|
||||||
spec.is_storage = desc.IsStorage(sharp);
|
spec.is_storage = desc.is_written;
|
||||||
if (!spec.is_storage) {
|
if (!spec.is_storage) {
|
||||||
spec.size = sharp.GetSize();
|
spec.size = sharp.GetSize();
|
||||||
}
|
}
|
||||||
@ -113,9 +113,9 @@ struct StageSpecialization {
|
|||||||
});
|
});
|
||||||
ForEachSharp(binding, images, info->images,
|
ForEachSharp(binding, images, info->images,
|
||||||
[](auto& spec, const auto& desc, AmdGpu::Image sharp) {
|
[](auto& spec, const auto& desc, AmdGpu::Image sharp) {
|
||||||
spec.type = desc.GetBoundType(sharp);
|
spec.type = sharp.GetBoundType(desc.is_array);
|
||||||
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
|
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
|
||||||
spec.is_storage = desc.IsStorage(sharp);
|
spec.is_storage = desc.is_written;
|
||||||
if (spec.is_storage) {
|
if (spec.is_storage) {
|
||||||
spec.dst_select = sharp.DstSelect();
|
spec.dst_select = sharp.DstSelect();
|
||||||
}
|
}
|
||||||
|
@ -287,6 +287,42 @@ struct Image {
|
|||||||
return GetDataFmt() >= DataFormat::FormatFmask8_1 &&
|
return GetDataFmt() >= DataFormat::FormatFmask8_1 &&
|
||||||
GetDataFmt() <= DataFormat::FormatFmask64_8;
|
GetDataFmt() <= DataFormat::FormatFmask64_8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ImageType GetBoundType(const bool is_array) const noexcept {
|
||||||
|
const auto base_type = GetType();
|
||||||
|
if (base_type == ImageType::Color1DArray && !is_array) {
|
||||||
|
return ImageType::Color1D;
|
||||||
|
}
|
||||||
|
if (base_type == ImageType::Color2DArray && !is_array) {
|
||||||
|
return ImageType::Color2D;
|
||||||
|
}
|
||||||
|
if (base_type == ImageType::Color2DMsaaArray && !is_array) {
|
||||||
|
return ImageType::Color2DMsaa;
|
||||||
|
}
|
||||||
|
return base_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 NumViewLevels(const bool is_array) const noexcept {
|
||||||
|
switch (GetBoundType(is_array)) {
|
||||||
|
case ImageType::Color2DMsaa:
|
||||||
|
case ImageType::Color2DMsaaArray:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return last_level - base_level + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 NumViewLayers(const bool is_array) const noexcept {
|
||||||
|
switch (GetBoundType(is_array)) {
|
||||||
|
case ImageType::Color1D:
|
||||||
|
case ImageType::Color2D:
|
||||||
|
case ImageType::Color2DMsaa:
|
||||||
|
case ImageType::Color3D:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return last_array - base_array + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Image) == 32); // 256bits
|
static_assert(sizeof(Image) == 32); // 256bits
|
||||||
|
|
||||||
|
@ -59,9 +59,8 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
|
|||||||
for (const auto& image : info->images) {
|
for (const auto& image : info->images) {
|
||||||
bindings.push_back({
|
bindings.push_back({
|
||||||
.binding = binding++,
|
.binding = binding++,
|
||||||
.descriptorType = image.IsStorage(image.GetSharp(*info))
|
.descriptorType = image.is_written ? vk::DescriptorType::eStorageImage
|
||||||
? vk::DescriptorType::eStorageImage
|
: vk::DescriptorType::eSampledImage,
|
||||||
: vk::DescriptorType::eSampledImage,
|
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eCompute,
|
.stageFlags = vk::ShaderStageFlagBits::eCompute,
|
||||||
});
|
});
|
||||||
|
@ -367,9 +367,8 @@ void GraphicsPipeline::BuildDescSetLayout() {
|
|||||||
for (const auto& image : stage->images) {
|
for (const auto& image : stage->images) {
|
||||||
bindings.push_back({
|
bindings.push_back({
|
||||||
.binding = binding++,
|
.binding = binding++,
|
||||||
.descriptorType = image.IsStorage(image.GetSharp(*stage))
|
.descriptorType = image.is_written ? vk::DescriptorType::eStorageImage
|
||||||
? vk::DescriptorType::eStorageImage
|
: vk::DescriptorType::eSampledImage,
|
||||||
: vk::DescriptorType::eSampledImage,
|
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = gp_stage_flags,
|
.stageFlags = gp_stage_flags,
|
||||||
});
|
});
|
||||||
|
@ -661,7 +661,7 @@ void Rasterizer::BindTextures(const Shader::Info& stage, Shader::Backend::Bindin
|
|||||||
if (image->binding.is_bound) {
|
if (image->binding.is_bound) {
|
||||||
// The image is already bound. In case if it is about to be used as storage we need
|
// The image is already bound. In case if it is about to be used as storage we need
|
||||||
// to force general layout on it.
|
// to force general layout on it.
|
||||||
image->binding.force_general |= image_desc.IsStorage(tsharp);
|
image->binding.force_general |= image_desc.is_written;
|
||||||
}
|
}
|
||||||
if (image->binding.is_target) {
|
if (image->binding.is_target) {
|
||||||
// The image is already bound as target. Since we read and output to it need to force
|
// The image is already bound as target. Since we read and output to it need to force
|
||||||
|
@ -30,7 +30,7 @@ vk::ImageViewType ConvertImageViewType(AmdGpu::ImageType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept
|
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();
|
const auto dfmt = image.GetDataFmt();
|
||||||
auto nfmt = image.GetNumberFmt();
|
auto nfmt = image.GetNumberFmt();
|
||||||
if (is_storage && nfmt == AmdGpu::NumberFormat::Srgb) {
|
if (is_storage && nfmt == AmdGpu::NumberFormat::Srgb) {
|
||||||
@ -43,9 +43,9 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso
|
|||||||
|
|
||||||
range.base.level = image.base_level;
|
range.base.level = image.base_level;
|
||||||
range.base.layer = image.base_array;
|
range.base.layer = image.base_array;
|
||||||
range.extent.levels = desc.NumViewLevels(image);
|
range.extent.levels = image.NumViewLevels(desc.is_array);
|
||||||
range.extent.layers = desc.NumViewLayers(image);
|
range.extent.layers = image.NumViewLayers(desc.is_array);
|
||||||
type = ConvertImageViewType(desc.GetBoundType(image));
|
type = ConvertImageViewType(image.GetBoundType(desc.is_array));
|
||||||
|
|
||||||
if (!is_storage) {
|
if (!is_storage) {
|
||||||
mapping = Vulkan::LiverpoolToVK::ComponentMapping(image.DstSelect());
|
mapping = Vulkan::LiverpoolToVK::ComponentMapping(image.DstSelect());
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
struct TextureDesc : public BaseDesc {
|
struct TextureDesc : public BaseDesc {
|
||||||
TextureDesc() = default;
|
TextureDesc() = default;
|
||||||
TextureDesc(const AmdGpu::Image& image, const Shader::ImageResource& desc)
|
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}} {}
|
ImageInfo{image, desc}, ImageViewInfo{image, desc}} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user