diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 828325796..809eace95 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -921,23 +921,40 @@ bool IsValid(const VkWriteDescriptorSet &write, uint32_t arrayElement) return false; } -void DescriptorSetBindingElement::RemoveBindRefs(VkResourceRecord *record) +void DescriptorSetSlotBufferInfo::SetFrom(const VkDescriptorBufferInfo &bufInfo) +{ + buffer = GetResID(bufInfo.buffer); + offset = bufInfo.offset; + range = bufInfo.range; +} + +void DescriptorSetSlotImageInfo::SetFrom(const VkDescriptorImageInfo &imInfo, bool setSampler, + bool setImageView) +{ + if(setSampler) + sampler = GetResID(imInfo.sampler); + if(setImageView) + imageView = GetResID(imInfo.imageView); + imageLayout = imInfo.imageLayout; +} + +void DescriptorSetSlot::RemoveBindRefs(VulkanResourceManager *rm, VkResourceRecord *record) { SCOPED_LOCK(record->descInfo->refLock); - if(texelBufferView != VK_NULL_HANDLE) + if(texelBufferView != ResourceId()) { - record->RemoveBindFrameRef(GetResID(texelBufferView)); + record->RemoveBindFrameRef(texelBufferView); - VkResourceRecord *viewRecord = GetRecord(texelBufferView); + VkResourceRecord *viewRecord = rm->GetResourceRecord(texelBufferView); if(viewRecord && viewRecord->baseResource != ResourceId()) record->RemoveBindFrameRef(viewRecord->baseResource); } - if(imageInfo.imageView != VK_NULL_HANDLE) + if(imageInfo.imageView != ResourceId()) { - record->RemoveBindFrameRef(GetResID(imageInfo.imageView)); + record->RemoveBindFrameRef(imageInfo.imageView); - VkResourceRecord *viewRecord = GetRecord(imageInfo.imageView); + VkResourceRecord *viewRecord = rm->GetResourceRecord(imageInfo.imageView); if(viewRecord) { record->RemoveBindFrameRef(viewRecord->baseResource); @@ -945,34 +962,35 @@ void DescriptorSetBindingElement::RemoveBindRefs(VkResourceRecord *record) record->RemoveBindFrameRef(viewRecord->baseResourceMem); } } - if(imageInfo.sampler != VK_NULL_HANDLE) + if(imageInfo.sampler != ResourceId()) { - record->RemoveBindFrameRef(GetResID(imageInfo.sampler)); + record->RemoveBindFrameRef(imageInfo.sampler); } - if(bufferInfo.buffer != VK_NULL_HANDLE) + if(bufferInfo.buffer != ResourceId()) { - record->RemoveBindFrameRef(GetResID(bufferInfo.buffer)); + record->RemoveBindFrameRef(bufferInfo.buffer); - VkResourceRecord *bufRecord = GetRecord(bufferInfo.buffer); + VkResourceRecord *bufRecord = rm->GetResourceRecord(bufferInfo.buffer); if(bufRecord && bufRecord->baseResource != ResourceId()) record->RemoveBindFrameRef(bufRecord->baseResource); } // NULL everything out now so that we don't accidentally reference an object // that was removed already - texelBufferView = VK_NULL_HANDLE; - bufferInfo.buffer = VK_NULL_HANDLE; - imageInfo.imageView = VK_NULL_HANDLE; - imageInfo.sampler = VK_NULL_HANDLE; + texelBufferView = ResourceId(); + bufferInfo.buffer = ResourceId(); + imageInfo.imageView = ResourceId(); + imageInfo.sampler = ResourceId(); } -void DescriptorSetBindingElement::AddBindRefs(VkResourceRecord *record, FrameRefType ref) +void DescriptorSetSlot::AddBindRefs(VulkanResourceManager *rm, VkResourceRecord *record, + FrameRefType ref) { SCOPED_LOCK(record->descInfo->refLock); - if(texelBufferView != VK_NULL_HANDLE) + if(texelBufferView != ResourceId()) { - VkResourceRecord *bufView = GetRecord(texelBufferView); + VkResourceRecord *bufView = rm->GetResourceRecord(texelBufferView); record->AddBindFrameRef(bufView->GetResourceID(), eFrameRef_Read, bufView->resInfo && bufView->resInfo->IsSparse()); if(bufView->baseResource != ResourceId()) @@ -980,34 +998,21 @@ void DescriptorSetBindingElement::AddBindRefs(VkResourceRecord *record, FrameRef if(bufView->baseResourceMem != ResourceId()) record->AddMemFrameRef(bufView->baseResourceMem, bufView->memOffset, bufView->memSize, ref); } - if(imageInfo.imageView != VK_NULL_HANDLE) + if(imageInfo.imageView != ResourceId()) { - VkResourceRecord *view = GetRecord(imageInfo.imageView); + VkResourceRecord *view = rm->GetResourceRecord(imageInfo.imageView); record->AddImgFrameRef(view, ref); } - if(imageInfo.sampler != VK_NULL_HANDLE) + if(imageInfo.sampler != ResourceId()) { - record->AddBindFrameRef(GetResID(imageInfo.sampler), eFrameRef_Read); + record->AddBindFrameRef(imageInfo.sampler, eFrameRef_Read); } - if(bufferInfo.buffer != VK_NULL_HANDLE) + if(bufferInfo.buffer != ResourceId()) { - VkResourceRecord *buf = GetRecord(bufferInfo.buffer); - record->AddBindFrameRef(GetResID(bufferInfo.buffer), eFrameRef_Read, + VkResourceRecord *buf = rm->GetResourceRecord(bufferInfo.buffer); + record->AddBindFrameRef(bufferInfo.buffer, eFrameRef_Read, buf->resInfo && buf->resInfo->IsSparse()); if(buf->baseResource != ResourceId()) record->AddMemFrameRef(buf->baseResource, buf->memOffset, buf->memSize, ref); } -} - -void DescriptorSetSlot::CreateFrom(const DescriptorSetBindingElement &slot) -{ - bufferInfo.buffer = GetResID(slot.bufferInfo.buffer); - bufferInfo.offset = slot.bufferInfo.offset; - bufferInfo.range = slot.bufferInfo.range; - - imageInfo.sampler = GetResID(slot.imageInfo.sampler); - imageInfo.imageView = GetResID(slot.imageInfo.imageView); - imageInfo.imageLayout = slot.imageInfo.imageLayout; - - texelBufferView = GetResID(slot.texelBufferView); -} +} \ No newline at end of file diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index b82dc2510..2d4e123ee 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -392,27 +392,17 @@ struct MemoryAllocation #define IsReplayingAndReading() (ser.IsReading() && IsReplayMode(m_State)) struct VkResourceRecord; +class VulkanResourceManager; FrameRefType GetRefType(VkDescriptorType descType); -// the possible contents of a descriptor set slot, -// taken from the VkWriteDescriptorSet -struct DescriptorSetBindingElement -{ - VkDescriptorBufferInfo bufferInfo; - VkDescriptorImageInfo imageInfo; - VkBufferView texelBufferView; - - void RemoveBindRefs(VkResourceRecord *record); - void AddBindRefs(VkResourceRecord *record, FrameRefType ref); -}; - -// serialisable snapshot of descriptor set slots. Needed because if we snapshot -// DescriptorSetBindingElement -// the VkBuffer or VkImageView handles may have been deleted and recreated by the time we fetch -// their ResourceId +// tracking for descriptor set slots. Needed because if we use something without IDs for tracking +// binding elements the handles may be deleted and recreated, and stale bindings could interfere +// with new bindings struct DescriptorSetSlotBufferInfo { + void SetFrom(const VkDescriptorBufferInfo &bufInfo); + ResourceId buffer; VkDeviceSize offset; VkDeviceSize range; @@ -420,6 +410,8 @@ struct DescriptorSetSlotBufferInfo struct DescriptorSetSlotImageInfo { + void SetFrom(const VkDescriptorImageInfo &imInfo, bool setSampler, bool setImageView); + ResourceId sampler; ResourceId imageView; VkImageLayout imageLayout; @@ -427,7 +419,8 @@ struct DescriptorSetSlotImageInfo struct DescriptorSetSlot { - void CreateFrom(const DescriptorSetBindingElement &slot); + void RemoveBindRefs(VulkanResourceManager *rm, VkResourceRecord *record); + void AddBindRefs(VulkanResourceManager *rm, VkResourceRecord *record, FrameRefType ref); // VkDescriptorBufferInfo DescriptorSetSlotBufferInfo bufferInfo; diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 012aa8ef1..babc84275 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -3794,7 +3794,7 @@ void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, for(uint32_t a = 0; a < layout.bindings[bind].descriptorCount; a++) { - DescriptorSetBindingElement &slot = descset.currentBindings[bind][a]; + DescriptorSetSlot &slot = descset.currentBindings[bind][a]; ResourceId id; @@ -3803,20 +3803,20 @@ void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - if(slot.imageInfo.imageView != VK_NULL_HANDLE) - id = c.m_ImageView[GetResID(slot.imageInfo.imageView)].image; + if(slot.imageInfo.imageView != ResourceId()) + id = c.m_ImageView[slot.imageInfo.imageView].image; break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - if(slot.texelBufferView != VK_NULL_HANDLE) - id = c.m_BufferView[GetResID(slot.texelBufferView)].buffer; + if(slot.texelBufferView != ResourceId()) + id = c.m_BufferView[slot.texelBufferView].buffer; break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - if(slot.bufferInfo.buffer != VK_NULL_HANDLE) - id = GetResID(slot.bufferInfo.buffer); + if(slot.bufferInfo.buffer != ResourceId()) + id = slot.bufferInfo.buffer; break; default: RDCERR("Unexpected type %d", layout.bindings[bind].descriptorType); break; } diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 752a88cc6..5317b6c02 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -697,7 +697,7 @@ private: DescriptorSetInfo &operator=(const DescriptorSetInfo &) = default; ~DescriptorSetInfo() { clear(); } ResourceId layout; - std::vector currentBindings; + std::vector currentBindings; bool push; void clear() diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 09e864557..392fbfb11 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -127,18 +127,18 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo } } -void DescSetLayout::CreateBindingsArray(std::vector &descBindings) const +void DescSetLayout::CreateBindingsArray(std::vector &descBindings) const { descBindings.resize(bindings.size()); for(size_t i = 0; i < bindings.size(); i++) { - descBindings[i] = new DescriptorSetBindingElement[bindings[i].descriptorCount]; - memset(descBindings[i], 0, sizeof(DescriptorSetBindingElement) * bindings[i].descriptorCount); + descBindings[i] = new DescriptorSetSlot[bindings[i].descriptorCount]; + memset(descBindings[i], 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount); } } void DescSetLayout::UpdateBindingsArray(const DescSetLayout &prevLayout, - std::vector &descBindings) const + std::vector &descBindings) const { // if we have fewer bindings now, delete the orphaned bindings arrays for(size_t i = bindings.size(); i < prevLayout.bindings.size(); i++) @@ -151,14 +151,13 @@ void DescSetLayout::UpdateBindingsArray(const DescSetLayout &prevLayout, for(size_t i = 0; i < bindings.size(); i++) { // allocate new slot array - DescriptorSetBindingElement *newSlots = - new DescriptorSetBindingElement[bindings[i].descriptorCount]; - memset(newSlots, 0, sizeof(DescriptorSetBindingElement) * bindings[i].descriptorCount); + DescriptorSetSlot *newSlots = new DescriptorSetSlot[bindings[i].descriptorCount]; + memset(newSlots, 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount); // copy over any previous bindings that overlapped if(i < prevLayout.bindings.size()) memcpy(newSlots, descBindings[i], - sizeof(DescriptorSetBindingElement) * + sizeof(DescriptorSetSlot) * RDCMIN(prevLayout.bindings[i].descriptorCount, bindings[i].descriptorCount)); // delete old array, and assign the new one diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index e3433dabd..8860f7cf4 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -60,9 +60,9 @@ struct DescSetLayout void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkDescriptorSetLayoutCreateInfo *pCreateInfo); - void CreateBindingsArray(std::vector &descBindings) const; + void CreateBindingsArray(std::vector &descBindings) const; void UpdateBindingsArray(const DescSetLayout &prevLayout, - std::vector &descBindings) const; + std::vector &descBindings) const; struct Binding { diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 095e7a56f..8fed21077 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -63,7 +63,7 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res) { for(uint32_t b = 0; b < layout.bindings[i].descriptorCount; b++) { - initialContents.descriptorSlots[e++].CreateFrom(record->descInfo->descBindings[i][b]); + initialContents.descriptorSlots[e++] = record->descInfo->descBindings[i][b]; } } } @@ -651,7 +651,7 @@ uint64_t WrappedVulkan::GetSize_InitialState(ResourceId id, const VkInitialConte for(size_t i = 0; i < layout.bindings.size(); i++) NumBindings += layout.bindings[i].descriptorCount; - return 32 + NumBindings * sizeof(DescriptorSetBindingElement); + return 32 + NumBindings * sizeof(DescriptorSetSlot); } else if(initial.type == eResBuffer) { @@ -1487,13 +1487,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten // need to blat over the current descriptor set contents, so these are available // when we want to fetch pipeline state - std::vector &bindings = m_DescriptorSetState[id].currentBindings; + std::vector &bindings = m_DescriptorSetState[id].currentBindings; for(uint32_t i = 0; i < initial.numDescriptors; i++) { RDCASSERT(writes[i].dstBinding < bindings.size()); - DescriptorSetBindingElement *bind = bindings[writes[i].dstBinding]; + DescriptorSetSlot *bind = bindings[writes[i].dstBinding]; for(uint32_t d = 0; d < writes[i].descriptorCount; d++) { @@ -1502,18 +1502,20 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) { - bind[idx].texelBufferView = writes[i].pTexelBufferView[d]; + bind[idx].texelBufferView = GetResID(writes[i].pTexelBufferView[d]); } else if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { - bind[idx].bufferInfo = writes[i].pBufferInfo[d]; + bind[idx].bufferInfo.SetFrom(writes[i].pBufferInfo[d]); } else { - bind[idx].imageInfo = writes[i].pImageInfo[d]; + // we don't ever pass invalid parameters so we can unconditionally set both. Invalid + // elements are set to VK_NULL_HANDLE which is safe + bind[idx].imageInfo.SetFrom(writes[i].pImageInfo[d], true, true); } } } diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index 4c8e9bbf0..b8ecc78a4 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -1382,7 +1382,7 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe, if(bind.descriptorCount == 0 || bind.stageFlags == 0) continue; - DescriptorSetBindingElement *slot = setInfo.currentBindings[b]; + DescriptorSetSlot *slot = setInfo.currentBindings[b]; write.dstBinding = uint32_t(b + newBindingsCount); write.dstArrayElement = 0; @@ -1399,7 +1399,14 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe, { VkDescriptorImageInfo *out = new VkDescriptorImageInfo[write.descriptorCount]; for(uint32_t w = 0; w < write.descriptorCount; w++) - out[w] = slot[w].imageInfo; + { + const DescriptorSetSlotImageInfo &src = slot[w].imageInfo; + + out[w].imageLayout = src.imageLayout; + out[w].sampler = GetResourceManager()->GetCurrentHandle(src.sampler); + out[w].imageView = GetResourceManager()->GetCurrentHandle(src.imageView); + } + write.pImageInfo = out; allocImgWrites.push_back(out); break; @@ -1409,7 +1416,8 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe, { VkBufferView *out = new VkBufferView[write.descriptorCount]; for(uint32_t w = 0; w < write.descriptorCount; w++) - out[w] = slot[w].texelBufferView; + out[w] = + GetResourceManager()->GetCurrentHandle(slot[w].texelBufferView); write.pTexelBufferView = out; allocBufViewWrites.push_back(out); break; @@ -1421,7 +1429,13 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe, { VkDescriptorBufferInfo *out = new VkDescriptorBufferInfo[write.descriptorCount]; for(uint32_t w = 0; w < write.descriptorCount; w++) - out[w] = slot[w].bufferInfo; + { + const DescriptorSetSlotBufferInfo &src = slot[w].bufferInfo; + + out[w].offset = src.offset; + out[w].range = src.range; + out[w].buffer = GetResourceManager()->GetCurrentHandle(src.buffer); + } write.pBufferInfo = out; allocBufWrites.push_back(out); break; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index f26a7e734..9dc160f80 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1598,7 +1598,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) dst.bindings.resize(m_pDriver->m_DescriptorSetState[src].currentBindings.size()); for(size_t b = 0; b < m_pDriver->m_DescriptorSetState[src].currentBindings.size(); b++) { - DescriptorSetBindingElement *info = m_pDriver->m_DescriptorSetState[src].currentBindings[b]; + DescriptorSetSlot *info = m_pDriver->m_DescriptorSetState[src].currentBindings[b]; const DescSetLayout::Binding &layoutBind = c.m_DescSetLayout[layoutId].bindings[b]; curBind.bind = (uint32_t)b; @@ -1699,9 +1699,9 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) dst.bindings[b].binds[a].samplerResourceId = layoutBind.immutableSampler[a]; dst.bindings[b].binds[a].immutableSampler = true; } - else if(info[a].imageInfo.sampler != VK_NULL_HANDLE) + else if(info[a].imageInfo.sampler != ResourceId()) { - dst.bindings[b].binds[a].samplerResourceId = GetResID(info[a].imageInfo.sampler); + dst.bindings[b].binds[a].samplerResourceId = info[a].imageInfo.sampler; } if(dst.bindings[b].binds[a].samplerResourceId != ResourceId()) @@ -1749,12 +1749,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT || layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) { - VkImageView view = info[a].imageInfo.imageView; + ResourceId viewid = info[a].imageInfo.imageView; - if(view != VK_NULL_HANDLE) + if(viewid != ResourceId()) { - ResourceId viewid = GetResID(view); - dst.bindings[b].binds[a].viewResourceId = rm->GetOriginalID(viewid); dst.bindings[b].binds[a].resourceResourceId = rm->GetOriginalID(c.m_ImageView[viewid].image); @@ -1784,12 +1782,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) { - VkBufferView view = info[a].texelBufferView; + ResourceId viewid = info[a].texelBufferView; - if(view != VK_NULL_HANDLE) + if(viewid != ResourceId()) { - ResourceId viewid = GetResID(view); - dst.bindings[b].binds[a].viewResourceId = rm->GetOriginalID(viewid); dst.bindings[b].binds[a].resourceResourceId = rm->GetOriginalID(c.m_BufferView[viewid].buffer); @@ -1828,9 +1824,9 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) { dst.bindings[b].binds[a].viewResourceId = ResourceId(); - if(info[a].bufferInfo.buffer != VK_NULL_HANDLE) + if(info[a].bufferInfo.buffer != ResourceId()) dst.bindings[b].binds[a].resourceResourceId = - rm->GetOriginalID(GetResID(info[a].bufferInfo.buffer)); + rm->GetOriginalID(info[a].bufferInfo.buffer); dst.bindings[b].binds[a].byteOffset = info[a].bufferInfo.offset; if(dynamicOffset) diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 9d6f8ade4..8e6a026e3 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -1013,7 +1013,7 @@ struct DescriptorSetData // descriptor set bindings for this descriptor set. Filled out on // create from the layout. - std::vector descBindings; + std::vector descBindings; // lock protecting bindFrameRefs and bindMemRefs Threading::CriticalSection refLock; diff --git a/renderdoc/driver/vulkan/vk_state.cpp b/renderdoc/driver/vulkan/vk_state.cpp index eb4edc7d3..f042d927c 100644 --- a/renderdoc/driver/vulkan/vk_state.cpp +++ b/renderdoc/driver/vulkan/vk_state.cpp @@ -444,7 +444,7 @@ void VulkanRenderState::BindDescriptorSet(const DescSetLayout &descLayout, VkCom push.descriptorType = bind.descriptorType; push.descriptorCount = bind.descriptorCount; - DescriptorSetBindingElement *slots = setInfo.currentBindings[b]; + DescriptorSetSlot *slots = setInfo.currentBindings[b]; if(push.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || push.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) @@ -452,7 +452,8 @@ void VulkanRenderState::BindDescriptorSet(const DescSetLayout &descLayout, VkCom VkBufferView *dst = new VkBufferView[push.descriptorCount]; for(uint32_t a = 0; a < push.descriptorCount; a++) - dst[a] = Unwrap(slots[a].texelBufferView); + dst[a] = + Unwrap(GetResourceManager()->GetCurrentHandle(slots[a].texelBufferView)); push.pTexelBufferView = dst; allocBufViewWrites.push_back(dst); @@ -467,9 +468,12 @@ void VulkanRenderState::BindDescriptorSet(const DescSetLayout &descLayout, VkCom for(uint32_t a = 0; a < push.descriptorCount; a++) { - dst[a] = slots[a].imageInfo; - dst[a].sampler = Unwrap(dst[a].sampler); - dst[a].imageView = Unwrap(dst[a].imageView); + const DescriptorSetSlotImageInfo &src = slots[a].imageInfo; + + dst[a].imageLayout = src.imageLayout; + dst[a].sampler = Unwrap(GetResourceManager()->GetCurrentHandle(src.sampler)); + dst[a].imageView = + Unwrap(GetResourceManager()->GetCurrentHandle(src.imageView)); } push.pImageInfo = dst; @@ -481,8 +485,11 @@ void VulkanRenderState::BindDescriptorSet(const DescSetLayout &descLayout, VkCom for(uint32_t a = 0; a < push.descriptorCount; a++) { - dst[a] = slots[a].bufferInfo; - dst[a].buffer = Unwrap(dst[a].buffer); + const DescriptorSetSlotBufferInfo &src = slots[a].bufferInfo; + + dst[a].offset = src.offset; + dst[a].range = src.range; + dst[a].buffer = Unwrap(GetResourceManager()->GetCurrentHandle(src.buffer)); } push.pBufferInfo = dst; diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index efbef9bc2..1cfa298ff 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -3728,7 +3728,7 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo const DescSetLayout &desclayout = m_CreationInfo.m_DescSetLayout[descSetLayouts[set]]; - std::vector &bindings = m_DescriptorSetState[setId].currentBindings; + std::vector &bindings = m_DescriptorSetState[setId].currentBindings; ResourceId prevLayout = m_DescriptorSetState[setId].layout; if(prevLayout == ResourceId()) @@ -3749,7 +3749,7 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo RDCASSERT(writeDesc.dstBinding < bindings.size()); - DescriptorSetBindingElement **bind = &bindings[writeDesc.dstBinding]; + DescriptorSetSlot **bind = &bindings[writeDesc.dstBinding]; const DescSetLayout::Binding *layoutBinding = &desclayout.bindings[writeDesc.dstBinding]; uint32_t curIdx = writeDesc.dstArrayElement; @@ -3767,7 +3767,7 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo curIdx = 0; } - (*bind)[curIdx].texelBufferView = writeDesc.pTexelBufferView[d]; + (*bind)[curIdx].texelBufferView = GetResID(writeDesc.pTexelBufferView[d]); } } else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || @@ -3787,7 +3787,18 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo curIdx = 0; } - (*bind)[curIdx].imageInfo = writeDesc.pImageInfo[d]; + bool sampler = true; + bool imageView = true; + + // ignore descriptors not part of the write, as they might not even point to a valid + // object so trying to get their ID could crash + if(layoutBinding->immutableSampler || + writeDesc.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + sampler = false; + if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) + imageView = false; + + (*bind)[curIdx].imageInfo.SetFrom(writeDesc.pImageInfo[d], sampler, imageView); } } else @@ -3803,7 +3814,7 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo curIdx = 0; } - (*bind)[curIdx].bufferInfo = writeDesc.pBufferInfo[d]; + (*bind)[curIdx].bufferInfo.SetFrom(writeDesc.pBufferInfo[d]); } } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 7d098f9b8..83f022be4 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -651,13 +651,13 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), 1, &unwrapped, 0, NULL); // update our local tracking - std::vector &bindings = + std::vector &bindings = m_DescriptorSetState[GetResID(writeDesc.dstSet)].currentBindings; { RDCASSERT(writeDesc.dstBinding < bindings.size()); - DescriptorSetBindingElement **bind = &bindings[writeDesc.dstBinding]; + DescriptorSetSlot **bind = &bindings[writeDesc.dstBinding]; layoutBinding = &layout.bindings[writeDesc.dstBinding]; curIdx = writeDesc.dstArrayElement; @@ -675,7 +675,7 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr curIdx = 0; } - (*bind)[curIdx].texelBufferView = writeDesc.pTexelBufferView[d]; + (*bind)[curIdx].texelBufferView = GetResID(writeDesc.pTexelBufferView[d]); } } else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || @@ -695,7 +695,18 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr curIdx = 0; } - (*bind)[curIdx].imageInfo = writeDesc.pImageInfo[d]; + bool sampler = true; + bool imageView = true; + + // ignore descriptors not part of the write, as they might not even point to a valid + // object so trying to get their ID could crash + if(layoutBinding->immutableSampler || + writeDesc.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + sampler = false; + if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) + imageView = false; + + (*bind)[curIdx].imageInfo.SetFrom(writeDesc.pImageInfo[d], sampler, imageView); } } else @@ -711,7 +722,7 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr curIdx = 0; } - (*bind)[curIdx].bufferInfo = writeDesc.pBufferInfo[d]; + (*bind)[curIdx].bufferInfo.SetFrom(writeDesc.pBufferInfo[d]); } } } @@ -731,10 +742,8 @@ void WrappedVulkan::ReplayDescriptorSetCopy(VkDevice device, const VkCopyDescrip ResourceId srcSetId = GetResID(copyDesc.srcSet); // update our local tracking - std::vector &dstbindings = - m_DescriptorSetState[dstSetId].currentBindings; - std::vector &srcbindings = - m_DescriptorSetState[srcSetId].currentBindings; + std::vector &dstbindings = m_DescriptorSetState[dstSetId].currentBindings; + std::vector &srcbindings = m_DescriptorSetState[srcSetId].currentBindings; { RDCASSERT(copyDesc.dstBinding < dstbindings.size()); @@ -748,8 +757,8 @@ void WrappedVulkan::ReplayDescriptorSetCopy(VkDevice device, const VkCopyDescrip const DescSetLayout::Binding *layoutSrcBinding = &srclayout.bindings[copyDesc.srcBinding]; const DescSetLayout::Binding *layoutDstBinding = &dstlayout.bindings[copyDesc.dstBinding]; - DescriptorSetBindingElement **dstbind = &dstbindings[copyDesc.dstBinding]; - DescriptorSetBindingElement **srcbind = &srcbindings[copyDesc.srcBinding]; + DescriptorSetSlot **dstbind = &dstbindings[copyDesc.dstBinding]; + DescriptorSetSlot **srcbind = &srcbindings[copyDesc.srcBinding]; uint32_t curDstIdx = copyDesc.dstArrayElement; uint32_t curSrcIdx = copyDesc.srcArrayElement; @@ -1013,7 +1022,7 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, RDCASSERT(descWrite.dstBinding < record->descInfo->descBindings.size()); - DescriptorSetBindingElement **binding = &record->descInfo->descBindings[descWrite.dstBinding]; + DescriptorSetSlot **binding = &record->descInfo->descBindings[descWrite.dstBinding]; const DescSetLayout::Binding *layoutBinding = &layout.bindings[descWrite.dstBinding]; @@ -1057,14 +1066,14 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, curIdx = 0; } - DescriptorSetBindingElement &bind = (*binding)[curIdx]; + DescriptorSetSlot &bind = (*binding)[curIdx]; - bind.RemoveBindRefs(record); + bind.RemoveBindRefs(GetResourceManager(), record); if(descWrite.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || descWrite.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) { - bind.texelBufferView = descWrite.pTexelBufferView[d]; + bind.texelBufferView = GetResID(descWrite.pTexelBufferView[d]); } else if(descWrite.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || descWrite.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || @@ -1072,24 +1081,25 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, descWrite.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || descWrite.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) { - bind.imageInfo = descWrite.pImageInfo[d]; + bool sampler = true; + bool imageView = true; - // ignore descriptors not part of the write, by NULL'ing out those members - // as they might not even point to a valid object + // ignore descriptors not part of the write, as they might not even point to a valid + // object so trying to get their ID could crash + if(layoutBinding->immutableSampler || + descWrite.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + sampler = false; if(descWrite.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) - bind.imageInfo.imageView = VK_NULL_HANDLE; - else if(descWrite.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) - bind.imageInfo.sampler = VK_NULL_HANDLE; + imageView = false; - if(layoutBinding->immutableSampler) - bind.imageInfo.sampler = VK_NULL_HANDLE; + bind.imageInfo.SetFrom(descWrite.pImageInfo[d], sampler, imageView); } else { - bind.bufferInfo = descWrite.pBufferInfo[d]; + bind.bufferInfo.SetFrom(descWrite.pBufferInfo[d]); } - bind.AddBindRefs(record, ref); + bind.AddBindRefs(GetResourceManager(), record, ref); } } @@ -1110,9 +1120,9 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, RDCASSERT(pDescriptorCopies[i].dstBinding < dstrecord->descInfo->descBindings.size()); RDCASSERT(pDescriptorCopies[i].srcBinding < srcrecord->descInfo->descBindings.size()); - DescriptorSetBindingElement **dstbinding = + DescriptorSetSlot **dstbinding = &dstrecord->descInfo->descBindings[pDescriptorCopies[i].dstBinding]; - DescriptorSetBindingElement **srcbinding = + DescriptorSetSlot **srcbinding = &srcrecord->descInfo->descBindings[pDescriptorCopies[i].srcBinding]; const DescSetLayout::Binding *dstlayoutBinding = @@ -1144,11 +1154,11 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, curSrcIdx = 0; } - DescriptorSetBindingElement &bind = (*dstbinding)[curDstIdx]; + DescriptorSetSlot &bind = (*dstbinding)[curDstIdx]; - bind.RemoveBindRefs(dstrecord); + bind.RemoveBindRefs(GetResourceManager(), dstrecord); bind = (*srcbinding)[curSrcIdx]; - bind.AddBindRefs(dstrecord, ref); + bind.AddBindRefs(GetResourceManager(), dstrecord, ref); } } } @@ -1396,7 +1406,7 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( RDCASSERT(entry.dstBinding < record->descInfo->descBindings.size()); - DescriptorSetBindingElement **binding = &record->descInfo->descBindings[entry.dstBinding]; + DescriptorSetSlot **binding = &record->descInfo->descBindings[entry.dstBinding]; const DescSetLayout::Binding *layoutBinding = &layout.bindings[entry.dstBinding]; @@ -1427,14 +1437,14 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( const byte *src = (const byte *)pData + entry.offset + entry.stride * d; - DescriptorSetBindingElement &bind = (*binding)[curIdx]; + DescriptorSetSlot &bind = (*binding)[curIdx]; - bind.RemoveBindRefs(record); + bind.RemoveBindRefs(GetResourceManager(), record); if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) { - bind.texelBufferView = *(VkBufferView *)src; + bind.texelBufferView = GetResID(*(const VkBufferView *)src); } else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || @@ -1442,21 +1452,27 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate( entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) { - bind.imageInfo = *(VkDescriptorImageInfo *)src; + const VkDescriptorImageInfo &srcInfo = *(const VkDescriptorImageInfo *)src; - // ignore descriptors not part of the write, by NULL'ing out those members - // as they might not even point to a valid object + bool sampler = true; + bool imageView = true; + + // ignore descriptors not part of the write, as they might not even point to a valid + // object so trying to get their ID could crash + if(layoutBinding->immutableSampler || + entry.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + sampler = false; if(entry.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) - bind.imageInfo.imageView = VK_NULL_HANDLE; - else if(entry.descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) - bind.imageInfo.sampler = VK_NULL_HANDLE; + imageView = false; + + bind.imageInfo.SetFrom(srcInfo, sampler, imageView); } else { - bind.bufferInfo = *(VkDescriptorBufferInfo *)src; + bind.bufferInfo.SetFrom(*(const VkDescriptorBufferInfo *)src); } - bind.AddBindRefs(record, ref); + bind.AddBindRefs(GetResourceManager(), record, ref); } } } diff --git a/util/test/demos/vk/vk_parameter_zoo.cpp b/util/test/demos/vk/vk_parameter_zoo.cpp index 0e45ce96a..693c4c29a 100644 --- a/util/test/demos/vk/vk_parameter_zoo.cpp +++ b/util/test/demos/vk/vk_parameter_zoo.cpp @@ -72,6 +72,21 @@ void main() Color = vertIn.col; } +)EOSHADER"; + + const std::string pixel2 = R"EOSHADER( +#version 450 core +#extension GL_EXT_samplerless_texture_functions : enable + +layout(location = 0, index = 0) out vec4 Color; + +layout(binding = 0) uniform texture2D tex; + +void main() +{ + Color = vec4(0, 1, 0, 1) * texelFetch(tex, ivec2(0), 0); +} + )EOSHADER"; int main() @@ -138,6 +153,15 @@ void main() VkPipelineLayout immutlayout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({immutsetlayout})); + VkDescriptorSetLayout setlayout2 = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ + {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + })); + + VkDescriptorSet descset2 = allocateDescriptorSet(setlayout2); + + VkPipelineLayout layout2 = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout2})); + vkh::GraphicsPipelineCreateInfo pipeCreateInfo; pipeCreateInfo.layout = layout; @@ -160,6 +184,15 @@ void main() VkPipeline immutpipe = createGraphicsPipeline(pipeCreateInfo); + pipeCreateInfo.stages = { + CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"), + CompileShaderModule(pixel2, ShaderLang::glsl, ShaderStage::frag, "main"), + }; + + pipeCreateInfo.layout = layout2; + + VkPipeline pipe2 = createGraphicsPipeline(pipeCreateInfo); + { // invalid handle - should not be used because the flag for derived pipelines is not used pipeCreateInfo.basePipelineHandle = (VkPipeline)0x1234; @@ -236,7 +269,8 @@ void main() AllocatedImage img(this, vkh::ImageCreateInfo(4, 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, - VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT), VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY})); VkImage validImage = img.image; @@ -252,6 +286,15 @@ void main() vkh::ImageMemoryBarrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, img.image), }); + vkCmdClearColorImage(cmd, img.image, VK_IMAGE_LAYOUT_GENERAL, + vkh::ClearColorValue(1.0f, 1.0f, 1.0f, 1.0f), 1, + vkh::ImageSubresourceRange()); + vkh::cmdPipelineBarrier( + cmd, { + vkh::ImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_GENERAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, img.image), + }); vkEndCommandBuffer(cmd); Submit(99, 99, {cmd}); } @@ -462,6 +505,53 @@ void main() vkCreateDescriptorUpdateTemplateKHR(device, &createInfo, NULL, &pushtempl); } + // check that stale views in descriptors don't cause problems if the handle is re-used + + VkImageView view1, view2; + CHECK_VKR(vkCreateImageView(device, vkh::ImageViewCreateInfo(img.image, VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT), + NULL, &view1)); + CHECK_VKR(vkCreateImageView(device, vkh::ImageViewCreateInfo(img.image, VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT), + NULL, &view2)); + + vkh::updateDescriptorSets( + device, { + // bind view1 to binding 0, we will override this + vkh::WriteDescriptorSet(descset2, 0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + {vkh::DescriptorImageInfo(view1)}), + // we bind view2 to binding 1. This will become stale + vkh::WriteDescriptorSet(descset2, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + {vkh::DescriptorImageInfo(view2)}), + }); + + vkDestroyImageView(device, view2, NULL); + + // create view3. Under RD, this is expected to get the same handle as view2 (but a new ID) + VkImageView view3; + CHECK_VKR(vkCreateImageView(device, vkh::ImageViewCreateInfo(img.image, VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT), + NULL, &view3)); + + if(rdoc) + { + TEST_ASSERT(view2 == view3, + "Expected view3 to be a re-used handle. Test isn't going to be valid"); + } + + vkh::updateDescriptorSets( + device, + { + // bind view3 to 0. This means the same handle is now in both binding but only binding 0 + // is valid, binding 1 refers to the 'old' version of this handle. + vkh::WriteDescriptorSet(descset2, 0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + {vkh::DescriptorImageInfo(view3)}), + // this unbinds the stale view2. Nothing should happen, but if we're comparing by handle + // this may remove a reference to view3 since it will have the same handle + vkh::WriteDescriptorSet(descset2, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + {vkh::DescriptorImageInfo(view1)}), + }); + while(Running()) { VkCommandBuffer cmd = GetCommandBuffer(); @@ -498,6 +588,11 @@ void main() vkCmdDraw(cmd, 3, 1, 0, 0); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2); + vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout2, 0, {descset2}, {}); + + vkCmdDraw(cmd, 3, 1, 0, 0); + vkCmdEndRenderPass(cmd); FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL); @@ -509,6 +604,13 @@ void main() Present(); } + vkDeviceWaitIdle(device); + + vkDestroySampler(device, validSampler, NULL); + + vkDestroyImageView(device, view1, NULL); + vkDestroyImageView(device, view3, NULL); + if(KHR_descriptor_update_template && KHR_push_descriptor) vkDestroyDescriptorUpdateTemplateKHR(device, pushtempl, NULL); diff --git a/util/test/tests/Vulkan/VK_Parameter_Zoo.py b/util/test/tests/Vulkan/VK_Parameter_Zoo.py index 7d9faffd1..acc8589f4 100644 --- a/util/test/tests/Vulkan/VK_Parameter_Zoo.py +++ b/util/test/tests/Vulkan/VK_Parameter_Zoo.py @@ -6,37 +6,14 @@ class VK_Parameter_Zoo(rdtest.TestCase): demos_test_name = 'VK_Parameter_Zoo' def check_capture(self): - draw = self.find_draw("Draw") + draw = self.get_last_draw() + + self.check(draw is not None) + + draw = draw.previous self.controller.SetFrameEvent(draw.eventId, False) - postvs_data = self.get_postvs(rd.MeshDataStage.VSOut, 0, draw.numIndices) + pipe: rd.PipeState = self.controller.GetPipelineState() - postvs_ref = { - 0: { - 'vtx': 0, - 'idx': 0, - 'gl_PerVertex.gl_Position': [-0.5, 0.5, 0.0, 1.0], - 'vertOut.pos': [-0.5, 0.5, 0.0, 1.0], - 'vertOut.col': [1.0, 0.0, 0.0, 1.0], - 'vertOut.uv': [0.0, 0.0, 0.0, 1.0], - }, - 1: { - 'vtx': 1, - 'idx': 1, - 'gl_PerVertex.gl_Position': [0.0, -0.5, 0.0, 1.0], - 'vertOut.pos': [0.0, -0.5, 0.0, 1.0], - 'vertOut.col': [0.0, 1.0, 0.0, 1.0], - 'vertOut.uv': [0.0, 1.0, 0.0, 1.0], - }, - 2: { - 'vtx': 2, - 'idx': 2, - 'gl_PerVertex.gl_Position': [0.5, 0.5, 0.0, 1.0], - 'vertOut.pos': [0.5, 0.5, 0.0, 1.0], - 'vertOut.col': [0.0, 0.0, 1.0, 1.0], - 'vertOut.uv': [1.0, 0.0, 0.0, 1.0], - }, - } - - self.check_mesh_data(postvs_ref, postvs_data) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [0.0, 1.0, 0.0, 1.0])