mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-26 01:11:49 +00:00
329 lines
13 KiB
Python
329 lines
13 KiB
Python
import renderdoc as rd
|
|
import rdtest
|
|
|
|
|
|
class VK_Parameter_Zoo(rdtest.TestCase):
|
|
demos_test_name = 'VK_Parameter_Zoo'
|
|
|
|
def check_capture(self):
|
|
action = self.find_action("Color Draw")
|
|
|
|
self.check(action is not None)
|
|
|
|
action = action.next
|
|
|
|
self.controller.SetFrameEvent(action.eventId, False)
|
|
|
|
pipe: rd.PipeState = self.controller.GetPipelineState()
|
|
|
|
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [0.0, 1.0, 0.0, 1.0])
|
|
|
|
# Readback reported extension support
|
|
descriptor_update_template = self.find_action("KHR_descriptor_update_template") is not None
|
|
push_descriptor = self.find_action("KHR_push_descriptor") is not None
|
|
|
|
# Find the action that contains resource references
|
|
action = self.find_action("References")
|
|
self.check(action is not None)
|
|
action = action.next
|
|
self.controller.SetFrameEvent(action.eventId, False)
|
|
|
|
vkpipe: rd.VKState = self.controller.GetVulkanPipelineState()
|
|
|
|
res_names = {}
|
|
for res in self.controller.GetResources():
|
|
res: rd.ResourceDescription
|
|
res_names[res.resourceId] = res.name
|
|
|
|
expected_binds = [
|
|
{
|
|
'sampname': 'refsamp'
|
|
},
|
|
{
|
|
'resname': 'refcombinedimg',
|
|
'sampname': 'refcombinedsamp'
|
|
},
|
|
{
|
|
'resname': 'refsampled'
|
|
},
|
|
{
|
|
'resname': 'refstorage'
|
|
},
|
|
{
|
|
'resname': 'refunitexel'
|
|
},
|
|
{
|
|
'resname': 'refstoretexel'
|
|
},
|
|
{
|
|
'resname': 'refunibuf'
|
|
},
|
|
{
|
|
'resname': 'refstorebuf'
|
|
},
|
|
{
|
|
'resname': 'refunibufdyn'
|
|
},
|
|
{
|
|
'resname': 'refstorebufdyn'
|
|
},
|
|
]
|
|
|
|
setidx = 0
|
|
for descset in vkpipe.graphics.descriptorSets:
|
|
descset: rd.VKDescriptorSet
|
|
|
|
if setidx == 2 and not descset.pushDescriptor:
|
|
raise rdtest.TestFailureException("Expected set {} to be a push set", setidx)
|
|
|
|
if setidx != 2 and descset.pushDescriptor:
|
|
raise rdtest.TestFailureException("Expected set {} to be a non-push set", setidx)
|
|
|
|
range: rd.DescriptorRange = rd.DescriptorRange()
|
|
range.offset = 0
|
|
# push descriptors don't include dynamic descriptors so don't fetch those
|
|
range.count = len([
|
|
e for e in expected_binds
|
|
if ('sampname' in e or not descset.pushDescriptor or 'dyn' not in e['resname'])
|
|
])
|
|
range.descriptorSize = 1
|
|
|
|
descs = self.controller.GetDescriptors(descset.descriptorSetResourceId, [range])
|
|
samps = self.controller.GetSamplerDescriptors(descset.descriptorSetResourceId, [range])
|
|
|
|
for bindidx, (desc, samp) in enumerate(zip(descs, samps)):
|
|
sampname = res_names.get(samp.object, '!' + str(setidx))
|
|
resname = res_names.get(desc.resource, '!' + str(setidx))
|
|
|
|
expected_samp = expected_binds[bindidx].get('sampname', '!') + str(setidx)
|
|
expected_res = expected_binds[bindidx].get('resname', '!') + str(setidx)
|
|
|
|
if not sampname == expected_samp:
|
|
raise rdtest.TestFailureException(
|
|
"Expected binding {} in set {} to have sampler {} but got {}".format(
|
|
bindidx, setidx, expected_samp, sampname))
|
|
|
|
if not resname == expected_res:
|
|
raise rdtest.TestFailureException(
|
|
"Expected binding {} in set {} to have resource {} but got {}".format(
|
|
bindidx, setidx, expected_res, resname))
|
|
|
|
rdtest.log.success("Resources in set {} were found as expected".format(setidx))
|
|
|
|
setidx = setidx + 1
|
|
|
|
# Since we can only have one push descriptor set we have a second action for push AND template updates
|
|
if descriptor_update_template and push_descriptor:
|
|
action = self.find_action("PushTemplReferences")
|
|
self.check(action is not None)
|
|
action = action.next
|
|
self.controller.SetFrameEvent(action.eventId, False)
|
|
|
|
vkpipe: rd.VKState = self.controller.GetVulkanPipelineState()
|
|
|
|
descset: rd.VKDescriptorSet = vkpipe.graphics.descriptorSets[2]
|
|
|
|
if not descset.pushDescriptor:
|
|
raise rdtest.TestFailureException("Expected set 2 to be a push set")
|
|
|
|
range: rd.DescriptorRange = rd.DescriptorRange()
|
|
range.offset = 0
|
|
# push descriptors don't include dynamic descriptors so don't fetch those
|
|
range.count = len([
|
|
e for e in expected_binds
|
|
if ('sampname' in e or not descset.pushDescriptor or 'dyn' not in e['resname'])
|
|
])
|
|
range.descriptorSize = 1
|
|
|
|
descs = self.controller.GetDescriptors(descset.descriptorSetResourceId, [range])
|
|
samps = self.controller.GetSamplerDescriptors(descset.descriptorSetResourceId, [range])
|
|
|
|
for bindidx, (desc, samp) in enumerate(zip(descs, samps)):
|
|
sampname = res_names.get(samp.object, '!' + str(setidx))
|
|
resname = res_names.get(desc.resource, '!' + str(setidx))
|
|
|
|
expected_samp = expected_binds[bindidx].get('sampname', '!') + str(setidx)
|
|
expected_res = expected_binds[bindidx].get('resname', '!') + str(setidx)
|
|
|
|
if not sampname == expected_samp:
|
|
raise rdtest.TestFailureException(
|
|
"Expected binding {} in set {} to have sampler {} but got {}".format(
|
|
bindidx, setidx, expected_samp, sampname))
|
|
|
|
if not resname == expected_res:
|
|
raise rdtest.TestFailureException(
|
|
"Expected binding {} in set {} to have resource {} but got {}".format(
|
|
bindidx, setidx, expected_res, resname))
|
|
|
|
rdtest.log.success("Resources in push template set were found as expected")
|
|
|
|
rdtest.log.success("All resources were found as expected")
|
|
|
|
action = self.find_action("Tools available")
|
|
|
|
self.check(len(action.children) > 1)
|
|
self.check(any([d.customName == 'RenderDoc' for d in action.children]))
|
|
|
|
rdtest.log.success("RenderDoc tool was listed as available")
|
|
|
|
for variant in [1, 2]:
|
|
action = self.find_action(f"ASM Draw {variant}")
|
|
|
|
self.check(action is not None)
|
|
|
|
action = action.next
|
|
|
|
self.controller.SetFrameEvent(action.eventId, False)
|
|
|
|
pipe = self.controller.GetPipelineState()
|
|
|
|
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Vertex)
|
|
access = pipe.GetDescriptorAccess()
|
|
|
|
self.check_eq(len(ro), 1)
|
|
|
|
if not (rd.DescriptorType.Image, 0, 1) in [(a.type, a.index, a.arrayElement) for a in access]:
|
|
raise rdtest.TestFailureException(
|
|
f"Graphics bind 0[1] isn't the accessed descriptor {str(rd.DumpObject(access))}")
|
|
|
|
vkpipe: rd.VKState = self.controller.GetVulkanPipelineState()
|
|
self.check(len(vkpipe.viewportScissor.viewportScissors) == 0)
|
|
|
|
postvs_data = self.get_postvs(action, rd.MeshDataStage.VSOut, 0, action.numIndices)
|
|
|
|
postvs_ref = {
|
|
0: {
|
|
'vtx': 0,
|
|
'idx': 0,
|
|
'_Position': [-1.0, 1.0, 0.0, 1.0],
|
|
},
|
|
1: {
|
|
'vtx': 1,
|
|
'idx': 1,
|
|
'_Position': [1.0, 1.0, 0.0, 1.0],
|
|
},
|
|
2: {
|
|
'vtx': 2,
|
|
'idx': 2,
|
|
'_Position': [-1.0, -1.0, 0.0, 1.0],
|
|
},
|
|
3: {
|
|
'vtx': 3,
|
|
'idx': 3,
|
|
'_Position': [1.0, -1.0, 0.0, 1.0],
|
|
},
|
|
}
|
|
|
|
self.check_mesh_data(postvs_ref, postvs_data)
|
|
|
|
rdtest.log.success(f"ASM Draw {variant} is as expected")
|
|
|
|
inline_ubo_actions = [
|
|
self.find_action("Inline UBO Draw"),
|
|
self.find_action("Inline UBO + Templ Draw"),
|
|
self.find_action("Inline UBO + Templ Dyn Draw"),
|
|
]
|
|
action = self.find_action("Inline UBO Draw")
|
|
|
|
for action in inline_ubo_actions:
|
|
if action is None:
|
|
continue
|
|
|
|
rdtest.log.print(f"Checking {action.customName}")
|
|
|
|
self.controller.SetFrameEvent(action.next.eventId, False)
|
|
|
|
self.check_triangle(fore=[1.0, 0.0, 1.0, 1.0])
|
|
|
|
stage = rd.ShaderStage.Pixel
|
|
|
|
pipe = self.controller.GetPipelineState()
|
|
ubo1 = pipe.GetConstantBlock(stage, 0, 0).descriptor
|
|
ubo2 = pipe.GetConstantBlock(stage, 1, 0).descriptor
|
|
|
|
ubo1_vars = self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
|
pipe.GetShader(
|
|
stage), stage,
|
|
pipe.GetShaderEntryPoint(
|
|
stage), 0,
|
|
ubo1.resource, ubo1.byteOffset, ubo1.byteSize)
|
|
ubo2_vars = self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
|
|
pipe.GetShader(
|
|
stage), stage,
|
|
pipe.GetShaderEntryPoint(
|
|
stage), 1,
|
|
ubo2.resource, ubo2.byteOffset, ubo2.byteSize)
|
|
|
|
if len(ubo1_vars) != 1 or ubo1_vars[0].name != "col":
|
|
raise rdtest.TestFailureException("Didn't find ubo1 col variable")
|
|
|
|
if len(ubo2_vars) != 1 or ubo2_vars[0].name != "col":
|
|
raise rdtest.TestFailureException("Didn't find ubo2 col variable")
|
|
|
|
if ubo1_vars[0].value.f32v[0:4] != (1.0, 0.0, 0.0, 0.0):
|
|
raise rdtest.TestFailureException(f"ubo1 col value incorrect: {ubo1_vars[0].value.f32v[0:4]}")
|
|
|
|
if ubo2_vars[0].value.f32v[0:4] != (0.0, 0.0, 1.0, 1.0):
|
|
raise rdtest.TestFailureException(f"ubo2 col value incorrect: {ubo2_vars[0].value.f32v[0:4]}")
|
|
|
|
rdtest.log.success(f"{action.customName} is as expected")
|
|
|
|
action = self.find_action("Immutable Draw")
|
|
|
|
self.check(action is not None)
|
|
|
|
action = action.next
|
|
|
|
self.controller.SetFrameEvent(action.eventId, False)
|
|
|
|
pipe = self.controller.GetPipelineState()
|
|
|
|
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Fragment)
|
|
|
|
if len(ro) != 1:
|
|
raise rdtest.TestFailureException("Expected only one resource to be used")
|
|
|
|
if ro[0].sampler.filter.minify != rd.FilterMode.Linear:
|
|
raise rdtest.TestFailureException("Expected linear sampler at binding slot 0 in immutable action")
|
|
|
|
if self.get_resource(ro[0].descriptor.secondary).name != "validSampler":
|
|
raise rdtest.TestFailureException("Expected validSampler to be at binding slot 0 in immutable action")
|
|
|
|
rdtest.log.success("Immutable Draw is as expected")
|
|
|
|
sdfile = self.controller.GetStructuredFile()
|
|
|
|
# Check for resource leaks
|
|
if len(sdfile.chunks) > 500:
|
|
raise rdtest.TestFailureException("Too many chunks found: {}".format(len(sdfile.chunks)))
|
|
|
|
action = self.find_action("before_empty")
|
|
action = self.get_action(action.eventId + 1)
|
|
self.check("vkQueueSubmit" in action.GetName(sdfile))
|
|
a = action.GetName(sdfile)
|
|
action = self.get_action(action.eventId + 1)
|
|
self.check("vkQueueSubmit" in action.GetName(sdfile))
|
|
self.check("No Command Buffers" in action.GetName(sdfile))
|
|
self.check(a != action.GetName(sdfile))
|
|
|
|
action = self.get_action(action.eventId + 1)
|
|
if "after_empty" not in action.GetName(sdfile):
|
|
self.check("vkQueueSubmit2" in action.GetName(sdfile))
|
|
a = action.GetName(sdfile)
|
|
action = self.get_action(action.eventId + 1)
|
|
self.check("vkQueueSubmit2" in action.GetName(sdfile))
|
|
self.check("No Command Buffers" in action.GetName(sdfile))
|
|
self.check(a != action.GetName(sdfile))
|
|
|
|
rdtest.log.success("Empty queue submits are as expected")
|
|
|
|
action = self.find_action("Dynamic Array Draw")
|
|
|
|
action = action.next
|
|
|
|
self.controller.SetFrameEvent(action.eventId, False)
|
|
|
|
self.check_triangle()
|
|
|
|
rdtest.log.success("Dynamic Array Draw is as expected")
|