mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Ensure re-used handles in descriptor sets don't cause problems
* Previously if a handle was reused, and then a stale descriptor referencing the old handle was removed it would remove the *new* object from the list of referenced resources. This could cause a resource to be not included in a capture if nothing else added a new reference.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@ private:
|
||||
DescriptorSetInfo &operator=(const DescriptorSetInfo &) = default;
|
||||
~DescriptorSetInfo() { clear(); }
|
||||
ResourceId layout;
|
||||
std::vector<DescriptorSetBindingElement *> currentBindings;
|
||||
std::vector<DescriptorSetSlot *> currentBindings;
|
||||
bool push;
|
||||
|
||||
void clear()
|
||||
|
||||
@@ -127,18 +127,18 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
|
||||
}
|
||||
}
|
||||
|
||||
void DescSetLayout::CreateBindingsArray(std::vector<DescriptorSetBindingElement *> &descBindings) const
|
||||
void DescSetLayout::CreateBindingsArray(std::vector<DescriptorSetSlot *> &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<DescriptorSetBindingElement *> &descBindings) const
|
||||
std::vector<DescriptorSetSlot *> &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
|
||||
|
||||
@@ -60,9 +60,9 @@ struct DescSetLayout
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkDescriptorSetLayoutCreateInfo *pCreateInfo);
|
||||
|
||||
void CreateBindingsArray(std::vector<DescriptorSetBindingElement *> &descBindings) const;
|
||||
void CreateBindingsArray(std::vector<DescriptorSetSlot *> &descBindings) const;
|
||||
void UpdateBindingsArray(const DescSetLayout &prevLayout,
|
||||
std::vector<DescriptorSetBindingElement *> &descBindings) const;
|
||||
std::vector<DescriptorSetSlot *> &descBindings) const;
|
||||
|
||||
struct Binding
|
||||
{
|
||||
|
||||
@@ -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<DescriptorSetBindingElement *> &bindings = m_DescriptorSetState[id].currentBindings;
|
||||
std::vector<DescriptorSetSlot *> &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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<VkSampler>(src.sampler);
|
||||
out[w].imageView = GetResourceManager()->GetCurrentHandle<VkImageView>(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<VkBufferView>(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<VkBuffer>(src.buffer);
|
||||
}
|
||||
write.pBufferInfo = out;
|
||||
allocBufWrites.push_back(out);
|
||||
break;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1013,7 +1013,7 @@ struct DescriptorSetData
|
||||
|
||||
// descriptor set bindings for this descriptor set. Filled out on
|
||||
// create from the layout.
|
||||
std::vector<DescriptorSetBindingElement *> descBindings;
|
||||
std::vector<DescriptorSetSlot *> descBindings;
|
||||
|
||||
// lock protecting bindFrameRefs and bindMemRefs
|
||||
Threading::CriticalSection refLock;
|
||||
|
||||
@@ -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<VkBufferView>(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<VkSampler>(src.sampler));
|
||||
dst[a].imageView =
|
||||
Unwrap(GetResourceManager()->GetCurrentHandle<VkImageView>(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<VkBuffer>(src.buffer));
|
||||
}
|
||||
|
||||
push.pBufferInfo = dst;
|
||||
|
||||
@@ -3728,7 +3728,7 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo
|
||||
|
||||
const DescSetLayout &desclayout = m_CreationInfo.m_DescSetLayout[descSetLayouts[set]];
|
||||
|
||||
std::vector<DescriptorSetBindingElement *> &bindings = m_DescriptorSetState[setId].currentBindings;
|
||||
std::vector<DescriptorSetSlot *> &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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DescriptorSetBindingElement *> &bindings =
|
||||
std::vector<DescriptorSetSlot *> &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<DescriptorSetBindingElement *> &dstbindings =
|
||||
m_DescriptorSetState[dstSetId].currentBindings;
|
||||
std::vector<DescriptorSetBindingElement *> &srcbindings =
|
||||
m_DescriptorSetState[srcSetId].currentBindings;
|
||||
std::vector<DescriptorSetSlot *> &dstbindings = m_DescriptorSetState[dstSetId].currentBindings;
|
||||
std::vector<DescriptorSetSlot *> &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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user