int sample_main(int argc, char *argv[]) {
    VkResult U_ASSERT_ONLY res;
    struct sample_info info = {};
    char sample_title[] = "Pipeline Cache";
    const bool depthPresent = true;

    process_command_line_args(info, argc, argv);
    init_global_layer_properties(info);
    init_instance_extension_names(info);
    init_device_extension_names(info);
    init_instance(info, sample_title);
    init_enumerate_device(info);
    init_window_size(info, 500, 500);
    init_connection(info);
    init_window(info);
    init_swapchain_extension(info);
    init_device(info);
    init_command_pool(info);
    init_command_buffer(info);
    execute_begin_command_buffer(info);
    init_device_queue(info);
    init_swap_chain(info);
    init_depth_buffer(info);
    init_texture(info, "blue.ppm");
    init_uniform_buffer(info);
    init_descriptor_and_pipeline_layouts(info, true);
    init_renderpass(info, depthPresent);
    init_shaders(info, vertShaderText, fragShaderText);
    init_framebuffers(info, depthPresent);
    init_vertex_buffer(info, g_vb_texture_Data, sizeof(g_vb_texture_Data),
                       sizeof(g_vb_texture_Data[0]), true);
    init_descriptor_pool(info, true);
    init_descriptor_set(info, true);

    /* VULKAN_KEY_START */

    // Check disk for existing cache data
    size_t startCacheSize = 0;
    void *startCacheData = nullptr;

    std::string directoryName = get_file_directory();
    std::string readFileName = directoryName + "pipeline_cache_data.bin";
    FILE *pReadFile = fopen(readFileName.c_str(), "rb");

    if (pReadFile) {

        // Determine cache size
        fseek(pReadFile, 0, SEEK_END);
        startCacheSize = ftell(pReadFile);
        rewind(pReadFile);

        // Allocate memory to hold the initial cache data
        startCacheData = (char *)malloc(sizeof(char) * startCacheSize);
        if (startCacheData == nullptr) {
            fputs("Memory error", stderr);
            exit(EXIT_FAILURE);
        }

        // Read the data into our buffer
        size_t result = fread(startCacheData, 1, startCacheSize, pReadFile);
        if (result != startCacheSize) {
            fputs("Reading error", stderr);
            free(startCacheData);
            exit(EXIT_FAILURE);
        }

        // Clean up and print results
        fclose(pReadFile);
        printf("  Pipeline cache HIT!\n");
        printf("  cacheData loaded from %s\n", readFileName.c_str());

    } else {
        // No cache found on disk
        printf("  Pipeline cache miss!\n");
    }

    if (startCacheData != nullptr) {
        // clang-format off
        //
        // Check for cache validity
        //
        // TODO: Update this as the spec evolves. The fields are not defined by the header.
        //
        // The code below supports SDK 0.10 Vulkan spec, which contains the following table:
        //
        // Offset	 Size            Meaning
        // ------    ------------    ------------------------------------------------------------------
        //      0               4    a device ID equal to VkPhysicalDeviceProperties::DeviceId written
        //                           as a stream of bytes, with the least significant byte first
        //
        //      4    VK_UUID_SIZE    a pipeline cache ID equal to VkPhysicalDeviceProperties::pipelineCacheUUID
        //
        //
        // The code must be updated for latest Vulkan spec, which contains the following table:
        //
        // Offset	 Size            Meaning
        // ------    ------------    ------------------------------------------------------------------
        //      0               4    length in bytes of the entire pipeline cache header written as a
        //                           stream of bytes, with the least significant byte first
        //      4               4    a VkPipelineCacheHeaderVersion value written as a stream of bytes,
        //                           with the least significant byte first
        //      8               4    a vendor ID equal to VkPhysicalDeviceProperties::vendorID written
        //                           as a stream of bytes, with the least significant byte first
        //     12               4    a device ID equal to VkPhysicalDeviceProperties::deviceID written
        //                           as a stream of bytes, with the least significant byte first
        //     16    VK_UUID_SIZE    a pipeline cache ID equal to VkPhysicalDeviceProperties::pipelineCacheUUID
        //
        // clang-format on
        uint32_t headerLength = 0;
        uint32_t cacheHeaderVersion = 0;
        uint32_t vendorID = 0;
        uint32_t deviceID = 0;
        uint8_t pipelineCacheUUID[VK_UUID_SIZE] = {};

        memcpy(&headerLength, (uint8_t *)startCacheData + 0, 4);
        memcpy(&cacheHeaderVersion, (uint8_t *)startCacheData + 4, 4);
        memcpy(&vendorID, (uint8_t *)startCacheData + 8, 4);
        memcpy(&deviceID, (uint8_t *)startCacheData + 12, 4);
        memcpy(pipelineCacheUUID, (uint8_t *)startCacheData + 16, VK_UUID_SIZE);

        // Check each field and report bad values before freeing existing cache
        bool badCache = false;

        if (headerLength <= 0) {
            badCache = true;
            printf("  Bad header length in %s.\n", readFileName.c_str());
            printf("    Cache contains: 0x%.8x\n", headerLength);
        }

        if (cacheHeaderVersion != VK_PIPELINE_CACHE_HEADER_VERSION_ONE) {
            badCache = true;
            printf("  Unsupported cache header version in %s.\n", readFileName.c_str());
            printf("    Cache contains: 0x%.8x\n", cacheHeaderVersion);
        }

        if (vendorID != info.gpu_props.vendorID) {
            badCache = true;
            printf("  Vendor ID mismatch in %s.\n", readFileName.c_str());
            printf("    Cache contains: 0x%.8x\n", vendorID);
            printf("    Driver expects: 0x%.8x\n", info.gpu_props.vendorID);
        }

        if (deviceID != info.gpu_props.deviceID) {
            badCache = true;
            printf("  Device ID mismatch in %s.\n", readFileName.c_str());
            printf("    Cache contains: 0x%.8x\n", deviceID);
            printf("    Driver expects: 0x%.8x\n", info.gpu_props.deviceID);
        }

        if (memcmp(pipelineCacheUUID, info.gpu_props.pipelineCacheUUID,
                   sizeof(pipelineCacheUUID)) != 0) {
            badCache = true;
            printf("  UUID mismatch in %s.\n", readFileName.c_str());
            printf("    Cache contains: ");
            print_UUID(pipelineCacheUUID);
            printf("\n");
            printf("    Driver expects: ");
            print_UUID(info.gpu_props.pipelineCacheUUID);
            printf("\n");
        }

        if (badCache) {
            // Don't submit initial cache data if any version info is incorrect
            free(startCacheData);
            startCacheSize = 0;
            startCacheData = nullptr;

            // And clear out the old cache file for use in next run
            printf("  Deleting cache entry %s to repopulate.\n", readFileName.c_str());
            if (remove(readFileName.c_str()) != 0) {
                fputs("Reading error", stderr);
                exit(EXIT_FAILURE);
            }
        }
    }

    // Feed the initial cache data into pipeline creation
    VkPipelineCacheCreateInfo pipelineCache;
    pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
    pipelineCache.pNext = NULL;
    pipelineCache.initialDataSize = startCacheSize;
    pipelineCache.pInitialData = startCacheData;
    pipelineCache.flags = 0;
    res = vkCreatePipelineCache(info.device, &pipelineCache, nullptr,
                                &info.pipelineCache);
    assert(res == VK_SUCCESS);

    // Free our initialData now that pipeline has been created
    free(startCacheData);

    // Time (roughly) taken to create the graphics pipeline
    timestamp_t start = get_milliseconds();
    init_pipeline(info, depthPresent);
    timestamp_t elapsed = get_milliseconds() - start;
    printf("  vkCreateGraphicsPipeline time: %0.f ms\n", (double)elapsed);

    // Begin standard draw stuff

    init_presentable_image(info);
    VkClearValue clear_values[2];
    init_clear_color_and_depth(info, clear_values);
    VkRenderPassBeginInfo rp_begin;
    init_render_pass_begin_info(info, rp_begin);
    rp_begin.clearValueCount = 2;
    rp_begin.pClearValues = clear_values;
    vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
    vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline);
    vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
                            info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS,
                            info.desc_set.data(), 0, NULL);
    const VkDeviceSize offsets[1] = {0};
    vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets);
    init_viewports(info);
    init_scissors(info);
    vkCmdDraw(info.cmd, 12 * 3, 1, 0, 0);
    vkCmdEndRenderPass(info.cmd);
    execute_pre_present_barrier(info);
    res = vkEndCommandBuffer(info.cmd);
    assert(res == VK_SUCCESS);
    VkFence drawFence = {};
    init_fence(info, drawFence);
    VkPipelineStageFlags pipe_stage_flags =
        VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    VkSubmitInfo submit_info = {};
    init_submit_info(info, submit_info, pipe_stage_flags);
    /* Queue the command buffer for execution */
    res = vkQueueSubmit(info.queue, 1, &submit_info, drawFence);
    assert(res == VK_SUCCESS);
    /* Now present the image in the window */
    VkPresentInfoKHR present = {};
    init_present_info(info, present);
    /* Make sure command buffer is finished before presenting */
    do {
        res =
            vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT);
    } while (res == VK_TIMEOUT);
    assert(res == VK_SUCCESS);
    res = vkQueuePresentKHR(info.queue, &present);
    assert(res == VK_SUCCESS);
    wait_seconds(1);
    if (info.save_images)
        write_ppm(info, "pipeline_cache");

    // End standard draw stuff

    if (startCacheData) {
        // TODO: Create another pipeline, preferably different from the first
        // one and merge it here.  Then store the merged one.
    }

    // Store away the cache that we've populated.  This could conceivably happen
    // earlier, depends on when the pipeline cache stops being populated
    // internally.
    size_t endCacheSize = 0;
    void *endCacheData = nullptr;

    // Call with nullptr to get cache size
    res = vkGetPipelineCacheData(info.device, info.pipelineCache, &endCacheSize,
                           nullptr);
    assert(res == VK_SUCCESS);

    // Allocate memory to hold the populated cache data
    endCacheData = (char *)malloc(sizeof(char) * endCacheSize);
    if (!endCacheData) {
        fputs("Memory error", stderr);
        exit(EXIT_FAILURE);
    }

    // Call again with pointer to buffer
    res = vkGetPipelineCacheData(info.device, info.pipelineCache, &endCacheSize,
                           endCacheData);
    assert(res == VK_SUCCESS);

    // Write the file to disk, overwriting whatever was there
    FILE *pWriteFile;
    std::string writeFileName = directoryName + "pipeline_cache_data.bin";
    pWriteFile = fopen(writeFileName.c_str(), "wb");
    if (pWriteFile) {
        fwrite(endCacheData, sizeof(char), endCacheSize, pWriteFile);
        fclose(pWriteFile);
        printf("  cacheData written to %s\n", writeFileName.c_str());
    } else {
        // Something bad happened
        printf("  Unable to write cache data to disk!\n");
    }

    /* VULKAN_KEY_END */

    vkDestroyFence(info.device, drawFence, NULL);
    vkDestroySemaphore(info.device, info.presentCompleteSemaphore, NULL);
    destroy_pipeline(info);
    destroy_pipeline_cache(info);
    destroy_textures(info);
    destroy_descriptor_pool(info);
    destroy_vertex_buffer(info);
    destroy_framebuffers(info);
    destroy_shaders(info);
    destroy_renderpass(info);
    destroy_descriptor_and_pipeline_layouts(info);
    destroy_uniform_buffer(info);
    destroy_depth_buffer(info);
    destroy_swap_chain(info);
    destroy_command_buffer(info);
    destroy_command_pool(info);
    destroy_device(info);
    destroy_window(info);
    destroy_instance(info);
    return 0;
}
예제 #2
0
/* print the extX file system support block information */
void print_super_block(struct super_block sb)
{
		const char *help[]={
		"文件系统总的i-节点数",
		"文件系统总块数",
		"文件系统预保留的快数",
		"空闲快数",
		"空闲i-节点数",
		"0号快组起始快号",
		"快大小(此值为1024左移动位数)",
		"片段大小(与快大小字段相同)",
		"每个快组所包含快数",
		"每个快组所包含片段数",
		"每个快组i-节点数",
		"最后挂载时间",
		"最后写入时间",
		"当前挂载数",
		"最大挂载数",
		"签名标志53EF",
		"文件系统状态(1-正常,3-有错误)",
		"错误处理方式",
		"辅版本级别",
		"最后进行一致性检查时间",
		"一致性检查间隔时间",
		"创建本文件系统的操作系统(0-linux)",
		"主版本级别(1-动态)",
		"默认UID保留块",
		"默认GID保留块",
		"第一个非保留i-节点",
		"每个i-节点结构大小",
		"本超级块所在的块组号",
		"兼容特征标志(0x10-自调节大小)",
		"非兼容特征标志",
		"只读兼容特征标志(1-稀疏超级快和组描述符表)",
		"文件系统ID",
		"卷名",
		"最后挂载路径",
		"位图使用运算法则",
		"文件再分配块数",
		"目录再分配块数",
		"未使用",
		"日志ID",
		"日志i-节点",
		"日志设备",
		"孤立i-节点表头",
		"未使用",
	};
	char data[50][50];
	memset(data,0,sizeof(data));
	int i=0;
	format_print(data[i++],0x00,0x03,sb.total_Node);
	format_print(data[i++],0x04,0x07,sb.total_Blocks);
	format_print(data[i++],0x08,0x0B,sb.retain_Blcoks);
	format_print(data[i++],0x0C,0x0F,sb.free_Blocks);
	format_print(data[i++],0x10,0x13,sb.free_Node);
	format_print(data[i++],0x14,0x17,sb.No_0_Block);
	format_print_Ex(data[i++],0x18,0x1B,sb.block_Size,1024 << sb.block_Size);
	format_print_Ex(data[i++],0x1C,0x1F,sb.part_Size,1024 << sb.part_Size);
	format_print(data[i++],0x20,0x23,sb.block_Group_Blocks);
	format_print(data[i++],0x24,0x27,sb.block_Group_Parts);
	format_print(data[i++],0x28,0x2B,sb.block_Group_Nodes);
	
	
	format_print_Ex_t(data[i++],0x2C,0x2F,sb.last_Mount_Time);
	format_print_Ex_t(data[i++],0x30,0x33,sb.last_Write_Time);
	
	
	format_print(data[i++],0x34,0x35,sb.current_Mounts);
	format_print(data[i++],0x36,0x37,sb.max_Mounts);
	format_print(data[i++],0x38,0x39,sb.signature_Logo);
	format_print(data[i++],0x3A,0x3B,sb.filesystem_State);
	format_print(data[i++],0x3C,0x3D,sb.err_deal_with);
	format_print(data[i++],0x3E,0X3F,sb.assist_Version);
	
	format_print_Ex_t(data[i++],0x40,0x43,sb.last_Check_Time);
	format_print(data[i++],0x44,0x47,sb.check_Interval_Time);
	
	format_print(data[i++],0x48,0x4B,sb.create_os);
	format_print(data[i++],0x4C,0x4F,sb.main_Version);
	format_print(data[i++],0x50,0x51,sb.UID_Block);
	format_print(data[i++],0x52,0x53,sb.GID_Block);
	format_print(data[i++],0x54,0x57,sb.No_1_Noretain_Node);
	format_print(data[i++],0x58,0x59,sb.node_Size);
	format_print(data[i++],0x5A,0x5B,sb.super_Block_Group);
	format_print(data[i++],0x5C,0x5F,sb.signature_Compatible);
	format_print(data[i++],0x60,0x63,sb.signature_Uncompatible);
	format_print(data[i++],0x64,0x67,sb.signature_Readonly_Compatible);

	//char data 
	format_print_s(data[i++],0x68,0x77,"no print now"/*sb.filesytem_ID*/);
	format_print_s(data[i++],0x78,0x87,sb.volume_Name);
	format_print_s(data[i++],0x88,0xC7,sb.last_Mount_Path);
	format_print(data[i++],0xC8,0xCB,sb.bitmap_rules);
	format_print(data[i++],0xCC,0xCC,sb.file_Redistribution_Blocks);
	format_print(data[i++],0xCD,0xCD,sb.dir_Redistribution_Blocks);
	format_print(data[i++],0xCE,0xCF,sb.no_Used1);
	//char data 
	format_print_s(data[i++],0xD0,0xDF,sb.log_ID);
	format_print(data[i++],0xE0,0xE3,sb.log_Node);
	format_print(data[i++],0xE4,0xE7,sb.log_drive);
	format_print(data[i++],0xE8,0xEB,sb.isolate_Node_Table_Head);
	format_print_s(data[i++],0xEC,0x3FF,"no print now"/*sb.no_Used2*/);
	

	int count=i,max=0,tmp;
	for ( i=0;i<count;i++){ tmp=strlen(data[i]); max=max < tmp? tmp:max;}
	
	printf("文件系统UUID: %s\n",print_UUID(sb.filesytem_ID));
	for ( i=0;i<count;i++)
	{
		printf("%s",data[i]);
		for (tmp=max-strlen(data[i])+3;tmp>0;tmp--) printf(" ");
		printf("%s\n",help[i]);
	}
}