Skip to content

Commit

Permalink
Vulkan: Lazy create descriptor bindings and array elements in state (#…
Browse files Browse the repository at this point in the history
…2384)

* Vulkan: Lazy create descriptor bindings and array elements in state

Some applications allocate a lot of descriptors a head but only update a
few of them a few times. Allocating those bindings and elements only
when the descriptors are updated can reduce the state tracking overhead
for such cases.
  • Loading branch information
Qining authored Nov 22, 2018
1 parent 54c246e commit c928b2f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 41 deletions.
6 changes: 5 additions & 1 deletion gapii/cc/vulkan_inlines.inc
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ inline void VulkanSpy::vkErrInvalidImageLayout(CallObserver*, VkImage img, uint3

inline void VulkanSpy::vkErrInvalidImageSubresource(CallObserver*, VkImage img, std::string subresourceType, uint32_t value) {
GAPID_WARNING("Error: Accessing invalid image subresource at Image: %" PRIu64 ", %s: %" PRIu32, img, subresourceType.c_str(), value);
}
}

inline void VulkanSpy::vkErrInvalidDescriptorBindingType(CallObserver*, VkDescriptorSet set, uint32_t binding, uint32_t layout_type, uint32_t update_type) {
GAPID_WARNING("Error: Updating descriptor binding at: %" PRIu64 ": %" PRIu32 " with type: %" PRIu32 ", but the type defined in descriptor set layout is: %" PRIu32 "", set, binding, layout_type, update_type);
}
67 changes: 27 additions & 40 deletions gapis/api/vulkan/api/descriptor.api
Original file line number Diff line number Diff line change
Expand Up @@ -284,38 +284,6 @@ cmd VkResult vkAllocateDescriptorSets(
pool := DescriptorPools[info.descriptorPool]
pool.DescriptorSets[handle] = object
object.Layout = DescriptorSetLayouts[layouts[i]]
for j in (0 .. object.Layout.MaximumBinding + 1) {
if j in object.Layout.Bindings {
binding := object.Layout.Bindings[j]
descriptorBinding := new!DescriptorBinding(
BindingType: binding.Type)
imageInfos := descriptorBinding.ImageBinding
bufferInfos := descriptorBinding.BufferBinding
bufferViews := descriptorBinding.BufferViewBindings
for k in (0 .. binding.Count) {
switch binding.Type {
case VK_DESCRIPTOR_TYPE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
imageInfos[k] = new!VkDescriptorImageInfo()
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
bufferViews[k] = as!VkBufferView(0)
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
bufferInfos[k] = new!VkDescriptorBufferInfo()
}
}
descriptorBinding.ImageBinding = imageInfos
descriptorBinding.BufferBinding = bufferInfos
descriptorBinding.BufferViewBindings = bufferViews
object.Bindings[j] = descriptorBinding
}
}
DescriptorSets[handle] = object
}
}
Expand Down Expand Up @@ -575,7 +543,7 @@ cmd void vkUpdateDescriptorSets(
}
}
}

