mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
212 lines
9.8 KiB
Python
212 lines
9.8 KiB
Python
import renderdoc as rd
|
|
import rdtest
|
|
|
|
# Not a real test, re-used by API-specific tests
|
|
class Discard_Zoo(rdtest.TestCase):
|
|
internal = True
|
|
|
|
def check_val(self, picked, val, fmt):
|
|
if type(val) != list:
|
|
val = [val, val, val, val]
|
|
|
|
if fmt.compType == rd.CompType.UInt or fmt.compType == rd.CompType.SInt or fmt.type == rd.ResourceFormatType.S8:
|
|
val = [int(a) for a in val]
|
|
return rdtest.value_compare(picked.intValue[0:fmt.compCount], val[0:fmt.compCount])
|
|
else:
|
|
comp_val = picked.floatValue[0:fmt.compCount]
|
|
if fmt.compType == rd.CompType.Depth or fmt.type in [rd.ResourceFormatType.D16S8, rd.ResourceFormatType.D24S8, rd.ResourceFormatType.D32S8]:
|
|
comp_val = [min(1.0, a) for a in comp_val]
|
|
|
|
return rdtest.value_compare(comp_val, val[0:fmt.compCount])
|
|
|
|
def check_texture(self, id, discarded: bool):
|
|
tex: rd.TextureDescription = self.get_texture(id)
|
|
res: rd.ResourceDescription = self.get_resource(id)
|
|
|
|
fmt: rd.ResourceFormat = tex.format
|
|
|
|
props: rd.APIProperties = self.controller.GetAPIProperties()
|
|
gl = (props.pipelineType == rd.GraphicsAPI.OpenGL)
|
|
|
|
name = '{} - {}x{} {} mip {} slice {}x MSAA {} format texture'.format(res.name, tex.width, tex.height,
|
|
tex.mips, tex.arraysize,
|
|
tex.msSamp, tex.format.Name())
|
|
|
|
minval = 0.0
|
|
maxval = 1000.0
|
|
|
|
if fmt.type == rd.ResourceFormatType.R9G9B9E5:
|
|
maxval = 998.0
|
|
elif fmt.type == rd.ResourceFormatType.BC6:
|
|
maxval = 996.0
|
|
elif fmt.type == rd.ResourceFormatType.R10G10B10A2 and fmt.compType == rd.CompType.UInt:
|
|
maxval = [127.0, 127.0, 127.0, 3.0]
|
|
elif fmt.type in [rd.ResourceFormatType.D16S8, rd.ResourceFormatType.D24S8, rd.ResourceFormatType.D32S8]:
|
|
maxval = 1.0
|
|
fmt.compCount = 2
|
|
|
|
if "DepthOnly" in res.name:
|
|
minval = [minval, float(0x40)/float(255)]
|
|
maxval = [maxval, float(0x40)/float(255)]
|
|
elif "StencilOnly" in res.name:
|
|
minval = [0.4, minval]
|
|
maxval = [0.4, maxval]
|
|
elif fmt.type == rd.ResourceFormatType.S8:
|
|
minval = [0.0]
|
|
maxval = [255.0]
|
|
fmt.compCount = 1
|
|
elif fmt.compType == rd.CompType.UNorm or fmt.compType == rd.CompType.Depth:
|
|
maxval = 1.0
|
|
elif fmt.compType == rd.CompType.UInt or fmt.compType == rd.CompType.SInt:
|
|
maxval = 127.0
|
|
|
|
# ignore alpha in BC1 and BC6
|
|
if fmt.type == rd.ResourceFormatType.BC1 or fmt.type == rd.ResourceFormatType.BC6:
|
|
fmt.compCount = 3
|
|
|
|
for mip in range(tex.mips):
|
|
for slice in range(tex.arraysize):
|
|
for samp in range(tex.msSamp):
|
|
sub = rd.Subresource(mip, slice, samp)
|
|
|
|
sub_discarded = discarded
|
|
|
|
if "Mip" in res.name:
|
|
idx = res.name.index('Mip')+3
|
|
try:
|
|
idx2 = res.name.index(' ', idx)
|
|
except ValueError:
|
|
idx2 = len(res.name)
|
|
if mip not in [int(m) for m in res.name[idx:idx2].split(',')]:
|
|
sub_discarded = False
|
|
|
|
if "Slice" in res.name:
|
|
idx = res.name.index('Slice') + 5
|
|
try:
|
|
idx2 = res.name.index(' ', idx)
|
|
except ValueError:
|
|
idx2 = len(res.name)
|
|
if slice not in [int(s) for s in res.name[idx:idx2].split(',')]:
|
|
sub_discarded = False
|
|
|
|
if "NoDiscard" in res.name:
|
|
sub_discarded = False
|
|
|
|
w = max(1, tex.width >> mip)
|
|
h = max(1, tex.height >> mip)
|
|
|
|
if not sub_discarded or "DiscardRect" in res.name:
|
|
# if not discarded, or we only discarded a rect, check a few locations in the corners and ensure
|
|
# that we don't see our pattern colours.
|
|
for (x, y) in [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (1, 1), (2, 2), (3, 3),
|
|
(4, 4), (w - 1, h - 1), (w - 2, h - 2), (w - 1, 0), (w - 1, 1), (w - 1, 2),
|
|
(0, h - 1), (1, h - 1), (2, h - 1), (3, h - 2)]:
|
|
# underflow can happen with 1D textures or tiny mips
|
|
if x < 0:
|
|
x = 0
|
|
if y < 0:
|
|
y = 0
|
|
|
|
if gl and h > 1:
|
|
y = h - 1 - y
|
|
|
|
picked: rd.PixelValue = self.controller.PickPixel(id, x, y, sub, rd.CompType.Typeless)
|
|
|
|
if self.check_val(picked, minval, fmt) or self.check_val(picked, maxval, fmt):
|
|
raise rdtest.TestFailureException(
|
|
'{} has unexpected value at {},{}: {}'.format(name, x, y,
|
|
picked.floatValue))
|
|
|
|
if sub_discarded:
|
|
seen = [False, False]
|
|
# Check that pixels inside the rect only show our pattern colours (we don't check the actual
|
|
# pattern)
|
|
for (x, y) in [(50, 50), (51, 50), (52, 50), (53, 50), (54, 50), (55, 50), (51, 52), (120, 123),
|
|
(124, 124), (119, 122), (119, 124), (122, 124), (70, 70), (80, 85), (73, 124),
|
|
(123, 60)]:
|
|
# overflow can happen with 1D textures or tiny mips
|
|
if x >= w:
|
|
x = w-1
|
|
if y >= h:
|
|
y = h-1
|
|
|
|
if gl and h > 1:
|
|
y = h - 1 - y
|
|
|
|
picked: rd.PixelValue = self.controller.PickPixel(id, x, y, sub, rd.CompType.Typeless)
|
|
|
|
is_min = self.check_val(picked, minval, fmt)
|
|
is_max = self.check_val(picked, maxval, fmt)
|
|
|
|
if not is_min and not is_max:
|
|
raise rdtest.TestFailureException(
|
|
'{} has unexpected value at {},{}: {}'.format(name, x, y,
|
|
picked.floatValue))
|
|
|
|
if is_min:
|
|
seen[0] = True
|
|
if is_max:
|
|
seen[1] = True
|
|
|
|
# Do an additional checks outside the rect
|
|
if "DiscardRect" not in res.name:
|
|
for (x, y) in [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (1, 1), (2, 2), (3, 3),
|
|
(4, 4), (w - 1, h - 1), (w - 2, h - 2), (w - 1, 0), (w - 1, 1), (w - 1, 2),
|
|
(0, h - 1), (1, h - 1), (2, h - 1), (3, h - 2)]:
|
|
# underflow can happen with 1D textures or tiny mips
|
|
if x < 0:
|
|
x = 0
|
|
if y < 0:
|
|
y = 0
|
|
|
|
if gl and h > 1:
|
|
y = h - 1 - y
|
|
|
|
picked: rd.PixelValue = self.controller.PickPixel(id, x, y, sub, rd.CompType.Typeless)
|
|
|
|
is_min = self.check_val(picked, minval, fmt)
|
|
is_max = self.check_val(picked, maxval, fmt)
|
|
|
|
if not is_min and not is_max:
|
|
raise rdtest.TestFailureException(
|
|
'{} has unexpected value at {},{}: {}'.format(name, x, y,
|
|
picked.floatValue))
|
|
|
|
if is_min:
|
|
seen[0] = True
|
|
if is_max:
|
|
seen[1] = True
|
|
|
|
# We also expect to have seen both colours. That means if we only saw black for example then we
|
|
# fail
|
|
if not seen[0] or not seen[1]:
|
|
raise rdtest.TestFailureException('{} doesn\'t contain expected pattern'.format(name))
|
|
|
|
rdtest.log.success('{} is OK {} discarding'.format(name, "after" if discarded else "before"))
|
|
|
|
def check_textures(self):
|
|
action = self.find_action("TestStart")
|
|
|
|
self.check(action is not None)
|
|
|
|
self.controller.SetFrameEvent(action.eventId, True)
|
|
|
|
for tex in self.controller.GetTextures():
|
|
tex: rd.TextureDescription
|
|
res: rd.ResourceDescription = self.get_resource(tex.resourceId)
|
|
|
|
if "Discard" in res.name:
|
|
self.check_texture(tex.resourceId, False)
|
|
|
|
action = self.find_action("TestEnd")
|
|
|
|
self.check(action is not None)
|
|
|
|
self.controller.SetFrameEvent(action.eventId, True)
|
|
|
|
for tex in self.controller.GetTextures():
|
|
tex: rd.TextureDescription
|
|
res: rd.ResourceDescription = self.get_resource(tex.resourceId)
|
|
|
|
if "Discard" in res.name:
|
|
self.check_texture(tex.resourceId, True) |