Exemple #1
0
    def check_export(self, capture_filename):
        recomp_path = util.get_tmp_path('recompressed.rdc')
        conv_zipxml_path = util.get_tmp_path('conv.zip.xml')
        conv_path = util.get_tmp_path('conv.rdc')

        origrdc = rd.OpenCaptureFile()
        status = origrdc.OpenFile(capture_filename, '', None)

        self.check(status == rd.ReplayStatus.Succeeded, "Couldn't open '{}': {}".format(capture_filename, str(status)))

        # Export to rdc, to recompress
        origrdc.Convert(recomp_path, '', None, None)
        origrdc.Convert(conv_zipxml_path, 'zip.xml', None, None)

        origrdc.Shutdown()

        # Load up the zip.xml file
        zipxml = rd.OpenCaptureFile()
        status = zipxml.OpenFile(conv_zipxml_path, 'zip.xml', None)

        self.check(status == rd.ReplayStatus.Succeeded, "Couldn't open '{}': {}".format(conv_zipxml_path, str(status)))

        # Convert out to rdc
        zipxml.Convert(conv_path, '', None, None)

        zipxml.Shutdown()

        if not util.md5_compare(recomp_path, conv_path):
            raise TestFailureException("Recompressed capture file doesn't match re-imported capture file", conv_path, recomp_path, conv_zipxml_path)

        log.success("Recompressed and re-imported capture files are identical")
    def check_capture(self):
        self.check_final_backbuffer()

        # Open the capture and grab the thumbnail, check that it is all green too (dirty way of verifying we didn't
        # break in-app updates but somehow end up with the right data)
        cap = rd.OpenCaptureFile()

        # Open a particular file
        status = cap.OpenFile(self.capture_filename, '', None)

        # Make sure the file opened successfully
        if status != rd.ReplayStatus.Succeeded:
            cap.Shutdown()
            raise rdtest.TestFailureException("Couldn't open '{}': {}".format(
                self.capture_filename, str(status)))

        thumb: rd.Thumbnail = cap.GetThumbnail(rd.FileType.PNG, 0)

        tmp_path = rdtest.get_tmp_path('thumbnail.png')

        with open(tmp_path, 'wb') as f:
            f.write(thumb.data)

        # The original thumbnail should also be identical, since we have the uncompressed extended thumbnail.
        ref_path = self.get_ref_path('backbuffer.png')

        if not rdtest.png_compare(tmp_path, ref_path):
            raise rdtest.TestFailureException(
                "Reference backbuffer and thumbnail image differ", tmp_path,
                ref_path)

        rdtest.log.success("Thumbnail is identical to reference")
Exemple #3
0
    def __enter__(self):
        self.cap = rd.OpenCaptureFile()
        status = self.cap.OpenFile(self.filename, '', None)

        if status != rd.ReplayStatus.Succeeded:
            print("Couldn't open file: " + str(status))
            self.err = True
            return None

        if not self.cap.LocalReplaySupport():
            print("Capture cannot be replayed")
            self.err = True
            return None

        status, self.controller = self.cap.OpenCapture(rd.ReplayOptions(),
                                                       None)

        if status != rd.ReplayStatus.Succeeded:
            print("Couldn't initialise replay: " + str(status))
            if status == 15:
                print(
                    "This is likely due to an unsupported version of RenderDoc. Please use RenderDoc 1.1 or RenderDoc 1.2 Portable."
                )
            self.cap.Shutdown()
            self.err = True
            return None
        return self.controller
