int vkDisplay::init(const unsigned int gpu_idx)
{
    //m_gpuIdx = gpu_idx;
#if 0
    VkResult result = init_vk(gpu_idx);
    if (result != VK_SUCCESS) {
        vktrace_LogError("could not init vulkan library");
        return -1;
    } else {
        m_initedVK = true;
    }
#endif
#if defined(PLATFORM_LINUX)
    const xcb_setup_t *setup;
    xcb_screen_iterator_t iter;
    int scr;
    m_pXcbConnection = xcb_connect(NULL, &scr);
    setup = xcb_get_setup(m_pXcbConnection);
    iter = xcb_setup_roots_iterator(setup);
    while (scr-- > 0)
        xcb_screen_next(&iter);
    m_pXcbScreen = iter.data;
#endif
    return 0;
}
Example #2
0
bool InjectTracersIntoProcess(vktrace_process_info* pInfo)
{
    bool bRecordingThreadsCreated = true;
    vktrace_thread tracingThread;
    if (vktrace_platform_remote_load_library(pInfo->hProcess, NULL, &tracingThread, NULL)) {
        // prepare data for capture threads
        pInfo->pCaptureThreads[0].pProcessInfo = pInfo;
        pInfo->pCaptureThreads[0].recordingThread = VKTRACE_NULL_THREAD;

        // create thread to record trace packets from the tracer
        pInfo->pCaptureThreads[0].recordingThread = vktrace_platform_create_thread(Process_RunRecordTraceThread, &(pInfo->pCaptureThreads[0]));
        if (pInfo->pCaptureThreads[0].recordingThread == VKTRACE_NULL_THREAD) {
            vktrace_LogError("Failed to create trace recording thread.");
            bRecordingThreadsCreated = false;
        }

    } else {
        // failed to inject a DLL
        bRecordingThreadsCreated = false;
    }
    return bRecordingThreadsCreated;
}
VkResult vkDisplay::init_vk(unsigned int gpu_idx)
{
#if 0
    VkApplicationInfo appInfo = {};
    appInfo.pApplicationName = APP_NAME;
    appInfo.pEngineName = "";
    appInfo.apiVersion = VK_API_VERSION;
    VkResult res = vkInitAndEnumerateGpus(&appInfo, NULL, VK_MAX_PHYSICAL_GPUS, &m_gpuCount, m_gpus);
    if ( res == VK_SUCCESS ) {
        // retrieve the GPU information for all GPUs
        for( uint32_t gpu = 0; gpu < m_gpuCount; gpu++)
        {
            size_t gpuInfoSize = sizeof(m_gpuProps[0]);

            // get the GPU physical properties:
            res = vkGetGpuInfo( m_gpus[gpu], VK_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, &gpuInfoSize, &m_gpuProps[gpu]);
            if (res != VK_SUCCESS)
                vktrace_LogWarning("Failed to retrieve properties for gpu[%d] result %d", gpu, res);
        }
        res = VK_SUCCESS;
    } else if ((gpu_idx + 1) > m_gpuCount) {
        vktrace_LogError("vkInitAndEnumerate number of gpus does not include requested index: num %d, requested %d", m_gpuCount, gpu_idx);
        return -1;
    } else {
        vktrace_LogError("vkInitAndEnumerate failed");
        return res;
    }
    // TODO add multi-gpu support always use gpu[gpu_idx] for now
    // get all extensions supported by this device gpu[gpu_idx]
    // first check if extensions are available and save a list of them
    bool foundWSIExt = false;
    for( int ext = 0; ext < sizeof( extensions ) / sizeof( extensions[0] ); ext++)
    {
        res = vkGetExtensionSupport( m_gpus[gpu_idx], extensions[ext] );
        if (res == VK_SUCCESS) {
            m_extensions.push_back((char *) extensions[ext]);
            if (!strcmp(extensions[ext], "VK_WSI_WINDOWS"))
                foundWSIExt = true;
        }
    }
    if (!foundWSIExt) {
        vktrace_LogError("VK_WSI_WINDOWS extension not supported by gpu[%d]", gpu_idx);
        return VK_ERROR_INCOMPATIBLE_DEVICE;
    }
    // TODO generalize this: use one universal queue for now
    VkDeviceQueueCreateInfo dqci = {};
    dqci.queueCount = 1;
    dqci.queueType = VK_QUEUE_UNIVERSAL;
    std::vector<float> queue_priorities (dqci.queueCount, 0.0);
    dqci.pQueuePriorities = queue_priorities.data();
    // create the device enabling validation level 4
    const char * const * extensionNames = &m_extensions[0];
    VkDeviceCreateInfo info = {};
    info.queueCreateInfoCount = 1;
    info.pQueueCreateInfos = &dqci;
    info.enabledExtensionCount = static_cast <uint32_t> (m_extensions.size());
    info.ppEnabledExtensionNames = extensionNames;
    info.flags = VK_DEVICE_CREATE_VALIDATION;
    info.maxValidationLevel = VK_VALIDATION_LEVEL_4;
    bool32_t vkTrue = VK_TRUE;
    res = vkDbgSetGlobalOption( VK_DBG_OPTION_BREAK_ON_ERROR, sizeof( vkTrue ), &vkTrue );
    if (res != VK_SUCCESS)
        vktrace_LogWarning("Could not set debug option break on error");
    res = vkCreateDevice( m_gpus[0], &info, &m_dev[gpu_idx]);
    return res;
#else
    return VK_ERROR_INITIALIZATION_FAILED;
#endif
}
int vkDisplay::create_window(const unsigned int width, const unsigned int height)
{
#if defined(PLATFORM_LINUX)

    uint32_t value_mask, value_list[32];
    m_XcbWindow = xcb_generate_id(m_pXcbConnection);

    value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    value_list[0] = m_pXcbScreen->black_pixel;
    value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
                    XCB_EVENT_MASK_EXPOSURE;

    xcb_create_window(m_pXcbConnection,
            XCB_COPY_FROM_PARENT,
            m_XcbWindow, m_pXcbScreen->root,
            0, 0, width, height, 0,
            XCB_WINDOW_CLASS_INPUT_OUTPUT,
            m_pXcbScreen->root_visual,
            value_mask, value_list);

    xcb_map_window(m_pXcbConnection, m_XcbWindow);
    xcb_flush(m_pXcbConnection);
    // TODO : Not sure of best place to put this, but I have all the info I need here so just setting it all here for now
    //m_XcbPlatformHandle.connection = m_pXcbConnection;
    //m_XcbPlatformHandle.root = m_pXcbScreen->root;
    m_surface.base.platform = VK_ICD_WSI_PLATFORM_XCB;
    m_surface.connection = m_pXcbConnection;
    m_surface.window = m_XcbWindow;
    return 0;
#elif defined(WIN32)
    // Register Window class
    WNDCLASSEX wcex = {};
	m_connection = GetModuleHandle(0);
    wcex.cbSize = sizeof( WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WindowProcVk;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = m_connection;
    wcex.hIcon = LoadIcon(wcex.hInstance, MAKEINTRESOURCE( IDI_ICON));
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW);
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = APP_NAME;
    wcex.hIconSm = LoadIcon( wcex.hInstance, MAKEINTRESOURCE( IDI_ICON));
    if( !RegisterClassEx( &wcex))
    {
        vktrace_LogError("Failed to register windows class");
        return -1;
    }

    // create the window
    m_windowHandle = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, 0, 0,
                          width, height, NULL, NULL, wcex.hInstance, NULL);

    if (m_windowHandle)
    {
        ShowWindow( m_windowHandle, SW_SHOWDEFAULT);
        m_windowWidth = width;
        m_windowHeight = height;
    } else {
        vktrace_LogError("Failed to create window");
        return -1;
    }
    // TODO : Not sure of best place to put this, but I have all the info I need here so just setting it all here for now
    m_surface.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
    m_surface.hinstance = wcex.hInstance;
    m_surface.hwnd = m_windowHandle;
    return 0;
