mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: support signed sampled images
This commit is contained in:
@@ -163,15 +163,32 @@ uint32_t ImageViewSpatialComponents(ImageViewKind view) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ImageViewImageType(EmitterState& state, ImageViewKind view, bool integer) {
|
||||
const auto component = integer ? TypeU32(state) : TypeF32(state);
|
||||
return state.builder.Type(OpTypeImage,
|
||||
{component, ImageSpirvDimension(view), 0, ImageSpirvArrayed(view),
|
||||
ImageSpirvMultisampled(view), 1, ImageFormatUnknown});
|
||||
uint32_t SampledImageScalarType(EmitterState& state, SampledImageClass image_class) {
|
||||
switch (image_class) {
|
||||
case SampledImageClass::Float: return TypeF32(state);
|
||||
case SampledImageClass::Uint: return TypeU32(state);
|
||||
case SampledImageClass::Sint: return TypeI32(state);
|
||||
case SampledImageClass::Count: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ImageViewSampledImageType(EmitterState& state, ImageViewKind view, bool integer) {
|
||||
return state.builder.Type(OpTypeSampledImage, {ImageViewImageType(state, view, integer)});
|
||||
uint32_t SampledImageVectorType(EmitterState& state, SampledImageClass image_class,
|
||||
uint32_t components) {
|
||||
return state.builder.Type(OpTypeVector,
|
||||
{SampledImageScalarType(state, image_class), components});
|
||||
}
|
||||
|
||||
uint32_t ImageViewImageType(EmitterState& state, ImageViewKind view,
|
||||
SampledImageClass image_class) {
|
||||
return state.builder.Type(OpTypeImage, {SampledImageScalarType(state, image_class),
|
||||
ImageSpirvDimension(view), 0, ImageSpirvArrayed(view),
|
||||
ImageSpirvMultisampled(view), 1, ImageFormatUnknown});
|
||||
}
|
||||
|
||||
uint32_t ImageViewSampledImageType(EmitterState& state, ImageViewKind view,
|
||||
SampledImageClass image_class) {
|
||||
return state.builder.Type(OpTypeSampledImage, {ImageViewImageType(state, view, image_class)});
|
||||
}
|
||||
|
||||
uint32_t ImageViewSizeType(EmitterState& state, ImageViewKind view) {
|
||||
@@ -218,17 +235,18 @@ uint32_t StorageImageVariable(const EmitterState& state, StorageImageClass image
|
||||
uint32_t LoadSampledImageDescriptor(EmitterState& state, const IR::MemoryInfo& mem, uint32_t use_pc,
|
||||
ImageViewKind view) {
|
||||
(void)use_pc;
|
||||
const bool integer = mem.kind == IR::ResourceKind::ImageUint;
|
||||
const auto kind = SampledBindingKind(integer, view);
|
||||
const auto image_class = SampledImageClassFor(mem.kind);
|
||||
const auto kind = SampledBindingKind(image_class, view);
|
||||
const auto binding = ResourceForDescriptor(state, kind, mem.resource);
|
||||
const auto variable = state.sampled_image_variables[SampledImageIndex(integer, view)];
|
||||
const auto variable = state.sampled_image_variables[SampledImageIndex(image_class, view)];
|
||||
const auto pointer_type = state.builder.Type(
|
||||
OpTypePointer, {StorageClassUniformConstant, ImageViewImageType(state, view, integer)});
|
||||
OpTypePointer, {StorageClassUniformConstant, ImageViewImageType(state, view, image_class)});
|
||||
const auto pointer =
|
||||
DescriptorElementPointer(state, pointer_type, variable, binding.array_index, kind,
|
||||
mem.resource, "sampled image descriptor array was not emitted");
|
||||
const auto image = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpLoad, ImageViewImageType(state, view, integer), image, pointer});
|
||||
state.builder.AddFunction(
|
||||
{OpLoad, ImageViewImageType(state, view, image_class), image, pointer});
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -252,13 +270,12 @@ uint32_t MakeSampledImage(EmitterState& state, const IR::MemoryInfo& mem, uint32
|
||||
const auto sampler = LoadSamplerDescriptor(state, mem.sampler, use_pc);
|
||||
if (image == 0 || sampler == 0) {
|
||||
ExitDescriptorBindingFailure(
|
||||
state, SampledBindingKind(mem.kind == IR::ResourceKind::ImageUint, view), mem.resource,
|
||||
state, SampledBindingKind(SampledImageClassFor(mem.kind), view), mem.resource,
|
||||
"sampled image or sampler descriptor load failed");
|
||||
}
|
||||
const auto sampled_image = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpSampledImage,
|
||||
ImageViewSampledImageType(state, view, mem.kind == IR::ResourceKind::ImageUint),
|
||||
{OpSampledImage, ImageViewSampledImageType(state, view, SampledImageClassFor(mem.kind)),
|
||||
sampled_image, image, sampler});
|
||||
return sampled_image;
|
||||
}
|
||||
|
||||
@@ -199,8 +199,27 @@ uint32_t FloatBits(ValueEmitContext& ctx, uint32_t value) {
|
||||
return Unary(ctx.state, OpBitcast, TypeU32(ctx.state), value);
|
||||
}
|
||||
|
||||
uint32_t ResultVector(ValueEmitContext& ctx, uint32_t value, bool integer, bool dref,
|
||||
const IR::MemoryInfo& mem, bool gather = false) {
|
||||
uint32_t SampledComponentBits(ValueEmitContext& ctx, uint32_t value,
|
||||
SampledImageClass image_class) {
|
||||
return image_class == SampledImageClass::Uint
|
||||
? value
|
||||
: Unary(ctx.state, OpBitcast, TypeU32(ctx.state), value);
|
||||
}
|
||||
|
||||
uint32_t SampledComponentZero(EmitterState& state, SampledImageClass image_class) {
|
||||
switch (image_class) {
|
||||
case SampledImageClass::Float: return ZeroF32(state);
|
||||
case SampledImageClass::Uint: return ConstantU32(state, 0);
|
||||
case SampledImageClass::Sint: return ConstantI32(state, 0);
|
||||
case SampledImageClass::Count: return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ResultVector(ValueEmitContext& ctx, uint32_t value, SampledImageClass image_class,
|
||||
bool dref, const IR::MemoryInfo& mem, bool gather = false) {
|
||||
const auto value_class = dref ? SampledImageClass::Float : image_class;
|
||||
const bool integer = IsIntegerSampledImage(value_class);
|
||||
if (mem.data_bits == 16u) {
|
||||
uint32_t packed[4] = {ConstantU32(ctx.state, 0), ConstantU32(ctx.state, 0),
|
||||
ConstantU32(ctx.state, 0), ConstantU32(ctx.state, 0)};
|
||||
@@ -209,25 +228,27 @@ uint32_t ResultVector(ValueEmitContext& ctx, uint32_t value, bool integer, bool
|
||||
const auto component = gather ? index : DmaskComponent(mem.dmask, index);
|
||||
const auto result = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction({OpCompositeExtract,
|
||||
integer ? TypeU32(ctx.state) : TypeF32(ctx.state),
|
||||
result, value, component});
|
||||
SampledImageScalarType(ctx.state, value_class), result,
|
||||
value, component});
|
||||
return result;
|
||||
};
|
||||
for (uint32_t word = 0; word < mem.data_dwords; word++) {
|
||||
const auto low_index = word * 2u;
|
||||
const auto high_index = low_index + 1u;
|
||||
const auto low = scalar(low_index);
|
||||
const auto high = high_index < mem.component_count
|
||||
? scalar(high_index)
|
||||
: (integer ? ConstantU32(ctx.state, 0) : ZeroF32(ctx.state));
|
||||
const auto high = high_index < mem.component_count
|
||||
? scalar(high_index)
|
||||
: SampledComponentZero(ctx.state, value_class);
|
||||
if (integer) {
|
||||
const auto mask = ConstantU32(ctx.state, 0xffffu);
|
||||
packed[word] =
|
||||
Binary(ctx.state, OpBitwiseOr, TypeU32(ctx.state),
|
||||
Binary(ctx.state, OpBitwiseAnd, TypeU32(ctx.state), low, mask),
|
||||
Binary(ctx.state, OpShiftLeftLogical, TypeU32(ctx.state),
|
||||
Binary(ctx.state, OpBitwiseAnd, TypeU32(ctx.state), high, mask),
|
||||
ConstantU32(ctx.state, 16u)));
|
||||
const auto low_bits = SampledComponentBits(ctx, low, value_class);
|
||||
const auto high_bits = SampledComponentBits(ctx, high, value_class);
|
||||
const auto mask = ConstantU32(ctx.state, 0xffffu);
|
||||
packed[word] = Binary(
|
||||
ctx.state, OpBitwiseOr, TypeU32(ctx.state),
|
||||
Binary(ctx.state, OpBitwiseAnd, TypeU32(ctx.state), low_bits, mask),
|
||||
Binary(ctx.state, OpShiftLeftLogical, TypeU32(ctx.state),
|
||||
Binary(ctx.state, OpBitwiseAnd, TypeU32(ctx.state), high_bits, mask),
|
||||
ConstantU32(ctx.state, 16u)));
|
||||
} else {
|
||||
const auto pair = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction(
|
||||
@@ -250,9 +271,9 @@ uint32_t ResultVector(ValueEmitContext& ctx, uint32_t value, bool integer, bool
|
||||
}
|
||||
const auto scalar = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction({OpCompositeExtract,
|
||||
integer ? TypeU32(ctx.state) : TypeF32(ctx.state), scalar,
|
||||
SampledImageScalarType(ctx.state, value_class), scalar,
|
||||
value, index});
|
||||
component[index] = integer ? scalar : FloatBits(ctx, scalar);
|
||||
component[index] = SampledComponentBits(ctx, scalar, value_class);
|
||||
}
|
||||
const auto result = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction({OpCompositeConstruct, TypeU32Vector(ctx.state, 4), result,
|
||||
@@ -363,8 +384,7 @@ Format::BufferFormatInfo ImageConversionFormat(const EmitterState& state,
|
||||
const auto format = state.program.info.images[mem.resource].conversion_format;
|
||||
if (format == Prospero::BufferFormat::kInvalid) return {};
|
||||
const auto info = Format::GetFormatInfo(format);
|
||||
EXIT_IF(!Prospero::IsSampledTextureFormat(format) ||
|
||||
!Prospero::IsUintTextureFormat(format) ||
|
||||
EXIT_IF(Prospero::SampledTextureNumericClass(format) != Prospero::TextureNumericClass::Uint ||
|
||||
Prospero::RemapTextureFormat(format) == format ||
|
||||
info.type != Format::ComponentType::Uint || !info.packed_bitfield ||
|
||||
info.byte_size != sizeof(uint32_t) || info.component_count == 0u ||
|
||||
@@ -440,7 +460,7 @@ uint32_t UnpackImageGather(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uin
|
||||
}
|
||||
|
||||
uint32_t EmitOneDimensionalGatherLz(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint32_t pc,
|
||||
uint32_t coord, bool integer) {
|
||||
uint32_t coord, SampledImageClass image_class) {
|
||||
auto& state = ctx.state;
|
||||
state.builder.RequireCapability(CapabilityImageQuery);
|
||||
const auto image = LoadSampledImageDescriptor(state, mem, pc, ImageViewKind::Dim1D);
|
||||
@@ -457,8 +477,8 @@ uint32_t EmitOneDimensionalGatherLz(ValueEmitContext& ctx, const IR::MemoryInfo&
|
||||
ConstantF32(state, 0x3f000000u))});
|
||||
|
||||
const auto sampled = MakeSampledImage(state, mem, pc, ImageViewKind::Dim1D);
|
||||
const auto vector_type = integer ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4);
|
||||
const auto scalar_type = integer ? TypeU32(state) : TypeF32(state);
|
||||
const auto vector_type = SampledImageVectorType(state, image_class, 4);
|
||||
const auto scalar_type = SampledImageScalarType(state, image_class);
|
||||
const auto component = ImageConversionFormat(state, mem).format == Prospero::BufferFormat::kInvalid
|
||||
? ImageGatherComponent(mem.dmask)
|
||||
: 0u;
|
||||
@@ -601,9 +621,9 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
return true;
|
||||
}
|
||||
if (op == IR::ValueOpcode::ImageRead) {
|
||||
const auto view = SampledImageViewKind(state, mem, pc);
|
||||
const bool integer = mem.kind == IR::ResourceKind::ImageUint;
|
||||
const auto condition = ctx.Arg(inst, 2);
|
||||
const auto view = SampledImageViewKind(state, mem, pc);
|
||||
const auto image_class = SampledImageClassFor(mem.kind);
|
||||
const auto condition = ctx.Arg(inst, 2);
|
||||
ctx.Define(
|
||||
inst,
|
||||
EmitValueOrDefaultIfCondition(
|
||||
@@ -614,17 +634,15 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
const auto coord = CoordU32(ctx, mem, *address, view);
|
||||
if (ImageSpirvMultisampled(view) != 0u) {
|
||||
state.builder.AddFunction(
|
||||
{OpImageFetch,
|
||||
integer ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4), color,
|
||||
{OpImageFetch, SampledImageVectorType(state, image_class, 4), color,
|
||||
image, coord, ImageOperandsSampleMask,
|
||||
AddressU32(ctx, mem, *address, ImageViewCoordinateComponents(view))});
|
||||
} else {
|
||||
state.builder.AddFunction(
|
||||
{OpImageFetch,
|
||||
integer ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4), color,
|
||||
{OpImageFetch, SampledImageVectorType(state, image_class, 4), color,
|
||||
image, coord, ImageOperandsLodMask, LodU32(ctx, mem, *address, view)});
|
||||
}
|
||||
return ResultVector(ctx, UnpackImageTexel(ctx, mem, color), integer, false,
|
||||
return ResultVector(ctx, UnpackImageTexel(ctx, mem, color), image_class, false,
|
||||
mem);
|
||||
}));
|
||||
return true;
|
||||
@@ -644,10 +662,10 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
return true;
|
||||
}
|
||||
if (op == IR::ValueOpcode::ImageSampleRaw || op == IR::ValueOpcode::ImageGatherRaw) {
|
||||
const auto view = SampledImageViewKind(state, mem, pc);
|
||||
const auto layout = Layout(mem, view);
|
||||
const bool integer = mem.kind == IR::ResourceKind::ImageUint;
|
||||
const bool dref = HasFlag(mem, Decoder::ImageSampleFlagCompare);
|
||||
const auto view = SampledImageViewKind(state, mem, pc);
|
||||
const auto layout = Layout(mem, view);
|
||||
const auto image_class = SampledImageClassFor(mem.kind);
|
||||
const bool dref = HasFlag(mem, Decoder::ImageSampleFlagCompare);
|
||||
if (dref && state.program.info.images[mem.resource].conversion_format !=
|
||||
Prospero::BufferFormat::kInvalid) {
|
||||
ctx.Fail(inst, "uses depth comparison with a packed integer image");
|
||||
@@ -663,8 +681,8 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
ctx.Fail(inst, "has an unsupported 1D gather variant");
|
||||
return true;
|
||||
}
|
||||
const auto sample = EmitOneDimensionalGatherLz(ctx, mem, pc, coord, integer);
|
||||
ctx.Define(inst, ResultVector(ctx, UnpackImageGather(ctx, mem, sample), integer,
|
||||
const auto sample = EmitOneDimensionalGatherLz(ctx, mem, pc, coord, image_class);
|
||||
ctx.Define(inst, ResultVector(ctx, UnpackImageGather(ctx, mem, sample), image_class,
|
||||
false, mem, true));
|
||||
return true;
|
||||
}
|
||||
@@ -685,7 +703,7 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
: ZeroF32(state)}
|
||||
: std::vector<uint32_t> {
|
||||
OpImageGather,
|
||||
integer ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4),
|
||||
SampledImageVectorType(state, image_class, 4),
|
||||
sample,
|
||||
sampled,
|
||||
coord,
|
||||
@@ -702,7 +720,8 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
}
|
||||
state.builder.AddFunction(words);
|
||||
ctx.Define(inst, ResultVector(ctx, UnpackImageGather(ctx, mem, sample),
|
||||
integer && !dref, false, mem, true));
|
||||
dref ? SampledImageClass::Float : image_class, false, mem,
|
||||
true));
|
||||
return true;
|
||||
}
|
||||
const bool explicit_lod = HasFlag(mem, Decoder::ImageSampleFlagDerivative) ||
|
||||
@@ -713,7 +732,7 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
? (dref ? OpImageSampleDrefExplicitLod : OpImageSampleExplicitLod)
|
||||
: (dref ? OpImageSampleDrefImplicitLod : OpImageSampleImplicitLod);
|
||||
const auto result_type =
|
||||
dref ? TypeF32(state) : (integer ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4));
|
||||
dref ? TypeF32(state) : SampledImageVectorType(state, image_class, 4);
|
||||
const auto dref_value =
|
||||
dref ? (layout.dref != NoImageComponent ? AddressF32(ctx, mem, *address, layout.dref)
|
||||
: ZeroF32(state))
|
||||
@@ -754,7 +773,7 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
if (image.indirect_root != mem.resource) {
|
||||
const auto sample = EmitSample(mem.resource);
|
||||
ctx.Define(inst, ResultVector(ctx, dref ? sample : UnpackImageTexel(ctx, mem, sample),
|
||||
integer, dref, mem));
|
||||
image_class, dref, mem));
|
||||
return true;
|
||||
}
|
||||
const auto* handle = image_arg.ResolveInstruction();
|
||||
@@ -847,7 +866,7 @@ bool EmitValueImage(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
state.builder.AddFunction(phi_words);
|
||||
ctx.Define(inst,
|
||||
ResultVector(ctx, dref ? phi_words[2] : UnpackImageTexel(ctx, mem, phi_words[2]),
|
||||
integer, dref, mem));
|
||||
image_class, dref, mem));
|
||||
return true;
|
||||
}
|
||||
const auto atomic_opcode = ImageAtomicOpcode(op);
|
||||
|
||||
@@ -337,6 +337,8 @@ enum class ImageViewKind {
|
||||
constexpr uint32_t SampledImageViewKindCount = static_cast<uint32_t>(ImageViewKind::Count);
|
||||
constexpr uint32_t StorageImageViewKindCount = static_cast<uint32_t>(ImageViewKind::Dim2DMsaa);
|
||||
|
||||
enum class SampledImageClass : uint32_t { Float, Uint, Sint, Count };
|
||||
|
||||
enum class StorageImageClass : uint32_t {
|
||||
FormatlessFloat,
|
||||
FormatlessUint,
|
||||
@@ -369,7 +371,9 @@ struct EmitterState {
|
||||
uint32_t flattened_srt_variable = 0;
|
||||
uint32_t lds_variable = 0;
|
||||
uint32_t scratch_variable = 0;
|
||||
std::array<uint32_t, 2u * SampledImageViewKindCount> sampled_image_variables {};
|
||||
std::array<uint32_t,
|
||||
static_cast<uint32_t>(SampledImageClass::Count) * SampledImageViewKindCount>
|
||||
sampled_image_variables {};
|
||||
std::array<uint32_t,
|
||||
static_cast<uint32_t>(StorageImageClass::Count) * StorageImageViewKindCount>
|
||||
storage_image_variables {};
|
||||
@@ -471,8 +475,22 @@ struct ImageSampleLayout {
|
||||
uint32_t grad_y = NoImageComponent;
|
||||
};
|
||||
|
||||
constexpr uint32_t SampledImageIndex(bool integer, ImageViewKind view) {
|
||||
return static_cast<uint32_t>(view) + (integer ? SampledImageViewKindCount : 0u);
|
||||
constexpr SampledImageClass SampledImageClassFor(IR::ResourceKind kind) {
|
||||
switch (kind) {
|
||||
case IR::ResourceKind::Image: return SampledImageClass::Float;
|
||||
case IR::ResourceKind::ImageUint: return SampledImageClass::Uint;
|
||||
case IR::ResourceKind::ImageSint: return SampledImageClass::Sint;
|
||||
default: return SampledImageClass::Count;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool IsIntegerSampledImage(SampledImageClass image_class) {
|
||||
return image_class == SampledImageClass::Uint || image_class == SampledImageClass::Sint;
|
||||
}
|
||||
|
||||
constexpr uint32_t SampledImageIndex(SampledImageClass image_class, ImageViewKind view) {
|
||||
return static_cast<uint32_t>(view) +
|
||||
static_cast<uint32_t>(image_class) * SampledImageViewKindCount;
|
||||
}
|
||||
|
||||
constexpr StorageImageClass StorageImageClassFor(bool uint_image, bool atomic) {
|
||||
@@ -490,8 +508,9 @@ constexpr uint32_t StorageImageIndex(StorageImageClass image_class, ImageViewKin
|
||||
static_cast<uint32_t>(image_class) * StorageImageViewKindCount;
|
||||
}
|
||||
|
||||
constexpr IR::DescriptorBindingKind SampledBindingKind(bool integer, ImageViewKind view) {
|
||||
if (integer) {
|
||||
constexpr IR::DescriptorBindingKind SampledBindingKind(SampledImageClass image_class,
|
||||
ImageViewKind view) {
|
||||
if (image_class == SampledImageClass::Uint) {
|
||||
switch (view) {
|
||||
case ImageViewKind::Dim1D: return IR::DescriptorBindingKind::SampledUint1D;
|
||||
case ImageViewKind::Dim1DArray: return IR::DescriptorBindingKind::SampledUint1DArray;
|
||||
@@ -504,6 +523,19 @@ constexpr IR::DescriptorBindingKind SampledBindingKind(bool integer, ImageViewKi
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (image_class == SampledImageClass::Sint) {
|
||||
switch (view) {
|
||||
case ImageViewKind::Dim1D: return IR::DescriptorBindingKind::SampledSint1D;
|
||||
case ImageViewKind::Dim1DArray: return IR::DescriptorBindingKind::SampledSint1DArray;
|
||||
case ImageViewKind::Dim2D: return IR::DescriptorBindingKind::SampledSint2D;
|
||||
case ImageViewKind::Dim2DArray: return IR::DescriptorBindingKind::SampledSint2DArray;
|
||||
case ImageViewKind::Dim3D: return IR::DescriptorBindingKind::SampledSint3D;
|
||||
case ImageViewKind::Dim2DMsaa: return IR::DescriptorBindingKind::SampledSint2DMsaa;
|
||||
case ImageViewKind::Dim2DMsaaArray:
|
||||
return IR::DescriptorBindingKind::SampledSint2DMsaaArray;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
switch (view) {
|
||||
case ImageViewKind::Dim1D: return IR::DescriptorBindingKind::Sampled1D;
|
||||
case ImageViewKind::Dim1DArray: return IR::DescriptorBindingKind::Sampled1DArray;
|
||||
@@ -641,9 +673,15 @@ uint32_t ImageViewCoordinateComponents(ImageViewKind view);
|
||||
|
||||
uint32_t ImageViewSpatialComponents(ImageViewKind view);
|
||||
|
||||
uint32_t ImageViewImageType(EmitterState& state, ImageViewKind view, bool integer);
|
||||
uint32_t SampledImageScalarType(EmitterState& state, SampledImageClass image_class);
|
||||
|
||||
uint32_t ImageViewSampledImageType(EmitterState& state, ImageViewKind view, bool integer);
|
||||
uint32_t SampledImageVectorType(EmitterState& state, SampledImageClass image_class,
|
||||
uint32_t components);
|
||||
|
||||
uint32_t ImageViewImageType(EmitterState& state, ImageViewKind view, SampledImageClass image_class);
|
||||
|
||||
uint32_t ImageViewSampledImageType(EmitterState& state, ImageViewKind view,
|
||||
SampledImageClass image_class);
|
||||
|
||||
uint32_t ImageViewSizeType(EmitterState& state, ImageViewKind view);
|
||||
|
||||
|
||||
@@ -188,14 +188,14 @@ void DefineDescriptorVariables(EmitterState& state) {
|
||||
TypeStorageBufferPointer(state), StorageClassStorageBuffer);
|
||||
}
|
||||
for (uint32_t i = 0; i < state.sampled_image_variables.size(); i++) {
|
||||
const auto view = static_cast<ImageViewKind>(i % SampledImageViewKindCount);
|
||||
const bool integer = i >= SampledImageViewKindCount;
|
||||
const auto kind = SampledBindingKind(integer, view);
|
||||
const auto view = static_cast<ImageViewKind>(i % SampledImageViewKindCount);
|
||||
const auto image_class = static_cast<SampledImageClass>(i / SampledImageViewKindCount);
|
||||
const auto kind = SampledBindingKind(image_class, view);
|
||||
if (DescriptorBinding(state, kind) == nullptr) {
|
||||
continue;
|
||||
}
|
||||
const auto count = ConstantU32(state, DescriptorCount(state, kind));
|
||||
const auto image_type = ImageViewImageType(state, view, integer);
|
||||
const auto image_type = ImageViewImageType(state, view, image_class);
|
||||
const auto array_type = state.builder.Type(OpTypeArray, {image_type, count});
|
||||
const auto pointer_type = TypePointer(state, StorageClassUniformConstant, array_type);
|
||||
state.sampled_image_variables[i] =
|
||||
@@ -607,11 +607,19 @@ void AddDescriptorAnnotationsAndNames(EmitterState& state) {
|
||||
"sampled_uint_2d_array",
|
||||
"sampled_uint_3d",
|
||||
"sampled_uint_2d_msaa",
|
||||
"sampled_uint_2d_msaa_array"};
|
||||
"sampled_uint_2d_msaa_array",
|
||||
"sampled_sint_1d",
|
||||
"sampled_sint_1d_array",
|
||||
"sampled_sint_2d",
|
||||
"sampled_sint_2d_array",
|
||||
"sampled_sint_3d",
|
||||
"sampled_sint_2d_msaa",
|
||||
"sampled_sint_2d_msaa_array"};
|
||||
for (uint32_t i = 0; i < state.sampled_image_variables.size(); i++) {
|
||||
const auto view = static_cast<ImageViewKind>(i % SampledImageViewKindCount);
|
||||
const auto image_class = static_cast<SampledImageClass>(i / SampledImageViewKindCount);
|
||||
Decorate(state.sampled_image_variables[i], SampledNames[i],
|
||||
SampledBindingKind(i >= SampledImageViewKindCount, view));
|
||||
SampledBindingKind(image_class, view));
|
||||
}
|
||||
constexpr const char* StorageNames[] = {"storage_1d",
|
||||
"storage_1d_array",
|
||||
|
||||
Reference in New Issue
Block a user