Exemple #4
0
    def check_capture(self):
        tex = rd.TextureDisplay()

        # At each action, the centre pixel of the viewport should be green
        action = self.get_first_action()
        while action is not None:
            self.controller.SetFrameEvent(action.eventId, False)

            if action.flags & rd.ActionFlags.Drawcall:
                pipe = self.controller.GetPipelineState()
                tex = self.controller.GetPipelineState().GetOutputTargets()[0].resourceId

                view: rd.Viewport = self.controller.GetPipelineState().GetViewport(0)

                x,y = int(view.x + view.width / 2), int(view.y + view.height / 2)

                # convert to top-left co-ordinates for use with PickPixel
                y = self.get_texture(tex).height - y

                self.check_pixel_value(tex, x, y, [0.0, 1.0, 0.0, 1.0])

            action = action.next

        rdtest.log.success("Draws are all green")

        # Now save the backbuffer to disk
        ref_path = rdtest.get_tmp_path('backbuffer.png')

        save_data = rd.TextureSave()
        save_data.resourceId = tex
        save_data.destType = rd.FileType.PNG

        self.controller.SaveTexture(save_data, ref_path)

        # Open the capture and grab the thumbnail, check that it is all green too (dirty way of verifying we didn't
        # break in-app updates but somehow end up with the right data)
        cap = rd.OpenCaptureFile()

        # Open a particular file
        status = cap.OpenFile(self.capture_filename, '', None)

        # Make sure the file opened successfully
        if status != rd.ReplayStatus.Succeeded:
            cap.Shutdown()
            raise rdtest.TestFailureException("Couldn't open '{}': {}".format(self.capture_filename, str(status)))

        thumb: rd.Thumbnail = cap.GetThumbnail(rd.FileType.PNG, 0)

        tmp_path = rdtest.get_tmp_path('thumbnail.png')

        with open(tmp_path, 'wb') as f:
            f.write(thumb.data)

        # The original thumbnail should also be identical, since we have the uncompressed extended thumbnail.

        if not rdtest.png_compare(tmp_path, ref_path):
            raise rdtest.TestFailureException("Reference backbuffer and thumbnail image differ", tmp_path, ref_path)

        rdtest.log.success("Thumbnail is identical to reference")
    def __init__(self, height, width, distThr):
        super(GTAVMeshCapture, self).__init__()
        self.cap = rd.OpenCaptureFile()
        self.controller = None
        self.drawcalls = None
        self.height = height
        self.width = width

        self.dist_threshold = distThr
Exemple #6
0
    def check_capture(self):
        # Need capture access. Rather than trying to keep the original around, we just open a new one
        cap = rd.OpenCaptureFile()

        # Open a particular file
        status = cap.OpenFile(self.capture_filename, '', None)

        # Make sure the file opened successfully
        if status != rd.ReplayStatus.Succeeded:
            cap.Shutdown()
            raise rdtest.TestFailureException(
                "Couldn't open capture for access: {}".format(
                    self.capture_filename, str(status)))

        if not cap.HasCallstacks():
            raise rdtest.TestFailureException(
                "Capture does not report having callstacks")

        if not cap.InitResolver(False, None):
            raise rdtest.TestFailureException(
                "Failed to initialise callstack resolver")

        draw = self.find_draw("Draw")

        event: rd.APIEvent = draw.events[-1]

        expected_funcs = [
            "GL_Callstacks::testFunction",
            "GL_Callstacks::main",
        ]

        expected_lines = [7001, 8002]

        callstack = cap.GetResolve(list(event.callstack))

        if len(callstack) < len(expected_funcs):
            raise rdtest.TestFailureException(
                "Resolved callstack isn't long enough ({} stack frames), expected at least {}"
                .format(len(event.callstack), len(expected_funcs)))

        for i in range(len(expected_funcs)):
            stack: str = callstack[i]
            if expected_funcs[i] not in stack:
                raise rdtest.TestFailureException(
                    "Expected '{}' in '{}'".format(expected_funcs[i], stack))
            idx = callstack[i].find("line")
            if idx < 0:
                raise rdtest.TestFailureException(
                    "Expected a line number in '{}'".format(stack))

            if int(stack[idx + 5:]) != expected_lines[i]:
                raise rdtest.TestFailureException(
                    "Expected line number {} in '{}'".format(
                        expected_lines[i], stack))

        rdtest.log.success("Callstacks are as expected")
def get_local_controller(rdc_path: str):
    cap = rd.OpenCaptureFile()
    status = cap.OpenFile(rdc_path, '', None)

    if status != rd.ReplayStatus.Succeeded:
        raise RuntimeError("Couldn't open file: " + str(status))

    if not cap.LocalReplaySupport():
        raise RuntimeError("Capture cannot be replayed")

    status, controller = cap.OpenCapture(rd.ReplayOptions(), None)

    if status != rd.ReplayStatus.Succeeded:
        raise RuntimeError("Couldn't initialise replay: " + str(status))

    return controller