#endif
}
BOOL vktrace_process_spawn(vktrace_process_info* pInfo)
{
    assert(pInfo != NULL);

#if defined(WIN32)
    {
    unsigned long processCreateFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;
    char fullExePath[_MAX_PATH];
    PROCESS_INFORMATION processInformation;
    STARTUPINFO si = { 0 };
    si.cb = sizeof(si);

    memset(&processInformation, 0, sizeof(PROCESS_INFORMATION));
    memset(fullExePath, 0, sizeof(char)*_MAX_PATH);
    fullExePath[0] = 0;

    SetLastError(0);
    if (0==SearchPath(NULL, pInfo->exeName, ".exe", ARRAYSIZE(fullExePath), fullExePath, NULL))
    {
        vktrace_LogVerbose("Failed to spawn '%s'.", pInfo->exeName);
        return FALSE;
    }

    if (!CreateProcess(fullExePath, pInfo->fullProcessCmdLine, NULL, NULL, TRUE,
        processCreateFlags, NULL, pInfo->workingDirectory,
        &si, &processInformation))
    {
        vktrace_LogVerbose("Failed to spawn '%s'.", fullExePath);
        return FALSE;
    }

    pInfo->hProcess = processInformation.hProcess;
    pInfo->hThread = processInformation.hThread;
    pInfo->processId = processInformation.dwProcessId;
    // TODO : Do we need to do anything with processInformation.dwThreadId?
    }
#elif defined(PLATFORM_LINUX)
    pInfo->processId = fork();
    if (pInfo->processId == -1)
    {
        vktrace_LogError("Failed to spawn process.");
        return FALSE;
    }
    else if (pInfo->processId == 0)
    {
        // Inside new process
        char *args[128];
        const char delim[] = " \t";
        unsigned int idx;

        // Change process name so the the tracer DLLs will behave as expected when loaded.
        // NOTE: Must be 15 characters or less.
        const char * tmpProcName = "vktraceChildProcess";
        prctl(PR_SET_NAME, (unsigned long)tmpProcName, 0, 0, 0);

        // Change working directory
        if (chdir(pInfo->workingDirectory) == -1)
        {
            vktrace_LogError("Failed to set working directory.");
        }

        args[0] = pInfo->exeName;
        args[127] = NULL;
        idx = 1;
        args[idx] = strtok(pInfo->processArgs, delim);
        while ( args[idx] != NULL && idx < 128)
        {
            idx++;
            args[idx] = strtok(NULL, delim);
        }
        vktrace_LogDebug("exec process=%s argc=%u\n", pInfo->exeName, idx);
#if 0  //uncoment to print out list of env vars
        char *env = environ[0];
        idx = 0;
        while (env && strlen(env)) {
            if (strstr(env, "VK") || strstr(env, "LD"))
                vktrace_LogDebug("env[%d] = %s", idx++, env);
            else
                idx++;
            env = environ[idx];
        }
#endif
        if (execv(pInfo->exeName, args) < 0)
        {
            vktrace_LogError("Failed to spawn process.");
            exit(1);
        }
    }
#endif

    return TRUE;
}
Example #6
0
// ------------------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    memset(&g_settings, 0, sizeof(vktrace_settings));

    vktrace_LogSetCallback(loggingCallback);
    vktrace_LogSetLevel(VKTRACE_LOG_ERROR);

    // setup defaults
    memset(&g_default_settings, 0, sizeof(vktrace_settings));
    g_default_settings.output_trace = vktrace_allocate_and_copy("vktrace_out.vktrace");
    g_default_settings.verbosity = "errors";
    g_default_settings.screenshotList = NULL;

    if (vktrace_SettingGroup_init(&g_settingGroup, NULL, argc, argv, &g_settings.arguments) != 0)
    {
        // invalid cmd-line parameters
        vktrace_SettingGroup_delete(&g_settingGroup);
        vktrace_free(g_default_settings.output_trace);
        return -1;
    }
    else
    {
        // Validate vktrace inputs
        BOOL validArgs = TRUE;

        if (g_settings.output_trace == NULL || strlen (g_settings.output_trace) == 0)
        {
            validArgs = FALSE;
        }
        else
        {
            size_t len = strlen(g_settings.output_trace);
            if (strncmp(&g_settings.output_trace[len-8], ".vktrace", 8) != 0)
            {
                // output trace filename does not end in .vktrace
                vktrace_LogError("Output trace file specified with -o parameter must have a '.vktrace' extension.");
                validArgs = FALSE;
            }
        }

        if (strcmp(g_settings.verbosity, "quiet") == 0)
            vktrace_LogSetLevel(VKTRACE_LOG_NONE);
        else if (strcmp(g_settings.verbosity, "errors") == 0)
            vktrace_LogSetLevel(VKTRACE_LOG_ERROR);
        else if (strcmp(g_settings.verbosity, "warnings") == 0)
            vktrace_LogSetLevel(VKTRACE_LOG_WARNING);
        else if (strcmp(g_settings.verbosity, "full") == 0)
            vktrace_LogSetLevel(VKTRACE_LOG_VERBOSE);
#if _DEBUG
        else if (strcmp(g_settings.verbosity, "debug") == 0)
            vktrace_LogSetLevel(VKTRACE_LOG_DEBUG);
#endif
        else
        {
            vktrace_LogSetLevel(VKTRACE_LOG_ERROR);
            validArgs = FALSE;
        }
		vktrace_set_global_var("_VK_TRACE_VERBOSITY", g_settings.verbosity);

        if (validArgs == FALSE)
        {
            vktrace_SettingGroup_print(&g_settingGroup);
            return -1;
        }

        if (g_settings.program == NULL || strlen(g_settings.program) == 0)
        {
            vktrace_LogWarning("No program (-p) parameter found: Will run vktrace as server.");
            printf("Running vktrace as server...\n");
            fflush(stdout);
            g_settings.arguments = NULL;
        }
        else
        {
            if (g_settings.working_dir == NULL || strlen(g_settings.working_dir) == 0)
            {
                CHAR* buf = VKTRACE_NEW_ARRAY(CHAR, 4096);
                vktrace_LogVerbose("No working directory (-w) parameter found: Assuming executable's path as working directory.");
                vktrace_platform_full_path(g_settings.program, 4096, buf);
                g_settings.working_dir = vktrace_platform_extract_path(buf);
                VKTRACE_DELETE(buf);
            }

            vktrace_LogVerbose("Running vktrace as parent process will spawn child process: %s", g_settings.program);
            if (g_settings.arguments != NULL && strlen(g_settings.arguments) > 0)
            {
                vktrace_LogVerbose("Args to be passed to child process: '%s'", g_settings.arguments);
            }
        }
    }

    if (g_settings.screenshotList)
    {
        // Export list to screenshot layer
        vktrace_set_global_var("_VK_SCREENSHOT", g_settings.screenshotList);
    }
    else
    {
        vktrace_set_global_var("_VK_SCREENSHOT","");
    }


    unsigned int serverIndex = 0;
    do {
        // Create and start the process or run in server mode

        BOOL procStarted = TRUE;
        vktrace_process_info procInfo;
        memset(&procInfo, 0, sizeof(vktrace_process_info));
        if (g_settings.program != NULL)
        {
            procInfo.exeName = vktrace_allocate_and_copy(g_settings.program);
            procInfo.processArgs = vktrace_allocate_and_copy(g_settings.arguments);
            procInfo.fullProcessCmdLine = vktrace_copy_and_append(g_settings.program, " ", g_settings.arguments);
            procInfo.workingDirectory = vktrace_allocate_and_copy(g_settings.working_dir);
            procInfo.traceFilename = vktrace_allocate_and_copy(g_settings.output_trace);
        } else
        {
            const char *pExtension = strrchr(g_settings.output_trace, '.');
            char *basename = vktrace_allocate_and_copy_n(g_settings.output_trace, (int) ((pExtension == NULL) ? strlen(g_settings.output_trace) : pExtension - g_settings.output_trace));
            char num[16];
#ifdef PLATFORM_LINUX
            snprintf(num, 16, "%u", serverIndex);
#elif defined(WIN32)
            _snprintf_s(num, 16, _TRUNCATE, "%u", serverIndex);
#endif
            procInfo.traceFilename = vktrace_copy_and_append(basename, num, pExtension);
         }

        procInfo.parentThreadId = vktrace_platform_get_thread_id();

        // setup tracer, only Vulkan tracer suppported
        PrepareTracers(&procInfo.pCaptureThreads);

        if (g_settings.program != NULL)
        {
            char *instEnv = vktrace_get_global_var("VK_INSTANCE_LAYERS");
            // Add ScreenShot layer if enabled
            if (g_settings.screenshotList && (!instEnv || !strstr(instEnv, "VK_LAYER_LUNARG_screenshot")))
            {
                if (!instEnv || strlen(instEnv)  == 0)
                    vktrace_set_global_var("VK_INSTANCE_LAYERS", "VK_LAYER_LUNARG_screenshot");
                else
                {
                    char *newEnv = vktrace_copy_and_append(instEnv, VKTRACE_LIST_SEPARATOR, "VK_LAYER_LUNARG_screenshot");
                    vktrace_set_global_var("VK_INSTANCE_LAYERS", newEnv);
                }
                instEnv = vktrace_get_global_var("VK_INSTANCE_LAYERS");
            }
            char *devEnv = vktrace_get_global_var("VK_DEVICE_LAYERS");
            if (g_settings.screenshotList && (!devEnv || !strstr(devEnv, "VK_LAYER_LUNARG_screenshot")))
            {
                if (!devEnv || strlen(devEnv) == 0)
                    vktrace_set_global_var("VK_DEVICE_LAYERS", "VK_LAYER_LUNARG_screenshot");
                else
                {
                    char *newEnv = vktrace_copy_and_append(devEnv, VKTRACE_LIST_SEPARATOR, "VK_LAYER_LUNARG_screenshot");
                    vktrace_set_global_var("VK_DEVICE_LAYERS", newEnv);
                }
                devEnv = vktrace_get_global_var("VK_DEVICE_LAYERS");
            }
            // Add vktrace_layer enable env var if needed
            if (!instEnv || strlen(instEnv) == 0)
            {
                vktrace_set_global_var("VK_INSTANCE_LAYERS", "VK_LAYER_LUNARG_vktrace");
            }
            else if (instEnv != strstr(instEnv, "VK_LAYER_LUNARG_vktrace"))
            {
                char *newEnv = vktrace_copy_and_append("VK_LAYER_LUNARG_vktrace", VKTRACE_LIST_SEPARATOR, instEnv);
                vktrace_set_global_var("VK_INSTANCE_LAYERS", newEnv);
            }
            if (!devEnv || strlen(devEnv) == 0)
            {
                vktrace_set_global_var("VK_DEVICE_LAYERS", "VK_LAYER_LUNARG_vktrace");
            }
            else if (devEnv != strstr(devEnv, "VK_LAYER_LUNARG_vktrace"))
            {
                char *newEnv = vktrace_copy_and_append("VK_LAYER_LUNARG_vktrace", VKTRACE_LIST_SEPARATOR, devEnv);
                vktrace_set_global_var("VK_DEVICE_LAYERS", newEnv);
            }
            // call CreateProcess to launch the application
            procStarted = vktrace_process_spawn(&procInfo);
        }
        if (procStarted == FALSE)
        {
            vktrace_LogError("Failed to setup remote process.");
        }
        else
        {
            if (InjectTracersIntoProcess(&procInfo) == FALSE)
            {
                vktrace_LogError("Failed to setup tracer communication threads.");
                return -1;
            }

            // create watchdog thread to monitor existence of remote process
            if (g_settings.program != NULL)
                procInfo.watchdogThread = vktrace_platform_create_thread(Process_RunWatchdogThread, &procInfo);

#if defined(PLATFORM_LINUX)
            // Sync wait for local threads and remote process to complete.

            vktrace_platform_sync_wait_for_thread(&(procInfo.pCaptureThreads[0].recordingThread));

            if (g_settings.program != NULL)
                vktrace_platform_sync_wait_for_thread(&procInfo.watchdogThread);
#else
            vktrace_platform_resume_thread(&procInfo.hThread);

            // Now into the main message loop, listen for hotkeys to send over.
            MessageLoop();
#endif
        }

        vktrace_process_info_delete(&procInfo);
        serverIndex++;
    } while (g_settings.program == NULL);

    vktrace_SettingGroup_delete(&g_settingGroup);
    vktrace_free(g_default_settings.output_trace);

    return 0;
}
//The function source code is modified from __HOOKED_vkFlushMappedMemoryRanges
//for coherent map, need this function to dump data so simulate target application write data when playback.
VkResult vkFlushMappedMemoryRangesWithoutAPICall(
    VkDevice device,
    uint32_t memoryRangeCount,
    const VkMappedMemoryRange* pMemoryRanges)
{
    VkResult result = VK_SUCCESS;
    vktrace_trace_packet_header* pHeader;
    size_t rangesSize = 0;
    size_t dataSize = 0;
    uint32_t iter;
    packet_vkFlushMappedMemoryRanges* pPacket = nullptr;

#ifdef USE_PAGEGUARD_SPEEDUP
    PBYTE *ppPackageData = new PBYTE[memoryRangeCount];
    bool bOPTTargetWithoutChange = getPageGuardControlInstance().vkFlushMappedMemoryRangesPageGuardHandle(device, memoryRangeCount, pMemoryRanges, ppPackageData);//the packet is not needed if no any change on data of all ranges
    if (bOPTTargetWithoutChange)
    {
        return result;
    }
#endif

    // find out how much memory is in the ranges
    for (iter = 0; iter < memoryRangeCount; iter++)
    {
        VkMappedMemoryRange* pRange = (VkMappedMemoryRange*)&pMemoryRanges[iter];
        rangesSize += vk_size_vkmappedmemoryrange(pRange);
        dataSize += (size_t)pRange->size;
    }
#ifdef USE_PAGEGUARD_SPEEDUP
    dataSize = getPageGuardControlInstance().getALLChangedPackageSizeInMappedMemory(device, memoryRangeCount, pMemoryRanges, ppPackageData);
#endif
    CREATE_TRACE_PACKET(vkFlushMappedMemoryRanges, rangesSize + sizeof(void*)*memoryRangeCount + dataSize);
    pPacket = interpret_body_as_vkFlushMappedMemoryRanges(pHeader);

    vktrace_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMemoryRanges), rangesSize, pMemoryRanges);
    vktrace_finalize_buffer_address(pHeader, (void**)&(pPacket->pMemoryRanges));

    // insert into packet the data that was written by CPU between the vkMapMemory call and here
    // create a temporary local ppData array and add it to the packet (to reserve the space for the array)
    void** ppTmpData = (void **)malloc(memoryRangeCount * sizeof(void*));
    vktrace_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->ppData), sizeof(void*)*memoryRangeCount, ppTmpData);
    free(ppTmpData);

    // now the actual memory
    vktrace_enter_critical_section(&g_memInfoLock);
    for (iter = 0; iter < memoryRangeCount; iter++)
    {
        VkMappedMemoryRange* pRange = (VkMappedMemoryRange*)&pMemoryRanges[iter];
        VKAllocInfo* pEntry = find_mem_info_entry(pRange->memory);

        if (pEntry != nullptr)
        {
            assert(pEntry->handle == pRange->memory);
            assert(pEntry->totalSize >= (pRange->size + pRange->offset));
            assert(pEntry->totalSize >= pRange->size);
            assert(pRange->offset >= pEntry->rangeOffset && (pRange->offset + pRange->size) <= (pEntry->rangeOffset + pEntry->rangeSize));
#ifdef USE_PAGEGUARD_SPEEDUP
            LPPageGuardMappedMemory pOPTMemoryTemp = getPageGuardControlInstance().findMappedMemoryObject(device, pRange);
            VkDeviceSize OPTPackageSizeTemp = 0;
            if (pOPTMemoryTemp)
            {
                PBYTE pOPTDataTemp = pOPTMemoryTemp->getChangedDataPackage(&OPTPackageSizeTemp);
                setFlagTovkFlushMappedMemoryRangesSpecial(pOPTDataTemp);
                vktrace_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->ppData[iter]), OPTPackageSizeTemp, pOPTDataTemp);
                pOPTMemoryTemp->clearChangedDataPackage();
                pOPTMemoryTemp->resetMemoryObjectAllChangedFlagAndPageGuard();
            }
            else
            {
                PBYTE pOPTDataTemp = getPageGuardControlInstance().getChangedDataPackageOutOfMap(ppPackageData, iter, &OPTPackageSizeTemp);
                setFlagTovkFlushMappedMemoryRangesSpecial(pOPTDataTemp);
                vktrace_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->ppData[iter]), OPTPackageSizeTemp, pOPTDataTemp);
                getPageGuardControlInstance().clearChangedDataPackageOutOfMap(ppPackageData, iter);
            }
