Compare commits

...

5 Commits

Author SHA1 Message Date
Gursukh Sembi
16cd1d7f94
Merge branch 'main' into RoughP2PEpollImpl 2026-04-04 21:07:38 +01:00
Niram7777
fb067bc43f
Vulkan device destroy images_view on Swapchain::Destroy (#4218) 2026-04-04 22:30:28 +03:00
Niram7777
b365d5fe78
Vulkan device destroy DescriptorPool on Shutdown (#4217)
Validation Error: [ VUID-vkDestroyDevice-device-05137 ] | MessageID = 0x4872eaa0
vkDestroyDevice(): Object Tracking - For VkDevice 0x55ac6bd22670, VkDescriptorPool 0x300000000030 has not been destroyed.
The Vulkan spec states: All child objects created on device that can be destroyed or freed must have been destroyed or freed prior to destroying device (https://docs.vulkan.org/spec/latest/chapters/devsandqueues.html#VUID-vkDestroyDevice-device-05137)
Objects: 1
    [0] VkDescriptorPool 0x300000000030
2026-04-04 21:57:22 +03:00
Marcin Mikołajczyk
73520ae094
GS fixes (#4213)
* Handle S_BFM_I32 in a copy shader

* GS: set dwords_per_vertex based on the number of buffer loads if different from VERT_ITEMSIZE
2026-04-04 13:02:44 +03:00
rainmakerv2
450472b51f
Update serdes.h (#4214) 2026-04-04 08:38:51 +03:00
6 changed files with 32 additions and 3 deletions

View File

@ -42,7 +42,8 @@ struct Archive {
}
void Advance(size_t size) {
ASSERT(offset + size <= container.size());
ASSERT_MSG(offset + size <= container.size(),
"Invalid or corrupted deserialization container/shader cache");
offset += size;
}
@ -104,7 +105,8 @@ struct Writer {
struct Reader {
template <typename T>
void Read(T* ptr, size_t size) {
ASSERT(ar.offset + size <= ar.container.size());
ASSERT_MSG(ar.offset + size <= ar.container.size(),
"Invalid or corrupted deserialization container/shader cache");
std::memcpy(reinterpret_cast<void*>(ptr), ar.CurrPtr(), size);
ar.Advance(size);
}

View File

@ -1219,6 +1219,10 @@ void ImGuiImplVulkanDestroyDeviceObjects() {
v.device.destroyDescriptorSetLayout(bd->descriptor_set_layout, v.allocator);
bd->descriptor_set_layout = VK_NULL_HANDLE;
}
if (bd->descriptor_pool) {
v.device.destroyDescriptorPool(bd->descriptor_pool, v.allocator);
bd->descriptor_pool = VK_NULL_HANDLE;
}
if (bd->pipeline_layout) {
v.device.destroyPipelineLayout(bd->pipeline_layout, v.allocator);
bd->pipeline_layout = VK_NULL_HANDLE;

View File

@ -45,6 +45,14 @@ CopyShaderData ParseCopyShader(std::span<const u32> code) {
sources[inst.dst[0].code] += inst.control.sopk.simm;
break;
}
case Gcn::Opcode::S_BFM_B32: {
ASSERT(inst.src[0].field == Gcn::OperandField::SignedConstIntPos &&
inst.src[1].field == Gcn::OperandField::SignedConstIntPos);
const auto src0 = inst.src[0].code - Gcn::OperandFieldRange::SignedConstIntPosMin + 1;
const auto src1 = inst.src[1].code - Gcn::OperandFieldRange::SignedConstIntPosMin + 1;
sources[inst.dst[0].code] = ((1 << src0) - 1) << src1;
break;
}
case Gcn::Opcode::EXP: {
const auto& exp = inst.control.exp;
const IR::Attribute semantic = static_cast<IR::Attribute>(exp.target);
@ -71,6 +79,7 @@ CopyShaderData ParseCopyShader(std::span<const u32> code) {
ASSERT(sources[index] != -1);
offsets[inst.src[1].code] += sources[index];
}
data.num_comps++;
break;
}
default:

View File

@ -15,6 +15,7 @@ struct CopyShaderData {
std::map<u32, std::pair<Shader::IR::Attribute, u32>> attr_map;
u32 num_attrs{0};
u32 output_vertices{0};
u32 num_comps{0};
};
CopyShaderData ParseCopyShader(std::span<const u32> code);

View File

@ -104,6 +104,13 @@ void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtim
output_vertices, info.gs_copy_data.output_vertices);
output_vertices = info.gs_copy_data.output_vertices;
}
u32 dwords_per_vertex = gs_info.out_vertex_data_size;
if (info.gs_copy_data.num_comps && info.gs_copy_data.num_comps != dwords_per_vertex) {
LOG_WARNING(Render_Vulkan,
"VERT_ITEMSIZE {} is different than actual number of dwords per vertex {}",
dwords_per_vertex, info.gs_copy_data.num_comps);
dwords_per_vertex = info.gs_copy_data.num_comps;
}
ForEachInstruction([&](IR::IREmitter& ir, IR::Inst& inst) {
const auto opcode = inst.GetOpcode();
@ -139,7 +146,7 @@ void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtim
const auto offset = inst.Flags<IR::BufferInstInfo>().inst_offset.Value();
const auto data = ir.BitCast<IR::F32>(IR::U32{inst.Arg(2)});
const auto comp_ofs = output_vertices * 4u;
const auto output_size = comp_ofs * gs_info.out_vertex_data_size;
const auto output_size = comp_ofs * dwords_per_vertex;
const auto vc_read_ofs = (((offset / comp_ofs) * comp_ofs) % output_size) * 16u;
const auto& it = info.gs_copy_data.attr_map.find(vc_read_ofs);

View File

@ -261,6 +261,12 @@ void Swapchain::Destroy() {
LOG_WARNING(Render_Vulkan, "Failed to wait for device to become idle: {}",
vk::to_string(wait_result));
}
for (auto& image_view : images_view) {
device.destroyImageView(image_view);
}
images_view.clear();
if (swapchain) {
device.destroySwapchainKHR(swapchain);
}