Implement VK_KHR_push_descriptor extension. Closes #905

This commit is contained in:
baldurk
2018-04-24 14:41:57 +01:00
parent ad5a0d7417
commit 94548886eb
20 changed files with 654 additions and 45 deletions
@@ -769,9 +769,11 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
const rdcarray<VKPipe::BindingElement> *slotBinds = NULL;
BindType bindType = BindType::Unknown;
ShaderStageMask stageBits = ShaderStageMask::Unknown;
bool pushDescriptor = false;
if(bindset < pipe.descriptorSets.count() && bind < pipe.descriptorSets[bindset].bindings.count())
{
pushDescriptor = pipe.descriptorSets[bindset].pushDescriptor;
slotBinds = &pipe.descriptorSets[bindset].bindings[bind].binds;
bindType = pipe.descriptorSets[bindset].bindings[bind].type;
stageBits = pipe.descriptorSets[bindset].bindings[bind].stageFlags;
@@ -817,6 +819,9 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
QString setname = QString::number(bindset);
if(pushDescriptor)
setname = tr("Push ") + setname;
QString slotname = QString::number(bind);
if(shaderRes && !shaderRes->name.isEmpty())
slotname += lit(": ") + shaderRes->name;
@@ -931,7 +936,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
if(!isbuf)
{
node = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(), setname, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(),
});
@@ -945,7 +950,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
QFormatStr("Viewing bytes %1 - %2").arg(descriptorBind->byteOffset).arg(descriptorLen);
node = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType),
QString(), setname, slotname, ToQStr(bindType),
descriptorBind ? descriptorBind->resourceResourceId : ResourceId(),
tr("%1 bytes").arg(len), range, QString(),
});
@@ -966,7 +971,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
range = QFormatStr("bytes %1 - %2").arg(descriptorBind->byteOffset).arg(descriptorLen);
node = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType),
QString(), setname, slotname, ToQStr(bindType),
descriptorBind ? descriptorBind->resourceResourceId : ResourceId(), format, range,
QString(),
});
@@ -984,7 +989,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
if(descriptorBind == NULL || descriptorBind->samplerResourceId == ResourceId())
{
node = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(), setname, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(),
});
@@ -992,8 +997,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
}
else
{
node =
new RDTreeWidgetItem(makeSampler(QString::number(bindset), slotname, *descriptorBind));
node = new RDTreeWidgetItem(makeSampler(setname, slotname, *descriptorBind));
if(!filledSlot)
setEmptyRow(node);
@@ -1014,7 +1018,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
if(descriptorBind == NULL || descriptorBind->resourceResourceId == ResourceId())
{
node = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(), setname, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(),
});
@@ -1055,7 +1059,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
dim += QFormatStr(", %1x MSAA").arg(samples);
node = new RDTreeWidgetItem({
QString(), bindset, slotname, typeName, descriptorBind->resourceResourceId, dim,
QString(), setname, slotname, typeName, descriptorBind->resourceResourceId, dim,
format, QString(),
});
@@ -1073,7 +1077,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
if(descriptorBind == NULL || descriptorBind->samplerResourceId == ResourceId())
{
samplerNode = new RDTreeWidgetItem({
QString(), bindset, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(), setname, slotname, ToQStr(bindType), ResourceId(), lit("-"), QString(),
QString(),
});
@@ -1151,8 +1155,11 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
BindType bindType = BindType::ConstantBuffer;
ShaderStageMask stageBits = ShaderStageMask::Unknown;
bool pushDescriptor = false;
if(bindset < pipe.descriptorSets.count() && bind < pipe.descriptorSets[bindset].bindings.count())
{
pushDescriptor = pipe.descriptorSets[bindset].pushDescriptor;
slotBinds = &pipe.descriptorSets[bindset].bindings[bind].binds;
bindType = pipe.descriptorSets[bindset].bindings[bind].type;
stageBits = pipe.descriptorSets[bindset].bindings[bind].stageFlags;
@@ -1183,6 +1190,9 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
QString setname = QString::number(bindset);
if(pushDescriptor)
setname = tr("Push ") + setname;
QString slotname = QString::number(bind);
if(cblock != NULL && !cblock->name.isEmpty())
slotname += lit(": ") + cblock->name;
@@ -2581,6 +2591,9 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
QString setname = QString::number(bindMap.bindset);
if(set.pushDescriptor)
setname = tr("Push ") + setname;
QString slotname = QFormatStr("%1: %2").arg(bindMap.bind).arg(b.name);
for(uint32_t a = 0; a < bind.descriptorCount; a++)
@@ -2643,6 +2656,9 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
QString setname = QString::number(bindMap.bindset);
if(set.pushDescriptor)
setname = tr("Push ") + setname;
QString slotname = QFormatStr("%1: %2").arg(bindMap.bind).arg(b.name);
for(uint32_t a = 0; a < bind.descriptorCount; a++)
@@ -2756,6 +2772,9 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
QString setname = QString::number(bindMap.bindset);
if(set.pushDescriptor)
setname = tr("Push ") + setname;
QString slotname = QFormatStr("%1: %2").arg(bindMap.bind).arg(b.name);
for(uint32_t a = 0; a < bind.descriptorCount; a++)
+6 -1
View File
@@ -218,7 +218,8 @@ struct DescriptorSet
bool operator==(const DescriptorSet &o) const
{
return layoutResourceId == o.layoutResourceId &&
descriptorSetResourceId == o.descriptorSetResourceId && bindings == o.bindings;
descriptorSetResourceId == o.descriptorSetResourceId &&
pushDescriptor == o.pushDescriptor && bindings == o.bindings;
}
bool operator<(const DescriptorSet &o) const
{
@@ -226,6 +227,8 @@ struct DescriptorSet
return layoutResourceId < o.layoutResourceId;
if(!(descriptorSetResourceId == o.descriptorSetResourceId))
return descriptorSetResourceId < o.descriptorSetResourceId;
if(!(pushDescriptor == o.pushDescriptor))
return pushDescriptor < o.pushDescriptor;
if(!(bindings == o.bindings))
return bindings < o.bindings;
return false;
@@ -234,6 +237,8 @@ struct DescriptorSet
ResourceId layoutResourceId;
DOCUMENT("The :class:`ResourceId` of the descriptor set object.");
ResourceId descriptorSetResourceId;
DOCUMENT("Indicates if this is a virtual 'push' descriptor set.");
bool pushDescriptor = false;
DOCUMENT(R"(A list of :class:`VKDescriptorBinding` with the bindings within this set.
This list is indexed by the binding, so it may be sparse (some entries do not contain any elements).
+1
View File
@@ -439,6 +439,7 @@ enum class VulkanChunk : uint32_t
vkRegisterDeviceEventEXT,
vkRegisterDisplayEventEXT,
vkCmdIndirectSubCommand,
vkCmdPushDescriptorSetKHR,
Max,
};
+8 -1
View File
@@ -623,6 +623,9 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_KHR_MAINTENANCE1_SPEC_VERSION,
},
{
VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION,
},
{
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION,
@@ -2226,6 +2229,11 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
return true;
break;
case VulkanChunk::vkCmdPushDescriptorSetKHR:
return Serialise_vkCmdPushDescriptorSetKHR(
ser, VK_NULL_HANDLE, VK_PIPELINE_BIND_POINT_GRAPHICS, VK_NULL_HANDLE, 0, 0, NULL);
break;
default:
{
SystemChunk system = (SystemChunk)chunk;
@@ -2865,7 +2873,6 @@ void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, vector<DebugMessa
DescriptorSetInfo &descset = m_DescriptorSetState[descSets[bindset].descSet];
DescSetLayout &layout = c.m_DescSetLayout[descset.layout];
ResourceId origId = GetResourceManager()->GetOriginalID(descSets[bindset].descSet);
ResourceId layoutId = GetResourceManager()->GetOriginalID(descset.layout);
if(layout.bindings.empty())
+16 -3
View File
@@ -186,6 +186,7 @@ class WrappedVulkan : public IFrameCapturer
private:
friend class VulkanReplay;
friend class VulkanDebugManager;
friend struct VulkanRenderState;
friend class VulkanShaderCache;
struct ScopedDebugMessageSink
@@ -473,6 +474,8 @@ private:
std::vector<std::pair<ResourceId, ImageRegionState> > imgbarriers;
ResourceId pushDescriptorID[64];
VulkanDrawcallTreeNode *draw; // the root draw to copy from when submitting
uint32_t eventCount; // how many events are in this cmd buffer, for quick skipping
uint32_t curEventID; // current event ID while reading or executing
@@ -586,14 +589,18 @@ private:
// need it on replay too
struct DescriptorSetInfo
{
~DescriptorSetInfo()
~DescriptorSetInfo() { clear(); }
ResourceId layout;
vector<DescriptorSetSlot *> currentBindings;
void clear()
{
layout = ResourceId();
for(size_t i = 0; i < currentBindings.size(); i++)
delete[] currentBindings[i];
currentBindings.clear();
}
ResourceId layout;
vector<DescriptorSetSlot *> currentBindings;
};
// capture-side data
@@ -1626,4 +1633,10 @@ public:
// VK_AMD_shader_info
VkResult vkGetShaderInfoAMD(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage,
VkShaderInfoTypeAMD infoType, size_t *pInfoSize, void *pInfo);
// VK_KHR_push_descriptor
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdPushDescriptorSetKHR, VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
uint32_t set, uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites);
};
+6 -1
View File
@@ -300,7 +300,8 @@
CheckExt(VK_KHR_external_semaphore_win32); \
CheckExt(VK_KHR_external_semaphore_fd); \
CheckExt(VK_KHR_get_memory_requirements2); \
CheckExt(VK_AMD_shader_info);
CheckExt(VK_AMD_shader_info); \
CheckExt(VK_KHR_push_descriptor);
#define HookInitVulkanInstanceExts() \
HookInitExtension(VK_KHR_surface, DestroySurfaceKHR); \
@@ -363,6 +364,7 @@
HookInitExtension(VK_KHR_get_memory_requirements2, GetImageMemoryRequirements2KHR); \
HookInitExtension(VK_KHR_get_memory_requirements2, GetImageSparseMemoryRequirements2KHR); \
HookInitExtension(VK_AMD_shader_info, GetShaderInfoAMD); \
HookInitExtension(VK_KHR_push_descriptor, CmdPushDescriptorSetKHR); \
HookInitDevice_PlatformSpecific()
#define DefineHooks() \
@@ -776,6 +778,9 @@
HookDefine6(VkResult, vkGetShaderInfoAMD, VkDevice, device, VkPipeline, pipeline, \
VkShaderStageFlagBits, shaderStage, VkShaderInfoTypeAMD, infoType, size_t *, \
pInfoSize, void *, pInfo); \
HookDefine6(void, vkCmdPushDescriptorSetKHR, VkCommandBuffer, commandBuffer, \
VkPipelineBindPoint, pipelineBindPoint, VkPipelineLayout, layout, uint32_t, set, \
uint32_t, descriptorWriteCount, const VkWriteDescriptorSet *, pDescriptorWrites); \
HookDefine_PlatformSpecific()
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
+30 -1
View File
@@ -30,6 +30,8 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
{
dynamicCount = 0;
flags = pCreateInfo->flags;
// descriptor set layouts can be sparse, such that only three bindings exist
// but they are at 0, 5 and 10.
// We assume here that while the layouts may be sparse that's mostly to allow
@@ -63,7 +65,7 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
}
}
void DescSetLayout::CreateBindingsArray(vector<DescriptorSetSlot *> &descBindings)
void DescSetLayout::CreateBindingsArray(std::vector<DescriptorSetSlot *> &descBindings) const
{
descBindings.resize(bindings.size());
for(size_t i = 0; i < bindings.size(); i++)
@@ -73,6 +75,33 @@ void DescSetLayout::CreateBindingsArray(vector<DescriptorSetSlot *> &descBinding
}
}
void DescSetLayout::UpdateBindingsArray(const DescSetLayout &prevLayout,
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++)
SAFE_DELETE_ARRAY(descBindings[i]);
// resize to the new number of bindings
descBindings.resize(bindings.size());
// re-allocate slots and move any previous bindings that overlapped over.
for(size_t i = 0; i < bindings.size(); i++)
{
// allocate new slot array
DescriptorSetSlot *newSlots = new DescriptorSetSlot[bindings[i].descriptorCount];
// copy over any previous bindings that overlapped
memcpy(newSlots, descBindings[i],
sizeof(DescriptorSetSlot) *
RDCMIN(prevLayout.bindings[i].descriptorCount, bindings[i].descriptorCount));
// delete old array, and assign the new one
SAFE_DELETE_ARRAY(descBindings[i]);
descBindings[i] = newSlots;
}
}
bool DescSetLayout::operator==(const DescSetLayout &other) const
{
// shortcut for equality to ourselves
+4 -1
View File
@@ -35,7 +35,9 @@ struct DescSetLayout
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo);
void CreateBindingsArray(vector<DescriptorSetSlot *> &descBindings);
void CreateBindingsArray(std::vector<DescriptorSetSlot *> &descBindings) const;
void UpdateBindingsArray(const DescSetLayout &prevLayout,
std::vector<DescriptorSetSlot *> &descBindings) const;
struct Binding
{
@@ -71,6 +73,7 @@ struct DescSetLayout
vector<Binding> bindings;
uint32_t dynamicCount;
VkDescriptorSetLayoutCreateFlags flags;
bool operator==(const DescSetLayout &other) const;
bool operator!=(const DescSetLayout &other) const { return !(*this == other); }
+26 -11
View File
@@ -55,21 +55,30 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
VkInitialContents initialContents(type, VkInitialContents::DescriptorSet);
for(size_t i = 0; i < layout.bindings.size(); i++)
initialContents.numDescriptors += layout.bindings[i].descriptorCount;
initialContents.descriptorSlots = new DescriptorSetSlot[initialContents.numDescriptors];
RDCEraseMem(initialContents.descriptorSlots,
sizeof(DescriptorSetSlot) * initialContents.numDescriptors);
uint32_t e = 0;
for(size_t i = 0; i < layout.bindings.size(); i++)
if((layout.flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) == 0)
{
for(uint32_t b = 0; b < layout.bindings[i].descriptorCount; b++)
for(size_t i = 0; i < layout.bindings.size(); i++)
initialContents.numDescriptors += layout.bindings[i].descriptorCount;
initialContents.descriptorSlots = new DescriptorSetSlot[initialContents.numDescriptors];
RDCEraseMem(initialContents.descriptorSlots,
sizeof(DescriptorSetSlot) * initialContents.numDescriptors);
uint32_t e = 0;
for(size_t i = 0; i < layout.bindings.size(); i++)
{
initialContents.descriptorSlots[e++] = record->descInfo->descBindings[i][b];
for(uint32_t b = 0; b < layout.bindings[i].descriptorCount; b++)
{
initialContents.descriptorSlots[e++] = record->descInfo->descBindings[i][b];
}
}
}
else
{
RDCERR("Push descriptor set with initial contents! Should never have been marked dirty");
initialContents.numDescriptors = 0;
initialContents.descriptorSlots = NULL;
}
GetResourceManager()->SetInitialContents(id, initialContents);
return true;
@@ -565,6 +574,12 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W
const DescSetLayout &layout =
m_CreationInfo.m_DescSetLayout[m_DescriptorSetState[liveid].layout];
if(layout.flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
{
RDCERR("Push descriptor set with initial contents!");
return true;
}
VkInitialContents initialContents(type, VkInitialContents::DescriptorSet);
initialContents.numDescriptors = (uint32_t)layout.bindings.size();
+12 -1
View File
@@ -1194,7 +1194,18 @@ void VulkanReplay::SavePipelineState()
ResourceId layoutId = m_pDriver->m_DescriptorSetState[src].layout;
dst.descriptorSetResourceId = rm->GetOriginalID(src);
// push descriptors don't have a real descriptor set backing them
if(c.m_DescSetLayout[layoutId].flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
{
dst.descriptorSetResourceId = ResourceId();
dst.pushDescriptor = true;
}
else
{
dst.descriptorSetResourceId = rm->GetOriginalID(src);
dst.pushDescriptor = false;
}
dst.layoutResourceId = rm->GetOriginalID(layoutId);
dst.bindings.resize(m_pDriver->m_DescriptorSetState[src].currentBindings.size());
for(size_t b = 0; b < m_pDriver->m_DescriptorSetState[src].currentBindings.size(); b++)
+3
View File
@@ -833,6 +833,9 @@ VkResourceRecord::~VkResourceRecord()
if(resType == eResDescriptorSetLayout || resType == eResDescriptorSet)
SAFE_DELETE(descInfo);
if(resType == eResPipelineLayout)
SAFE_DELETE(pipeLayoutInfo);
}
void SparseMapping::Update(uint32_t numBindings, const VkSparseImageMemoryBind *pBindings)
+6
View File
@@ -919,6 +919,11 @@ struct DescriptorSetData
map<ResourceId, pair<uint32_t, FrameRefType> > bindFrameRefs;
};
struct PipelineLayoutData
{
std::vector<DescSetLayout> layouts;
};
struct MemMapState
{
MemMapState()
@@ -1062,6 +1067,7 @@ public:
MemMapState *memMapState; // only for device memory
CmdBufferRecordingInfo *cmdInfo; // only for command buffers
AttachmentInfo *imageAttachments; // only for framebuffers and render passes
PipelineLayoutData *pipeLayoutInfo; // only for pipeline layouts
DescriptorSetData *descInfo; // only for descriptor sets and descriptor set layouts
};
+100 -10
View File
@@ -246,11 +246,8 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding bindin
}
}
ObjDisp(cmd)->CmdBindDescriptorSets(
Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, 1,
UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(
graphics.descSets[i].descSet)),
descLayout.dynamicCount, dynamicOffsets);
BindDescriptorSet(descLayout, cmd, layout, VK_PIPELINE_BIND_POINT_GRAPHICS, (uint32_t)i,
dynamicOffsets);
if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount)
SAFE_DELETE_ARRAY(dynamicOffsets);
@@ -315,11 +312,8 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding bindin
}
}
ObjDisp(cmd)->CmdBindDescriptorSets(
Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(layout), (uint32_t)i, 1,
UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(
compute.descSets[i].descSet)),
descLayout.dynamicCount, dynamicOffsets);
BindDescriptorSet(descLayout, cmd, layout, VK_PIPELINE_BIND_POINT_COMPUTE, (uint32_t)i,
dynamicOffsets);
if(compute.descSets[i].offsets.size() < descLayout.dynamicCount)
SAFE_DELETE_ARRAY(dynamicOffsets);
@@ -328,6 +322,102 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding bindin
}
}
void VulkanRenderState::BindDescriptorSet(const DescSetLayout &descLayout, VkCommandBuffer cmd,
VkPipelineLayout layout, VkPipelineBindPoint bindPoint,
uint32_t setIndex, uint32_t *dynamicOffsets)
{
ResourceId descSet = (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
? graphics.descSets[setIndex].descSet
: compute.descSets[setIndex].descSet;
if((descLayout.flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) == 0)
{
ObjDisp(cmd)->CmdBindDescriptorSets(
Unwrap(cmd), bindPoint, Unwrap(layout), (uint32_t)setIndex, 1,
UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(descSet)),
descLayout.dynamicCount, dynamicOffsets);
}
else
{
// this isn't a real descriptor set, it's a push descriptor, so we need to push the
// current state.
std::vector<VkWriteDescriptorSet> writes;
WrappedVulkan::DescriptorSetInfo &setInfo = m_pDriver->m_DescriptorSetState[descSet];
for(size_t b = 0; b < descLayout.bindings.size(); b++)
{
VkWriteDescriptorSet push = {};
// skip if this binding isn't used
if(descLayout.bindings[b].descriptorCount == 0)
continue;
push.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
// push.dstSet; // unused for push descriptors
push.dstBinding = (uint32_t)b;
push.dstArrayElement = 0;
push.descriptorType = descLayout.bindings[b].descriptorType;
push.descriptorCount = descLayout.bindings[b].descriptorCount;
DescriptorSetSlot *slots = setInfo.currentBindings[b];
if(push.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
push.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
VkBufferView *dst = new VkBufferView[push.descriptorCount];
for(uint32_t a = 0; a < push.descriptorCount; a++)
dst[a] = Unwrap(slots[a].texelBufferView);
push.pTexelBufferView = dst;
}
else if(push.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
push.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
push.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
push.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
push.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
{
VkDescriptorImageInfo *dst = new VkDescriptorImageInfo[push.descriptorCount];
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);
}
push.pImageInfo = dst;
}
else
{
VkDescriptorBufferInfo *dst = new VkDescriptorBufferInfo[push.descriptorCount];
for(uint32_t a = 0; a < push.descriptorCount; a++)
{
dst[a] = slots[a].bufferInfo;
dst[a].buffer = Unwrap(dst[a].buffer);
}
push.pBufferInfo = dst;
}
writes.push_back(push);
}
ObjDisp(cmd)->CmdPushDescriptorSetKHR(Unwrap(cmd), bindPoint, Unwrap(layout), setIndex,
(uint32_t)writes.size(), writes.data());
// delete dynamically allocated arrays
for(VkWriteDescriptorSet &push : writes)
{
SAFE_DELETE_ARRAY(push.pImageInfo);
SAFE_DELETE_ARRAY(push.pBufferInfo);
SAFE_DELETE_ARRAY(push.pTexelBufferView);
}
}
}
void VulkanRenderState::EndRenderPass(VkCommandBuffer cmd)
{
ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd));
+5
View File
@@ -30,6 +30,7 @@
struct VulkanCreationInfo;
class VulkanResourceManager;
class WrappedVulkan;
struct DescSetLayout;
struct VulkanRenderState
{
@@ -46,6 +47,10 @@ struct VulkanRenderState
void EndRenderPass(VkCommandBuffer cmd);
void BindPipeline(VkCommandBuffer cmd, PipelineBinding binding, bool subpass0);
void BindDescriptorSet(const DescSetLayout &descLayout, VkCommandBuffer cmd,
VkPipelineLayout layout, VkPipelineBindPoint bindPoint, uint32_t setIndex,
uint32_t *dynamicOffsets);
// dynamic state
vector<VkViewport> views;
vector<VkRect2D> scissors;
+2 -1
View File
@@ -28,7 +28,7 @@
template <>
std::string DoStringise(const VulkanChunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1098, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1099, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(VulkanChunk)
{
@@ -130,6 +130,7 @@ std::string DoStringise(const VulkanChunk &el)
STRINGISE_ENUM_CLASS(vkRegisterDeviceEventEXT);
STRINGISE_ENUM_CLASS(vkRegisterDisplayEventEXT);
STRINGISE_ENUM_CLASS_NAMED(vkCmdIndirectSubCommand, "Indirect sub-command");
STRINGISE_ENUM_CLASS(vkCmdPushDescriptorSetKHR);
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
@@ -594,6 +594,21 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman
{
m_LastCmdBufferID = CommandBuffer;
// when loading, allocate a new resource ID for each push descriptor slot in this command buffer
if(IsLoading(m_State))
{
for(size_t i = 0; i < ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID); i++)
m_BakedCmdBufferInfo[BakedCommandBuffer].pushDescriptorID[i] =
ResourceIDGen::GetNewUniqueID();
}
// clear/invalidate descriptor set state for this command buffer.
for(size_t i = 0; i < ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID); i++)
{
m_DescriptorSetState[m_BakedCmdBufferInfo[BakedCommandBuffer].pushDescriptorID[i]] =
DescriptorSetInfo();
}
m_BakedCmdBufferInfo[m_LastCmdBufferID].level = m_BakedCmdBufferInfo[BakedCommandBuffer].level =
AllocateInfo.level;
m_BakedCmdBufferInfo[m_LastCmdBufferID].beginFlags =
@@ -2924,6 +2939,368 @@ void WrappedVulkan::vkCmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer,
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdPushDescriptorSetKHR(SerialiserType &ser,
VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout, uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites)
{
SERIALISE_ELEMENT(commandBuffer);
SERIALISE_ELEMENT(pipelineBindPoint);
SERIALISE_ELEMENT(layout);
SERIALISE_ELEMENT(set);
SERIALISE_ELEMENT(descriptorWriteCount);
SERIALISE_ELEMENT_ARRAY(pDescriptorWrites, descriptorWriteCount);
Serialise_DebugMessages(ser);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
ResourceId setId = m_BakedCmdBufferInfo[m_LastCmdBufferID].pushDescriptorID[set];
if(IsActiveReplaying(m_State))
{
if(InRerecordRange(m_LastCmdBufferID))
{
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
if(IsPartialCmdBuf(m_LastCmdBufferID))
{
std::vector<VulkanRenderState::Pipeline::DescriptorAndOffsets> &descsets =
(pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_RenderState.graphics.descSets
: m_RenderState.compute.descSets;
// expand as necessary
if(descsets.size() < set + 1)
descsets.resize(set + 1);
descsets[set].descSet = setId;
}
// actual replay of the command will happen below
}
else
{
commandBuffer = VK_NULL_HANDLE;
}
}
else
{
// track while reading, as we need to track resource usage
std::vector<BakedCmdBufferInfo::CmdBufferState::DescriptorAndOffsets> &descsets =
(pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_BakedCmdBufferInfo[m_LastCmdBufferID].state.graphicsDescSets
: m_BakedCmdBufferInfo[m_LastCmdBufferID].state.computeDescSets;
// expand as necessary
if(descsets.size() < set + 1)
descsets.resize(set + 1);
// we use a 'special' ID for the push descriptor at this index, since there's no actual
// allocated object corresponding to it.
descsets[set].descSet = setId;
}
if(commandBuffer != VK_NULL_HANDLE)
{
// since we version push descriptors per-command buffer, we can safely update them always
// without worrying about overlap. We just need to check that we're in the record range so
// that we don't pull in descriptor updates after the point in the command buffer we're
// recording to
{
const std::vector<ResourceId> &descSetLayouts =
m_CreationInfo.m_PipelineLayout[GetResID(layout)].descSetLayouts;
const DescSetLayout &desclayout = m_CreationInfo.m_DescSetLayout[descSetLayouts[set]];
for(uint32_t i = 0; i < descriptorWriteCount; i++)
{
const VkWriteDescriptorSet &writeDesc = pDescriptorWrites[i];
// update our local tracking
std::vector<DescriptorSetSlot *> &bindings = m_DescriptorSetState[setId].currentBindings;
ResourceId prevLayout = m_DescriptorSetState[setId].layout;
if(prevLayout == ResourceId())
{
desclayout.CreateBindingsArray(bindings);
}
else if(prevLayout != descSetLayouts[set])
{
desclayout.UpdateBindingsArray(m_CreationInfo.m_DescSetLayout[prevLayout], bindings);
}
m_DescriptorSetState[setId].layout = descSetLayouts[set];
RDCASSERT(writeDesc.dstBinding < bindings.size());
DescriptorSetSlot **bind = &bindings[writeDesc.dstBinding];
const DescSetLayout::Binding *layoutBinding = &desclayout.bindings[writeDesc.dstBinding];
uint32_t curIdx = writeDesc.dstArrayElement;
if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
for(uint32_t d = 0; d < writeDesc.descriptorCount; d++, curIdx++)
{
// allow consecutive descriptor bind updates. See vkUpdateDescriptorSets for more
// explanation
if(curIdx >= layoutBinding->descriptorCount)
{
layoutBinding++;
bind++;
curIdx = 0;
}
(*bind)[curIdx].texelBufferView = writeDesc.pTexelBufferView[d];
}
}
else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
{
for(uint32_t d = 0; d < writeDesc.descriptorCount; d++, curIdx++)
{
// allow consecutive descriptor bind updates. See vkUpdateDescriptorSets for more
// explanation
if(curIdx >= layoutBinding->descriptorCount)
{
layoutBinding++;
bind++;
curIdx = 0;
}
(*bind)[curIdx].imageInfo = writeDesc.pImageInfo[d];
}
}
else
{
for(uint32_t d = 0; d < writeDesc.descriptorCount; d++, curIdx++)
{
// allow consecutive descriptor bind updates. See vkUpdateDescriptorSets for more
// explanation
if(curIdx >= layoutBinding->descriptorCount)
{
layoutBinding++;
bind++;
curIdx = 0;
}
(*bind)[curIdx].bufferInfo = writeDesc.pBufferInfo[d];
}
}
}
}
// now unwrap everything in-place to save on temp allocs.
VkWriteDescriptorSet *writes = (VkWriteDescriptorSet *)pDescriptorWrites;
for(uint32_t i = 0; i < descriptorWriteCount; i++)
{
for(uint32_t d = 0; d < writes[i].descriptorCount; d++)
{
VkBufferView *pTexelBufferView = (VkBufferView *)writes[i].pTexelBufferView;
VkDescriptorBufferInfo *pBufferInfo = (VkDescriptorBufferInfo *)writes[i].pBufferInfo;
VkDescriptorImageInfo *pImageInfo = (VkDescriptorImageInfo *)writes[i].pImageInfo;
if(pTexelBufferView)
pTexelBufferView[d] = Unwrap(pTexelBufferView[d]);
if(pBufferInfo)
pBufferInfo[d].buffer = Unwrap(pBufferInfo[d].buffer);
if(pImageInfo)
{
pImageInfo[d].imageView = Unwrap(pImageInfo[d].imageView);
pImageInfo[d].sampler = Unwrap(pImageInfo[d].sampler);
}
}
}
ObjDisp(commandBuffer)
->CmdPushDescriptorSetKHR(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(layout), set,
descriptorWriteCount, pDescriptorWrites);
}
}
return true;
}
void WrappedVulkan::vkCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout, uint32_t set,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites)
{
SCOPED_DBG_SINK();
{
// need to count up number of descriptor infos, to be able to alloc enough space
uint32_t numInfos = 0;
for(uint32_t i = 0; i < descriptorWriteCount; i++)
numInfos += pDescriptorWrites[i].descriptorCount;
byte *memory = GetTempMemory(sizeof(VkDescriptorBufferInfo) * numInfos +
sizeof(VkWriteDescriptorSet) * descriptorWriteCount);
RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkDescriptorImageInfo),
"Descriptor structs sizes are unexpected, ensure largest size is used");
VkWriteDescriptorSet *unwrappedWrites = (VkWriteDescriptorSet *)memory;
VkDescriptorBufferInfo *nextDescriptors =
(VkDescriptorBufferInfo *)(unwrappedWrites + descriptorWriteCount);
for(uint32_t i = 0; i < descriptorWriteCount; i++)
{
unwrappedWrites[i] = pDescriptorWrites[i];
unwrappedWrites[i].dstSet = Unwrap(unwrappedWrites[i].dstSet);
VkDescriptorBufferInfo *bufInfos = nextDescriptors;
VkDescriptorImageInfo *imInfos = (VkDescriptorImageInfo *)bufInfos;
VkBufferView *bufViews = (VkBufferView *)bufInfos;
nextDescriptors += pDescriptorWrites[i].descriptorCount;
RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkDescriptorImageInfo),
"Structure sizes mean not enough space is allocated for write data");
RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkBufferView),
"Structure sizes mean not enough space is allocated for write data");
// unwrap and assign the appropriate array
if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
unwrappedWrites[i].pTexelBufferView = (VkBufferView *)bufInfos;
for(uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++)
bufViews[j] = Unwrap(pDescriptorWrites[i].pTexelBufferView[j]);
}
else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
{
bool hasSampler =
(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
bool hasImage =
(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
unwrappedWrites[i].pImageInfo = (VkDescriptorImageInfo *)bufInfos;
for(uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++)
{
if(hasImage)
imInfos[j].imageView = Unwrap(pDescriptorWrites[i].pImageInfo[j].imageView);
if(hasSampler)
imInfos[j].sampler = Unwrap(pDescriptorWrites[i].pImageInfo[j].sampler);
imInfos[j].imageLayout = pDescriptorWrites[i].pImageInfo[j].imageLayout;
}
}
else
{
unwrappedWrites[i].pBufferInfo = bufInfos;
for(uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++)
{
bufInfos[j].buffer = Unwrap(pDescriptorWrites[i].pBufferInfo[j].buffer);
bufInfos[j].offset = pDescriptorWrites[i].pBufferInfo[j].offset;
bufInfos[j].range = pDescriptorWrites[i].pBufferInfo[j].range;
}
}
}
SERIALISE_TIME_CALL(ObjDisp(commandBuffer)
->CmdPushDescriptorSetKHR(Unwrap(commandBuffer), pipelineBindPoint,
Unwrap(layout), set, descriptorWriteCount,
unwrappedWrites));
}
if(IsCaptureMode(m_State))
{
VkResourceRecord *record = GetRecord(commandBuffer);
CACHE_THREAD_SERIALISER();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdPushDescriptorSetKHR);
Serialise_vkCmdPushDescriptorSetKHR(ser, commandBuffer, pipelineBindPoint, layout, set,
descriptorWriteCount, pDescriptorWrites);
record->AddChunk(scope.Get());
for(uint32_t i = 0; i < descriptorWriteCount; i++)
{
const VkWriteDescriptorSet &write = pDescriptorWrites[i];
FrameRefType ref = eFrameRef_Write;
switch(write.descriptorType)
{
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: ref = eFrameRef_Read; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: ref = eFrameRef_Write; break;
default: RDCERR("Unexpected descriptor type");
}
for(uint32_t d = 0; d < write.descriptorCount; d++)
{
if(write.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
write.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
record->MarkResourceFrameReferenced(GetResID(write.pTexelBufferView[d]), eFrameRef_Read);
if(GetRecord(write.pTexelBufferView[d])->baseResource != ResourceId())
record->MarkResourceFrameReferenced(GetRecord(write.pTexelBufferView[d])->baseResource,
ref);
}
else if(write.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
write.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
write.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
write.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
write.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
{
// ignore descriptors not part of the write, by NULL'ing out those members
// as they might not even point to a valid object
if(write.descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER)
{
record->MarkResourceFrameReferenced(GetResID(write.pImageInfo[d].imageView),
eFrameRef_Read);
if(GetRecord(write.pImageInfo[d].imageView)->baseResource != ResourceId())
record->MarkResourceFrameReferenced(
GetRecord(write.pImageInfo[d].imageView)->baseResource, ref);
}
if(write.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
write.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
record->MarkResourceFrameReferenced(GetResID(write.pImageInfo[d].sampler),
eFrameRef_Read);
}
else
{
record->MarkResourceFrameReferenced(GetResID(write.pBufferInfo[d].buffer), eFrameRef_Read);
if(GetRecord(write.pBufferInfo[d].buffer)->baseResource != ResourceId())
record->MarkResourceFrameReferenced(
GetRecord(write.pBufferInfo[d].buffer)->baseResource, ref);
}
}
}
}
}
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, VkDevice device,
const VkCommandPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool);
@@ -3011,3 +3388,8 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdDebugMarkerEndEXT, VkCommandBuffer co
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdDebugMarkerInsertEXT, VkCommandBuffer commandBuffer,
const VkDebugMarkerMarkerInfoEXT *pMarker);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdPushDescriptorSetKHR, VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
uint32_t set, uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites);
@@ -516,10 +516,15 @@ VkResult WrappedVulkan::vkAllocateDescriptorSets(VkDevice device,
capframe = IsActiveCapturing(m_State);
}
if(capframe)
GetResourceManager()->MarkPendingDirty(id);
else
GetResourceManager()->MarkDirtyResource(id);
// only mark descriptor set as dirty if it's not a push descriptor layout
if((layoutRecord->descInfo->layout->flags &
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) == 0)
{
if(capframe)
GetResourceManager()->MarkPendingDirty(id);
else
GetResourceManager()->MarkDirtyResource(id);
}
record->descInfo = new DescriptorSetData();
record->descInfo->layout = layoutRecord->descInfo->layout;
@@ -1248,6 +1248,10 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
ObjDisp(physicalDevice)
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);
RDCASSERT(m_PhysicalDeviceData.props.limits.maxBoundDescriptorSets <
ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID),
m_PhysicalDeviceData.props.limits.maxBoundDescriptorSets);
for(int i = VK_FORMAT_BEGIN_RANGE + 1; i < VK_FORMAT_END_RANGE; i++)
ObjDisp(physicalDevice)
->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), VkFormat(i),
@@ -180,10 +180,14 @@ VkResult WrappedVulkan::vkCreatePipelineLayout(VkDevice device,
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pPipelineLayout);
record->AddChunk(chunk);
record->pipeLayoutInfo = new PipelineLayoutData();
for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++)
{
VkResourceRecord *layoutrecord = GetRecord(pCreateInfo->pSetLayouts[i]);
record->AddParent(layoutrecord);
record->pipeLayoutInfo->layouts.push_back(*layoutrecord->descInfo->layout);
}
}
else
+2 -1
View File
@@ -1765,10 +1765,11 @@ void DoSerialise(SerialiserType &ser, VKPipe::DescriptorSet &el)
{
SERIALISE_MEMBER(layoutResourceId);
SERIALISE_MEMBER(descriptorSetResourceId);
SERIALISE_MEMBER(pushDescriptor);
SERIALISE_MEMBER(bindings);
SIZE_CHECK(32);
SIZE_CHECK(40);
}
template <typename SerialiserType>