mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
graphics: add 1D image descriptor support
This commit is contained in:
@@ -22,9 +22,13 @@ vk::ShaderStageFlags StageFlags(DescriptorCache::Stage stage) {
|
||||
|
||||
bool IsSampledImage(BindingKind kind) {
|
||||
switch (kind) {
|
||||
case BindingKind::Sampled1D:
|
||||
case BindingKind::Sampled1DArray:
|
||||
case BindingKind::Sampled2D:
|
||||
case BindingKind::Sampled2DArray:
|
||||
case BindingKind::Sampled3D:
|
||||
case BindingKind::SampledUint1D:
|
||||
case BindingKind::SampledUint1DArray:
|
||||
case BindingKind::SampledUint2D:
|
||||
case BindingKind::SampledUint2DArray:
|
||||
case BindingKind::SampledUint3D: return true;
|
||||
@@ -34,9 +38,13 @@ bool IsSampledImage(BindingKind kind) {
|
||||
|
||||
bool IsStorageImage(BindingKind kind) {
|
||||
switch (kind) {
|
||||
case BindingKind::Storage1D:
|
||||
case BindingKind::Storage1DArray:
|
||||
case BindingKind::Storage2D:
|
||||
case BindingKind::Storage2DArray:
|
||||
case BindingKind::Storage3D:
|
||||
case BindingKind::StorageUint1D:
|
||||
case BindingKind::StorageUint1DArray:
|
||||
case BindingKind::StorageUint2D:
|
||||
case BindingKind::StorageUint2DArray:
|
||||
case BindingKind::StorageUint3D: return true;
|
||||
|
||||
@@ -155,6 +155,8 @@ NativeAddressBuffer(RenderContext& context, CommandBuffer& command_buffer,
|
||||
static bool IsSupportedSampledColorResource(const ShaderRecompiler::IR::ImageResource& resource) {
|
||||
bool supported_dimension = false;
|
||||
switch (resource.dimension) {
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim1D:
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim1DArray:
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim2D:
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim2DArray:
|
||||
supported_dimension = true;
|
||||
@@ -295,14 +297,32 @@ static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource
|
||||
|
||||
static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::ImageResource& resource,
|
||||
const ShaderTextureResource& descriptor) {
|
||||
const auto tile = descriptor.TileMode();
|
||||
const auto tile = descriptor.TileMode();
|
||||
const bool is_color_1d =
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor1D);
|
||||
const bool is_color_1d_array =
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor1DArray);
|
||||
const bool valid_1d_slice =
|
||||
(is_color_1d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) ||
|
||||
(is_color_1d_array && descriptor.BaseArray5() <= descriptor.Depth());
|
||||
const bool is_1d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim1D &&
|
||||
descriptor.Height5() == 0 && valid_1d_slice;
|
||||
const bool is_1d_array =
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim1DArray &&
|
||||
is_color_1d_array && descriptor.Height5() == 0 &&
|
||||
descriptor.BaseArray5() <= descriptor.Depth();
|
||||
const bool is_color_2d =
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D);
|
||||
const bool is_color_2d_array =
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray);
|
||||
const bool valid_2d_slice =
|
||||
(is_color_2d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) ||
|
||||
(is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth());
|
||||
const bool is_2d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
|
||||
descriptor.Depth() == 0 && descriptor.BaseArray5() == 0;
|
||||
valid_2d_slice;
|
||||
const bool is_2d_array =
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) &&
|
||||
descriptor.BaseArray5() <= descriptor.Depth();
|
||||
is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth();
|
||||
const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D) &&
|
||||
descriptor.BaseArray5() == 0;
|
||||
@@ -321,8 +341,9 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
||||
const bool supported_swizzle =
|
||||
IsValidImageSwizzle(descriptor.DstSelXYZW()) &&
|
||||
(descriptor.DstSelXYZW() == DstSel(4, 5, 6, 7) || !resource.read);
|
||||
const bool supported_mip_view = descriptor.BaseLevel() == 0 || is_2d;
|
||||
return (is_2d || is_2d_array || is_3d) && supported_tile && supported_mip_view &&
|
||||
const bool supported_mip_view = descriptor.BaseLevel() == 0 || is_1d || is_2d;
|
||||
return (is_1d || is_1d_array || is_2d || is_2d_array || is_3d) && supported_tile &&
|
||||
supported_mip_view &&
|
||||
descriptor.BaseLevel() == descriptor.LastLevel() &&
|
||||
descriptor.LastLevel() <= descriptor.MaxMip() && descriptor.MinLod() == 0 &&
|
||||
supported_swizzle && descriptor.BCSwizzle() == 0 && !descriptor.MsaaDepth();
|
||||
@@ -471,6 +492,22 @@ static ImageViewInfo TextureViewInfo(const ShaderRecompiler::IR::ImageResource&
|
||||
view.mapping =
|
||||
storage ? vk::ComponentMapping {} : TextureGetComponentMapping(descriptor.DstSelXYZW());
|
||||
switch (resource.dimension) {
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim1D:
|
||||
view.type = vk::ImageViewType::e1D;
|
||||
view.base_layer = descriptor.BaseArray5();
|
||||
if (view.base_layer >= image_layers) {
|
||||
EXIT("texture base layer is out of bounds\n");
|
||||
}
|
||||
view.layer_count = 1;
|
||||
break;
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim1DArray:
|
||||
view.type = vk::ImageViewType::e1DArray;
|
||||
view.base_layer = descriptor.BaseArray5();
|
||||
if (view.base_layer >= image_layers) {
|
||||
EXIT("texture array base layer is out of bounds\n");
|
||||
}
|
||||
view.layer_count = image_layers - view.base_layer;
|
||||
break;
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim3D:
|
||||
view.type = vk::ImageViewType::e3D;
|
||||
view.base_layer = 0;
|
||||
@@ -484,11 +521,15 @@ static ImageViewInfo TextureViewInfo(const ShaderRecompiler::IR::ImageResource&
|
||||
}
|
||||
view.layer_count = image_layers - view.base_layer;
|
||||
break;
|
||||
default:
|
||||
view.type = vk::ImageViewType::e2D;
|
||||
view.base_layer = 0;
|
||||
case ShaderRecompiler::Decoder::ImageDimension::Dim2D:
|
||||
view.type = vk::ImageViewType::e2D;
|
||||
view.base_layer = descriptor.BaseArray5();
|
||||
if (view.base_layer >= image_layers) {
|
||||
EXIT("texture base layer is out of bounds\n");
|
||||
}
|
||||
view.layer_count = 1;
|
||||
break;
|
||||
default: EXIT("unsupported texture view dimension\n");
|
||||
}
|
||||
return view;
|
||||
}
|
||||
@@ -576,6 +617,10 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
||||
}
|
||||
|
||||
const auto pixel_format = TextureGetFormat(format);
|
||||
const auto storage_view_format = SrgbStorageViewFormat(pixel_format);
|
||||
const auto view_format =
|
||||
storage && storage_view_format != vk::Format::eUndefined ? storage_view_format
|
||||
: pixel_format;
|
||||
const auto block_bytes = Prospero::BlockCompressedBytesPerBlock(format);
|
||||
TextureCache::ImageDesc desc {};
|
||||
desc.info.data = {address, size.size};
|
||||
@@ -594,7 +639,7 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
||||
} else {
|
||||
PopulateTextureMipLayout(desc.info);
|
||||
}
|
||||
desc.view_info = TextureViewInfo(resource, descriptor, pixel_format, storage, view_levels,
|
||||
desc.view_info = TextureViewInfo(resource, descriptor, view_format, storage, view_levels,
|
||||
desc.info.resources.layers);
|
||||
desc.type = storage ? TextureCache::BindingType::Storage : TextureCache::BindingType::Texture;
|
||||
|
||||
@@ -612,7 +657,7 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
||||
(void)SelectSampledDepthView(image->info.pixel_format, pixel_format,
|
||||
descriptor.DstSelXYZW());
|
||||
} else if (storage) {
|
||||
ValidateStorageColorView(image->info.pixel_format, pixel_format, descriptor.DstSelXYZW());
|
||||
ValidateStorageColorView(image->info.pixel_format, view_format, descriptor.DstSelXYZW());
|
||||
} else {
|
||||
(void)SelectSampledColorView(image->info.pixel_format, pixel_format,
|
||||
descriptor.DstSelXYZW());
|
||||
|
||||
@@ -69,8 +69,19 @@ namespace {
|
||||
default: return false;
|
||||
}
|
||||
case vk::ImageType::e3D:
|
||||
return info.type == vk::ImageViewType::e3D && info.base_layer == 0 &&
|
||||
info.layer_count == 1;
|
||||
switch (info.type) {
|
||||
case vk::ImageViewType::e3D:
|
||||
return info.base_layer == 0 && info.layer_count == 1;
|
||||
case vk::ImageViewType::e2D:
|
||||
return static_cast<bool>(
|
||||
image.flags & vk::ImageCreateFlagBits::e2DArrayCompatible) &&
|
||||
info.level_count == 1 && info.layer_count == 1;
|
||||
case vk::ImageViewType::e2DArray:
|
||||
return static_cast<bool>(
|
||||
image.flags & vk::ImageCreateFlagBits::e2DArrayCompatible) &&
|
||||
info.level_count == 1;
|
||||
default: return false;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
@@ -333,11 +344,18 @@ vk::ImageView Image::FindView(const ImageViewInfo& view_info) {
|
||||
is_storage ? vk::ImageUsageFlagBits::eStorage : vk::ImageUsageFlags {};
|
||||
const bool format_compatible = normalized.format != vk::Format::eUndefined &&
|
||||
IsCompatibleViewFormat(image.format, normalized.format);
|
||||
const bool ranges_valid = normalized.level_count != 0 &&
|
||||
const bool slice_view = image.image_type == vk::ImageType::e3D &&
|
||||
(normalized.type == vk::ImageViewType::e2D ||
|
||||
normalized.type == vk::ImageViewType::e2DArray);
|
||||
const bool levels_valid = normalized.level_count != 0 &&
|
||||
normalized.base_level < image.mip_levels &&
|
||||
normalized.level_count <= image.mip_levels - normalized.base_level &&
|
||||
normalized.layer_count != 0 && normalized.base_layer < image.layers &&
|
||||
normalized.layer_count <= image.layers - normalized.base_layer;
|
||||
normalized.level_count <= image.mip_levels - normalized.base_level;
|
||||
const auto view_layers = slice_view && levels_valid
|
||||
? std::max(image.extent.depth >> normalized.base_level, 1u)
|
||||
: image.layers;
|
||||
const bool ranges_valid = levels_valid &&
|
||||
normalized.layer_count != 0 && normalized.base_layer < view_layers &&
|
||||
normalized.layer_count <= view_layers - normalized.base_layer;
|
||||
const bool mapping_valid =
|
||||
IsComponentSwizzle(normalized.mapping.r) && IsComponentSwizzle(normalized.mapping.g) &&
|
||||
IsComponentSwizzle(normalized.mapping.b) && IsComponentSwizzle(normalized.mapping.a);
|
||||
|
||||
@@ -38,19 +38,12 @@ namespace ImageViewOps {
|
||||
static_cast<int>(image_format), static_cast<int>(view_format), swizzle);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vk::Format BgraSrgbStorageViewFormat(vk::Format image_format) noexcept {
|
||||
return image_format == vk::Format::eB8G8R8A8Srgb ? vk::Format::eR8G8B8A8Unorm
|
||||
: vk::Format::eUndefined;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vk::Format SrgbStorageViewFormat(vk::Format image_format) noexcept {
|
||||
return image_format == vk::Format::eR8G8B8A8Srgb ? vk::Format::eR8G8B8A8Unorm
|
||||
: BgraSrgbStorageViewFormat(image_format);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsBgraSrgbStorageView(vk::Format image_format, vk::Format view_format,
|
||||
uint32_t swizzle) noexcept {
|
||||
return view_format == BgraSrgbStorageViewFormat(image_format) && swizzle == DstSel(6, 5, 4, 7);
|
||||
switch (image_format) {
|
||||
case vk::Format::eR8G8B8A8Srgb:
|
||||
case vk::Format::eB8G8R8A8Srgb: return vk::Format::eR8G8B8A8Unorm;
|
||||
default: return vk::Format::eUndefined;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsSupportedSampledColorView(vk::Format image_format,
|
||||
@@ -110,8 +103,10 @@ IsSupportedSampledDepthUintResource(const ShaderRecompiler::IR::ImageResource& r
|
||||
|
||||
inline void ValidateStorageColorView(vk::Format image_format, vk::Format view_format,
|
||||
uint32_t swizzle) noexcept {
|
||||
if ((image_format != view_format &&
|
||||
!IsBgraSrgbStorageView(image_format, view_format, swizzle)) ||
|
||||
const auto srgb_view = SrgbStorageViewFormat(image_format);
|
||||
const bool srgb_storage_view =
|
||||
srgb_view != vk::Format::eUndefined && view_format == srgb_view;
|
||||
if ((image_format != view_format && !srgb_storage_view) ||
|
||||
!IsValidImageSwizzle(swizzle)) {
|
||||
UnsupportedColorView("storage", image_format, view_format, swizzle);
|
||||
}
|
||||
@@ -121,7 +116,9 @@ inline void ValidateStorageColorView(vk::Format image_format, vk::Format view_fo
|
||||
IsSupportedStorageImageResource(const ShaderRecompiler::IR::ImageResource& resource) noexcept {
|
||||
return (resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImage ||
|
||||
resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint) &&
|
||||
(resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D ||
|
||||
(resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim1D ||
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim1DArray ||
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D ||
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D ||
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray) &&
|
||||
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.written &&
|
||||
|
||||
Reference in New Issue
Block a user