#else
            vktrace_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->ppData[iter]), pRange->size, pEntry->pData + pRange->offset);
#endif
            vktrace_finalize_buffer_address(pHeader, (void**)&(pPacket->ppData[iter]));
            pEntry->didFlush = true;
        }
        else
        {
            vktrace_LogError("Failed to copy app memory into trace packet (idx = %u) on vkFlushedMappedMemoryRanges", pHeader->global_packet_index);
        }
    }
#ifdef USE_PAGEGUARD_SPEEDUP
    delete[] ppPackageData;
#endif
    vktrace_leave_critical_section(&g_memInfoLock);

    // now finalize the ppData array since it is done being updated
    vktrace_finalize_buffer_address(pHeader, (void**)&(pPacket->ppData));

    //result = mdd(device)->devTable.FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
    vktrace_set_packet_entrypoint_end_time(pHeader);
    pPacket->device = device;
    pPacket->memoryRangeCount = memoryRangeCount;
    pPacket->result = result;

    FINISH_TRACE_PACKET();
    return result;
}
Example #8
0
vktrace_trace_packet_replay_library* ReplayFactory::Create(uint8_t tracerId)
{
    vktrace_trace_packet_replay_library* pReplayer = NULL;
    //void* pLibrary = NULL;

    const VKTRACE_TRACER_REPLAYER_INFO* pReplayerInfo = &(gs_tracerReplayerInfo[tracerId]);


    if (pReplayerInfo->tracerId != tracerId)
    {
        vktrace_LogError("Replayer info for TracerId (%d) failed consistency check.", tracerId);
        assert(!"TracerId in VKTRACE_TRACER_REPLAYER_INFO does not match the requested tracerId. The array needs to be corrected.");
    }

    // Vulkan library is built into replayer executable
    if (tracerId == VKTRACE_TID_VULKAN) {
        pReplayer = VKTRACE_NEW(vktrace_trace_packet_replay_library);
        if (pReplayer == NULL)
        {
            vktrace_LogError("Failed to allocate replayer library.");
        }
        else
        {
            pReplayer->pLibrary = NULL;

            pReplayer->SetLogCallback = VkReplaySetLogCallback;
            pReplayer->SetLogLevel = VkReplaySetLogLevel;

            pReplayer->RegisterDbgMsgCallback = VkReplayRegisterDbgMsgCallback;
            pReplayer->GetSettings = VkReplayGetSettings;
            pReplayer->UpdateFromSettings = VkReplayUpdateFromSettings;
            pReplayer->Initialize = VkReplayInitialize;
            pReplayer->Deinitialize = VkReplayDeinitialize;
            pReplayer->Interpret = VkReplayInterpret;
            pReplayer->Replay = VkReplayReplay;
            pReplayer->Dump = VkReplayDump;
            pReplayer->GetFrameNumber = VkReplayGetFrameNumber;
            pReplayer->ResetFrameNumber = VkReplayResetFrameNumber;
        }

    }
    
//    if (pReplayerInfo->needsReplayer == TRUE)
//    {
//        pLibrary = vktrace_platform_open_library(pReplayerInfo->replayerLibraryName);
//        if (pLibrary == NULL)
//        {
//            vktrace_LogError("Failed to load replayer '%s.", pReplayerInfo->replayerLibraryName);
//#if defined(PLATFORM_LINUX)
//            char* error = dlerror();
//            vktrace_LogError(error);
//#endif
//        }
//    }
//    else
//    {
//        vktrace_LogError("A replayer was requested for TracerId (%d), but it does not require a replayer.", tracerId);
//        assert(!"Invalid TracerId supplied to ReplayFactory");
//    }
//
//    if (pLibrary != NULL)
//    {
//        pReplayer = VKTRACE_NEW(vktrace_trace_packet_replay_library);
//        if (pReplayer == NULL)
//        {
//            vktrace_LogError("Failed to allocate replayer library.");
//            vktrace_platform_close_library(pLibrary);
//        }
//        else
//        {
//            pReplayer->pLibrary = pLibrary;
//
//            pReplayer->SetLogCallback = (funcptr_vkreplayer_setlogcallback)vktrace_platform_get_library_entrypoint(pLibrary, "SetLogCallback");
//            pReplayer->SetLogLevel = (funcptr_vkreplayer_setloglevel)vktrace_platform_get_library_entrypoint(pLibrary, "SetLogLevel");
//
//            pReplayer->RegisterDbgMsgCallback = (funcptr_vkreplayer_registerdbgmsgcallback)vktrace_platform_get_library_entrypoint(pLibrary, "RegisterDbgMsgCallback");
//            pReplayer->GetSettings = (funcptr_vkreplayer_getSettings)vktrace_platform_get_library_entrypoint(pLibrary, "GetSettings");
//            pReplayer->UpdateFromSettings = (funcptr_vkreplayer_updatefromsettings)vktrace_platform_get_library_entrypoint(pLibrary, "UpdateFromSettings");
//            pReplayer->Initialize = (funcptr_vkreplayer_initialize)vktrace_platform_get_library_entrypoint(pLibrary, "Initialize");
//            pReplayer->Deinitialize = (funcptr_vkreplayer_deinitialize)vktrace_platform_get_library_entrypoint(pLibrary, "Deinitialize");
//            pReplayer->Interpret = (funcptr_vkreplayer_interpret)vktrace_platform_get_library_entrypoint(pLibrary, "Interpret");
//            pReplayer->Replay = (funcptr_vkreplayer_replay)vktrace_platform_get_library_entrypoint(pLibrary, "Replay");
//            pReplayer->Dump = (funcptr_vkreplayer_dump)vktrace_platform_get_library_entrypoint(pLibrary, "Dump");
//
//            if (pReplayer->SetLogCallback == NULL ||
//                pReplayer->SetLogLevel == NULL ||
//                pReplayer->RegisterDbgMsgCallback == NULL ||
//                pReplayer->GetSettings == NULL ||
//                pReplayer->UpdateFromSettings == NULL ||
//                pReplayer->Initialize == NULL ||
//                pReplayer->Deinitialize == NULL ||
//                pReplayer->Interpret == NULL ||
//                pReplayer->Replay == NULL ||
//                pReplayer->Dump == NULL)
//            {
//                VKTRACE_DELETE(pReplayer);
//                vktrace_platform_close_library(pLibrary);
//                pReplayer = NULL;
//            }
//        }
//    }

    return pReplayer;
}
Example #9
0
int main_loop(Sequencer &seq, vktrace_trace_packet_replay_library *replayerArray[], vkreplayer_settings settings)
{
    int err = 0;
    vktrace_trace_packet_header *packet;
    unsigned int res;
    vktrace_trace_packet_replay_library *replayer = NULL;
    vktrace_trace_packet_message* msgPacket;
    struct seqBookmark startingPacket;

    bool trace_running = true;
    int prevFrameNumber = -1;

    // record the location of looping start packet
    seq.record_bookmark();
    seq.get_bookmark(startingPacket);
    while (settings.numLoops > 0)
    {
        while ((packet = seq.get_next_packet()) != NULL && trace_running)
        {
            switch (packet->packet_id) {
                case VKTRACE_TPI_MESSAGE:
                    msgPacket = vktrace_interpret_body_as_trace_packet_message(packet);
                    vktrace_LogAlways("Packet %lu: Traced Message (%s): %s", packet->global_packet_index, vktrace_LogLevelToShortString(msgPacket->type), msgPacket->message);
                    break;
                case VKTRACE_TPI_MARKER_CHECKPOINT:
                    break;
                case VKTRACE_TPI_MARKER_API_BOUNDARY:
                    break;
                case VKTRACE_TPI_MARKER_API_GROUP_BEGIN:
                    break;
                case VKTRACE_TPI_MARKER_API_GROUP_END:
                    break;
                case VKTRACE_TPI_MARKER_TERMINATE_PROCESS:
                    break;
                //TODO processing code for all the above cases
                default:
                {
                    if (packet->tracer_id >= VKTRACE_MAX_TRACER_ID_ARRAY_SIZE  || packet->tracer_id == VKTRACE_TID_RESERVED) {
                        vktrace_LogError("Tracer_id from packet num packet %d invalid.", packet->packet_id);
                        continue;
                    }
                    replayer = replayerArray[packet->tracer_id];
                    if (replayer == NULL) {
                        vktrace_LogWarning("Tracer_id %d has no valid replayer.", packet->tracer_id);
                        continue;
                    }
                    if (packet->packet_id >= VKTRACE_TPI_BEGIN_API_HERE)
                    {
                        // replay the API packet
                        res = replayer->Replay(replayer->Interpret(packet));
                        if (res != VKTRACE_REPLAY_SUCCESS)
                        {
                           vktrace_LogError("Failed to replay packet_id %d.",packet->packet_id);
                           return -1;
                        }

                        // frame control logic
                        int frameNumber = replayer->GetFrameNumber();
                        if (prevFrameNumber != frameNumber)
                        {
                            prevFrameNumber = frameNumber;

                            if (frameNumber == settings.loopStartFrame)
                            {
                                // record the location of looping start packet
                                seq.record_bookmark();
                                seq.get_bookmark(startingPacket);
                            }

                            if (frameNumber == settings.loopEndFrame)
                            {
                                trace_running = false;
                            }
                        }

                    } else {
                        vktrace_LogError("Bad packet type id=%d, index=%d.", packet->packet_id, packet->global_packet_index);
                        return -1;
                    }
                }
            }
        }
        settings.numLoops--;
        seq.set_bookmark(startingPacket);
        trace_running = true;
        if (replayer != NULL)
        {
            replayer->ResetFrameNumber();
        }
    }
    return err;
}