def loadCapture(filename):
    cap = rd.OpenCaptureFile()

    status = cap.OpenFile(filename, '', None)

    if status != rd.ReplayStatus.Succeeded:
        raise RuntimeError("Couldn't open file: " + str(status))
    if not cap.LocalReplaySupport():
        raise RuntimeError("Capture cannot be replayed")

    status, controller = cap.OpenCapture(rd.ReplayOptions(), None)

    if status != rd.ReplayStatus.Succeeded:
        if os.path.exists(RENDERDOC_DEBUG_FILE):
            print(open(RENDERDOC_DEBUG_FILE, "r").read())
        raise RuntimeError("Couldn't initialise replay: " + str(status))

    if os.path.exists(RENDERDOC_DEBUG_FILE):
        open(RENDERDOC_DEBUG_FILE, "w").write("")

    return (cap, controller)
def loadCapture(filename):
    # Open a capture file handle
    cap = rd.OpenCaptureFile()

    # Open a particular file - see also OpenBuffer to load from memory
    status = cap.OpenFile(filename, '', None)

    # Make sure the file opened successfully
    if status != rd.ReplayStatus.Succeeded:
        raise RuntimeError("Couldn't open file: " + str(status))

    # Make sure we can replay
    if not cap.LocalReplaySupport():
        raise RuntimeError("Capture cannot be replayed")

    # Initialise the replay
    status, controller = cap.OpenCapture(None)

    if status != rd.ReplayStatus.Succeeded:
        raise RuntimeError("Couldn't initialise replay: " + str(status))

    return (cap, controller)
Exemple #10
0
    def __enter__(self):
        self.cap = rd.OpenCaptureFile()
        status = self.cap.OpenFile(self.filename, '', None)

        if status != rd.ReplayStatus.Succeeded:
            print("Couldn't open file: " + str(status))
            self.err = True
            return None

        if not self.cap.LocalReplaySupport():
            print("Capture cannot be replayed")
            self.err = True
            return None

        status, self.controller = self.cap.OpenCapture(None)

        if status != rd.ReplayStatus.Succeeded:
            print("Couldn't initialise replay: " + str(status))
            self.cap.shutdown()
            self.err = True
            return None
        return self.controller
