Files
2023-03-23 16:16:02 +00:00

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)