mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
graphics: share signed storage conversion and support R16 image writes
Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
@@ -385,9 +385,10 @@ Format::BufferFormatInfo ImageConversionFormat(const EmitterState& state,
|
||||
const auto format = image.conversion_format;
|
||||
if (format == Prospero::BufferFormat::kInvalid) return {};
|
||||
const auto info = Format::GetFormatInfo(format);
|
||||
EXIT_IF(Prospero::RemapTextureFormat(format) == format || info.component_count == 0u ||
|
||||
const bool raw_signed = IR::RawSignedStorageFormat(image, format) != Prospero::BufferFormat::kInvalid;
|
||||
EXIT_IF((Prospero::RemapTextureFormat(format) == format && !raw_signed) || info.component_count == 0u ||
|
||||
info.component_count > 4u);
|
||||
EXIT_IF(info.type != Format::ComponentType::Uscaled &&
|
||||
EXIT_IF(!raw_signed && info.type != Format::ComponentType::Uscaled &&
|
||||
((info.type != Format::ComponentType::Uint &&
|
||||
info.type != Format::ComponentType::Unorm) || !info.packed_bitfield ||
|
||||
info.byte_size != sizeof(uint32_t)));
|
||||
@@ -610,15 +611,16 @@ uint32_t EmitOneDimensionalGatherLz(ValueEmitContext& ctx, const IR::MemoryInfo&
|
||||
uint32_t StoreTexel(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint32_t data, bool integer) {
|
||||
const auto swizzle = ctx.state.program.info.images[mem.resource].shader_swizzle;
|
||||
const auto info = ImageConversionFormat(ctx.state, mem);
|
||||
const bool packed = info.format != Prospero::BufferFormat::kInvalid;
|
||||
EXIT_IF(packed && (!info.packed_bitfield ||
|
||||
(info.type != Format::ComponentType::Uint &&
|
||||
info.type != Format::ComponentType::Unorm)));
|
||||
const bool converted = info.format != Prospero::BufferFormat::kInvalid;
|
||||
const bool packed = info.packed_bitfield;
|
||||
EXIT_IF(converted && info.type != Format::ComponentType::Sint &&
|
||||
(!packed || (info.type != Format::ComponentType::Uint &&
|
||||
info.type != Format::ComponentType::Unorm)));
|
||||
const auto zero = ConstantU32(ctx.state, 0);
|
||||
uint32_t values[4] {zero, zero, zero, zero};
|
||||
auto packed_value = zero;
|
||||
const auto dmask = mem.dmask != 0u ? mem.dmask : 1u;
|
||||
for (uint32_t component = 0; component < (packed ? info.component_count : 4u); component++) {
|
||||
for (uint32_t component = 0; component < (converted ? info.component_count : 4u); component++) {
|
||||
const auto source = InverseSwizzle(swizzle, component);
|
||||
const bool selected = source < 4u && ((dmask >> source) & 1u) != 0u;
|
||||
uint32_t raw = zero;
|
||||
@@ -638,9 +640,13 @@ uint32_t StoreTexel(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint32_t d
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packed) {
|
||||
if (converted) {
|
||||
if (!selected) continue;
|
||||
auto value = EncodeFormattedStoreComponent(ctx.state, info, component, raw, mem.data_bits);
|
||||
if (!packed) {
|
||||
values[component] = value;
|
||||
continue;
|
||||
}
|
||||
if (info.type == Format::ComponentType::Uint) {
|
||||
value = EmitUMin32(ctx.state, value,
|
||||
ConstantU32(ctx.state, (1u << info.component_bits[component]) - 1u));
|
||||
|
||||
@@ -435,6 +435,13 @@ uint32_t EncodeFormattedStoreComponent(EmitterState& state, const Format::Buffer
|
||||
data = EmitBitCastU32F32(state, EmitF16BitsToF32(state, data));
|
||||
}
|
||||
}
|
||||
if (info.type == Format::ComponentType::Sint && bits < 32u) {
|
||||
const auto maximum = (1u << (bits - 1u)) - 1u;
|
||||
data = EmitSMax32(state, data, ConstantU32(state, ~maximum));
|
||||
data = EmitSMin32(state, data, ConstantU32(state, maximum));
|
||||
return Binary(state, spv::OpBitwiseAnd, TypeU32(state), data,
|
||||
ConstantU32(state, (1u << bits) - 1u));
|
||||
}
|
||||
const bool normalized = info.type == Format::ComponentType::Unorm ||
|
||||
info.type == Format::ComponentType::Snorm;
|
||||
const bool scaled = info.type == Format::ComponentType::Uscaled ||
|
||||
|
||||
@@ -169,6 +169,17 @@ struct ImageResource {
|
||||
bool operator==(const ImageResource& other) const = default;
|
||||
};
|
||||
|
||||
[[nodiscard]] constexpr Prospero::BufferFormat
|
||||
RawSignedStorageFormat(const ImageResource& image, Prospero::BufferFormat format) {
|
||||
if (image.resource_class != ImageResourceClass::Storage || !image.written)
|
||||
return Prospero::BufferFormat::kInvalid;
|
||||
if (format == Prospero::BufferFormat::k32SInt && (image.atomic ? !image.atomic64 : !image.read))
|
||||
return Prospero::BufferFormat::k32UInt;
|
||||
if (format == Prospero::BufferFormat::k16SInt && !image.read && !image.atomic)
|
||||
return Prospero::BufferFormat::k16UInt;
|
||||
return Prospero::BufferFormat::kInvalid;
|
||||
}
|
||||
|
||||
struct SamplerResource {
|
||||
uint32_t source = 0;
|
||||
uint32_t first_use_pc = 0;
|
||||
|
||||
@@ -755,8 +755,9 @@ static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSna
|
||||
if (storage || image.conversion_format != Prospero::BufferFormat::kInvalid) {
|
||||
image.shader_swizzle = DescriptorImageSwizzle(descriptor);
|
||||
}
|
||||
const bool raw_sint_storage = storage && format == Prospero::BufferFormat::k32SInt &&
|
||||
base.written && (base.atomic ? !base.atomic64 : !base.read);
|
||||
const auto raw_sint_format = RawSignedStorageFormat(base, format);
|
||||
const bool raw_sint_storage = raw_sint_format != Prospero::BufferFormat::kInvalid;
|
||||
if (raw_sint_format == Prospero::BufferFormat::k16UInt) image.conversion_format = format;
|
||||
image.numeric_class = Prospero::SampledTextureNumericClass(
|
||||
Prospero::RemapTextureFormat(format));
|
||||
if (!storage && format == Prospero::BufferFormat::k11_11_10UNorm) {
|
||||
|
||||
Reference in New Issue
Block a user