Fix handling of descriptor feedback in iterating arrays

This commit is contained in:
baldurk
2022-11-21 14:15:07 +00:00
parent dfe07d6822
commit 69c1990035
5 changed files with 175 additions and 14 deletions
+3
View File
@@ -204,6 +204,9 @@ class TestCase:
else:
raise TestFailureException('Assertion Failure: {}'.format(msg))
def check_eq(self, a, b):
self.check(a == b, '{} != {}'.format(a, b))
def get_replay_options(self):
"""
Method to overload if you want to override the replay options used.
@@ -33,6 +33,28 @@ class D3D12_Descriptor_Indexing(rdtest.TestCase):
if root.views[i].dynamicallyUsed:
raise rdtest.TestFailureException("Compute root range 0[{}] i dynamically used".format(i))
# these lists are only expected to be empty because the descriptors aren't written to, and so with mutable
# consideration these aren't considered read-only with unknown contents
pipe = self.controller.GetPipelineState()
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Compute, False)
self.check_eq(ro, [])
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Compute, True)
self.check_eq(ro, [])
rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute, False)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 0)
self.check_eq(len(rw[0].resources), 32)
self.check(rw[0].resources[15].dynamicallyUsed)
self.check_eq(rw[0].resources[15].resourceId, root.views[15].resourceId)
rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute, True)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 15)
self.check_eq(len(rw[0].resources), 1)
self.check_eq(rw[0].resources[0].resourceId, root.views[15].resourceId)
self.check(rw[0].resources[0].dynamicallyUsed)
def check_capture(self):
for sm in ["sm_5_1", "sm_6_0", "sm_6_6"]:
@@ -162,4 +184,57 @@ class D3D12_Descriptor_Indexing(rdtest.TestCase):
raise rdtest.TestFailureException(
"Sampler {} expected to be used, but isn't.".format(elemId))
pipe = self.controller.GetPipelineState()
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Pixel, False)
self.check_eq(len(ro), 5)
self.check_eq(ro[0].dynamicallyUsedCount, 1)
self.check_eq(ro[0].firstIndex, 0)
self.check_eq(len(ro[0].resources), 1)
self.check_eq(ro[1].dynamicallyUsedCount, 1)
self.check_eq(ro[1].firstIndex, 0)
self.check_eq(len(ro[1].resources), 1)
self.check_eq(ro[2].dynamicallyUsedCount, 3)
self.check_eq(ro[2].firstIndex, 0)
self.check_eq(len(ro[2].resources), 32)
self.check_eq(ro[3].dynamicallyUsedCount, 3)
self.check_eq(ro[3].firstIndex, 0)
self.check_eq(len(ro[3].resources), 32)
self.check_eq(ro[4].dynamicallyUsedCount, 2)
self.check_eq(ro[4].firstIndex, 0)
self.check_eq(len(ro[4].resources), 32)
self.check(not ro[2].resources[18].dynamicallyUsed)
self.check(ro[2].resources[19].dynamicallyUsed)
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Pixel, True)
self.check_eq(len(ro), 5)
self.check_eq(ro[0].dynamicallyUsedCount, 1)
self.check_eq(ro[0].firstIndex, 0)
self.check_eq(len(ro[0].resources), 1)
self.check_eq(ro[1].dynamicallyUsedCount, 1)
self.check_eq(ro[1].firstIndex, 0)
self.check_eq(len(ro[1].resources), 1)
self.check_eq(ro[2].dynamicallyUsedCount, 3)
self.check_eq(ro[2].firstIndex, 19)
# this contains more resources after the dynamically used ones because of the mismatch between
# root signature elements and bindings
self.check_eq(len(ro[2].resources), 32-8)
self.check_eq(ro[3].dynamicallyUsedCount, 3)
self.check_eq(ro[3].firstIndex, 0)
# similar to above
self.check_eq(len(ro[3].resources), 32)
self.check_eq(ro[4].dynamicallyUsedCount, 2)
self.check_eq(ro[4].firstIndex, 0)
self.check_eq(len(ro[4].resources), 103-80+1)
rw = pipe.GetReadWriteResources(rd.ShaderStage.Pixel, False)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 0)
self.check_eq(len(rw[0].resources), 32)
self.check(rw[0].resources[15].dynamicallyUsed)
rw = pipe.GetReadWriteResources(rd.ShaderStage.Pixel, True)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 15)
self.check_eq(len(rw[0].resources), 1)
self.check(rw[0].resources[0].dynamicallyUsed)
rdtest.log.success("Dynamic usage is as expected for {}".format(sm))
@@ -11,13 +11,13 @@ class VK_Descriptor_Indexing(rdtest.TestCase):
self.check(action is not None)
self.controller.SetFrameEvent(action.eventId, False)
pipe: rd.VKState = self.controller.GetVulkanPipelineState()
vkpipe: rd.VKState = self.controller.GetVulkanPipelineState()
if len(pipe.compute.descriptorSets) != 1:
if len(vkpipe.compute.descriptorSets) != 1:
raise rdtest.TestFailureException("Wrong number of compute sets is bound: {}, not 1"
.format(len(pipe.compute.descriptorSets)))
.format(len(vkpipe.compute.descriptorSets)))
binding = pipe.compute.descriptorSets[0].bindings[0]
binding = vkpipe.compute.descriptorSets[0].bindings[0]
if binding.dynamicallyUsedCount != 1:
raise rdtest.TestFailureException("Compute bind 0 doesn't have the right used count {}"
@@ -26,11 +26,33 @@ class VK_Descriptor_Indexing(rdtest.TestCase):
if not binding.binds[15].dynamicallyUsed:
raise rdtest.TestFailureException("Compute bind 0[15] isn't dynamically used")
# these lists are only expected to be empty because the descriptors aren't written to, and so with mutable
# consideration these aren't considered read-only with unknown contents
pipe = self.controller.GetPipelineState()
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Compute, False)
self.check_eq(ro, [])
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Compute, True)
self.check_eq(ro, [])
rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute, False)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 0)
self.check_eq(len(rw[0].resources), 128)
self.check(rw[0].resources[15].dynamicallyUsed)
self.check_eq(rw[0].resources[15].resourceId, binding.binds[15].resourceResourceId)
rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute, True)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 15)
self.check_eq(len(rw[0].resources), 1)
self.check_eq(rw[0].resources[0].resourceId, binding.binds[15].resourceResourceId)
self.check(rw[0].resources[0].dynamicallyUsed)
action = self.find_action("Draw")
self.check(action is not None)
self.controller.SetFrameEvent(action.eventId, False)
pipe: rd.VKState = self.controller.GetVulkanPipelineState()
vkpipe: rd.VKState = self.controller.GetVulkanPipelineState()
# Check bindings:
# - buffer 15 in bind 0 should be used
@@ -44,11 +66,11 @@ class VK_Descriptor_Indexing(rdtest.TestCase):
2: { 'dynamicallyUsedCount': 2, 'used': [381, 386] },
}
if len(pipe.graphics.descriptorSets) != 1:
if len(vkpipe.graphics.descriptorSets) != 1:
raise rdtest.TestFailureException("Wrong number of sets is bound: {}, not 1"
.format(len(pipe.graphics.descriptorSets)))
.format(len(vkpipe.graphics.descriptorSets)))
desc_set: rd.VKDescriptorSet = pipe.graphics.descriptorSets[0]
desc_set: rd.VKDescriptorSet = vkpipe.graphics.descriptorSets[0]
binding: rd.VKDescriptorBinding
for bind, binding in enumerate(desc_set.bindings):
@@ -67,4 +89,38 @@ class VK_Descriptor_Indexing(rdtest.TestCase):
if not expected_used and actually_used:
raise rdtest.TestFailureException("Bind {} element {} expected to be unused, but is.".format(bind, idx))
pipe = self.controller.GetPipelineState()
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Pixel, False)
self.check_eq(len(ro), 2)
self.check_eq(ro[0].dynamicallyUsedCount, 6)
self.check_eq(ro[0].firstIndex, 0)
self.check_eq(len(ro[0].resources), 128)
self.check_eq(ro[1].dynamicallyUsedCount, 2)
self.check_eq(ro[1].firstIndex, 0)
self.check_eq(len(ro[1].resources), 512)
self.check(not ro[0].resources[18].dynamicallyUsed)
self.check(ro[0].resources[19].dynamicallyUsed)
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Pixel, True)
self.check_eq(len(ro), 2)
self.check_eq(ro[0].dynamicallyUsedCount, 6)
self.check_eq(ro[0].firstIndex, 4)
self.check_eq(len(ro[0].resources), 56)
self.check_eq(ro[1].dynamicallyUsedCount, 2)
self.check_eq(ro[1].firstIndex, 381)
self.check_eq(len(ro[1].resources), 6)
self.check(not ro[0].resources[14].dynamicallyUsed)
self.check(ro[0].resources[15].dynamicallyUsed)
rw = pipe.GetReadWriteResources(rd.ShaderStage.Pixel, False)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 0)
self.check_eq(len(rw[0].resources), 128)
self.check(rw[0].resources[15].dynamicallyUsed)
rw = pipe.GetReadWriteResources(rd.ShaderStage.Pixel, True)
self.check_eq(rw[0].dynamicallyUsedCount, 1)
self.check_eq(rw[0].firstIndex, 15)
self.check_eq(len(rw[0].resources), 1)
self.check(rw[0].resources[0].dynamicallyUsed)
rdtest.log.success("Dynamic usage is as expected")