TL; DR :
经过编译的spirv着色器在经过修改的示例进行测试的情况下会在运行时内联编译的spirvs工作的地方崩溃。崩溃发生在vulkan代码的深处。有什么作用?
详细信息:
我在使用编译的spirv着色器时遇到麻烦。我获取了“ draw-textured-cube”样本,将其提取到具有成对的cmake的最小环境中,并且对 util.cpp 进行了最小程度的编辑,以调整数据目录的路径。它编译并按预期工作。
然后我从文件开头的static const
cstring中提取了着色器代码,并将它们移到了自己的文件中。我将对init_shaders
的调用替换为仅读取文件并使用与init_shaders
相同的选项构建着色器模块的调用。我使用从原始示例 CMakeLists.txt 中未使用的功能获取的选项将glsl编译为spirv。
现在,它在创建管道时因访问冲突而崩溃(下面的完整错误文本)。带有或不带有验证层的Debug和Release版本的结果相同。在Visual Studio中逐步执行程序集会发现该错误至少发生在创建管道调用的至少16层(其中call
或非本地jmp
构成了一层,因为这些是最有可能的功能障碍) )。
Unhandled exception at 0x000000006894A525 (nvoglv64.dll) in main.exe: 0xC0000005: Access violation writing location 0x00000080A3CAA530. occurred
(确切的地址与预期的一样。)
SDK随附的任何示例都使用在运行时编译为spirv的内联glsl,但是所有注释都与此注释类似(来自纹理立方体示例):
/* For this sample, we'll start with GLSL so the shader function is plain */
/* and then use the glslang GLSLtoSPV utility to convert it to SPIR-V for */
/* the driver. We do this for clarity rather than using pre-compiled */
/* SPIR-V */
这似乎表明制作着色器的“正确”方法是使用预编译,但是我们没有给出有关如何实现此目的的有效示例/示例。我到过其他地方,但是找不到如何简单地(<10,000行)的示例来编译读取和显示spv着色器。
我对问题的最佳猜测是:1)glslValidator编译错误; 2)我读错了; 3)使用它们需要与运行时编译的着色器不同的选项(例如,着色器模块的创建信息)。无论如何,我已经开始希望vulkan具有更好的错误捕获功能。
很显然,到处都使用内联glsl是一种解决方法,如果那是需要的,我可以制作一堆.cpp
文件,每个着色器只有一个大cstring,这会增加运行时的初始负载,但是确实应该是更好的解决方案。
主机系统是Windows 7(x64),与程序所需的资源相比,它具有过多的资源。我的目标是Windows linux和(如果可能的话)mac,因此排除android,ios,控制台等的任何解决方案都适合我。
Main.cpp:
/*
* Vulkan Samples
*
* Copyright (C) 2015-2016 Valve Corporation
* Copyright (C) 2015-2016 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
VULKAN_SAMPLE_SHORT_DESCRIPTION
Draw Textured Cube
*/
/* This is part of the draw cube progression */
#include <util_init.hpp>
#include <assert.h>
#include <string.h>
#include <cstdlib>
#include "cube_data.h"
FILE* logfile;
#define FAIL {line = __LINE__; goto fail;}
unsigned int * loadSprv(const char* filename, size_t* codelen) {
struct stat fstat;
size_t len, offset = 0, read;
if (stat(filename, &fstat))
return NULL;
*codelen = len = fstat.st_size;
union {
unsigned int * ret;
unsigned char * bytes;
};
bytes = (unsigned char *)malloc((1 + len / 4) * 4 + 1);//padded to 32 bit barrier to accomodate unsigned int type
if (!ret) return NULL;
FILE* src = fopen(filename, "r");
if (!src) {
free(ret);
return NULL;
}
read = fread(bytes, 1, len, src);
while (read > 0 && len >= 0) {
len -= read;
offset += read;
read = fread(bytes + offset, 1, len, src);
}
bytes[offset] = 0;//null term, probably unneeded
fclose(src);
return ret;
}
int sample_main(int argc, char *argv[]) {
VkResult U_ASSERT_ONLY res = VK_SUCCESS;
struct sample_info info = {};
char sample_title[] = "Draw Textured Cube";
const bool depthPresent = true;
logfile = fopen("runtime.log", "w");
uint64_t line = 0;
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);
init_uniform_buffer(info);
init_descriptor_and_pipeline_layouts(info, true);
init_renderpass(info, depthPresent);
//init_shaders(info, vertShaderText, fragShaderText);
{
//|-X init_glslang (empty function on everything that's not android)
info.shaderStages[0] = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0,
VK_SHADER_STAGE_VERTEX_BIT, VK_NULL_HANDLE, "main", NULL};
VkShaderModuleCreateInfo moduleCreateInfo = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0,
0, NULL};
moduleCreateInfo.pCode = loadSprv("shaders\\sample.vert.spv", &moduleCreateInfo.codeSize);
if(!moduleCreateInfo.pCode) FAIL;
res = vkCreateShaderModule(info.device, &moduleCreateInfo, NULL, &info.shaderStages[0].module);
free((void*)moduleCreateInfo.pCode);
if (res) FAIL;
info.shaderStages[1] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0,
VK_SHADER_STAGE_FRAGMENT_BIT, VK_NULL_HANDLE, "main", NULL };
moduleCreateInfo.pCode = loadSprv("shaders\\sample.frag.spv", &moduleCreateInfo.codeSize);
res = vkCreateShaderModule(info.device, &moduleCreateInfo, NULL, &info.shaderStages[1].module);
free((void*)moduleCreateInfo.pCode);
if (res) FAIL;
}
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);
init_pipeline_cache(info);
init_pipeline(info, depthPresent);
/* VULKAN_KEY_START */
VkClearValue clear_values[2];
clear_values[0].color.float32[0] = 0.2f;
clear_values[0].color.float32[1] = 0.2f;
clear_values[0].color.float32[2] = 0.2f;
clear_values[0].color.float32[3] = 0.2f;
clear_values[1].depthStencil.depth = 1.0f;
clear_values[1].depthStencil.stencil = 0;
VkSemaphore imageAcquiredSemaphore;
VkSemaphoreCreateInfo imageAcquiredSemaphoreCreateInfo;
imageAcquiredSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
imageAcquiredSemaphoreCreateInfo.pNext = NULL;
imageAcquiredSemaphoreCreateInfo.flags = 0;
res = vkCreateSemaphore(info.device, &imageAcquiredSemaphoreCreateInfo, NULL, &imageAcquiredSemaphore);
assert(res == VK_SUCCESS);
// Get the index of the next available swapchain image:
res = vkAcquireNextImageKHR(info.device, info.swap_chain, UINT64_MAX, imageAcquiredSemaphore, VK_NULL_HANDLE,
&info.current_buffer);
// TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
// return codes
assert(res == VK_SUCCESS);
VkRenderPassBeginInfo rp_begin;
rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rp_begin.pNext = NULL;
rp_begin.renderPass = info.render_pass;
rp_begin.framebuffer = info.framebuffers[info.current_buffer];
rp_begin.renderArea.offset.x = 0;
rp_begin.renderArea.offset.y = 0;
rp_begin.renderArea.extent.width = info.width;
rp_begin.renderArea.extent.height = info.height;
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);
res = vkEndCommandBuffer(info.cmd);
assert(res == VK_SUCCESS);
const VkCommandBuffer cmd_bufs[] = { info.cmd };
VkFenceCreateInfo fenceInfo;
VkFence drawFence;
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.pNext = NULL;
fenceInfo.flags = 0;
vkCreateFence(info.device, &fenceInfo, NULL, &drawFence);
VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submit_info[1] = {};
submit_info[0].pNext = NULL;
submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info[0].waitSemaphoreCount = 1;
submit_info[0].pWaitSemaphores = &imageAcquiredSemaphore;
submit_info[0].pWaitDstStageMask = &pipe_stage_flags;
submit_info[0].commandBufferCount = 1;
submit_info[0].pCommandBuffers = cmd_bufs;
submit_info[0].signalSemaphoreCount = 0;
submit_info[0].pSignalSemaphores = NULL;
/* Queue the command buffer for execution */
res = vkQueueSubmit(info.graphics_queue, 1, submit_info, drawFence);
assert(res == VK_SUCCESS);
/* Now present the image in the window */
VkPresentInfoKHR present;
present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present.pNext = NULL;
present.swapchainCount = 1;
present.pSwapchains = &info.swap_chain;
present.pImageIndices = &info.current_buffer;
present.pWaitSemaphores = NULL;
present.waitSemaphoreCount = 0;
present.pResults = NULL;
/* 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.present_queue, &present);
assert(res == VK_SUCCESS);
wait_seconds(1);
/* VULKAN_KEY_END */
if (info.save_images) write_ppm(info, "draw_textured_cube");
vkDestroyFence(info.device, drawFence, NULL);
vkDestroySemaphore(info.device, imageAcquiredSemaphore, 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;
fail:
fprintf(logfile, "Fail. Res: %d. Line: %u\n", res, line);
return 1;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.11)
project (STUPID_CUBE)
# set (CMAKE_VERBOSE_MAKEFILE 1)
set(API_NAME "Vulkan" CACHE STRING "API name to use when building")
string(TOLOWER ${API_NAME} API_LOWERCASE)
include(GNUInstallDirs)
file(TO_CMAKE_PATH $ENV{VULKAN_SDK} VULKAN)
add_definitions("-DVULKAN_SAMPLES_BASE_DIR=\"${CMAKE_SOURCE_DIR}\"")
# The MAJOR number of the version we're building, used in naming
# vulkan-<major>.dll (and other files).
set(MAJOR "1")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set (CMAKE_INSTALL_PREFIX "")
set (UTILS_NAME vsamputils)
if(NOT WIN32)
include(FindPkgConfig)
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" OFF)
set(DEMOS_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for demos (XCB, XLIB, WAYLAND, DISPLAY)")
set(SAMPLES_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for api-samples (XCB, WAYLAND, DISPLAY)")
if (BUILD_WSI_XCB_SUPPORT)
find_package(XCB REQUIRED)
endif()
if (BUILD_WSI_WAYLAND_SUPPORT)
find_package(Wayland REQUIRED)
endif()
set (BUILDTGT_DIR build)
set (BINDATA_DIR x86_64/bin)
set (LIBSOURCE_DIR Lib)
else()
# For Windows, since 32-bit and 64-bit items can co-exist, we build each in its own build directory.
# 32-bit target data goes in build32, and 64-bit target data goes into build. So, include/link the
# appropriate data at build time.
if (CMAKE_CL_64)
set (BUILDTGT_DIR build)
set (BINDATA_DIR Bin)
set (LIBSOURCE_DIR Lib)
else()
set (BUILDTGT_DIR build32)
set (BINDATA_DIR Bin32)
set (LIBSOURCE_DIR Lib32)
endif()
endif()
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(COMMON_COMPILE_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
set(COMMON_COMPILE_FLAGS "${COMMON_COMPILE_FLAGS} -fno-strict-aliasing -fno-builtin-memcmp")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 ${COMMON_COMPILE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_COMPILE_FLAGS} -std=c++11")
if (UNIX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
endif()
endif()
find_program(GLSLANG_VALIDATOR NAMES glslangValidator
HINTS "${VULKAN}/glslang/${BUILDTGT_DIR}/install/bin"
"${VULKAN}/${BINDATA_DIR}" )
find_path(GLSLANG_SPIRV_INCLUDE_DIR SPIRV/spirv.hpp HINTS "${VULKAN}/source/glslang/"
"${VULKAN}/glslang"
DOC "Path to SPIRV/spirv.hpp")
find_path(SPIRV_TOOLS_INCLUDE_DIR spirv-tools/libspirv.h HINTS "${VULKAN}/spirv-tools/include"
"${VULKAN}/source/spirv-tools/include"
"${VULKAN}/spirv-tools/external/include"
"${VULKAN}/source/spirv-tools/external/include"
DOC "Path to spirv-tools/libspirv.h")
find_path(Vulkan_INCLUDE_DIR vulkan/vulkan.h HINTS "${VULKAN}"
"${VULKAN}/Include" )
if (WIN32)
set (GLSLANG_SEARCH_PATH "${VULKAN}/glslang/${BUILDTGT_DIR}/glslang/Release"
"${VULKAN}/glslang/${BUILDTGT_DIR}/glslang/OSDependent/Windows/Release"
"${VULKAN}/glslang/${BUILDTGT_DIR}/hlsl/Release"
"${VULKAN}/glslang/${BUILDTGT_DIR}/OGLCompilersDLL/Release"
"${VULKAN}/glslang/${BUILDTGT_DIR}/SPIRV/Release" )
set (SPIRV_TOOLS_SEARCH_PATH "${VULKAN}/spirv-tools/${BUILDTGT_DIR}/source/Release")
set (SPIRV_TOOLS_OPT_SEARCH_PATH "${VULKAN}/spirv-tools/${BUILDTGT_DIR}/source/opt/Release")
else()
set (GLSLANG_SEARCH_PATH "${VULKAN}/glslang/build/install/lib" "${VULKAN}/x86_64/lib/glslang" )
set (SPIRV_TOOLS_SEARCH_PATH "${VULKAN}/spirv-tools/build" "${VULKAN}/x86_64/lib/spirv-tools" )
set (SPIRV_TOOLS_OPT_SEARCH_PATH "${SPIRV_TOOLS_SEARCH_PATH}")
endif()
find_library(GLSLANG_LIB NAMES glslang
HINTS ${GLSLANG_SEARCH_PATH} )
find_library(OGLCompiler_LIB NAMES OGLCompiler
HINTS ${GLSLANG_SEARCH_PATH} )
find_library(OSDependent_LIB NAMES OSDependent
HINTS ${GLSLANG_SEARCH_PATH} )
find_library(HLSL_LIB NAMES HLSL
HINTS ${GLSLANG_SEARCH_PATH} )
find_library(SPIRV_LIB NAMES SPIRV
HINTS ${GLSLANG_SEARCH_PATH} )
find_library(SPIRV_TOOLS_LIB NAMES SPIRV-Tools
HINTS ${SPIRV_TOOLS_SEARCH_PATH} )
find_library(SPIRV_TOOLS_OPT_LIB NAMES SPIRV-Tools-opt
HINTS ${SPIRV_TOOLS_OPT_SEARCH_PATH} )
find_library(SPIRV_REMAPPER_LIB NAMES SPVRemapper
HINTS ${GLSLANG_SEARCH_PATH} )
# On Windows, we must pair Debug and Release appropriately
if (WIN32)
set (GLSLANG_DEBUG_SEARCH_PATH "${VULKAN}/glslang/${BUILDTGT_DIR}/glslang/Debug"
"${VULKAN}/glslang/${BUILDTGT_DIR}/glslang/OSDependent/Windows/Debug"
"${VULKAN}/glslang/${BUILDTGT_DIR}/hlsl/Debug"
"${VULKAN}/glslang/${BUILDTGT_DIR}/OGLCompilersDLL/Debug"
"${VULKAN}/glslang/${BUILDTGT_DIR}/SPIRV/Debug")
set (SPIRV_TOOLS_DEBUG_SEARCH_PATH "${VULKAN}/spirv-tools/${BUILDTGT_DIR}/source/Debug")
set (SPIRV_TOOLS_OPT_DEBUG_SEARCH_PATH "${VULKAN}/spirv-tools/${BUILDTGT_DIR}/source/opt/Debug")
add_library(glslang STATIC IMPORTED)
add_library(OGLCompiler STATIC IMPORTED)
add_library(OSDependent STATIC IMPORTED)
add_library(HLSL STATIC IMPORTED)
add_library(SPIRV STATIC IMPORTED)
add_library(Loader STATIC IMPORTED)
add_library(SPIRV-Tools STATIC IMPORTED)
add_library(SPIRV-Tools-opt STATIC IMPORTED)
add_library(SPVRemapper STATIC IMPORTED)
find_library(GLSLANG_DLIB NAMES glslangd
HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
find_library(OGLCompiler_DLIB NAMES OGLCompilerd
HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
find_library(OSDependent_DLIB NAMES OSDependentd
HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
find_library(HLSL_DLIB NAMES HLSLd
HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
find_library(SPIRV_DLIB NAMES SPIRVd
HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
find_library(SPIRV_TOOLS_DLIB NAMES SPIRV-Tools
HINTS ${SPIRV_TOOLS_DEBUG_SEARCH_PATH} )
find_library(SPIRV_TOOLS_OPT_DLIB NAMES SPIRV-Tools-opt
HINTS ${SPIRV_TOOLS_OPT_DEBUG_SEARCH_PATH} )
find_library(SPIRV_REMAPPER_DLIB NAMES SPVRemapperd
HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
set_target_properties(glslang PROPERTIES
IMPORTED_LOCATION "${GLSLANG_LIB}"
IMPORTED_LOCATION_DEBUG "${GLSLANG_DLIB}")
set_target_properties(OGLCompiler PROPERTIES
IMPORTED_LOCATION "${OGLCompiler_LIB}"
IMPORTED_LOCATION_DEBUG "${OGLCompiler_DLIB}")
set_target_properties(OSDependent PROPERTIES
IMPORTED_LOCATION "${OSDependent_LIB}"
IMPORTED_LOCATION_DEBUG "${OSDependent_DLIB}")
set_target_properties(HLSL PROPERTIES
IMPORTED_LOCATION "${HLSL_LIB}"
IMPORTED_LOCATION_DEBUG "${HLSL_DLIB}")
set_target_properties(SPIRV PROPERTIES
IMPORTED_LOCATION "${SPIRV_LIB}"
IMPORTED_LOCATION_DEBUG "${SPIRV_DLIB}")
set_target_properties(SPIRV-Tools PROPERTIES
IMPORTED_LOCATION "${SPIRV_TOOLS_LIB}"
IMPORTED_LOCATION_DEBUG "${SPIRV_TOOLS_DLIB}")
set_target_properties(SPIRV-Tools-opt PROPERTIES
IMPORTED_LOCATION "${SPIRV_TOOLS_OPT_LIB}"
IMPORTED_LOCATION_DEBUG "${SPIRV_TOOLS_OPT_DLIB}")
set_target_properties(SPVRemapper PROPERTIES
IMPORTED_LOCATION "${SPIRV_REMAPPER_LIB}"
IMPORTED_LOCATION_DEBUG "${SPIRV_REMAPPER_DLIB}")
set (SPIRV_TOOLS_LIBRARIES SPIRV-Tools-opt SPIRV-Tools)
set (GLSLANG_LIBRARIES glslang OGLCompiler OSDependent HLSL SPIRV SPVRemapper ${SPIRV_TOOLS_LIBRARIES})
else ()
set (SPIRV_TOOLS_LIBRARIES ${SPIRV_TOOLS_OPT_LIB} ${SPIRV_TOOLS_LIB})
set (GLSLANG_LIBRARIES ${GLSLANG_LIB} ${OGLCompiler_LIB} ${OSDependent_LIB} ${HLSL_LIB} ${SPIRV_LIB} ${SPIRV_REMAPPER_LIB} ${SPIRV_TOOLS_LIBRARIES})
endif()
set (GLMINCLUDES "${CMAKE_SOURCE_DIR}/utils")
# to run with source glslang libs/headers
if(UNIX)
add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
if (EXISTS "${VULKAN}/glslang")
set (GLSLANGDIR "${VULKAN}/glslang")
else()
set (GLSLANGDIR "${VULKAN}/source/glslang")
endif()
else()
set (GLSLANGDIR "${VULKAN}/glslang")
endif()
get_filename_component(GLMINC_PREFIX "${GLMINCLUDES}" ABSOLUTE)
if(NOT EXISTS ${GLMINC_PREFIX})
message(FATAL_ERROR "Necessary glm headers do not exist: " ${GLMINC_PREFIX})
endif()
get_filename_component(GLSLANG_PREFIX "${GLSLANGDIR}" ABSOLUTE)
if(NOT EXISTS ${GLSLANG_PREFIX})
message(FATAL_ERROR "Necessary glslang components do not exist: " ${GLSLANG_PREFIX})
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/utils)
if(WIN32)
set (MOVE_CMD "move")
set (VULKAN_LOADER_NAME "${API_LOWERCASE}-${MAJOR}")
else()
set (MOVE_CMD "mv")
set (PTHREAD "pthread")
set (VULKAN_LOADER_NAME "${API_LOWERCASE}")
endif()
if(EXISTS "${CMAKE_SOURCE_DIR}/layers")
set (VULKAN_LOADER ${VULKAN_LOADER_NAME})
else()
find_library(VULKAN_LOADER NAMES ${VULKAN_LOADER_NAME}
HINTS "${VULKAN}/${LIBSOURCE_DIR}" "${VULKAN}/x86_64/lib" )
endif()
add_definitions(-DAPI_NAME="${API_NAME}")
# If ANDROID is ON, turn on cross-compiling for it
if(ANDROID)
set(CMAKE_SYSTEM_NAME "Android")
set(CMAKE_SYSTEM_VERSION "7")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DWIN32_LEAN_AND_MEAN)
set(DisplayServer Win32)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
if (SAMPLES_WSI_SELECTION STREQUAL "XCB")
if (NOT BUILD_WSI_XCB_SUPPORT)
message( FATAL_ERROR "Selected XCB for samples build but not building Xcb support" )
endif()
add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
elseif (SAMPLES_WSI_SELECTION STREQUAL "XLIB")
if (NOT BUILD_WSI_XLIB_SUPPORT)
message( FATAL_ERROR "Selected XLIB for samples build but not building Xlib support" )
endif()
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR)
elseif (SAMPLES_WSI_SELECTION STREQUAL "WAYLAND")
if (NOT BUILD_WSI_WAYLAND_SUPPORT)
message( FATAL_ERROR "Selected Wayland for samples build but not building Wayland support" )
endif()
add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
endif()
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()
set(SAMPLES_DATA_DIR ${SAMPLES_DATA_DIR} "${CMAKE_SOURCE_DIR}/data")
set(SHADER_FILES ${SHADER_FILES} "")
include_directories( ${SAMPLES_DATA_DIR} ${GLSLANG_SPIRV_INCLUDE_DIR} ${GLMINC_PREFIX} ${Vulkan_INCLUDE_DIR})
# Additional includes for spirv-tools
include_directories(${SPIRV_TOOLS_INCLUDE_DIR})
if(WIN32)
set (MOVE_CMD "move")
set (VULKAN_LOADER_NAME "${API_LOWERCASE}-${MAJOR}")
else()
set (MOVE_CMD "mv")
set (PTHREAD "pthread")
set (VULKAN_LOADER_NAME "${API_LOWERCASE}")
endif()
if(EXISTS "${PROJECT_SOURCE_DIR}/${V_LVL_RELATIVE_LOCATION}/loader")
set (VULKAN_LOADER ${VULKAN_LOADER_NAME})
else()
find_library(VULKAN_LOADER NAMES ${VULKAN_LOADER_NAME}
HINTS "${V_LVL_RELATIVE_LOCATION}/${LIBSOURCE_DIR}" "${V_LVL_RELATIVE_LOCATION}/x86_64/lib" )
endif()
set (LIBGLM_INCLUDE_DIR ${V_LVL_RELATIVE_LOCATION}/libs)
if(NOT WIN32 AND NOT ANDROID)
if(SDK_INCLUDE_PATH)
include_directories(${SDK_INCLUDE_PATH})
endif()
if (BUILD_WSI_XCB_SUPPORT)
include_directories(${XCB_INCLUDE_DIRS})
link_libraries(${XCB_LIBRARIES} m )
endif()
if (BUILD_WSI_WAYLAND_SUPPORT)
include_directories(${WAYLAND_CLIENT_INCLUDE_DIR})
link_libraries(${WAYLAND_CLIENT_LIBRARIES})
endif()
link_libraries(${VULKAN_LOADER} m )
endif()
if(WIN32)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_USE_MATH_DEFINES")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_USE_MATH_DEFINES")
# If MSVC, disable some signed/unsigned mismatch warnings.
if (MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4267")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267")
endif()
else()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare")
endif()
if (NOT WIN32)
# extra setup for out-of-tree builds
if (NOT (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR))
add_custom_target(samples-binary-dir-symlinks ALL
COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/get-short-descripts.sh
VERBATIM
)
endif()
else()
if (NOT (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR))
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lunarg.ppm LUNARG)
endif()
endif()
#
# START BUILDING SAMPLES HERE
#
# Generate Android project.
option(ANDROID OFF)
# simple one file sample targets, no additional files
file(GLOB SHADERS RELATIVE "${CMAKE_SOURCE_DIR}" CONFIGURE_DEPENDS shaders/*.frag shaders/*.vert)
foreach(SFILE ${SHADERS})
add_custom_command (OUTPUT ${SFILE}.spv COMMAND ${GLSLANG_VALIDATOR} -s -V "${CMAKE_SOURCE_DIR}/${SFILE}" -o ${SFILE}.spv DEPENDS ${SFILE} )
endforeach(SFILE)
add_executable( main WIN32 main.cpp shaders/sample.frag.spv shaders/sample.vert.spv )
target_link_libraries(main ${UTILS_NAME} ${GLSLANG_LIBRARIES} ${VULKAN_LOADER} ${WINLIBS} ${SPIRV_TOOLS_LIBRARIES})
if (NOT ANDROID)
foreach (sample ${S_TARGETS})
install(TARGETS ${sample} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endforeach(sample)
add_subdirectory(utils)
endif()
与原始diff.util相比,我的:
< return std::string(VULKAN_SAMPLES_BASE_DIR) + "/API-Samples/data/";
---
> return std::string(VULKAN_SAMPLES_BASE_DIR) + "/data/";
sample.vert:
#version 400
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (std140, binding = 0) uniform buf {
mat4 mvp;
} ubuf;
layout (location = 0) in vec4 pos;
layout (location = 1) in vec2 inTexCoords;
layout (location = 0) out vec2 texcoord;
void main() {
texcoord = inTexCoords;
gl_Position = ubuf.mvp * pos;
}
sample.frag:
#version 400
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (binding = 1) uniform sampler2D tex;
layout (location = 0) in vec2 texcoord;
layout (location = 0) out vec4 outColor;
void main() {
outColor = textureLod(tex, texcoord, 0.0);
}
答案 0 :(得分:3)
在Windows上,您需要通过将fopen
模式标志指定为“ rb”以二进制模式打开二进制SPIR-V文件。 SPIR-V代码是32位无符号整数的序列,在Windows上,您需要使用“二进制”模式标志禁止任何行尾转换。在像Linux之类的POSIX兼容系统上,“ b”标志将被忽略,因此,如果要在多个平台上进行编译,则可以将其保留在代码中。