Exemple #11
0
    def check_capture(self, capture_filename: str,
                      controller: rd.ReplayController):
        self.controller = controller

        self.opengl_mode = (self.controller.GetAPIProperties().pipelineType ==
                            rd.GraphicsAPI.OpenGL)

        failed = False

        try:
            # First check with the local controller
            self.check_capture_with_controller('')
        except rdtest.TestFailureException as ex:
            rdtest.log.error(str(ex))
            failed = True

        # Now shut it down
        self.controller.Shutdown()
        self.controller = None

        # Launch a remote server
        rdtest.launch_remote_server()

        # Wait for it to start
        time.sleep(0.5)

        ret: Tuple[rd.ReplayStatus,
                   rd.RemoteServer] = rd.CreateRemoteServerConnection(
                       'localhost')
        status, remote = ret

        proxies = remote.LocalProxies()

        try:
            # Try D3D11 and GL as proxies, D3D12/Vulkan technically don't have proxying implemented even though they
            # will be listed in proxies
            for api in ['D3D11', 'OpenGL']:
                if api not in proxies:
                    continue

                try:
                    ret: Tuple[rd.ReplayStatus,
                               rd.ReplayController] = remote.OpenCapture(
                                   proxies.index(api), capture_filename,
                                   rd.ReplayOptions(), None)
                    status, self.controller = ret

                    # Now check with the proxy
                    self.check_capture_with_controller(api)
                except ValueError:
                    continue
                except rdtest.TestFailureException as ex:
                    rdtest.log.error(str(ex))
                    failed = True
                finally:
                    self.controller.Shutdown()
                    self.controller = None
        finally:
            remote.ShutdownServerAndConnection()

        # Now iterate over all the temp images saved out, load them as captures, and check the texture.
        dir_path = rdtest.get_tmp_path('')

        was_opengl = self.opengl_mode

        # We iterate in filename order, so that dds files get opened before png files.
        for file in os.scandir(dir_path):
            if '.dds' not in file.name and '.png' not in file.name:
                continue

            cap = rd.OpenCaptureFile()
            status = cap.OpenFile(file.path, 'rdc', None)

            if status != rd.ReplayStatus.Succeeded:
                rdtest.log.error("Couldn't open {}".format(file.name))
                failed = True
                continue

            ret: Tuple[rd.ReplayStatus, rd.ReplayController] = cap.OpenCapture(
                rd.ReplayOptions(), None)
            status, self.controller = ret

            # Some packed formats can't be opened, allow that
            if status == rd.ReplayStatus.ImageUnsupported and 'dds' in file.name:
                rdtest.log.print("Couldn't open {} - unsupported".format(
                    file.name))
                continue

            if status != rd.ReplayStatus.Succeeded:
                rdtest.log.error("Couldn't open {}".format(file.name))
                failed = True
                continue

            self.filename = file.name.replace('.dds', '').replace('.png', '')

            [a, b] = file.name.replace('.dds',
                                       ' (DDS)').replace('.png',
                                                         ' (PNG)').split('@')

            self.controller.SetFrameEvent(
                self.controller.GetDrawcalls()[0].eventId, True)

            try:
                self.opengl_mode = False
                fmt: rd.ResourceFormat = self.controller.GetTextures(
                )[0].format

                is_compressed = (rd.ResourceFormatType.BC1 <= fmt.type <=
                                 rd.ResourceFormatType.BC7
                                 or fmt.type == rd.ResourceFormatType.EAC
                                 or fmt.type == rd.ResourceFormatType.ETC2
                                 or fmt.type == rd.ResourceFormatType.ASTC
                                 or fmt.type == rd.ResourceFormatType.PVRTC)

                # OpenGL saves all non-compressed images to disk with a flip, since that's the expected order for
                # most formats. The effect of this is that we should apply the opengl_mode workaround for all files
                # *except* compressed textures
                if was_opengl and not is_compressed:
                    self.opengl_mode = True

                self.check_test(
                    a, b, Texture_Zoo.TEST_DDS
                    if '.dds' in file.name else Texture_Zoo.TEST_PNG)

                rdtest.log.success("{} loaded with the correct data".format(
                    file.name))
            except rdtest.TestFailureException as ex:
                rdtest.log.error(str(ex))
                failed = True

            self.controller.Shutdown()
            self.controller = None

        if failed:
            raise rdtest.TestFailureException(
                "Some tests were not as expected")
Exemple #12
0
import renderdoc as rd

# Open a capture file handle
cap = rd.OpenCaptureFile()

# Open a particular file - see also OpenBuffer to load from memory
status = cap.OpenFile('test.rdc', '', None)

# Make sure the file opened successfully
if status != rd.ReplayStatus.Succeeded:
    raise RuntimeError("Couldn't open file: " + str(status))

# Make sure we can replay
if not cap.LocalReplaySupport():
    raise RuntimeError("Capture cannot be replayed")

# Initialise the replay
status, controller = cap.OpenCapture(rd.ReplayOptions(), None)

if status != rd.ReplayStatus.Succeeded:
    raise RuntimeError("Couldn't initialise replay: " + str(status))

# Now we can use the controller!
print("%d top-level drawcalls" % len(controller.GetDrawcalls()))

controller.Shutdown()

