mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-08 13:11:02 +00:00
[vulkan] 3rd Vulkan Global Maintenance (#4189)
Following the philosophy on the previous Vulkan maintenance PR's, this one is reviewing the video_core to resolve VUID's related to the missing handling/ safechecks (UBO's case on missing StorageBufferAccess 8/16 bits on QCOM drivers, resulting on bad compute pipeline compiled), wiring topology representative to EDS2 configuration (following #4117), refactored the sampled image access via new memeber function for type "typeless" which adds a handling on the integer mistmatch (uint to sint, float to uint) + fixing bugs on current texture sampling (int) including the depth/stencil path resolve, maintenance to previous changes on query cache (resolving bugs from #3853), reduced the amount of binding BindVertexBufferEXT2 when a new tick/ frame is presented (with this being a reason for performance reduction on games where vertex polutes the stage, like BOTW/TOTK where grass is draw with vertex); implemented color border swizzle and color write enable for future improvements on EDS3, added initial implementation on Synchronization2 starting a path to ensure an access to VK 1.3 features safely and other smaller fixes along the road. Special Thanks: -> Mr. Smolio Gidolard (@gidoly) Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4189
This commit is contained in:
@@ -403,6 +403,9 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
|
||||
if (info.uses_sampled_1d) {
|
||||
ctx.AddCapability(spv::Capability::Sampled1D);
|
||||
}
|
||||
if (info.uses_image_1d) {
|
||||
ctx.AddCapability(spv::Capability::Image1D);
|
||||
}
|
||||
if (info.uses_sparse_residency) {
|
||||
ctx.AddCapability(spv::Capability::SparseResidency);
|
||||
}
|
||||
|
||||
@@ -202,7 +202,8 @@ void EmitGetIndirectBranchVariable(EmitContext&) {
|
||||
}
|
||||
|
||||
Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8 &&
|
||||
ctx.profile.support_uniform_and_storage_buffer_8bit) {
|
||||
const Id load{GetCbuf(ctx, ctx.U8, &UniformDefinitions::U8, sizeof(u8), binding, offset,
|
||||
ctx.load_const_func_u8)};
|
||||
return ctx.OpUConvert(ctx.U32[1], load);
|
||||
@@ -219,7 +220,8 @@ Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& of
|
||||
}
|
||||
|
||||
Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8 &&
|
||||
ctx.profile.support_uniform_and_storage_buffer_8bit) {
|
||||
const Id load{GetCbuf(ctx, ctx.S8, &UniformDefinitions::S8, sizeof(s8), binding, offset,
|
||||
ctx.load_const_func_u8)};
|
||||
return ctx.OpSConvert(ctx.U32[1], load);
|
||||
@@ -236,7 +238,8 @@ Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& of
|
||||
}
|
||||
|
||||
Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16 &&
|
||||
ctx.profile.support_uniform_and_storage_buffer_16bit) {
|
||||
const Id load{GetCbuf(ctx, ctx.U16, &UniformDefinitions::U16, sizeof(u16), binding, offset,
|
||||
ctx.load_const_func_u16)};
|
||||
return ctx.OpUConvert(ctx.U32[1], load);
|
||||
@@ -253,7 +256,8 @@ Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& o
|
||||
}
|
||||
|
||||
Id EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) {
|
||||
if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16 &&
|
||||
ctx.profile.support_uniform_and_storage_buffer_16bit) {
|
||||
const Id load{GetCbuf(ctx, ctx.S16, &UniformDefinitions::S16, sizeof(s16), binding, offset,
|
||||
ctx.load_const_func_u16)};
|
||||
return ctx.OpSConvert(ctx.U32[1], load);
|
||||
|
||||
@@ -260,6 +260,13 @@ bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||
return ctx.textures.at(info.descriptor_index).is_multisample;
|
||||
}
|
||||
|
||||
bool IsTextureInteger(EmitContext& ctx, const IR::TextureInstInfo& info) {
|
||||
if (info.type == TextureType::Buffer) {
|
||||
return false;
|
||||
}
|
||||
return ctx.textures.at(info.descriptor_index).is_integer;
|
||||
}
|
||||
|
||||
Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
if (info.relaxed_precision != 0) {
|
||||
@@ -480,11 +487,14 @@ Id EmitBoundImageWrite(EmitContext&) {
|
||||
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||
Id bias_lc, const IR::Value& offset) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const bool is_integer{IsTextureInteger(ctx, info)};
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
Id color;
|
||||
if (ctx.stage == Stage::Fragment) {
|
||||
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0,
|
||||
bias_lc, offset);
|
||||
return Emit(&EmitContext::OpImageSparseSampleImplicitLod,
|
||||
&EmitContext::OpImageSampleImplicitLod, ctx, inst, ctx.F32[4],
|
||||
color = Emit(&EmitContext::OpImageSparseSampleImplicitLod,
|
||||
&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
|
||||
@@ -492,26 +502,29 @@ 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);
|
||||
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
||||
color = Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, result_type,
|
||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
||||
}
|
||||
return is_integer ? ctx.OpBitcast(ctx.F32[4], color) : color;
|
||||
}
|
||||
|
||||
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||
Id lod, const IR::Value& offset) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const bool is_integer{IsTextureInteger(ctx, info)};
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
const ImageOperands operands(ctx, false, true, false, lod, offset);
|
||||
|
||||
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 (!is_integer && Settings::values.fix_bloom_effects.GetValue()) {
|
||||
result = ctx.OpVectorTimesScalar(ctx.F32[4], result, ctx.Const(0.98f));
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
return is_integer ? ctx.OpBitcast(ctx.F32[4], result) : result;
|
||||
}
|
||||
|
||||
Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
|
||||
@@ -547,30 +560,39 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
|
||||
Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||
const IR::Value& offset, const IR::Value& offset2) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const bool is_integer{IsTextureInteger(ctx, info)};
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
const ImageOperands operands(ctx, offset, offset2);
|
||||
if (ctx.profile.need_gather_subpixel_offset) {
|
||||
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
|
||||
}
|
||||
return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst,
|
||||
ctx.F32[4], Texture(ctx, info, index), coords, ctx.Const(info.gather_component),
|
||||
operands.MaskOptional(), operands.Span());
|
||||
const Id color{Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst,
|
||||
result_type, Texture(ctx, info, index), coords,
|
||||
ctx.Const(info.gather_component), operands.MaskOptional(),
|
||||
operands.Span())};
|
||||
return is_integer ? ctx.OpBitcast(ctx.F32[4], color) : color;
|
||||
}
|
||||
|
||||
Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||
const IR::Value& offset, const IR::Value& offset2, Id dref) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const bool is_integer{IsTextureInteger(ctx, info)};
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
const ImageOperands operands(ctx, offset, offset2);
|
||||
if (ctx.profile.need_gather_subpixel_offset) {
|
||||
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
|
||||
}
|
||||
return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst,
|
||||
ctx.F32[4], Texture(ctx, info, index), coords, dref, operands.MaskOptional(),
|
||||
operands.Span());
|
||||
const Id color{Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather,
|
||||
ctx, inst, result_type, Texture(ctx, info, index), coords, dref,
|
||||
operands.MaskOptional(), operands.Span())};
|
||||
return is_integer ? ctx.OpBitcast(ctx.F32[4], color) : color;
|
||||
}
|
||||
|
||||
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
|
||||
Id lod, Id ms) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const bool is_integer{IsTextureInteger(ctx, info)};
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
AddOffsetToCoordinates(ctx, info, coords, offset);
|
||||
if (info.type == TextureType::Buffer) {
|
||||
lod = Id{};
|
||||
@@ -580,8 +602,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 color{Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst,
|
||||
result_type, TextureImage(ctx, info, index), coords,
|
||||
operands.MaskOptional(), operands.Span())};
|
||||
return is_integer ? ctx.OpBitcast(ctx.F32[4], color) : color;
|
||||
}
|
||||
|
||||
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
|
||||
@@ -626,14 +650,17 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
|
||||
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||
Id derivatives, const IR::Value& offset, Id lod_clamp) {
|
||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||
const bool is_integer{IsTextureInteger(ctx, info)};
|
||||
const Id result_type{is_integer ? ctx.U32[4] : ctx.F32[4]};
|
||||
const auto operands = info.num_derivatives == 3
|
||||
? ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
|
||||
ctx.Def(offset), {}, lod_clamp)
|
||||
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
|
||||
info.num_derivatives, offset, lod_clamp);
|
||||
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
||||
const Id color{Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, result_type,
|
||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span())};
|
||||
return is_integer ? ctx.OpBitcast(ctx.F32[4], color) : color;
|
||||
}
|
||||
|
||||
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
|
||||
|
||||
@@ -30,7 +30,7 @@ enum class Operation {
|
||||
|
||||
Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
|
||||
const spv::ImageFormat format{spv::ImageFormat::Unknown};
|
||||
const Id type{ctx.F32[1]};
|
||||
const Id type{desc.is_integer ? ctx.U32[1] : ctx.F32[1]};
|
||||
const bool depth{desc.is_depth};
|
||||
const bool ms{desc.is_multisample};
|
||||
switch (desc.type) {
|
||||
@@ -1126,7 +1126,7 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) {
|
||||
}
|
||||
IR::Type types{info.used_constant_buffer_types | info.used_indirect_cbuf_types};
|
||||
if (True(types & IR::Type::U8)) {
|
||||
if (profile.support_int8) {
|
||||
if (profile.support_int8 && profile.support_uniform_and_storage_buffer_8bit) {
|
||||
DefineConstBuffers(*this, info, &UniformDefinitions::U8, binding, U8, 'u', sizeof(u8));
|
||||
DefineConstBuffers(*this, info, &UniformDefinitions::S8, binding, S8, 's', sizeof(s8));
|
||||
} else {
|
||||
@@ -1134,7 +1134,7 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) {
|
||||
}
|
||||
}
|
||||
if (True(types & IR::Type::U16)) {
|
||||
if (profile.support_int16) {
|
||||
if (profile.support_int16 && profile.support_uniform_and_storage_buffer_16bit) {
|
||||
DefineConstBuffers(*this, info, &UniformDefinitions::U16, binding, U16, 'u',
|
||||
sizeof(u16));
|
||||
DefineConstBuffers(*this, info, &UniformDefinitions::S16, binding, S16, 's',
|
||||
@@ -1196,10 +1196,18 @@ void EmitContext::DefineConstantBufferIndirectFunctions(const Info& info) {
|
||||
IR::Type types{info.used_indirect_cbuf_types};
|
||||
bool supports_aliasing = profile.support_descriptor_aliasing;
|
||||
if (supports_aliasing && True(types & IR::Type::U8)) {
|
||||
load_const_func_u8 = make_accessor(U8, &UniformDefinitions::U8);
|
||||
if (profile.support_int8 && profile.support_uniform_and_storage_buffer_8bit) {
|
||||
load_const_func_u8 = make_accessor(U8, &UniformDefinitions::U8);
|
||||
} else {
|
||||
types |= IR::Type::U32;
|
||||
}
|
||||
}
|
||||
if (supports_aliasing && True(types & IR::Type::U16)) {
|
||||
load_const_func_u16 = make_accessor(U16, &UniformDefinitions::U16);
|
||||
if (profile.support_int16 && profile.support_uniform_and_storage_buffer_16bit) {
|
||||
load_const_func_u16 = make_accessor(U16, &UniformDefinitions::U16);
|
||||
} else {
|
||||
types |= IR::Type::U32;
|
||||
}
|
||||
}
|
||||
if (supports_aliasing && True(types & IR::Type::F32)) {
|
||||
load_const_func_f32 = make_accessor(F32[1], &UniformDefinitions::F32);
|
||||
@@ -1375,6 +1383,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
|
||||
.image_type = image_type,
|
||||
.count = desc.count,
|
||||
.is_multisample = desc.is_multisample,
|
||||
.is_integer = desc.is_integer,
|
||||
});
|
||||
if (profile.supported_spirv >= 0x00010400) {
|
||||
interfaces.push_back(id);
|
||||
|
||||
@@ -42,6 +42,7 @@ struct TextureDefinition {
|
||||
Id image_type;
|
||||
u32 count;
|
||||
bool is_multisample;
|
||||
bool is_integer;
|
||||
};
|
||||
|
||||
struct TextureBufferDefinition {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -43,6 +46,10 @@ union TextureInstInfo {
|
||||
BitField<25, 2, u32> num_derivatives;
|
||||
BitField<27, 3, ImageFormat> image_format;
|
||||
BitField<30, 1, u32> ndv_is_active;
|
||||
/// Only meaningful for the sampled-texture family (ImageSampleImplicitLod, ImageFetch,
|
||||
/// ImageGather, etc.); unused/zero for storage-image opcodes, which carry their own
|
||||
/// is_integer via ImageDescriptor/ImageBufferDescriptor instead.
|
||||
BitField<31, 1, u32> is_integer;
|
||||
};
|
||||
static_assert(sizeof(TextureInstInfo) <= sizeof(u32));
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
@@ -569,6 +569,8 @@ void VisitUsages(Info& info, IR::Inst& inst) {
|
||||
case IR::Opcode::ImageRead: {
|
||||
const auto flags{inst.Flags<IR::TextureInstInfo>()};
|
||||
info.uses_typeless_image_reads |= flags.image_format == ImageFormat::Typeless;
|
||||
info.uses_image_1d |=
|
||||
flags.type == TextureType::Color1D || flags.type == TextureType::ColorArray1D;
|
||||
info.uses_sparse_residency |=
|
||||
inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp) != nullptr;
|
||||
break;
|
||||
@@ -577,6 +579,8 @@ void VisitUsages(Info& info, IR::Inst& inst) {
|
||||
const auto flags{inst.Flags<IR::TextureInstInfo>()};
|
||||
info.uses_typeless_image_writes |= flags.image_format == ImageFormat::Typeless;
|
||||
info.uses_image_buffers |= flags.type == TextureType::Buffer;
|
||||
info.uses_image_1d |=
|
||||
flags.type == TextureType::Color1D || flags.type == TextureType::ColorArray1D;
|
||||
break;
|
||||
}
|
||||
case IR::Opcode::SubgroupEqMask:
|
||||
@@ -761,9 +765,13 @@ void VisitUsages(Info& info, IR::Inst& inst) {
|
||||
case IR::Opcode::ImageAtomicAnd32:
|
||||
case IR::Opcode::ImageAtomicOr32:
|
||||
case IR::Opcode::ImageAtomicXor32:
|
||||
case IR::Opcode::ImageAtomicExchange32:
|
||||
case IR::Opcode::ImageAtomicExchange32: {
|
||||
const auto flags{inst.Flags<IR::TextureInstInfo>()};
|
||||
info.uses_atomic_image_u32 = true;
|
||||
info.uses_image_1d |=
|
||||
flags.type == TextureType::Color1D || flags.type == TextureType::ColorArray1D;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -566,6 +566,7 @@ public:
|
||||
})};
|
||||
// TODO: Read this from TIC
|
||||
texture_descriptors[index].is_multisample |= desc.is_multisample;
|
||||
texture_descriptors[index].is_integer |= desc.is_integer;
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -689,6 +690,21 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
||||
program.info.image_descriptors,
|
||||
};
|
||||
const u32 sampled_dynamic_cap = DynamicSampledTextureCap(program.info, host_info, DynamicSampledTextureArrayCount(to_replace));
|
||||
bool has_last_is_integer{false};
|
||||
u32 last_cbuf_index{};
|
||||
u32 last_cbuf_offset{};
|
||||
bool last_is_integer{false};
|
||||
const auto is_texture_pixel_format_integer{[&](const ConstBufferAddr& cbuf_addr) {
|
||||
if (has_last_is_integer && last_cbuf_index == cbuf_addr.index &&
|
||||
last_cbuf_offset == cbuf_addr.offset) {
|
||||
return last_is_integer;
|
||||
}
|
||||
last_is_integer = IsTexturePixelFormatIntegerCached(env, cbuf_addr);
|
||||
last_cbuf_index = cbuf_addr.index;
|
||||
last_cbuf_offset = cbuf_addr.offset;
|
||||
has_last_is_integer = true;
|
||||
return last_is_integer;
|
||||
}};
|
||||
for (TextureInst& texture_inst : to_replace) {
|
||||
// TODO: Handle arrays
|
||||
IR::Inst* const inst{texture_inst.inst};
|
||||
@@ -753,7 +769,7 @@ 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 bool is_integer{is_texture_pixel_format_integer(cbuf)};
|
||||
if (flags.type == TextureType::Buffer) {
|
||||
index = descriptors.Add(ImageBufferDescriptor{
|
||||
.format = flags.image_format,
|
||||
@@ -795,10 +811,12 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
||||
});
|
||||
} else {
|
||||
count = std::min(count, sampled_dynamic_cap);
|
||||
const bool is_integer{is_texture_pixel_format_integer(cbuf)};
|
||||
index = descriptors.Add(TextureDescriptor{
|
||||
.type = flags.type,
|
||||
.is_depth = flags.is_depth != 0,
|
||||
.is_multisample = is_multisample,
|
||||
.is_integer = is_integer,
|
||||
.has_secondary = cbuf.has_secondary,
|
||||
.cbuf_index = cbuf.index,
|
||||
.cbuf_offset = cbuf.offset,
|
||||
@@ -809,6 +827,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
|
||||
.count = count,
|
||||
.size_shift = size_shift,
|
||||
});
|
||||
flags.is_integer.Assign(is_integer ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ struct Profile {
|
||||
bool unified_descriptor_binding{};
|
||||
bool support_descriptor_aliasing{};
|
||||
bool support_int8{};
|
||||
bool support_uniform_and_storage_buffer_8bit{};
|
||||
bool support_int16{};
|
||||
bool support_uniform_and_storage_buffer_16bit{};
|
||||
bool support_int64{};
|
||||
bool support_vertex_instance_id{};
|
||||
bool support_float_controls{};
|
||||
|
||||
@@ -209,6 +209,7 @@ struct TextureDescriptor {
|
||||
TextureType type;
|
||||
bool is_depth;
|
||||
bool is_multisample;
|
||||
bool is_integer;
|
||||
bool has_secondary;
|
||||
u32 cbuf_index;
|
||||
u32 cbuf_offset;
|
||||
|
||||
Reference in New Issue
Block a user