mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 03:18:55 +02:00
[vulkan] Replaced old logic for DescriptorType for a numeric handling per type to avoid mismatches during format binding
This commit is contained in:
parent
d0e42e36f0
commit
2d9673bc95
6 changed files with 112 additions and 41 deletions
|
|
@ -14,6 +14,25 @@
|
|||
|
||||
namespace Shader::Backend::SPIRV {
|
||||
namespace {
|
||||
Id GetResultType(EmitContext& ctx, NumericType numeric_type) {
|
||||
switch (numeric_type) {
|
||||
case NumericType::Float:
|
||||
return ctx.F32[4];
|
||||
case NumericType::SignedInt:
|
||||
return ctx.S32[4];
|
||||
case NumericType::UnsignedInt:
|
||||
return ctx.U32[4];
|
||||
}
|
||||
throw LogicError("Invalid numeric type {}", static_cast<u32>(numeric_type));
|
||||
}
|
||||
|
||||
NumericType GetTextureNumericType(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||
if (info.type == TextureType::Buffer) {
|
||||
return ctx.texture_buffers.at(info.descriptor_index).numeric_type;
|
||||
}
|
||||
return ctx.textures.at(info.descriptor_index).numeric_type;
|
||||
}
|
||||
|
||||
class ImageOperands {
|
||||
public:
|
||||
[[maybe_unused]] static constexpr bool ImageSampleOffsetAllowed = false;
|
||||
|
|
@ -201,10 +220,10 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
|
|||
const TextureBufferDefinition& def{ctx.texture_buffers.at(info.descriptor_index)};
|
||||
if (def.count > 1) {
|
||||
const Id idx{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)};
|
||||
const Id ptr{ctx.OpAccessChain(ctx.image_buffer_type, def.id, idx)};
|
||||
return ctx.OpLoad(ctx.image_buffer_type, ptr);
|
||||
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx)};
|
||||
return ctx.OpLoad(def.image_type, ptr);
|
||||
}
|
||||
return ctx.OpLoad(ctx.image_buffer_type, def.id);
|
||||
return ctx.OpLoad(def.image_type, def.id);
|
||||
} else {
|
||||
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
|
||||
if (def.count > 1) {
|
||||
|
|
@ -216,23 +235,24 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
|
|||
}
|
||||
}
|
||||
|
||||
std::pair<Id, bool> Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
|
||||
std::pair<Id, NumericType> Image(EmitContext& ctx, const IR::Value& index,
|
||||
IR::TextureInstInfo info) {
|
||||
if (info.type == TextureType::Buffer) {
|
||||
const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)};
|
||||
if (def.count > 1) {
|
||||
const Id idx{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)};
|
||||
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx)};
|
||||
return {ctx.OpLoad(def.image_type, ptr), def.is_integer};
|
||||
return {ctx.OpLoad(def.image_type, ptr), def.numeric_type};
|
||||
}
|
||||
return {ctx.OpLoad(def.image_type, def.id), def.is_integer};
|
||||
return {ctx.OpLoad(def.image_type, def.id), def.numeric_type};
|
||||
} else {
|
||||
const ImageDefinition def{ctx.images.at(info.descriptor_index)};
|
||||
if (def.count > 1) {
|
||||
const Id idx{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)};
|
||||
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx)};
|
||||
return {ctx.OpLoad(def.image_type, ptr), def.is_integer};
|
||||
return {ctx.OpLoad(def.image_type, ptr), def.numeric_type};
|
||||
}
|
||||
return {ctx.OpLoad(def.image_type, def.id), def.is_integer};
|
||||
return {ctx.OpLoad(def.image_type, def.id), def.numeric_type};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,8 +481,9 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
|
|||
if (ctx.stage == Stage::Fragment) {
|
||||
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0,
|
||||
bias_lc, offset);
|
||||
const Id result_type{GetResultType(ctx, GetTextureNumericType(ctx, info))};
|
||||
return Emit(&EmitContext::OpImageSparseSampleImplicitLod,
|
||||
&EmitContext::OpImageSampleImplicitLod, ctx, inst, ctx.F32[4],
|
||||
&EmitContext::OpImageSampleImplicitLod, ctx, inst, result_type,
|
||||
Texture(ctx, info, index), coords, operands.MaskOptional(), operands.Span());
|
||||
} else {
|
||||
// We can't use implicit lods on non-fragment stages on SPIR-V. Maxwell hardware behaves as
|
||||
|
|
@ -470,8 +491,9 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
|
|||
// derivatives
|
||||
const Id lod{ctx.Const(0.0f)};
|
||||
const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod, offset);
|
||||
const Id result_type{GetResultType(ctx, GetTextureNumericType(ctx, info))};
|
||||
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, result_type,
|
||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
||||
}
|
||||
}
|
||||
|
|
@ -480,12 +502,14 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
|
|||
Id lod, const IR::Value& offset) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const ImageOperands operands(ctx, false, true, false, lod, offset);
|
||||
const NumericType numeric_type{GetTextureNumericType(ctx, info)};
|
||||
const Id result_type{GetResultType(ctx, numeric_type)};
|
||||
|
||||
Id result = Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, result_type,
|
||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
||||
#ifdef ANDROID
|
||||
if (Settings::values.fix_bloom_effects.GetValue()) {
|
||||
if (numeric_type == NumericType::Float && Settings::values.fix_bloom_effects.GetValue()) {
|
||||
result = ctx.OpVectorTimesScalar(ctx.F32[4], result, ctx.Const(0.98f));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -529,8 +553,9 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id
|
|||
if (ctx.profile.need_gather_subpixel_offset) {
|
||||
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
|
||||
}
|
||||
const Id result_type{GetResultType(ctx, GetTextureNumericType(ctx, info))};
|
||||
return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst,
|
||||
ctx.F32[4], Texture(ctx, info, index), coords, ctx.Const(info.gather_component),
|
||||
result_type, Texture(ctx, info, index), coords, ctx.Const(info.gather_component),
|
||||
operands.MaskOptional(), operands.Span());
|
||||
}
|
||||
|
||||
|
|
@ -558,8 +583,10 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c
|
|||
lod = Id{};
|
||||
}
|
||||
const ImageOperands operands(lod, ms);
|
||||
return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4],
|
||||
TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span());
|
||||
const Id result_type{GetResultType(ctx, GetTextureNumericType(ctx, info))};
|
||||
return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst,
|
||||
result_type, TextureImage(ctx, info, index), coords, operands.MaskOptional(),
|
||||
operands.Span());
|
||||
}
|
||||
|
||||
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
|
||||
|
|
@ -609,8 +636,9 @@ Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
|
|||
ctx.Def(offset), {}, lod_clamp)
|
||||
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
|
||||
info.num_derivatives, offset, lod_clamp);
|
||||
const Id result_type{GetResultType(ctx, GetTextureNumericType(ctx, info))};
|
||||
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, result_type,
|
||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
||||
}
|
||||
|
||||
|
|
@ -620,11 +648,11 @@ Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id co
|
|||
LOG_WARNING(Shader_SPIRV, "Typeless image read not supported by host");
|
||||
return ctx.ConstantNull(ctx.U32[4]);
|
||||
}
|
||||
const auto [image, is_integer] = Image(ctx, index, info);
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
const auto [image, numeric_type] = Image(ctx, index, info);
|
||||
const Id result_type{GetResultType(ctx, numeric_type)};
|
||||
Id color{Emit(&EmitContext::OpImageSparseRead, &EmitContext::OpImageRead, ctx, inst,
|
||||
result_type, image, coords, std::nullopt, std::span<const Id>{})};
|
||||
if (!is_integer) {
|
||||
if (numeric_type == NumericType::Float) {
|
||||
color = ctx.OpBitcast(ctx.U32[4], color);
|
||||
}
|
||||
return color;
|
||||
|
|
@ -632,8 +660,8 @@ Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id co
|
|||
|
||||
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id color) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const auto [image, is_integer] = Image(ctx, index, info);
|
||||
if (!is_integer) {
|
||||
const auto [image, numeric_type] = Image(ctx, index, info);
|
||||
if (numeric_type == NumericType::Float) {
|
||||
color = ctx.OpBitcast(ctx.F32[4], color);
|
||||
}
|
||||
ctx.OpImageWrite(image, coords, color);
|
||||
|
|
|
|||
|
|
@ -28,9 +28,21 @@ enum class Operation {
|
|||
FPMax,
|
||||
};
|
||||
|
||||
Id GetNumericTypeId(EmitContext& ctx, NumericType numeric_type) {
|
||||
switch (numeric_type) {
|
||||
case NumericType::Float:
|
||||
return ctx.F32[1];
|
||||
case NumericType::SignedInt:
|
||||
return ctx.S32[1];
|
||||
case NumericType::UnsignedInt:
|
||||
return ctx.U32[1];
|
||||
}
|
||||
throw InvalidArgument("Invalid numeric type {}", static_cast<u32>(numeric_type));
|
||||
}
|
||||
|
||||
Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
|
||||
const spv::ImageFormat format{spv::ImageFormat::Unknown};
|
||||
const Id type{ctx.F32[1]};
|
||||
const Id type{GetNumericTypeId(ctx, desc.numeric_type)};
|
||||
const bool depth{desc.is_depth};
|
||||
const bool ms{desc.is_multisample};
|
||||
switch (desc.type) {
|
||||
|
|
@ -1304,22 +1316,26 @@ void EmitContext::DefineTextureBuffers(const Info& info, u32& binding) {
|
|||
if (info.texture_buffer_descriptors.empty()) {
|
||||
return;
|
||||
}
|
||||
const spv::ImageFormat format{spv::ImageFormat::Unknown};
|
||||
image_buffer_type = TypeImage(F32[1], spv::Dim::Buffer, 0U, false, false, 1, format);
|
||||
|
||||
const Id type{TypePointer(spv::StorageClass::UniformConstant, image_buffer_type)};
|
||||
texture_buffers.reserve(info.texture_buffer_descriptors.size());
|
||||
for (const TextureBufferDescriptor& desc : info.texture_buffer_descriptors) {
|
||||
if (desc.count != 1) {
|
||||
throw NotImplementedException("Array of texture buffers");
|
||||
}
|
||||
const spv::ImageFormat format{spv::ImageFormat::Unknown};
|
||||
const Id image_type{
|
||||
TypeImage(GetNumericTypeId(*this, desc.numeric_type), spv::Dim::Buffer, 0U, false,
|
||||
false, 1, format)};
|
||||
const Id type{TypePointer(spv::StorageClass::UniformConstant, image_type)};
|
||||
const Id id{AddGlobalVariable(type, spv::StorageClass::UniformConstant)};
|
||||
Decorate(id, spv::Decoration::Binding, binding);
|
||||
Decorate(id, spv::Decoration::DescriptorSet, 0U);
|
||||
Name(id, NameOf(stage, desc, "texbuf"));
|
||||
texture_buffers.push_back({
|
||||
.id = id,
|
||||
.image_type = image_type,
|
||||
.pointer_type = type,
|
||||
.count = desc.count,
|
||||
.numeric_type = desc.numeric_type,
|
||||
});
|
||||
if (profile.supported_spirv >= 0x00010400) {
|
||||
interfaces.push_back(id);
|
||||
|
|
@ -1332,7 +1348,7 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) {
|
|||
image_buffers.reserve(info.image_buffer_descriptors.size());
|
||||
for (const ImageBufferDescriptor& desc : info.image_buffer_descriptors) {
|
||||
const spv::ImageFormat format{GetImageFormat(desc.format)};
|
||||
const Id sampled_type{desc.is_integer ? U32[1] : F32[1]};
|
||||
const Id sampled_type{GetNumericTypeId(*this, desc.numeric_type)};
|
||||
const Id image_type{
|
||||
TypeImage(sampled_type, spv::Dim::Buffer, false, false, false, 2, format)};
|
||||
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)};
|
||||
|
|
@ -1345,7 +1361,7 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) {
|
|||
.image_type = image_type,
|
||||
.pointer_type = pointer_type,
|
||||
.count = desc.count,
|
||||
.is_integer = desc.is_integer,
|
||||
.numeric_type = desc.numeric_type,
|
||||
});
|
||||
if (profile.supported_spirv >= 0x00010400) {
|
||||
interfaces.push_back(id);
|
||||
|
|
@ -1372,6 +1388,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
|
|||
.image_type = image_type,
|
||||
.count = desc.count,
|
||||
.is_multisample = desc.is_multisample,
|
||||
.numeric_type = desc.numeric_type,
|
||||
});
|
||||
if (profile.supported_spirv >= 0x00010400) {
|
||||
interfaces.push_back(id);
|
||||
|
|
@ -1387,7 +1404,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
|
|||
void EmitContext::DefineImages(const Info& info, u32& binding, u32& scaling_index) {
|
||||
images.reserve(info.image_descriptors.size());
|
||||
for (const ImageDescriptor& desc : info.image_descriptors) {
|
||||
const Id sampled_type{desc.is_integer ? U32[1] : F32[1]};
|
||||
const Id sampled_type{GetNumericTypeId(*this, desc.numeric_type)};
|
||||
const Id image_type{ImageType(*this, desc, sampled_type)};
|
||||
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)};
|
||||
const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)};
|
||||
|
|
@ -1399,7 +1416,7 @@ void EmitContext::DefineImages(const Info& info, u32& binding, u32& scaling_inde
|
|||
.image_type = image_type,
|
||||
.pointer_type = pointer_type,
|
||||
.count = desc.count,
|
||||
.is_integer = desc.is_integer,
|
||||
.numeric_type = desc.numeric_type,
|
||||
});
|
||||
if (profile.supported_spirv >= 0x00010400) {
|
||||
interfaces.push_back(id);
|
||||
|
|
|
|||
|
|
@ -41,11 +41,15 @@ struct TextureDefinition {
|
|||
Id image_type;
|
||||
u32 count;
|
||||
bool is_multisample;
|
||||
NumericType numeric_type;
|
||||
};
|
||||
|
||||
struct TextureBufferDefinition {
|
||||
Id id;
|
||||
Id image_type;
|
||||
Id pointer_type;
|
||||
u32 count;
|
||||
NumericType numeric_type;
|
||||
};
|
||||
|
||||
struct ImageBufferDefinition {
|
||||
|
|
@ -53,7 +57,7 @@ struct ImageBufferDefinition {
|
|||
Id image_type;
|
||||
Id pointer_type;
|
||||
u32 count;
|
||||
bool is_integer;
|
||||
NumericType numeric_type;
|
||||
};
|
||||
|
||||
struct ImageDefinition {
|
||||
|
|
@ -61,7 +65,7 @@ struct ImageDefinition {
|
|||
Id image_type;
|
||||
Id pointer_type;
|
||||
u32 count;
|
||||
bool is_integer;
|
||||
NumericType numeric_type;
|
||||
};
|
||||
|
||||
struct UniformDefinitions {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "shader_recompiler/host_translate_info.h"
|
||||
#include "shader_recompiler/ir_opt/passes.h"
|
||||
#include "shader_recompiler/shader_info.h"
|
||||
#include "video_core/surface.h"
|
||||
|
||||
namespace Shader::Optimization {
|
||||
namespace {
|
||||
|
|
@ -33,6 +34,16 @@ using TextureInstVector = boost::container::small_vector<TextureInst, 24>;
|
|||
constexpr u32 DESCRIPTOR_SIZE = 8;
|
||||
constexpr u32 DESCRIPTOR_SIZE_SHIFT = static_cast<u32>(std::countr_zero(DESCRIPTOR_SIZE));
|
||||
|
||||
NumericType GetNumericType(TexturePixelFormat format) {
|
||||
const auto pixel_format = static_cast<VideoCore::Surface::PixelFormat>(format);
|
||||
if (!VideoCore::Surface::IsPixelFormatInteger(pixel_format)) {
|
||||
return NumericType::Float;
|
||||
}
|
||||
return VideoCore::Surface::IsPixelFormatSignedInteger(pixel_format)
|
||||
? NumericType::SignedInt
|
||||
: NumericType::UnsignedInt;
|
||||
}
|
||||
|
||||
IR::Opcode IndexedInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::BindlessImageSampleImplicitLod:
|
||||
|
|
@ -430,7 +441,8 @@ public:
|
|||
|
||||
u32 Add(const TextureBufferDescriptor& desc) {
|
||||
return Add(texture_buffer_descriptors, desc, [&desc](const auto& existing) {
|
||||
return desc.cbuf_index == existing.cbuf_index &&
|
||||
return desc.numeric_type == existing.numeric_type &&
|
||||
desc.cbuf_index == existing.cbuf_index &&
|
||||
desc.cbuf_offset == existing.cbuf_offset &&
|
||||
desc.shift_left == existing.shift_left &&
|
||||
desc.secondary_cbuf_index == existing.secondary_cbuf_index &&
|
||||
|
|
@ -449,13 +461,13 @@ public:
|
|||
})};
|
||||
image_buffer_descriptors[index].is_written |= desc.is_written;
|
||||
image_buffer_descriptors[index].is_read |= desc.is_read;
|
||||
image_buffer_descriptors[index].is_integer |= desc.is_integer;
|
||||
return index;
|
||||
}
|
||||
|
||||
u32 Add(const TextureDescriptor& desc) {
|
||||
const u32 index{Add(texture_descriptors, desc, [&desc](const auto& existing) {
|
||||
return desc.type == existing.type && desc.is_depth == existing.is_depth &&
|
||||
desc.numeric_type == existing.numeric_type &&
|
||||
desc.has_secondary == existing.has_secondary &&
|
||||
desc.cbuf_index == existing.cbuf_index &&
|
||||
desc.cbuf_offset == existing.cbuf_offset &&
|
||||
|
|
@ -479,7 +491,6 @@ public:
|
|||
})};
|
||||
image_descriptors[index].is_written |= desc.is_written;
|
||||
image_descriptors[index].is_read |= desc.is_read;
|
||||
image_descriptors[index].is_integer |= desc.is_integer;
|
||||
return index;
|
||||
}
|
||||
|
||||
|
|
@ -651,13 +662,13 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
|||
}
|
||||
const bool is_written{inst->GetOpcode() != IR::Opcode::ImageRead};
|
||||
const bool is_read{inst->GetOpcode() != IR::Opcode::ImageWrite};
|
||||
const bool is_integer{IsTexturePixelFormatIntegerCached(env, cbuf)};
|
||||
const NumericType numeric_type{GetNumericType(ReadTexturePixelFormatCached(env, cbuf))};
|
||||
if (flags.type == TextureType::Buffer) {
|
||||
index = descriptors.Add(ImageBufferDescriptor{
|
||||
.format = flags.image_format,
|
||||
.is_written = is_written,
|
||||
.is_read = is_read,
|
||||
.is_integer = is_integer,
|
||||
.numeric_type = numeric_type,
|
||||
.cbuf_index = cbuf.index,
|
||||
.cbuf_offset = cbuf.offset,
|
||||
.count = cbuf.count,
|
||||
|
|
@ -669,7 +680,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
|||
.format = flags.image_format,
|
||||
.is_written = is_written,
|
||||
.is_read = is_read,
|
||||
.is_integer = is_integer,
|
||||
.numeric_type = numeric_type,
|
||||
.cbuf_index = cbuf.index,
|
||||
.cbuf_offset = cbuf.offset,
|
||||
.count = cbuf.count,
|
||||
|
|
@ -681,6 +692,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
|||
default:
|
||||
if (flags.type == TextureType::Buffer) {
|
||||
index = descriptors.Add(TextureBufferDescriptor{
|
||||
.numeric_type = GetNumericType(ReadTexturePixelFormatCached(env, cbuf)),
|
||||
.has_secondary = cbuf.has_secondary,
|
||||
.cbuf_index = cbuf.index,
|
||||
.cbuf_offset = cbuf.offset,
|
||||
|
|
@ -696,6 +708,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
|||
.type = flags.type,
|
||||
.is_depth = flags.is_depth != 0,
|
||||
.is_multisample = is_multisample,
|
||||
.numeric_type = GetNumericType(ReadTexturePixelFormatCached(env, cbuf)),
|
||||
.has_secondary = cbuf.has_secondary,
|
||||
.cbuf_index = cbuf.index,
|
||||
.cbuf_offset = cbuf.offset,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ enum class TextureType : u32 {
|
|||
};
|
||||
constexpr u32 NUM_TEXTURE_TYPES = 9;
|
||||
|
||||
enum class NumericType : u8 {
|
||||
Float,
|
||||
SignedInt,
|
||||
UnsignedInt,
|
||||
};
|
||||
|
||||
enum class TexturePixelFormat {
|
||||
A8B8G8R8_UNORM,
|
||||
A8B8G8R8_SNORM,
|
||||
|
|
@ -177,6 +183,7 @@ struct StorageBufferDescriptor {
|
|||
};
|
||||
|
||||
struct TextureBufferDescriptor {
|
||||
NumericType numeric_type;
|
||||
bool has_secondary;
|
||||
u32 cbuf_index;
|
||||
u32 cbuf_offset;
|
||||
|
|
@ -195,7 +202,7 @@ struct ImageBufferDescriptor {
|
|||
ImageFormat format;
|
||||
bool is_written;
|
||||
bool is_read;
|
||||
bool is_integer;
|
||||
NumericType numeric_type;
|
||||
u32 cbuf_index;
|
||||
u32 cbuf_offset;
|
||||
u32 count;
|
||||
|
|
@ -209,6 +216,7 @@ struct TextureDescriptor {
|
|||
TextureType type;
|
||||
bool is_depth;
|
||||
bool is_multisample;
|
||||
NumericType numeric_type;
|
||||
bool has_secondary;
|
||||
u32 cbuf_index;
|
||||
u32 cbuf_offset;
|
||||
|
|
@ -228,7 +236,7 @@ struct ImageDescriptor {
|
|||
ImageFormat format;
|
||||
bool is_written;
|
||||
bool is_read;
|
||||
bool is_integer;
|
||||
NumericType numeric_type;
|
||||
u32 cbuf_index;
|
||||
u32 cbuf_offset;
|
||||
u32 count;
|
||||
|
|
|
|||
|
|
@ -867,7 +867,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
const auto& blend{key.state.attachments[index]};
|
||||
const bool supports_blending = !VideoCore::Surface::IsPixelFormatInteger(key.color_formats[index]);
|
||||
const PixelFormat color_format{DecodeFormat(key.state.color_formats[index])};
|
||||
const bool supports_blending = !VideoCore::Surface::IsPixelFormatInteger(color_format);
|
||||
const std::array mask{blend.Mask()};
|
||||
VkColorComponentFlags write_mask{};
|
||||
for (size_t i = 0; i < mask_table.size(); ++i) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue