mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-19 04:05:41 +00:00
* These come from long ago when using PyCharm with not as good type checking and with renderdoc module stubs that were incomplete so needed help identifying types.
401 lines
14 KiB
Python
401 lines
14 KiB
Python
import renderdoc as rd
|
|
import rdtest
|
|
|
|
# Not a real test, re-used by API-specific tests
|
|
class Draw_Zoo(rdtest.TestCase):
|
|
internal = True
|
|
|
|
def vid(self, action: rd.ActionDescription, val: int):
|
|
# For D3D, Vertex ID is either 0-based for non indexed calls, or the raw index. That means no baseVertex applied
|
|
if rd.IsD3D(self.props.pipelineType):
|
|
if action.flags & rd.ActionFlags.Indexed:
|
|
return float(val - action.baseVertex)
|
|
return float(val)
|
|
|
|
# For GL and vulkan it includes all offsets - so for non-indexed that includes vertexOffset, and for indexed
|
|
# that includes baseVertex
|
|
if action.flags & rd.ActionFlags.Indexed:
|
|
return float(val)
|
|
return float(val + action.vertexOffset)
|
|
|
|
def iid(self, action: rd.ActionDescription, val: int):
|
|
# See above - similar for instance ID, but only vulkan includes the instanceOffset in instance ID
|
|
|
|
if (self.props.pipelineType == rd.GraphicsAPI.Vulkan) and action.flags & rd.ActionFlags.Instanced:
|
|
return float(val + action.instanceOffset)
|
|
|
|
return float(val)
|
|
|
|
def check_action(self, action: rd.ActionDescription, ref_data):
|
|
rdtest.log.print("Checking action {}".format(action.eventId))
|
|
|
|
self.controller.SetFrameEvent(action.eventId, True)
|
|
|
|
self.pipe = self.controller.GetPipelineState()
|
|
|
|
refl = self.pipe.GetShaderReflection(rd.ShaderStage.Vertex)
|
|
|
|
num_verts = len(ref_data['pos'])
|
|
|
|
vsin_pos_name = 'pos'
|
|
for sig in refl.inputSignature:
|
|
if 'pos' in sig.varName.lower() or 'pos' in sig.semanticName.lower():
|
|
vsin_pos_name = sig.varName
|
|
if vsin_pos_name == '':
|
|
vsin_pos_name = sig.semanticName
|
|
break
|
|
|
|
vsout_pos_name = 'pos'
|
|
for sig in refl.outputSignature:
|
|
if sig.systemValue == rd.ShaderBuiltin.Position:
|
|
vsout_pos_name = sig.varName
|
|
if vsout_pos_name == '':
|
|
vsout_pos_name = sig.semanticName
|
|
break
|
|
|
|
out_tex = self.pipe.GetOutputTargets()[0].resource
|
|
|
|
vsin_ref = {}
|
|
restarts = []
|
|
|
|
if 'restarts' in ref_data:
|
|
restarts = ref_data['restarts']
|
|
|
|
ib = self.pipe.GetIBuffer()
|
|
|
|
striprestart_index = self.pipe.GetRestartIndex() & ((1 << (ib.byteStride*8)) - 1)
|
|
|
|
for v in range(num_verts):
|
|
if v in restarts:
|
|
vsin_ref[v] = {
|
|
'vtx': v,
|
|
'idx': striprestart_index,
|
|
}
|
|
else:
|
|
vsin_ref[v] = {
|
|
'vtx': v,
|
|
'idx': ref_data['base']+v,
|
|
vsin_pos_name: ref_data['pos'][v],
|
|
}
|
|
|
|
self.check_mesh_data(vsin_ref, self.get_vsin(action))
|
|
|
|
num_instances = action.numInstances
|
|
if not (action.flags & rd.ActionFlags.Instanced):
|
|
num_instances = 1
|
|
|
|
rdtest.log.success("Checked vertex in data")
|
|
|
|
for inst in range(num_instances):
|
|
conv_out_pos = lambda x: [x[0] + float(inst) * 0.5, x[1], x[2], 1.0]
|
|
|
|
vsout_ref = {}
|
|
|
|
for v in range(num_verts):
|
|
if v in restarts:
|
|
vsout_ref[v] = {
|
|
'vtx': v,
|
|
'idx': striprestart_index,
|
|
}
|
|
else:
|
|
vsout_ref[v] = {
|
|
'vtx': v,
|
|
'idx': ref_data['base']+v,
|
|
vsout_pos_name: conv_out_pos(ref_data['pos'][v]),
|
|
'VID': self.vid(action, ref_data['base']+v),
|
|
'IID': self.iid(action, inst),
|
|
}
|
|
|
|
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst)
|
|
|
|
self.check_mesh_data(vsout_ref, postvs)
|
|
|
|
rdtest.log.success("Checked vertex out data in instance {}".format(inst))
|
|
|
|
if self.props.shaderDebugging and refl.debugInfo.debuggable:
|
|
for vtx in range(num_verts):
|
|
if vtx in restarts:
|
|
continue
|
|
|
|
idx = vsout_ref[vtx]['idx']
|
|
|
|
self.check_vertex_debug(vtx, idx, inst, postvs)
|
|
else:
|
|
rdtest.log.print('Not checking shader debugging, unsupported')
|
|
|
|
for vert, coord in enumerate(ref_data['pixels'][inst]):
|
|
if coord[0] == 0 and coord[1] == 0:
|
|
continue
|
|
val = (self.vid(action, ref_data['base'] + vert), self.iid(action, inst), float(inst) * 0.5,
|
|
postvs[vert]['COLOR'][1] + postvs[vert]['TEXCOORD'][0])
|
|
self.check_pixel_value(out_tex, coord[0], coord[1], val, eps=0.3)
|
|
|
|
rdtest.log.success("Checked pixels in instance {}".format(inst))
|
|
|
|
rdtest.log.success("Checked action {}".format(action.eventId))
|
|
|
|
def check_capture(self):
|
|
test_marker = self.find_action("Test")
|
|
self.check_capture_action(test_marker)
|
|
|
|
def check_capture_action(self, marker: rd.ActionDescription):
|
|
self.props = self.controller.GetAPIProperties()
|
|
|
|
action = marker.nextAction
|
|
|
|
rdtest.log.begin_section("Non-indexed, non-instanced cases")
|
|
|
|
# Basic case
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, 0.5, 0.0], [0.0, -0.5, 0.0], [0.5, 0.5, 0.0]],
|
|
'pixels': [[(12, 12), (24, 34), (35, 12)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.vertexOffset == 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# Vertex offset in the action
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, -0.5, 0.0], [0.0, 0.5, 0.0], [0.5, -0.5, 0.0]],
|
|
'pixels': [[(60, 35), (72, 13), (83, 35)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.vertexOffset > 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# Vertex offset in action and in vertex binding
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, 0.0, 0.0], [0.0, -0.5, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [[(108, 23), (119, 35), (119, 13)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.vertexOffset > 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset > 0
|
|
action = action.nextAction
|
|
|
|
rdtest.log.end_section("Non-indexed, non-instanced cases")
|
|
|
|
rdtest.log.begin_section("indexed, non-instanced")
|
|
|
|
# Basic case
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, 0.5, 0.0], [0.0, -0.5, 0.0], [0.5, 0.5, 0.0]],
|
|
'pixels': [[(12, 60), (24, 82), (35, 60)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.indexOffset == 0
|
|
assert action.baseVertex == 0
|
|
assert action.vertexOffset == 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset == 0
|
|
assert self.pipe.GetIBuffer().byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# first index in the action
|
|
ref = {
|
|
'base': 5,
|
|
'pos': [[-0.5, -0.5, 0.0], [0.0, 0.5, 0.0], [0.5, -0.5, 0.0]],
|
|
'pixels': [[(60, 83), (72, 61), (83, 83)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.indexOffset > 0
|
|
assert action.baseVertex == 0
|
|
assert action.vertexOffset == 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset == 0
|
|
assert self.pipe.GetIBuffer().byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# first index and base vertex in the action
|
|
ref = {
|
|
'base': 13,
|
|
'pos': [[-0.5, 0.0, 0.0], [0.0, -0.5, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [[(108, 71), (119, 83), (119, 61)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.indexOffset > 0
|
|
assert action.baseVertex < 0
|
|
assert action.vertexOffset == 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset == 0
|
|
assert self.pipe.GetIBuffer().byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# first index and base vertex in the action, and vertex binding offset
|
|
ref = {
|
|
'base': 3,
|
|
'pos': [[-0.5, 0.0, 0.0], [0.0, -0.5, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [[(156, 71), (167, 83), (167, 61)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.indexOffset > 0
|
|
assert action.baseVertex < 0
|
|
assert action.vertexOffset == 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset > 0
|
|
assert self.pipe.GetIBuffer().byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# first index and base vertex in the action, and vertex & index binding offset
|
|
ref = {
|
|
'base': 4,
|
|
'pos': [[0.0, -0.5, 0.0], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [[(216, 82), (226, 71), (216, 61)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.indexOffset > 0
|
|
assert action.baseVertex < 0
|
|
assert action.vertexOffset == 0
|
|
assert self.pipe.GetVBuffers()[0].byteOffset > 0
|
|
# OpenGL doesn't support offset on index buffer bindings
|
|
if self.props.pipelineType != rd.GraphicsAPI.OpenGL:
|
|
assert self.pipe.GetIBuffer().byteOffset > 0
|
|
action = action.nextAction
|
|
|
|
# Skip indexed strips for now
|
|
ref = {
|
|
'base': 30,
|
|
'pos': [
|
|
[-0.5, 0.2, 0.0], [-0.5, 0.0, 0.0],
|
|
[-0.3, 0.2, 0.0], [-0.3, 0.0, 0.0],
|
|
[-0.1, 0.2, 0.0],
|
|
[], # restart
|
|
[0.1, 0.2, 0.0], [0.1, 0.0, 0.0],
|
|
[0.3, 0.2, 0.0], [0.3, 0.0, 0.0],
|
|
[0.5, 0.2, 0.0], [0.5, 0.0, 0.0],
|
|
],
|
|
'restarts': [5],
|
|
'pixels': [[(252, 67), (252, 71), (256, 67)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
action = action.nextAction
|
|
|
|
ref = {
|
|
'base': 30,
|
|
'pos': [
|
|
[-0.5, 0.2, 0.0], [-0.5, 0.0, 0.0],
|
|
[-0.3, 0.2, 0.0], [-0.3, 0.0, 0.0],
|
|
[-0.1, 0.2, 0.0],
|
|
[], # restart
|
|
[0.1, 0.2, 0.0], [0.1, 0.0, 0.0],
|
|
[0.3, 0.2, 0.0], [0.3, 0.0, 0.0],
|
|
[0.5, 0.2, 0.0], [0.5, 0.0, 0.0],
|
|
],
|
|
'restarts': [5],
|
|
'pixels': [[(300, 67), (300, 71), (304, 67)]],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
action = action.nextAction
|
|
|
|
rdtest.log.end_section("indexed, non-instanced")
|
|
|
|
rdtest.log.begin_section("non-indexed, instanced")
|
|
|
|
# Basic case
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, 0.5, 0.0], [0.0, -0.5, 0.0], [0.5, 0.5, 0.0]],
|
|
'pixels': [
|
|
[(12, 108), (24, 130), (0, 0)],
|
|
[(24, 108), (36, 130), (47, 108)],
|
|
],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.instanceOffset == 0
|
|
assert self.pipe.GetVBuffers()[1].byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# instance offset in the action
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, -0.5, 0.0], [0.0, 0.5, 0.0], [0.5, -0.5, 0.0]],
|
|
'pixels': [
|
|
[(60, 131), (72, 109), (0, 0)],
|
|
[(72, 131), (84, 109), (95, 131)],
|
|
],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.instanceOffset > 0
|
|
assert self.pipe.GetVBuffers()[1].byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# instance offset in the action and offset on the instanced VB
|
|
ref = {
|
|
'base': 0,
|
|
'pos': [[-0.5, 0.0, 0.0], [0.0, -0.5, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [
|
|
[(108, 120), (119, 131), (119, 108)],
|
|
[(120, 120), (131, 131), (131, 108)],
|
|
],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.instanceOffset > 0
|
|
assert self.pipe.GetVBuffers()[1].byteOffset > 0
|
|
action = action.nextAction
|
|
|
|
rdtest.log.end_section("non-indexed, instanced")
|
|
|
|
rdtest.log.begin_section("indexed, instanced")
|
|
|
|
# Basic case
|
|
ref = {
|
|
'base': 5,
|
|
'pos': [[-0.5, -0.5, 0.0], [0.0, 0.5, 0.0], [0.5, -0.5, 0.0]],
|
|
'pixels': [
|
|
[(12, 179), (24, 157), (0, 0)],
|
|
[(24, 179), (36, 157), (47, 179)],
|
|
],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.instanceOffset == 0
|
|
assert self.pipe.GetVBuffers()[1].byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# instance offset in the action
|
|
ref = {
|
|
'base': 13,
|
|
'pos': [[-0.5, 0.0, 0.0], [0.0, -0.5, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [
|
|
[(60, 168), (71, 179), (71, 156)],
|
|
[(72, 168), (83, 179), (83, 156)],
|
|
],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.instanceOffset > 0
|
|
assert self.pipe.GetVBuffers()[1].byteOffset == 0
|
|
action = action.nextAction
|
|
|
|
# instance offset in the action and offset on the instanced VB
|
|
ref = {
|
|
'base': 23,
|
|
'pos': [[0.0, -0.5, 0.0], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0]],
|
|
'pixels': [
|
|
[(120, 178), (130, 168), (120, 157)],
|
|
[(132, 178), (142, 168), (132, 157)],
|
|
],
|
|
}
|
|
|
|
self.check_action(action, ref)
|
|
assert action.instanceOffset > 0
|
|
assert self.pipe.GetVBuffers()[1].byteOffset > 0
|
|
action = action.nextAction
|
|
|
|
rdtest.log.end_section("indexed, instanced")
|