cap.Shutdown()
Exemple #13
0
    def check_capture(self):
        # Make an output so we can pick pixels
        out: rd.ReplayOutput = self.controller.CreateOutput(
            rd.CreateHeadlessWindowingData(100, 100),
            rd.ReplayOutputType.Texture)

        self.check(out is not None)

        tex = rd.TextureDisplay()

        # At each draw, the centre pixel of the viewport should be green
        draw = self.get_first_draw()
        while draw is not None:
            self.controller.SetFrameEvent(draw.eventId, False)

            if draw.flags & rd.DrawFlags.Drawcall:
                tex.resourceId = self.controller.GetPipelineState(
                ).GetOutputTargets()[0].resourceId
                out.SetTextureDisplay(tex)

                view: rd.Viewport = self.controller.GetPipelineState(
                ).GetViewport(0)

                x, y = int(view.x + view.width / 2), int(view.y +
                                                         view.height / 2)

                # convert to top-left co-ordinates for use with PickPixel
                y = self.get_texture(tex.resourceId).height - y

                picked: rd.PixelValue = out.PickPixel(tex.resourceId, False, x,
                                                      y, 0, 0, 0)

                if not rdtest.value_compare(picked.floatValue,
                                            [0.0, 1.0, 0.0, 1.0]):
                    raise rdtest.TestFailureException(
                        "Picked value {} at {} doesn't match expected green".
                        format(picked.floatValue, (x, y)))

            draw = draw.next

        rdtest.log.success("Draws are all green")

        # Now save the backbuffer to disk
        ref_path = rdtest.get_tmp_path('backbuffer.png')

        save_data = rd.TextureSave()
        save_data.resourceId = tex.resourceId
        save_data.destType = rd.FileType.PNG

        self.controller.SaveTexture(save_data, ref_path)

        # Open the capture and grab the thumbnail, check that it is all green too (dirty way of verifying we didn't
        # break in-app updates but somehow end up with the right data)
        cap = rd.OpenCaptureFile()

        # Open a particular file
        status = cap.OpenFile(self.capture_filename, '', None)

        # Make sure the file opened successfully
        if status != rd.ReplayStatus.Succeeded:
            cap.Shutdown()
            raise rdtest.TestFailureException("Couldn't open '{}': {}".format(
                self.capture_filename, str(status)))

        thumb: rd.Thumbnail = cap.GetThumbnail(rd.FileType.PNG, 0)

        tmp_path = rdtest.get_tmp_path('thumbnail.png')

        with open(tmp_path, 'wb') as f:
            f.write(thumb.data)

        # The original thumbnail should also be identical, since we have the uncompressed extended thumbnail.

        if not rdtest.png_compare(tmp_path, ref_path):
            raise rdtest.TestFailureException(
                "Reference backbuffer and thumbnail image differ", tmp_path,
                ref_path)

        rdtest.log.success("Thumbnail is identical to reference")

        out.Shutdown()
Exemple #14
0
    def check_capture(self):
        # Need capture access. Rather than trying to keep the original around, we just open a new one
        cap = rd.OpenCaptureFile()

        # Open a particular file
        result = cap.OpenFile(self.capture_filename, '', None)

        # Make sure the file opened successfully
        if result != rd.ResultCode.Succeeded:
            cap.Shutdown()
            raise rdtest.TestFailureException(
                "Couldn't open capture for access: {}".format(
                    self.capture_filename, str(result)))

        if not cap.HasCallstacks():
            raise rdtest.TestFailureException(
                "Capture does not report having callstacks")

        if not cap.InitResolver(False, resolve_progress):
            raise rdtest.TestFailureException(
                "Failed to initialise callstack resolver")

        action = self.find_action("Draw")

        event: rd.APIEvent = action.events[-1]

        expected_funcs = [
            "GL_Callstacks::testFunction",
            "GL_Callstacks::main",
        ]

        expected_lines = [7001, 8002]

        sdfile = self.controller.GetStructuredFile()

        if event.chunkIndex < 0 or event.chunkIndex > len(sdfile.chunks):
            raise rdtest.TestFailureException(
                "Event {} has invalid chunk index {}".format(
                    event.eventId, event.chunkIndex))

        chunk = sdfile.chunks[event.chunkIndex]

        callstack = cap.GetResolve(list(chunk.metadata.callstack))

        if len(callstack) < len(expected_funcs):
            raise rdtest.TestFailureException(
                "Resolved callstack isn't long enough ({} stack frames), expected at least {}"
                .format(len(event.callstack), len(expected_funcs)))

        for i in range(len(expected_funcs)):
            stack: str = callstack[i]
            if expected_funcs[i] not in stack:
                raise rdtest.TestFailureException(
                    "Expected '{}' in '{}'".format(expected_funcs[i], stack))
            idx = callstack[i].find("line")
            if idx < 0:
                raise rdtest.TestFailureException(
                    "Expected a line number in '{}'".format(stack))

            if int(stack[idx + 5:]) != expected_lines[i]:
                raise rdtest.TestFailureException(
                    "Expected line number {} in '{}'".format(
                        expected_lines[i], stack))

        rdtest.log.success("Callstacks are as expected")
 def __init__(self):
     super(GTA5Capture, self).__init__()
     self.cap = rd.OpenCaptureFile()
     self.drawcalls = None
     self.controller = None
     self.projMat = np.zeros([4, 4])