cs := pDescriptorCopies[0:descriptorCopyCount]
for i in (0 .. descriptorCopyCount) {
c := cs[i]
Expand All @@ -600,7 +568,16 @@ cmd void vkUpdateDescriptorSets(
set := DescriptorSets[w.DstSet]
binding := w.Binding
arrayIndex := w.BindingArrayIndex
setBinding := set.Bindings[binding]
setBinding := switch set.Bindings[binding] == null {
case false:
set.Bindings[binding]
case true:
new!DescriptorBinding(BindingType: set.Layout.Bindings[binding].Type)
}
if set.Layout.Bindings[binding].Type != setBinding.BindingType {
vkErrInvalidDescriptorBindingType(set.VulkanHandle, binding, set.Layout.Bindings[binding].Type, setBinding.BindingType)
}

switch w.Type {
case VK_DESCRIPTOR_TYPE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Expand Down Expand Up @@ -639,7 +616,7 @@ cmd void vkUpdateDescriptorSets(
}
}
}

case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
Expand All @@ -658,8 +635,18 @@ cmd void vkUpdateDescriptorSets(
for _ , _ , c in copies {
srcSet := DescriptorSets[c.SrcSet]
dstSet := DescriptorSets[c.DstSet]
srcBinding := srcSet.Bindings[c.SrcBinding]
dstBinding := dstSet.Bindings[c.DstBinding]
srcBinding := switch (c.SrcBinding in srcSet.Bindings) {
case false:
srcSet.Bindings[c.SrcBinding]
case true:
new!DescriptorBinding(BindingType: srcSet.Layout.Bindings[c.SrcBinding].Type)
}
dstBinding := switch (c.DstBinding in dstSet.Bindings) {
case false:
dstSet.Bindings[c.DstBinding]
case true:
new!DescriptorBinding(BindingType: dstSet.Layout.Bindings[c.DstBinding].Type)
}
switch (srcBinding.BindingType) {
case VK_DESCRIPTOR_TYPE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Expand Down Expand Up @@ -733,7 +720,7 @@ vkCmdBindDescriptorSetsArgs {
map!(u32, u32) DynamicOffsets
}

@internal class
@internal class
emptyBufferOffsets {
map!(u32, map!(u32, map!(VkDeviceSize, bool))) BufferBindingOffsets
}
Expand Down Expand Up @@ -778,7 +765,7 @@ sub void dovkCmdBindDescriptorSets(ref!vkCmdBindDescriptorSetsArgs args) {
case false:
emptyBufferOffsets().BufferBindingOffsets
}

// Since the pDynamicOffsets point into the bindings in order of
// binding index, and then array index, we have to loop over all
// of the Bindings in order of the binding number.
Expand Down Expand Up @@ -815,7 +802,7 @@ sub void dovkCmdBindDescriptorSets(ref!vkCmdBindDescriptorSetsArgs args) {

if !hasBeenRead.b {
oldSets := ProcessedDescriptorSets.val[set].bufferOffsets
ProcessedDescriptorSets.val[set] =
ProcessedDescriptorSets.val[set] =
ProcessedDescriptorSet(oldSets, true)

}
Expand Down
1 change: 1 addition & 0 deletions gapis/api/vulkan/errors.api
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern void vkErrNotNullPointer(string pointerType)
extern void vkErrUnrecognizedExtension(string name)
extern void vkErrExpectNVDedicatedlyAllocatedHandle(string handleType, u64 handle)
extern void vkErrInvalidDescriptorArrayElement(u64 set, u32 binding, u32 arrayIndex)
extern void vkErrInvalidDescriptorBindingType(VkDescriptorSet set, u32 binding, VkDescriptorType layoutType, VkDescriptorType updateType)
extern void vkErrCommandBufferIncomplete(VkCommandBuffer cmdbuf)
extern void vkErrInvalidImageLayout(VkImage img, u32 aspect, u32 layer, u32 level, VkImageLayout layout, VkImageLayout expectedLayout)
extern void vkErrInvalidImageSubresource(VkImage img, string subresourceType, u32 value)
Expand Down
8 changes: 8 additions & 0 deletions gapis/api/vulkan/externs.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,14 @@ func (e externs) vkErrInvalidImageSubresource(img VkImage, subresourceType strin
e.onVkError(issue)
}

func (e externs) vkErrInvalidDescriptorBindingType(set VkDescriptorSet, binding uint32, layoutType, updateType VkDescriptorType) {
var issue replay.Issue
issue.Command = e.cmdID
issue.Severity = service.Severity_ErrorLevel
issue.Error = fmt.Errorf("Updating descriptor binding at: %v: %d with type: %v, but the type defined in descriptor set layout is: %v", set, binding, layoutType, updateType)
e.onVkError(issue)
}

type fenceSignal uint64

func (e externs) recordFenceSignal(fence VkFence) {
Expand Down

0 comments on commit c928b2f

Please sign in to comment.