shader: separate formatless storage from image atomics

Co-authored-by: shadowbeat070 <70843316+shadowbeat070@users.noreply.github.com>
Co-authored-by: Senaxx <Senaxx@users.noreply.github.com>
This commit is contained in:
nmzik
2026-08-21 01:39:22 +02:00
parent 719e20d470
commit 770bdb9571
11 changed files with 345 additions and 172 deletions
+33 -5
View File
@@ -325,6 +325,11 @@ enum class DescriptorBindingKind {
StorageUint2D,
StorageUint2DArray,
StorageUint3D,
StorageAtomic1D,
StorageAtomic1DArray,
StorageAtomic2D,
StorageAtomic2DArray,
StorageAtomic3D,
Samplers,
Gds,
AddressMemory,
@@ -362,6 +367,9 @@ DescriptorBindingForImage(const ImageResource& image) {
default: return std::nullopt;
}
case ResourceKind::StorageImage:
if (image.atomic) {
return std::nullopt;
}
switch (image.dimension) {
case Dimension::Dim1D: return Kind::Storage1D;
case Dimension::Dim1DArray: return Kind::Storage1DArray;
@@ -372,11 +380,31 @@ DescriptorBindingForImage(const ImageResource& image) {
}
case ResourceKind::StorageImageUint:
switch (image.dimension) {
case Dimension::Dim1D: return Kind::StorageUint1D;
case Dimension::Dim1DArray: return Kind::StorageUint1DArray;
case Dimension::Dim2D: return Kind::StorageUint2D;
case Dimension::Dim2DArray: return Kind::StorageUint2DArray;
case Dimension::Dim3D: return Kind::StorageUint3D;
case Dimension::Dim1D:
if (image.atomic) {
return Kind::StorageAtomic1D;
}
return Kind::StorageUint1D;
case Dimension::Dim1DArray:
if (image.atomic) {
return Kind::StorageAtomic1DArray;
}
return Kind::StorageUint1DArray;
case Dimension::Dim2D:
if (image.atomic) {
return Kind::StorageAtomic2D;
}
return Kind::StorageUint2D;
case Dimension::Dim2DArray:
if (image.atomic) {
return Kind::StorageAtomic2DArray;
}
return Kind::StorageUint2DArray;
case Dimension::Dim3D:
if (image.atomic) {
return Kind::StorageAtomic3D;
}
return Kind::StorageUint3D;
default: return std::nullopt;
}
default: return std::nullopt;
@@ -37,6 +37,11 @@ constexpr std::array ImageBindingKinds = {
DescriptorBindingKind::StorageUint2D,
DescriptorBindingKind::StorageUint2DArray,
DescriptorBindingKind::StorageUint3D,
DescriptorBindingKind::StorageAtomic1D,
DescriptorBindingKind::StorageAtomic1DArray,
DescriptorBindingKind::StorageAtomic2D,
DescriptorBindingKind::StorageAtomic2DArray,
DescriptorBindingKind::StorageAtomic3D,
};
bool CollectUserData(const Program& program, std::vector<uint32_t>& result) {
@@ -81,10 +81,15 @@ uint32_t ByteExtent(const MemoryInfo& memory) {
return end > UINT32_MAX ? UINT32_MAX : static_cast<uint32_t>(end);
}
bool IsStorageImage(ResourceKind kind) {
return kind == ResourceKind::StorageImage || kind == ResourceKind::StorageImageUint;
}
ImageMipMode MipMode(const MemoryInfo& memory) {
const bool storage =
memory.kind == ResourceKind::StorageImage || memory.kind == ResourceKind::StorageImageUint;
return storage && memory.image_has_mip ? ImageMipMode::DynamicStorage : ImageMipMode::None;
if (IsStorageImage(memory.kind) && memory.image_has_mip) {
return ImageMipMode::DynamicStorage;
}
return ImageMipMode::None;
}
class Tracker {
@@ -650,9 +655,14 @@ private:
const bool depth = (memory.image_sample_flags & Decoder::ImageSampleFlagCompare) != 0;
for (uint32_t i = 0; i < m_info.images.size(); i++) {
auto& image = m_info.images[i];
if (image.source == source && image.kind == memory.kind &&
const bool compatible_kind = image.kind == memory.kind || (IsStorageImage(image.kind) &&
IsStorageImage(memory.kind));
if (image.source == source && compatible_kind &&
image.dimension == memory.image_dimension && image.mip_mode == mip &&
image.depth_compare == depth && image.r128 == memory.image_r128) {
if (memory.kind == ResourceKind::StorageImageUint) {
image.kind = ResourceKind::StorageImageUint;
}
Merge(image, op, pc);
return i;
}