mirror of https://github.com/bkaradzic/bgfx
Updated spirv-cross.
This commit is contained in:
parent
2044efc6ca
commit
1f69e5e5d9
|
@ -13,168 +13,341 @@
|
|||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(SPIRV-Cross)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
project(SPIRV-Cross LANGUAGES CXX C)
|
||||
enable_testing()
|
||||
|
||||
option(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS "Instead of throwing exceptions assert" OFF)
|
||||
option(SPIRV_CROSS_SHARED "Build the C API as a single shared library." OFF)
|
||||
option(SPIRV_CROSS_STATIC "Build the C and C++ API as static libraries." ON)
|
||||
option(SPIRV_CROSS_CLI "Build the CLI binary. Requires SPIRV_CROSS_STATIC." ON)
|
||||
option(SPIRV_CROSS_ENABLE_TESTS "Enable SPIRV-Cross tests." ON)
|
||||
|
||||
option(SPIRV_CROSS_SANITIZE_ADDRESS "Sanitize address" OFF)
|
||||
option(SPIRV_CROSS_SANITIZE_MEMORY "Sanitize memory" OFF)
|
||||
option(SPIRV_CROSS_SANITIZE_THREADS "Sanitize threads" OFF)
|
||||
option(SPIRV_CROSS_SANITIZE_UNDEFINED "Sanitize undefined" OFF)
|
||||
|
||||
if(${CMAKE_GENERATOR} MATCHES "Makefile")
|
||||
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
|
||||
message(FATAL_ERROR "Build out of tree to avoid overwriting Makefile")
|
||||
endif()
|
||||
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
|
||||
message(FATAL_ERROR "Build out of tree to avoid overwriting Makefile")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(spirv-compiler-options "")
|
||||
set(spirv-compiler-defines "")
|
||||
set(spirv-cross-link-flags "")
|
||||
|
||||
if(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
|
||||
set(spirv-compiler-defines ${spirv-compiler-defines} SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
|
||||
set(spirv-compiler-defines ${spirv-compiler-defines} SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
|
||||
endif()
|
||||
|
||||
# To specify special debug or optimization options, use
|
||||
# -DCMAKE_CXX_COMPILE_FLAGS
|
||||
# However, we require the C++11 dialect.
|
||||
if (NOT "${MSVC}")
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -std=c++11 -Wall -Wextra -Werror -Wshadow)
|
||||
set(spirv-compiler-defines ${spirv-compiler-defines} __STDC_LIMIT_MACROS)
|
||||
if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -Wall -Wextra -Werror -Wshadow)
|
||||
|
||||
if(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -fno-exceptions)
|
||||
endif()
|
||||
if (SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -fno-exceptions)
|
||||
endif()
|
||||
|
||||
if (SPIRV_CROSS_SANITIZE_ADDRESS)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -fsanitize=address)
|
||||
set(spirv-cross-link-flags "${spirv-cross-link-flags} -fsanitize=address")
|
||||
endif()
|
||||
|
||||
if (SPIRV_CROSS_SANITIZE_UNDEFINED)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -fsanitize=undefined)
|
||||
set(spirv-cross-link-flags "${spirv-cross-link-flags} -fsanitize=undefined")
|
||||
endif()
|
||||
|
||||
if (SPIRV_CROSS_SANITIZE_MEMORY)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -fsanitize=memory)
|
||||
set(spirv-cross-link-flags "${spirv-cross-link-flags} -fsanitize=memory")
|
||||
endif()
|
||||
|
||||
if (SPIRV_CROSS_SANITIZE_THREADS)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} -fsanitize=thread)
|
||||
set(spirv-cross-link-flags "${spirv-cross-link-flags} -fsanitize=thread")
|
||||
endif()
|
||||
elseif (MSVC)
|
||||
set(spirv-compiler-options ${spirv-compiler-options} /wd4267)
|
||||
endif()
|
||||
|
||||
macro(extract_headers out_abs file_list)
|
||||
set(${out_abs}) # absolute paths
|
||||
foreach(_a ${file_list})
|
||||
# get_filename_component only returns the longest extension, so use a regex
|
||||
string(REGEX REPLACE ".*\\.(h|hpp)" "\\1" ext ${_a})
|
||||
if(("${ext}" STREQUAL "h") OR ("${ext}" STREQUAL "hpp"))
|
||||
list(APPEND ${out_abs} "${_a}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${out_abs}) # absolute paths
|
||||
foreach(_a ${file_list})
|
||||
# get_filename_component only returns the longest extension, so use a regex
|
||||
string(REGEX REPLACE ".*\\.(h|hpp)" "\\1" ext ${_a})
|
||||
|
||||
# For shared library, we are only interested in the C header.
|
||||
if (SPIRV_CROSS_STATIC)
|
||||
if(("${ext}" STREQUAL "h") OR ("${ext}" STREQUAL "hpp"))
|
||||
list(APPEND ${out_abs} "${_a}")
|
||||
endif()
|
||||
else()
|
||||
if("${ext}" STREQUAL "h")
|
||||
list(APPEND ${out_abs} "${_a}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(spirv_cross_add_library name config_name)
|
||||
add_library(${name} ${ARGN})
|
||||
extract_headers(hdrs "${ARGN}")
|
||||
target_include_directories(${name} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:include/spirv_cross>)
|
||||
set_target_properties(${name} PROPERTIES
|
||||
PUBLIC_HEADERS "${hdrs}")
|
||||
target_compile_options(${name} PRIVATE ${spirv-compiler-options})
|
||||
target_compile_definitions(${name} PRIVATE ${spirv-compiler-defines})
|
||||
install(TARGETS ${name}
|
||||
EXPORT ${config_name}Config
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
PUBLIC_HEADER DESTINATION include/spirv_cross)
|
||||
install(FILES ${hdrs} DESTINATION include/spirv_cross)
|
||||
install(EXPORT ${config_name}Config DESTINATION share/${config_name}/cmake)
|
||||
export(TARGETS ${name} FILE ${config_name}Config.cmake)
|
||||
add_library(${name} ${ARGN})
|
||||
extract_headers(hdrs "${ARGN}")
|
||||
target_include_directories(${name} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:include/spirv_cross>)
|
||||
set_target_properties(${name} PROPERTIES
|
||||
PUBLIC_HEADERS "${hdrs}")
|
||||
target_compile_options(${name} PRIVATE ${spirv-compiler-options})
|
||||
target_compile_definitions(${name} PRIVATE ${spirv-compiler-defines})
|
||||
install(TARGETS ${name}
|
||||
EXPORT ${config_name}Config
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
PUBLIC_HEADER DESTINATION include/spirv_cross)
|
||||
install(FILES ${hdrs} DESTINATION include/spirv_cross)
|
||||
install(EXPORT ${config_name}Config DESTINATION share/${config_name}/cmake)
|
||||
export(TARGETS ${name} FILE ${config_name}Config.cmake)
|
||||
endmacro()
|
||||
|
||||
set(spirv-cross-core-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.std.450.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_common.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_parser.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_parser.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_parsed_ir.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_parsed_ir.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cfg.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cfg.cpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-core spirv_cross_core STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.std.450.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_common.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_parser.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_parser.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_parsed_ir.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_parsed_ir.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cfg.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cfg.cpp)
|
||||
set(spirv-cross-c-sources
|
||||
spirv.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_c.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_c.h)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-glsl spirv_cross_glsl STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_glsl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_glsl.hpp)
|
||||
set(spirv-cross-glsl-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_glsl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_glsl.hpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-cpp spirv_cross_cpp STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cpp.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cpp.cpp)
|
||||
set(spirv-cross-cpp-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cpp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cpp.hpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-reflect spirv_cross_reflect STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.cpp)
|
||||
set(spirv-cross-msl-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_msl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_msl.hpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-msl spirv_cross_msl STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_msl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_msl.cpp)
|
||||
set(spirv-cross-hlsl-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_hlsl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_hlsl.hpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-hlsl spirv_cross_hlsl STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_hlsl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_hlsl.cpp)
|
||||
set(spirv-cross-reflect-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.hpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-util spirv_cross_util STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_util.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_util.cpp)
|
||||
set(spirv-cross-util-sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_util.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cross_util.hpp)
|
||||
|
||||
add_executable(spirv-cross main.cpp)
|
||||
target_compile_options(spirv-cross PRIVATE ${spirv-compiler-options})
|
||||
target_compile_definitions(spirv-cross PRIVATE ${spirv-compiler-defines})
|
||||
if (SPIRV_CROSS_STATIC)
|
||||
spirv_cross_add_library(spirv-cross-core spirv_cross_core STATIC
|
||||
${spirv-cross-core-sources})
|
||||
|
||||
install(TARGETS spirv-cross RUNTIME DESTINATION bin)
|
||||
target_link_libraries(spirv-cross spirv-cross-glsl spirv-cross-hlsl spirv-cross-cpp spirv-cross-reflect spirv-cross-msl spirv-cross-util spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-util spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-glsl spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-msl spirv-cross-glsl)
|
||||
target_link_libraries(spirv-cross-hlsl spirv-cross-glsl)
|
||||
target_link_libraries(spirv-cross-cpp spirv-cross-glsl)
|
||||
spirv_cross_add_library(spirv-cross-c spirv_cross_c STATIC
|
||||
${spirv-cross-c-sources})
|
||||
|
||||
# Set up tests, using only the simplest modes of the test_shaders
|
||||
# script. You have to invoke the script manually to:
|
||||
# - Update the reference files
|
||||
# - Get cycle counts from malisc
|
||||
# - Keep failing outputs
|
||||
find_package(PythonInterp)
|
||||
if (${PYTHONINTERP_FOUND})
|
||||
if (${PYTHON_VERSION_MAJOR} GREATER 2)
|
||||
add_test(NAME spirv-cross-test
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-no-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-no-opt
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-metal
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-metal-no-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl-no-opt
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-hlsl
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-hlsl-no-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl-no-opt
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --opt --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-metal-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --opt --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-hlsl-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --opt --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-reflection
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --reflect --parallel
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-reflection
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Testing disabled. Could not find python3. If you have python3 installed try running "
|
||||
"cmake with -DPYTHON_EXECUTABLE:FILEPATH=/path/to/python3 to help it find the executable")
|
||||
spirv_cross_add_library(spirv-cross-glsl spirv_cross_glsl STATIC
|
||||
${spirv-cross-glsl-sources})
|
||||
|
||||
spirv_cross_add_library(spirv-cross-cpp spirv_cross_cpp STATIC
|
||||
${spirv-cross-cpp-sources})
|
||||
|
||||
spirv_cross_add_library(spirv-cross-reflect spirv_cross_reflect STATIC
|
||||
${spirv-cross-reflect-sources})
|
||||
|
||||
spirv_cross_add_library(spirv-cross-msl spirv_cross_msl STATIC
|
||||
${spirv-cross-msl-sources})
|
||||
|
||||
spirv_cross_add_library(spirv-cross-hlsl spirv_cross_hlsl STATIC
|
||||
${spirv-cross-hlsl-sources})
|
||||
|
||||
spirv_cross_add_library(spirv-cross-util spirv_cross_util STATIC
|
||||
${spirv-cross-util-sources})
|
||||
|
||||
target_link_libraries(spirv-cross-util PRIVATE spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-glsl PRIVATE spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-msl PRIVATE spirv-cross-glsl)
|
||||
target_link_libraries(spirv-cross-hlsl PRIVATE spirv-cross-glsl)
|
||||
target_link_libraries(spirv-cross-cpp PRIVATE spirv-cross-glsl)
|
||||
target_link_libraries(spirv-cross-c PRIVATE
|
||||
spirv-cross-core
|
||||
spirv-cross-glsl
|
||||
spirv-cross-hlsl
|
||||
spirv-cross-msl
|
||||
spirv-cross-cpp
|
||||
spirv-cross-reflect)
|
||||
endif()
|
||||
|
||||
if (SPIRV_CROSS_SHARED)
|
||||
set(spirv-cross-abi-major 0)
|
||||
set(spirv-cross-abi-minor 1)
|
||||
set(spirv-cross-abi-patch 0)
|
||||
set(SPIRV_CROSS_VERSION ${spirv-cross-abi-major}.${spirv-cross-abi-minor}.${spirv-cross-abi-patch})
|
||||
set(SPIRV_CROSS_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
set(SPIRV_CROSS_INSTALL_INC_DIR ${CMAKE_INSTALL_PREFIX}/include/spirv_cross)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pkg-config/spirv-cross-c-shared.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/spirv-cross-c-shared.pc @ONLY)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/spirv-cross-c-shared.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pkgconfig)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-c-shared spirv_cross_c_shared SHARED
|
||||
${spirv-cross-core-sources}
|
||||
${spirv-cross-glsl-sources}
|
||||
${spirv-cross-cpp-sources}
|
||||
${spirv-cross-reflect-sources}
|
||||
${spirv-cross-msl-sources}
|
||||
${spirv-cross-hlsl-sources}
|
||||
${spirv-cross-c-sources})
|
||||
if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))
|
||||
# Only export the C API.
|
||||
target_compile_options(spirv-cross-c-shared PRIVATE -fvisibility=hidden)
|
||||
if (NOT APPLE)
|
||||
set_target_properties(spirv-cross-c-shared PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(spirv-cross-c-shared PRIVATE SPVC_EXPORT_SYMBOLS)
|
||||
|
||||
set_target_properties(spirv-cross-c-shared PROPERTIES
|
||||
VERSION ${SPIRV_CROSS_VERSION}
|
||||
SOVERSION ${spirv-cross-abi-major})
|
||||
endif()
|
||||
|
||||
if (SPIRV_CROSS_CLI)
|
||||
if (NOT SPIRV_CROSS_STATIC)
|
||||
message(FATAL_ERROR "Must build static libraries if building CLI.")
|
||||
endif()
|
||||
add_executable(spirv-cross main.cpp)
|
||||
target_compile_options(spirv-cross PRIVATE ${spirv-compiler-options})
|
||||
target_compile_definitions(spirv-cross PRIVATE ${spirv-compiler-defines})
|
||||
set_target_properties(spirv-cross PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
|
||||
install(TARGETS spirv-cross RUNTIME DESTINATION bin)
|
||||
target_link_libraries(spirv-cross PRIVATE
|
||||
spirv-cross-glsl
|
||||
spirv-cross-hlsl
|
||||
spirv-cross-cpp
|
||||
spirv-cross-reflect
|
||||
spirv-cross-msl
|
||||
spirv-cross-util
|
||||
spirv-cross-core)
|
||||
|
||||
if (SPIRV_CROSS_ENABLE_TESTS)
|
||||
# Set up tests, using only the simplest modes of the test_shaders
|
||||
# script. You have to invoke the script manually to:
|
||||
# - Update the reference files
|
||||
# - Get cycle counts from malisc
|
||||
# - Keep failing outputs
|
||||
find_package(PythonInterp)
|
||||
find_program(spirv-cross-glslang NAMES glslangValidator
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/glslang-build/output/bin
|
||||
NO_DEFAULT_PATH)
|
||||
find_program(spirv-cross-spirv-as NAMES spirv-as
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/spirv-tools-build/output/bin
|
||||
NO_DEFAULT_PATH)
|
||||
find_program(spirv-cross-spirv-val NAMES spirv-val
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/spirv-tools-build/output/bin
|
||||
NO_DEFAULT_PATH)
|
||||
find_program(spirv-cross-spirv-opt NAMES spirv-opt
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/external/spirv-tools-build/output/bin
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
if ((${spirv-cross-glslang} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-as} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-val} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-opt} MATCHES "NOTFOUND"))
|
||||
set(SPIRV_CROSS_ENABLE_TESTS OFF)
|
||||
message("Could not find glslang or SPIRV-Tools build under external/. Run ./checkout_glslang_spirv_tools.sh and ./build_glslang_spirv_tools.sh. Testing will be disabled.")
|
||||
else()
|
||||
set(SPIRV_CROSS_ENABLE_TESTS ON)
|
||||
message("Found glslang and SPIRV-Tools. Enabling test suite.")
|
||||
message("Found glslangValidator in: ${spirv-cross-glslang}.")
|
||||
message("Found spirv-as in: ${spirv-cross-spirv-as}.")
|
||||
message("Found spirv-val in: ${spirv-cross-spirv-val}.")
|
||||
message("Found spirv-opt in: ${spirv-cross-spirv-opt}.")
|
||||
endif()
|
||||
|
||||
set(spirv-cross-externals
|
||||
--glslang "${spirv-cross-glslang}"
|
||||
--spirv-as "${spirv-cross-spirv-as}"
|
||||
--spirv-opt "${spirv-cross-spirv-opt}"
|
||||
--spirv-val "${spirv-cross-spirv-val}")
|
||||
|
||||
if (${PYTHONINTERP_FOUND} AND SPIRV_CROSS_ENABLE_TESTS)
|
||||
if (${PYTHON_VERSION_MAJOR} GREATER 2)
|
||||
add_executable(spirv-cross-c-api-test tests-other/c_api_test.c)
|
||||
target_link_libraries(spirv-cross-c-api-test spirv-cross-c)
|
||||
set_target_properties(spirv-cross-c-api-test PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
|
||||
if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))
|
||||
target_compile_options(spirv-cross-c-api-test PRIVATE -std=c89 -Wall -Wextra)
|
||||
endif()
|
||||
add_test(NAME spirv-cross-c-api-test
|
||||
COMMAND $<TARGET_FILE:spirv-cross-c-api-test> ${CMAKE_CURRENT_SOURCE_DIR}/tests-other/c_api_test.spv)
|
||||
add_test(NAME spirv-cross-test
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-no-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-no-opt
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-metal
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-metal-no-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl-no-opt
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-hlsl
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-hlsl-no-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl-no-opt
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --opt --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-metal-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --opt --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-hlsl-opt
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --opt --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
add_test(NAME spirv-cross-test-reflection
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --reflect --parallel
|
||||
${spirv-cross-externals}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders-reflection
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
|
||||
endif()
|
||||
elseif(NOT ${PYTHONINTERP_FOUND})
|
||||
message(WARNING "Testing disabled. Could not find python3. If you have python3 installed try running "
|
||||
"cmake with -DPYTHON_EXECUTABLE:FILEPATH=/path/to/python3 to help it find the executable")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -10,7 +10,7 @@ STATIC_LIB := lib$(TARGET).a
|
|||
|
||||
DEPS := $(OBJECTS:.o=.d) $(CLI_OBJECTS:.o=.d)
|
||||
|
||||
CXXFLAGS += -std=c++11 -Wall -Wextra -Wshadow -D__STDC_LIMIT_MACROS
|
||||
CXXFLAGS += -std=c++11 -Wall -Wextra -Wshadow
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CXXFLAGS += -O0 -g
|
||||
|
|
|
@ -10,7 +10,7 @@ SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader
|
|||
- Convert SPIR-V to readable, usable and efficient GLSL
|
||||
- Convert SPIR-V to readable, usable and efficient Metal Shading Language (MSL)
|
||||
- Convert SPIR-V to readable, usable and efficient HLSL
|
||||
- Convert SPIR-V to debuggable C++ [EXPERIMENTAL]
|
||||
- Convert SPIR-V to debuggable C++ [DEPRECATED]
|
||||
- Convert SPIR-V to a JSON reflection format [EXPERIMENTAL]
|
||||
- Reflection API to simplify the creation of Vulkan pipeline layouts
|
||||
- Reflection API to modify and tweak OpDecorations
|
||||
|
@ -48,11 +48,18 @@ SPIRV-Cross is only useful as a library here. Use the CMake build to link SPIRV-
|
|||
|
||||
The make and CMake build flavors offer the option to treat exceptions as assertions. To disable exceptions for make just append `SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=1` to the command line. For CMake append `-DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=ON`. By default exceptions are enabled.
|
||||
|
||||
### Static, shared and CLI
|
||||
|
||||
You can use `-DSPIRV_CROSS_STATIC=ON/OFF` `-DSPIRV_CROSS_SHARED=ON/OFF` `-DSPIRV_CROSS_CLI=ON/OFF` to control which modules are built (and installed).
|
||||
|
||||
## Usage
|
||||
|
||||
### Using the C++ API
|
||||
|
||||
For more in-depth documentation than what's provided in this README, please have a look at the [Wiki](https://github.com/KhronosGroup/SPIRV-Cross/wiki).
|
||||
The C++ API is the main API for SPIRV-Cross. For more in-depth documentation than what's provided in this README,
|
||||
please have a look at the [Wiki](https://github.com/KhronosGroup/SPIRV-Cross/wiki).
|
||||
**NOTE**: This API is not guaranteed to be ABI-stable, and it is highly recommended to link against this API statically.
|
||||
The API is generally quite stable, but it can change over time, see the C API for more stability.
|
||||
|
||||
To perform reflection and convert to other shader languages you can use the SPIRV-Cross API.
|
||||
For example:
|
||||
|
@ -99,19 +106,143 @@ int main()
|
|||
}
|
||||
```
|
||||
|
||||
### Using the C API wrapper
|
||||
|
||||
To facilitate C compatibility and compatibility with foreign programming languages, a C89-compatible API wrapper is provided. Unlike the C++ API,
|
||||
the goal of this wrapper is to be fully stable, both API and ABI-wise.
|
||||
This is the only interface which is supported when building SPIRV-Cross as a shared library.
|
||||
|
||||
An important point of the wrapper is that all memory allocations are contained in the `spvc_context`.
|
||||
This simplifies the use of the API greatly. However, you should destroy the context as soon as reasonable,
|
||||
or use `spvc_context_release_allocations()` if you intend to reuse the `spvc_context` object again soon.
|
||||
|
||||
Most functions return a `spvc_result`, where `SPVC_SUCCESS` is the only success code.
|
||||
For brevity, the code below does not do any error checking.
|
||||
|
||||
```c
|
||||
#include <spirv_cross_c.h>
|
||||
|
||||
const SpvId *spirv = get_spirv_data();
|
||||
size_t word_count = get_spirv_word_count();
|
||||
|
||||
spvc_context context = NULL;
|
||||
spvc_parsed_ir ir = NULL;
|
||||
spvc_compiler compiler_glsl = NULL;
|
||||
spvc_compiler_options options = NULL;
|
||||
spvc_resources resources = NULL;
|
||||
const spvc_reflected_resource *list = NULL;
|
||||
const char *result = NULL;
|
||||
size_t count;
|
||||
size_t i;
|
||||
|
||||
// Create context.
|
||||
spvc_context_create(&context);
|
||||
|
||||
// Set debug callback.
|
||||
spvc_context_set_error_callback(context, error_callback, userdata);
|
||||
|
||||
// Parse the SPIR-V.
|
||||
spvc_context_parse_spirv(context, spirv, word_count, &ir);
|
||||
|
||||
// Hand it off to a compiler instance and give it ownership of the IR.
|
||||
spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler_glsl);
|
||||
|
||||
// Do some basic reflection.
|
||||
spvc_compiler_create_shader_resources(compiler_glsl, &resources);
|
||||
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
printf("ID: %u, BaseTypeID: %u, TypeID: %u, Name: %s\n", list[i].id, list[i].base_type_id, list[i].type_id,
|
||||
list[i].name);
|
||||
printf(" Set: %u, Binding: %u\n",
|
||||
spvc_compiler_get_decoration(compiler_glsl, list[i].id, SpvDecorationDescriptorSet),
|
||||
spvc_compiler_get_decoration(compiler_glsl, list[i].id, SpvDecorationBinding));
|
||||
}
|
||||
|
||||
// Modify options.
|
||||
spvc_compiler_create_compiler_options(context, &options);
|
||||
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_GLSL_VERSION, 330);
|
||||
spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_GLSL_ES, SPVC_FALSE);
|
||||
spvc_compiler_install_compiler_options(compiler_glsl, options);
|
||||
|
||||
spvc_compiler_compile(compiler, &result);
|
||||
printf("Cross-compiled source: %s\n", result);
|
||||
|
||||
// Frees all memory we allocated so far.
|
||||
spvc_context_destroy(context);
|
||||
```
|
||||
|
||||
### Linking
|
||||
|
||||
#### CMake add_subdirectory()
|
||||
|
||||
This is the recommended way if you are using CMake and want to link against SPIRV-Cross statically.
|
||||
|
||||
#### Integrating SPIRV-Cross in a custom build system
|
||||
|
||||
To add SPIRV-Cross to your own codebase, just copy the source and header files from root directory
|
||||
and build the relevant .cpp files you need. Make sure to build with C++11 support, e.g. `-std=c++11` in GCC and Clang.
|
||||
Alternatively, the Makefile generates a libspirv-cross.a static library during build that can be linked in.
|
||||
|
||||
### Creating a SPIR-V file from GLSL with glslang
|
||||
#### Linking against SPIRV-Cross as a system library
|
||||
|
||||
It is possible to link against SPIRV-Cross when it is installed as a system library,
|
||||
which would be mostly relevant for Unix-like platforms.
|
||||
|
||||
##### pkg-config
|
||||
|
||||
For Unix-based systems, a pkg-config is installed for the C API, e.g.:
|
||||
|
||||
```
|
||||
$ pkg-config spirv-cross-c-shared --libs --cflags
|
||||
-I/usr/local/include/spirv_cross -L/usr/local/lib -lspirv-cross-c-shared
|
||||
```
|
||||
|
||||
##### CMake
|
||||
|
||||
If the project is installed, it can be found with `find_package()`, e.g.:
|
||||
|
||||
```
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
project(Test LANGUAGES C)
|
||||
|
||||
find_package(spirv_cross_c_shared)
|
||||
if (spirv_cross_c_shared_FOUND)
|
||||
message(STATUS "Found SPIRV-Cross C API! :)")
|
||||
else()
|
||||
message(STATUS "Could not find SPIRV-Cross C API! :(")
|
||||
endif()
|
||||
|
||||
add_executable(test test.c)
|
||||
target_link_libraries(test spirv-cross-c-shared)
|
||||
```
|
||||
|
||||
test.c:
|
||||
```c
|
||||
#include <spirv_cross_c.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
spvc_context context;
|
||||
spvc_context_create(&context);
|
||||
spvc_context_destroy(context);
|
||||
}
|
||||
```
|
||||
|
||||
### CLI
|
||||
|
||||
The CLI is suitable for basic cross-compilation tasks, but it cannot support the full flexibility that the API can.
|
||||
Some examples below.
|
||||
|
||||
#### Creating a SPIR-V file from GLSL with glslang
|
||||
|
||||
```
|
||||
glslangValidator -H -V -o test.spv test.frag
|
||||
```
|
||||
|
||||
### Converting a SPIR-V file to GLSL ES
|
||||
#### Converting a SPIR-V file to GLSL ES
|
||||
|
||||
```
|
||||
glslangValidator -H -V -o test.spv shaders/comp/basic.comp
|
||||
|
@ -122,7 +253,7 @@ glslangValidator -H -V -o test.spv shaders/comp/basic.comp
|
|||
|
||||
```
|
||||
glslangValidator -H -V -o test.spv shaders/comp/basic.comp
|
||||
./spirv-cross --version 330 test.spv --output test.comp
|
||||
./spirv-cross --version 330 --no-es test.spv --output test.comp
|
||||
```
|
||||
|
||||
#### Disable prettifying optimizations
|
||||
|
@ -278,17 +409,22 @@ Contributions to SPIRV-Cross are welcome. See Testing and Licensing sections for
|
|||
### Testing
|
||||
|
||||
SPIRV-Cross maintains a test suite of shaders with reference output of how the output looks after going through a roundtrip through
|
||||
glslangValidator then back through SPIRV-Cross again. The reference files are stored inside the repository in order to be able to track regressions.
|
||||
glslangValidator/spirv-as then back through SPIRV-Cross again.
|
||||
The reference files are stored inside the repository in order to be able to track regressions.
|
||||
|
||||
All pull requests should ensure that test output does not change unexpectedly. This can be tested with:
|
||||
|
||||
```
|
||||
./test_shaders.py shaders
|
||||
./test_shaders.py shaders --opt
|
||||
./test_shaders.py shaders-hlsl --hlsl
|
||||
./test_shaders.py shaders-hlsl --hlsl --opt
|
||||
./test_shaders.py shaders-msl --msl
|
||||
./test_shaders.py shaders-msl --msl --opt
|
||||
./test_shaders.py shaders || exit 1
|
||||
./test_shaders.py shaders --opt || exit 1
|
||||
./test_shaders.py shaders-no-opt || exit 1
|
||||
./test_shaders.py shaders-msl --msl || exit 1
|
||||
./test_shaders.py shaders-msl --msl --opt || exit 1
|
||||
./test_shaders.py shaders-msl-no-opt --msl || exit 1
|
||||
./test_shaders.py shaders-hlsl --hlsl || exit 1
|
||||
./test_shaders.py shaders-hlsl --hlsl --opt || exit 1
|
||||
./test_shaders.py shaders-hlsl-no-opt --hlsl || exit 1
|
||||
./test_shaders.py shaders-reflection --reflect || exit 1
|
||||
```
|
||||
|
||||
although there are a couple of convenience script for doing this:
|
||||
|
@ -316,6 +452,8 @@ A pull request which does not pass testing on Travis will not be accepted howeve
|
|||
|
||||
When adding support for new features to SPIRV-Cross, a new shader and reference file should be added which covers usage of the new shader features in question.
|
||||
|
||||
Travis CI runs the test suite with the CMake, by running `ctest`. This method is compatible with MSVC.
|
||||
|
||||
### Licensing
|
||||
|
||||
Contributors of new files should add a copyright header at the top of every new source code file with their copyright
|
||||
|
@ -332,13 +470,6 @@ command line:
|
|||
|
||||
./format_all.sh
|
||||
|
||||
## ABI concerns
|
||||
|
||||
### SPIR-V headers
|
||||
|
||||
The current repository uses the latest SPIR-V and GLSL.std.450 headers.
|
||||
SPIR-V files created from older headers could have ABI issues.
|
||||
|
||||
## Regression testing
|
||||
|
||||
In shaders/ a collection of shaders are maintained for purposes of regression testing.
|
||||
|
|
|
@ -1109,9 +1109,12 @@ static int main_inner(int argc, char *argv[])
|
|||
for (uint32_t i = 0; i < args.iterations; i++)
|
||||
{
|
||||
if (args.hlsl)
|
||||
glsl = static_cast<CompilerHLSL *>(compiler.get())->compile(move(args.hlsl_attr_remap));
|
||||
else
|
||||
glsl = compiler->compile();
|
||||
{
|
||||
for (auto &remap : args.hlsl_attr_remap)
|
||||
static_cast<CompilerHLSL *>(compiler.get())->add_vertex_attribute_remap(remap);
|
||||
}
|
||||
|
||||
glsl = compiler->compile();
|
||||
}
|
||||
|
||||
if (args.output)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=@SPIRV_CROSS_INSTALL_LIB_DIR@
|
||||
sharedlibdir=@SPIRV_CROSS_INSTALL_LIB_DIR@
|
||||
includedir=@SPIRV_CROSS_INSTALL_INC_DIR@
|
||||
|
||||
Name: spirv-cross-c-shared
|
||||
Description: C API for SPIRV-Cross
|
||||
Version: @SPIRV_CROSS_VERSION@
|
||||
|
||||
Requires:
|
||||
Libs: -L${libdir} -L${sharedlibdir} -lspirv-cross-c-shared
|
||||
Cflags: -I${includedir}
|
13
3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/do-while-loop-inverted-test.asm.frag
vendored
Normal file
13
3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/do-while-loop-inverted-test.asm.frag
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 450
|
||||
|
||||
void main()
|
||||
{
|
||||
int j = 0;
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
j = ((j + i) + 1) * j;
|
||||
i++;
|
||||
} while (!(i == 20));
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#version 450
|
||||
|
||||
void main()
|
||||
{
|
||||
int _13;
|
||||
for (int _12 = 0; !(_12 == 16); _12 = _13)
|
||||
{
|
||||
_13 = _12 + 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#version 450
|
||||
|
||||
void main()
|
||||
{
|
||||
int _13;
|
||||
for (int _12 = 0; _12 != 16; _12 = _13)
|
||||
{
|
||||
_13 = _12 + 1;
|
||||
}
|
||||
}
|
||||
|
11
3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/for-loop-inverted-test.asm.frag
vendored
Normal file
11
3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/for-loop-inverted-test.asm.frag
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#version 450
|
||||
|
||||
void main()
|
||||
{
|
||||
int _13;
|
||||
for (int _12 = 0; !(_12 == 16); _12 = _13)
|
||||
{
|
||||
_13 = _12 + 1;
|
||||
}
|
||||
}
|
||||
|
13
3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/while-loop-inverted-test.asm.frag
vendored
Normal file
13
3rdparty/spirv-cross/reference/shaders-no-opt/asm/frag/while-loop-inverted-test.asm.frag
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 450
|
||||
|
||||
void main()
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (!(i == 20))
|
||||
{
|
||||
j = ((j + i) + 1) * j;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
51
3rdparty/spirv-cross/shaders-no-opt/asm/frag/do-while-loop-inverted-test.asm.frag
vendored
Normal file
51
3rdparty/spirv-cross/shaders-no-opt/asm/frag/do-while-loop-inverted-test.asm.frag
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 7
|
||||
; Bound: 28
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %i "i"
|
||||
OpName %j "j"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_20 = OpConstant %int 20
|
||||
%bool = OpTypeBool
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%i = OpVariable %_ptr_Function_int Function
|
||||
%j = OpVariable %_ptr_Function_int Function
|
||||
OpStore %i %int_0
|
||||
OpStore %j %int_0
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
OpLoopMerge %13 %14 None
|
||||
OpBranch %12
|
||||
%12 = OpLabel
|
||||
%15 = OpLoad %int %j
|
||||
%16 = OpLoad %int %i
|
||||
%17 = OpIAdd %int %15 %16
|
||||
%19 = OpIAdd %int %17 %int_1
|
||||
%20 = OpLoad %int %j
|
||||
%21 = OpIMul %int %19 %20
|
||||
OpStore %j %21
|
||||
%22 = OpLoad %int %i
|
||||
%23 = OpIAdd %int %22 %int_1
|
||||
OpStore %i %23
|
||||
OpBranch %14
|
||||
%14 = OpLabel
|
||||
%24 = OpLoad %int %i
|
||||
%27 = OpIEqual %bool %24 %int_20
|
||||
OpBranchConditional %27 %13 %11
|
||||
%13 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
37
3rdparty/spirv-cross/shaders-no-opt/asm/frag/for-loop-dedicated-merge-block-inverted.asm.frag
vendored
Normal file
37
3rdparty/spirv-cross/shaders-no-opt/asm/frag/for-loop-dedicated-merge-block-inverted.asm.frag
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_16 = OpConstant %int 16
|
||||
%bool = OpTypeBool
|
||||
%int_1 = OpConstant %int 1
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
OpBranch %8
|
||||
%8 = OpLabel
|
||||
%10 = OpPhi %int %12 %7 %int_0 %5
|
||||
OpLoopMerge %6 %7 None
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
%16 = OpIEqual %bool %10 %int_16
|
||||
OpBranchConditional %16 %18 %19
|
||||
%18 = OpLabel
|
||||
OpBranch %6
|
||||
%19 = OpLabel
|
||||
OpBranch %17
|
||||
%17 = OpLabel
|
||||
%21 = OpIAdd %int %10 %int_1
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
%12 = OpPhi %int %21 %17
|
||||
OpBranch %8
|
||||
%6 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,37 @@
|
|||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_16 = OpConstant %int 16
|
||||
%bool = OpTypeBool
|
||||
%int_1 = OpConstant %int 1
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
OpBranch %8
|
||||
%8 = OpLabel
|
||||
%10 = OpPhi %int %12 %7 %int_0 %5
|
||||
OpLoopMerge %6 %7 None
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
%16 = OpINotEqual %bool %10 %int_16
|
||||
OpBranchConditional %16 %19 %18
|
||||
%18 = OpLabel
|
||||
OpBranch %6
|
||||
%19 = OpLabel
|
||||
OpBranch %17
|
||||
%17 = OpLabel
|
||||
%21 = OpIAdd %int %10 %int_1
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
%12 = OpPhi %int %21 %17
|
||||
OpBranch %8
|
||||
%6 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
35
3rdparty/spirv-cross/shaders-no-opt/asm/frag/for-loop-inverted-test.asm.frag
vendored
Normal file
35
3rdparty/spirv-cross/shaders-no-opt/asm/frag/for-loop-inverted-test.asm.frag
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_16 = OpConstant %int 16
|
||||
%bool = OpTypeBool
|
||||
%int_1 = OpConstant %int 1
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
OpBranch %8
|
||||
%8 = OpLabel
|
||||
%10 = OpPhi %int %12 %7 %int_0 %5
|
||||
OpLoopMerge %6 %7 None
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
%16 = OpIEqual %bool %10 %int_16
|
||||
OpBranchConditional %16 %6 %19
|
||||
%19 = OpLabel
|
||||
OpBranch %17
|
||||
%17 = OpLabel
|
||||
%21 = OpIAdd %int %10 %int_1
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
%12 = OpPhi %int %21 %17
|
||||
OpBranch %8
|
||||
%6 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
53
3rdparty/spirv-cross/shaders-no-opt/asm/frag/while-loop-inverted-test.asm.frag
vendored
Normal file
53
3rdparty/spirv-cross/shaders-no-opt/asm/frag/while-loop-inverted-test.asm.frag
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 7
|
||||
; Bound: 29
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %i "i"
|
||||
OpName %j "j"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_20 = OpConstant %int 20
|
||||
%bool = OpTypeBool
|
||||
%int_1 = OpConstant %int 1
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%i = OpVariable %_ptr_Function_int Function
|
||||
%j = OpVariable %_ptr_Function_int Function
|
||||
OpStore %i %int_0
|
||||
OpStore %j %int_0
|
||||
OpBranch %11
|
||||
%11 = OpLabel
|
||||
OpLoopMerge %13 %14 None
|
||||
OpBranch %15
|
||||
%15 = OpLabel
|
||||
%16 = OpLoad %int %i
|
||||
%19 = OpIEqual %bool %16 %int_20
|
||||
OpBranchConditional %19 %13 %12
|
||||
%12 = OpLabel
|
||||
%20 = OpLoad %int %j
|
||||
%21 = OpLoad %int %i
|
||||
%22 = OpIAdd %int %20 %21
|
||||
%24 = OpIAdd %int %22 %int_1
|
||||
%25 = OpLoad %int %j
|
||||
%26 = OpIMul %int %24 %25
|
||||
OpStore %j %26
|
||||
%27 = OpLoad %int %i
|
||||
%28 = OpIAdd %int %27 %int_1
|
||||
OpStore %i %28
|
||||
OpBranch %14
|
||||
%14 = OpLabel
|
||||
OpBranch %11
|
||||
%13 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2014-2019 The Khronos Group Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and/or associated documentation files (the "Materials"),
|
||||
|
@ -26,13 +26,16 @@
|
|||
// the Binary Section of the SPIR-V specification.
|
||||
|
||||
// Enumeration tokens for SPIR-V, in various styles:
|
||||
// C, C++, C++11, JSON, Lua, Python
|
||||
// C, C++, C++11, JSON, Lua, Python, C#, D
|
||||
//
|
||||
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
|
||||
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
|
||||
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
|
||||
// - C# will use enum classes in the Specification class located in the "Spv" namespace,
|
||||
// e.g.: Spv.Specification.SourceLanguage.GLSL
|
||||
// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
|
||||
//
|
||||
// Some tokens act like mask values, which can be OR'd together,
|
||||
// while others are mutually exclusive. The mask-like ones have
|
||||
|
@ -47,11 +50,11 @@ namespace spv {
|
|||
typedef unsigned int Id;
|
||||
|
||||
#define SPV_VERSION 0x10300
|
||||
#define SPV_REVISION 1
|
||||
#define SPV_REVISION 6
|
||||
|
||||
static const unsigned int MagicNumber = 0x07230203;
|
||||
static const unsigned int Version = 0x00010300;
|
||||
static const unsigned int Revision = 1;
|
||||
static const unsigned int Revision = 6;
|
||||
static const unsigned int OpCodeMask = 0xffff;
|
||||
static const unsigned int WordCountShift = 16;
|
||||
|
||||
|
@ -73,6 +76,14 @@ enum ExecutionModel {
|
|||
ExecutionModelFragment = 4,
|
||||
ExecutionModelGLCompute = 5,
|
||||
ExecutionModelKernel = 6,
|
||||
ExecutionModelTaskNV = 5267,
|
||||
ExecutionModelMeshNV = 5268,
|
||||
ExecutionModelRayGenerationNV = 5313,
|
||||
ExecutionModelIntersectionNV = 5314,
|
||||
ExecutionModelAnyHitNV = 5315,
|
||||
ExecutionModelClosestHitNV = 5316,
|
||||
ExecutionModelMissNV = 5317,
|
||||
ExecutionModelCallableNV = 5318,
|
||||
ExecutionModelMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -80,6 +91,7 @@ enum AddressingModel {
|
|||
AddressingModelLogical = 0,
|
||||
AddressingModelPhysical32 = 1,
|
||||
AddressingModelPhysical64 = 2,
|
||||
AddressingModelPhysicalStorageBuffer64EXT = 5348,
|
||||
AddressingModelMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -87,6 +99,7 @@ enum MemoryModel {
|
|||
MemoryModelSimple = 0,
|
||||
MemoryModelGLSL450 = 1,
|
||||
MemoryModelOpenCL = 2,
|
||||
MemoryModelVulkanKHR = 3,
|
||||
MemoryModelMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -130,7 +143,17 @@ enum ExecutionMode {
|
|||
ExecutionModeLocalSizeId = 38,
|
||||
ExecutionModeLocalSizeHintId = 39,
|
||||
ExecutionModePostDepthCoverage = 4446,
|
||||
ExecutionModeDenormPreserve = 4459,
|
||||
ExecutionModeDenormFlushToZero = 4460,
|
||||
ExecutionModeSignedZeroInfNanPreserve = 4461,
|
||||
ExecutionModeRoundingModeRTE = 4462,
|
||||
ExecutionModeRoundingModeRTZ = 4463,
|
||||
ExecutionModeStencilRefReplacingEXT = 5027,
|
||||
ExecutionModeOutputLinesNV = 5269,
|
||||
ExecutionModeOutputPrimitivesNV = 5270,
|
||||
ExecutionModeDerivativeGroupQuadsNV = 5289,
|
||||
ExecutionModeDerivativeGroupLinearNV = 5290,
|
||||
ExecutionModeOutputTrianglesNV = 5298,
|
||||
ExecutionModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -148,6 +171,13 @@ enum StorageClass {
|
|||
StorageClassAtomicCounter = 10,
|
||||
StorageClassImage = 11,
|
||||
StorageClassStorageBuffer = 12,
|
||||
StorageClassCallableDataNV = 5328,
|
||||
StorageClassIncomingCallableDataNV = 5329,
|
||||
StorageClassRayPayloadNV = 5338,
|
||||
StorageClassHitAttributeNV = 5339,
|
||||
StorageClassIncomingRayPayloadNV = 5342,
|
||||
StorageClassShaderRecordBufferNV = 5343,
|
||||
StorageClassPhysicalStorageBufferEXT = 5349,
|
||||
StorageClassMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -275,6 +305,10 @@ enum ImageOperandsShift {
|
|||
ImageOperandsConstOffsetsShift = 5,
|
||||
ImageOperandsSampleShift = 6,
|
||||
ImageOperandsMinLodShift = 7,
|
||||
ImageOperandsMakeTexelAvailableKHRShift = 8,
|
||||
ImageOperandsMakeTexelVisibleKHRShift = 9,
|
||||
ImageOperandsNonPrivateTexelKHRShift = 10,
|
||||
ImageOperandsVolatileTexelKHRShift = 11,
|
||||
ImageOperandsMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -288,6 +322,10 @@ enum ImageOperandsMask {
|
|||
ImageOperandsConstOffsetsMask = 0x00000020,
|
||||
ImageOperandsSampleMask = 0x00000040,
|
||||
ImageOperandsMinLodMask = 0x00000080,
|
||||
ImageOperandsMakeTexelAvailableKHRMask = 0x00000100,
|
||||
ImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
|
||||
ImageOperandsNonPrivateTexelKHRMask = 0x00000400,
|
||||
ImageOperandsVolatileTexelKHRMask = 0x00000800,
|
||||
};
|
||||
|
||||
enum FPFastMathModeShift {
|
||||
|
@ -388,11 +426,20 @@ enum Decoration {
|
|||
DecorationMaxByteOffset = 45,
|
||||
DecorationAlignmentId = 46,
|
||||
DecorationMaxByteOffsetId = 47,
|
||||
DecorationNoSignedWrap = 4469,
|
||||
DecorationNoUnsignedWrap = 4470,
|
||||
DecorationExplicitInterpAMD = 4999,
|
||||
DecorationOverrideCoverageNV = 5248,
|
||||
DecorationPassthroughNV = 5250,
|
||||
DecorationViewportRelativeNV = 5252,
|
||||
DecorationSecondaryViewportRelativeNV = 5256,
|
||||
DecorationPerPrimitiveNV = 5271,
|
||||
DecorationPerViewNV = 5272,
|
||||
DecorationPerTaskNV = 5273,
|
||||
DecorationPerVertexNV = 5285,
|
||||
DecorationNonUniformEXT = 5300,
|
||||
DecorationRestrictPointerEXT = 5355,
|
||||
DecorationAliasedPointerEXT = 5356,
|
||||
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||
DecorationHlslSemanticGOOGLE = 5635,
|
||||
DecorationMax = 0x7fffffff,
|
||||
|
@ -469,6 +516,34 @@ enum BuiltIn {
|
|||
BuiltInPositionPerViewNV = 5261,
|
||||
BuiltInViewportMaskPerViewNV = 5262,
|
||||
BuiltInFullyCoveredEXT = 5264,
|
||||
BuiltInTaskCountNV = 5274,
|
||||
BuiltInPrimitiveCountNV = 5275,
|
||||
BuiltInPrimitiveIndicesNV = 5276,
|
||||
BuiltInClipDistancePerViewNV = 5277,
|
||||
BuiltInCullDistancePerViewNV = 5278,
|
||||
BuiltInLayerPerViewNV = 5279,
|
||||
BuiltInMeshViewCountNV = 5280,
|
||||
BuiltInMeshViewIndicesNV = 5281,
|
||||
BuiltInBaryCoordNV = 5286,
|
||||
BuiltInBaryCoordNoPerspNV = 5287,
|
||||
BuiltInFragSizeEXT = 5292,
|
||||
BuiltInFragmentSizeNV = 5292,
|
||||
BuiltInFragInvocationCountEXT = 5293,
|
||||
BuiltInInvocationsPerPixelNV = 5293,
|
||||
BuiltInLaunchIdNV = 5319,
|
||||
BuiltInLaunchSizeNV = 5320,
|
||||
BuiltInWorldRayOriginNV = 5321,
|
||||
BuiltInWorldRayDirectionNV = 5322,
|
||||
BuiltInObjectRayOriginNV = 5323,
|
||||
BuiltInObjectRayDirectionNV = 5324,
|
||||
BuiltInRayTminNV = 5325,
|
||||
BuiltInRayTmaxNV = 5326,
|
||||
BuiltInInstanceCustomIndexNV = 5327,
|
||||
BuiltInObjectToWorldNV = 5330,
|
||||
BuiltInWorldToObjectNV = 5331,
|
||||
BuiltInHitTNV = 5332,
|
||||
BuiltInHitKindNV = 5333,
|
||||
BuiltInIncomingRayFlagsNV = 5351,
|
||||
BuiltInMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -527,6 +602,9 @@ enum MemorySemanticsShift {
|
|||
MemorySemanticsCrossWorkgroupMemoryShift = 9,
|
||||
MemorySemanticsAtomicCounterMemoryShift = 10,
|
||||
MemorySemanticsImageMemoryShift = 11,
|
||||
MemorySemanticsOutputMemoryKHRShift = 12,
|
||||
MemorySemanticsMakeAvailableKHRShift = 13,
|
||||
MemorySemanticsMakeVisibleKHRShift = 14,
|
||||
MemorySemanticsMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -542,12 +620,18 @@ enum MemorySemanticsMask {
|
|||
MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
|
||||
MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
|
||||
MemorySemanticsImageMemoryMask = 0x00000800,
|
||||
MemorySemanticsOutputMemoryKHRMask = 0x00001000,
|
||||
MemorySemanticsMakeAvailableKHRMask = 0x00002000,
|
||||
MemorySemanticsMakeVisibleKHRMask = 0x00004000,
|
||||
};
|
||||
|
||||
enum MemoryAccessShift {
|
||||
MemoryAccessVolatileShift = 0,
|
||||
MemoryAccessAlignedShift = 1,
|
||||
MemoryAccessNontemporalShift = 2,
|
||||
MemoryAccessMakePointerAvailableKHRShift = 3,
|
||||
MemoryAccessMakePointerVisibleKHRShift = 4,
|
||||
MemoryAccessNonPrivatePointerKHRShift = 5,
|
||||
MemoryAccessMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -556,6 +640,9 @@ enum MemoryAccessMask {
|
|||
MemoryAccessVolatileMask = 0x00000001,
|
||||
MemoryAccessAlignedMask = 0x00000002,
|
||||
MemoryAccessNontemporalMask = 0x00000004,
|
||||
MemoryAccessMakePointerAvailableKHRMask = 0x00000008,
|
||||
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||
};
|
||||
|
||||
enum Scope {
|
||||
|
@ -564,6 +651,7 @@ enum Scope {
|
|||
ScopeWorkgroup = 2,
|
||||
ScopeSubgroup = 3,
|
||||
ScopeInvocation = 4,
|
||||
ScopeQueueFamilyKHR = 5,
|
||||
ScopeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -572,6 +660,9 @@ enum GroupOperation {
|
|||
GroupOperationInclusiveScan = 1,
|
||||
GroupOperationExclusiveScan = 2,
|
||||
GroupOperationClusteredReduce = 3,
|
||||
GroupOperationPartitionedReduceNV = 6,
|
||||
GroupOperationPartitionedInclusiveScanNV = 7,
|
||||
GroupOperationPartitionedExclusiveScanNV = 8,
|
||||
GroupOperationMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -675,6 +766,14 @@ enum Capability {
|
|||
CapabilityVariablePointers = 4442,
|
||||
CapabilityAtomicStorageOps = 4445,
|
||||
CapabilitySampleMaskPostDepthCoverage = 4447,
|
||||
CapabilityStorageBuffer8BitAccess = 4448,
|
||||
CapabilityUniformAndStorageBuffer8BitAccess = 4449,
|
||||
CapabilityStoragePushConstant8 = 4450,
|
||||
CapabilityDenormPreserve = 4464,
|
||||
CapabilityDenormFlushToZero = 4465,
|
||||
CapabilitySignedZeroInfNanPreserve = 4466,
|
||||
CapabilityRoundingModeRTE = 4467,
|
||||
CapabilityRoundingModeRTZ = 4468,
|
||||
CapabilityFloat16ImageAMD = 5008,
|
||||
CapabilityImageGatherBiasLodAMD = 5009,
|
||||
CapabilityFragmentMaskAMD = 5010,
|
||||
|
@ -688,9 +787,34 @@ enum Capability {
|
|||
CapabilityShaderStereoViewNV = 5259,
|
||||
CapabilityPerViewAttributesNV = 5260,
|
||||
CapabilityFragmentFullyCoveredEXT = 5265,
|
||||
CapabilityMeshShadingNV = 5266,
|
||||
CapabilityImageFootprintNV = 5282,
|
||||
CapabilityFragmentBarycentricNV = 5284,
|
||||
CapabilityComputeDerivativeGroupQuadsNV = 5288,
|
||||
CapabilityFragmentDensityEXT = 5291,
|
||||
CapabilityShadingRateNV = 5291,
|
||||
CapabilityGroupNonUniformPartitionedNV = 5297,
|
||||
CapabilityShaderNonUniformEXT = 5301,
|
||||
CapabilityRuntimeDescriptorArrayEXT = 5302,
|
||||
CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,
|
||||
CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,
|
||||
CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,
|
||||
CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,
|
||||
CapabilitySampledImageArrayNonUniformIndexingEXT = 5307,
|
||||
CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,
|
||||
CapabilityStorageImageArrayNonUniformIndexingEXT = 5309,
|
||||
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
|
||||
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
|
||||
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||
CapabilityRayTracingNV = 5340,
|
||||
CapabilityVulkanMemoryModelKHR = 5345,
|
||||
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
|
||||
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
|
||||
CapabilityComputeDerivativeGroupLinearNV = 5350,
|
||||
CapabilitySubgroupShuffleINTEL = 5568,
|
||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||
CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
|
||||
CapabilityMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -1051,6 +1175,15 @@ enum Op {
|
|||
OpGroupSMaxNonUniformAMD = 5007,
|
||||
OpFragmentMaskFetchAMD = 5011,
|
||||
OpFragmentFetchAMD = 5012,
|
||||
OpImageSampleFootprintNV = 5283,
|
||||
OpGroupNonUniformPartitionNV = 5296,
|
||||
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||
OpReportIntersectionNV = 5334,
|
||||
OpIgnoreIntersectionNV = 5335,
|
||||
OpTerminateRayNV = 5336,
|
||||
OpTraceNV = 5337,
|
||||
OpTypeAccelerationStructureNV = 5341,
|
||||
OpExecuteCallableNV = 5344,
|
||||
OpSubgroupShuffleINTEL = 5571,
|
||||
OpSubgroupShuffleDownINTEL = 5572,
|
||||
OpSubgroupShuffleUpINTEL = 5573,
|
||||
|
@ -1059,6 +1192,8 @@ enum Op {
|
|||
OpSubgroupBlockWriteINTEL = 5576,
|
||||
OpSubgroupImageBlockReadINTEL = 5577,
|
||||
OpSubgroupImageBlockWriteINTEL = 5578,
|
||||
OpSubgroupImageMediaBlockReadINTEL = 5580,
|
||||
OpSubgroupImageMediaBlockWriteINTEL = 5581,
|
||||
OpDecorateStringGOOGLE = 5632,
|
||||
OpMemberDecorateStringGOOGLE = 5633,
|
||||
OpMax = 0x7fffffff,
|
||||
|
|
|
@ -59,7 +59,7 @@ report_and_abort(const std::string &msg)
|
|||
class CompilerError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
CompilerError(const std::string &str)
|
||||
explicit CompilerError(const std::string &str)
|
||||
: std::runtime_error(str)
|
||||
{
|
||||
}
|
||||
|
@ -359,7 +359,8 @@ struct SPIRUndef : IVariant
|
|||
{
|
||||
type = TypeUndef
|
||||
};
|
||||
SPIRUndef(uint32_t basetype_)
|
||||
|
||||
explicit SPIRUndef(uint32_t basetype_)
|
||||
: basetype(basetype_)
|
||||
{
|
||||
}
|
||||
|
@ -511,7 +512,7 @@ struct SPIRExtension : IVariant
|
|||
SPV_AMD_gcn_shader
|
||||
};
|
||||
|
||||
SPIRExtension(Extension ext_)
|
||||
explicit SPIRExtension(Extension ext_)
|
||||
: ext(ext_)
|
||||
{
|
||||
}
|
||||
|
@ -546,7 +547,7 @@ struct SPIREntryPoint
|
|||
} workgroup_size;
|
||||
uint32_t invocations = 0;
|
||||
uint32_t output_vertices = 0;
|
||||
spv::ExecutionModel model;
|
||||
spv::ExecutionModel model = spv::ExecutionModelMax;
|
||||
};
|
||||
|
||||
struct SPIRExpression : IVariant
|
||||
|
@ -606,7 +607,7 @@ struct SPIRFunctionPrototype : IVariant
|
|||
type = TypeFunctionPrototype
|
||||
};
|
||||
|
||||
SPIRFunctionPrototype(uint32_t return_type_)
|
||||
explicit SPIRFunctionPrototype(uint32_t return_type_)
|
||||
: return_type(return_type_)
|
||||
{
|
||||
}
|
||||
|
@ -857,7 +858,7 @@ struct SPIRAccessChain : IVariant
|
|||
int32_t static_index_)
|
||||
: basetype(basetype_)
|
||||
, storage(storage_)
|
||||
, base(base_)
|
||||
, base(std::move(base_))
|
||||
, dynamic_index(std::move(dynamic_index_))
|
||||
, static_index(static_index_)
|
||||
{
|
||||
|
@ -1215,7 +1216,7 @@ struct SPIRConstant : IVariant
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t constant_type;
|
||||
uint32_t constant_type = 0;
|
||||
ConstantMatrix m;
|
||||
|
||||
// If this constant is a specialization constant (i.e. created with OpSpecConstant*).
|
||||
|
|
|
@ -931,50 +931,6 @@ void Compiler::parse_fixup()
|
|||
fixup_type_alias();
|
||||
}
|
||||
|
||||
void Compiler::flatten_interface_block(uint32_t id)
|
||||
{
|
||||
auto &var = get<SPIRVariable>(id);
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
auto &flags = ir.meta[type.self].decoration.decoration_flags;
|
||||
|
||||
if (!type.array.empty())
|
||||
SPIRV_CROSS_THROW("Type is array of UBOs.");
|
||||
if (type.basetype != SPIRType::Struct)
|
||||
SPIRV_CROSS_THROW("Type is not a struct.");
|
||||
if (!flags.get(DecorationBlock))
|
||||
SPIRV_CROSS_THROW("Type is not a block.");
|
||||
if (type.member_types.empty())
|
||||
SPIRV_CROSS_THROW("Member list of struct is empty.");
|
||||
|
||||
uint32_t t = type.member_types[0];
|
||||
for (auto &m : type.member_types)
|
||||
if (t != m)
|
||||
SPIRV_CROSS_THROW("Types in block differ.");
|
||||
|
||||
auto &mtype = get<SPIRType>(t);
|
||||
if (!mtype.array.empty())
|
||||
SPIRV_CROSS_THROW("Member type cannot be arrays.");
|
||||
if (mtype.basetype == SPIRType::Struct)
|
||||
SPIRV_CROSS_THROW("Member type cannot be struct.");
|
||||
|
||||
// Inherit variable name from interface block name.
|
||||
ir.meta[var.self].decoration.alias = ir.meta[type.self].decoration.alias;
|
||||
|
||||
auto storage = var.storage;
|
||||
if (storage == StorageClassUniform)
|
||||
storage = StorageClassUniformConstant;
|
||||
|
||||
// Change type definition in-place into an array instead.
|
||||
// Access chains will still work as-is.
|
||||
uint32_t array_size = uint32_t(type.member_types.size());
|
||||
type = mtype;
|
||||
type.array.push_back(array_size);
|
||||
type.pointer = true;
|
||||
type.storage = storage;
|
||||
type.parent_type = t;
|
||||
var.storage = storage;
|
||||
}
|
||||
|
||||
void Compiler::update_name_cache(unordered_set<string> &cache_primary, const unordered_set<string> &cache_secondary,
|
||||
string &name)
|
||||
{
|
||||
|
@ -1155,11 +1111,6 @@ uint32_t Compiler::get_member_decoration(uint32_t id, uint32_t index, Decoration
|
|||
return ir.get_member_decoration(id, index, decoration);
|
||||
}
|
||||
|
||||
uint64_t Compiler::get_member_decoration_mask(uint32_t id, uint32_t index) const
|
||||
{
|
||||
return get_member_decoration_bitset(id, index).get_lower();
|
||||
}
|
||||
|
||||
const Bitset &Compiler::get_member_decoration_bitset(uint32_t id, uint32_t index) const
|
||||
{
|
||||
return ir.get_member_decoration_bitset(id, index);
|
||||
|
@ -1412,11 +1363,6 @@ const std::string Compiler::get_block_fallback_name(uint32_t id) const
|
|||
return get_name(id);
|
||||
}
|
||||
|
||||
uint64_t Compiler::get_decoration_mask(uint32_t id) const
|
||||
{
|
||||
return get_decoration_bitset(id).get_lower();
|
||||
}
|
||||
|
||||
const Bitset &Compiler::get_decoration_bitset(uint32_t id) const
|
||||
{
|
||||
return ir.get_decoration_bitset(id);
|
||||
|
@ -1474,12 +1420,29 @@ bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method
|
|||
// which the code backend can use to create cleaner code.
|
||||
// for(;;) { if (cond) { some_body; } else { break; } }
|
||||
// is the pattern we're looking for.
|
||||
bool ret = block.terminator == SPIRBlock::Select && block.merge == SPIRBlock::MergeLoop &&
|
||||
block.true_block != block.merge_block && block.true_block != block.self &&
|
||||
block.false_block == block.merge_block;
|
||||
const auto *false_block = maybe_get<SPIRBlock>(block.false_block);
|
||||
const auto *true_block = maybe_get<SPIRBlock>(block.true_block);
|
||||
const auto *merge_block = maybe_get<SPIRBlock>(block.merge_block);
|
||||
|
||||
if (ret && method == SPIRBlock::MergeToSelectContinueForLoop)
|
||||
bool false_block_is_merge = block.false_block == block.merge_block ||
|
||||
(false_block && merge_block && execution_is_noop(*false_block, *merge_block));
|
||||
|
||||
bool true_block_is_merge = block.true_block == block.merge_block ||
|
||||
(true_block && merge_block && execution_is_noop(*true_block, *merge_block));
|
||||
|
||||
bool positive_candidate =
|
||||
block.true_block != block.merge_block && block.true_block != block.self && false_block_is_merge;
|
||||
|
||||
bool negative_candidate =
|
||||
block.false_block != block.merge_block && block.false_block != block.self && true_block_is_merge;
|
||||
|
||||
bool ret = block.terminator == SPIRBlock::Select && block.merge == SPIRBlock::MergeLoop &&
|
||||
(positive_candidate || negative_candidate);
|
||||
|
||||
if (ret && positive_candidate && method == SPIRBlock::MergeToSelectContinueForLoop)
|
||||
ret = block.true_block == block.continue_block;
|
||||
else if (ret && negative_candidate && method == SPIRBlock::MergeToSelectContinueForLoop)
|
||||
ret = block.false_block == block.continue_block;
|
||||
|
||||
// If we have OpPhi which depends on branches which came from our own block,
|
||||
// we need to flush phi variables in else block instead of a trivial break,
|
||||
|
@ -1508,9 +1471,25 @@ bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method
|
|||
return false;
|
||||
|
||||
auto &child = get<SPIRBlock>(block.next_block);
|
||||
|
||||
const auto *false_block = maybe_get<SPIRBlock>(child.false_block);
|
||||
const auto *true_block = maybe_get<SPIRBlock>(child.true_block);
|
||||
const auto *merge_block = maybe_get<SPIRBlock>(block.merge_block);
|
||||
|
||||
bool false_block_is_merge = child.false_block == block.merge_block ||
|
||||
(false_block && merge_block && execution_is_noop(*false_block, *merge_block));
|
||||
|
||||
bool true_block_is_merge = child.true_block == block.merge_block ||
|
||||
(true_block && merge_block && execution_is_noop(*true_block, *merge_block));
|
||||
|
||||
bool positive_candidate =
|
||||
child.true_block != block.merge_block && child.true_block != block.self && false_block_is_merge;
|
||||
|
||||
bool negative_candidate =
|
||||
child.false_block != block.merge_block && child.false_block != block.self && true_block_is_merge;
|
||||
|
||||
ret = child.terminator == SPIRBlock::Select && child.merge == SPIRBlock::MergeNone &&
|
||||
child.false_block == block.merge_block && child.true_block != block.merge_block &&
|
||||
child.true_block != block.self;
|
||||
(positive_candidate || negative_candidate);
|
||||
|
||||
// If we have OpPhi which depends on branches which came from our own block,
|
||||
// we need to flush phi variables in else block instead of a trivial break,
|
||||
|
@ -1628,8 +1607,20 @@ SPIRBlock::ContinueBlockType Compiler::continue_block_type(const SPIRBlock &bloc
|
|||
return SPIRBlock::ForLoop;
|
||||
else
|
||||
{
|
||||
const auto *false_block = maybe_get<SPIRBlock>(block.false_block);
|
||||
const auto *true_block = maybe_get<SPIRBlock>(block.true_block);
|
||||
const auto *merge_block = maybe_get<SPIRBlock>(dominator.merge_block);
|
||||
|
||||
bool positive_do_while = block.true_block == dominator.self &&
|
||||
(block.false_block == dominator.merge_block ||
|
||||
(false_block && merge_block && execution_is_noop(*false_block, *merge_block)));
|
||||
|
||||
bool negative_do_while = block.false_block == dominator.self &&
|
||||
(block.true_block == dominator.merge_block ||
|
||||
(true_block && merge_block && execution_is_noop(*true_block, *merge_block)));
|
||||
|
||||
if (block.merge == SPIRBlock::MergeNone && block.terminator == SPIRBlock::Select &&
|
||||
block.true_block == dominator.self && block.false_block == dominator.merge_block)
|
||||
(positive_do_while || negative_do_while))
|
||||
{
|
||||
return SPIRBlock::DoWhileLoop;
|
||||
}
|
||||
|
@ -1904,11 +1895,6 @@ bool Compiler::types_are_logically_equivalent(const SPIRType &a, const SPIRType
|
|||
return true;
|
||||
}
|
||||
|
||||
uint64_t Compiler::get_execution_mode_mask() const
|
||||
{
|
||||
return get_entry_point().flags.get_lower();
|
||||
}
|
||||
|
||||
const Bitset &Compiler::get_execution_mode_bitset() const
|
||||
{
|
||||
return get_entry_point().flags;
|
||||
|
@ -2094,14 +2080,6 @@ void Compiler::inherit_expression_dependencies(uint32_t dst, uint32_t source_exp
|
|||
e_deps.erase(unique(begin(e_deps), end(e_deps)), end(e_deps));
|
||||
}
|
||||
|
||||
vector<string> Compiler::get_entry_points() const
|
||||
{
|
||||
vector<string> entries;
|
||||
for (auto &entry : ir.entry_points)
|
||||
entries.push_back(entry.second.orig_name);
|
||||
return entries;
|
||||
}
|
||||
|
||||
vector<EntryPoint> Compiler::get_entry_points_and_stages() const
|
||||
{
|
||||
vector<EntryPoint> entries;
|
||||
|
@ -2110,13 +2088,6 @@ vector<EntryPoint> Compiler::get_entry_points_and_stages() const
|
|||
return entries;
|
||||
}
|
||||
|
||||
void Compiler::rename_entry_point(const std::string &old_name, const std::string &new_name)
|
||||
{
|
||||
auto &entry = get_first_entry_point(old_name);
|
||||
entry.orig_name = new_name;
|
||||
entry.name = new_name;
|
||||
}
|
||||
|
||||
void Compiler::rename_entry_point(const std::string &old_name, const std::string &new_name, spv::ExecutionModel model)
|
||||
{
|
||||
auto &entry = get_entry_point(old_name, model);
|
||||
|
@ -2124,28 +2095,12 @@ void Compiler::rename_entry_point(const std::string &old_name, const std::string
|
|||
entry.name = new_name;
|
||||
}
|
||||
|
||||
void Compiler::set_entry_point(const std::string &name)
|
||||
{
|
||||
auto &entry = get_first_entry_point(name);
|
||||
ir.default_entry_point = entry.self;
|
||||
}
|
||||
|
||||
void Compiler::set_entry_point(const std::string &name, spv::ExecutionModel model)
|
||||
{
|
||||
auto &entry = get_entry_point(name, model);
|
||||
ir.default_entry_point = entry.self;
|
||||
}
|
||||
|
||||
SPIREntryPoint &Compiler::get_entry_point(const std::string &name)
|
||||
{
|
||||
return get_first_entry_point(name);
|
||||
}
|
||||
|
||||
const SPIREntryPoint &Compiler::get_entry_point(const std::string &name) const
|
||||
{
|
||||
return get_first_entry_point(name);
|
||||
}
|
||||
|
||||
SPIREntryPoint &Compiler::get_first_entry_point(const std::string &name)
|
||||
{
|
||||
auto itr = find_if(
|
||||
|
@ -2196,11 +2151,6 @@ const SPIREntryPoint &Compiler::get_entry_point(const std::string &name, Executi
|
|||
return itr->second;
|
||||
}
|
||||
|
||||
const string &Compiler::get_cleansed_entry_point_name(const std::string &name) const
|
||||
{
|
||||
return get_first_entry_point(name).name;
|
||||
}
|
||||
|
||||
const string &Compiler::get_cleansed_entry_point_name(const std::string &name, ExecutionModel model) const
|
||||
{
|
||||
return get_entry_point(name, model).name;
|
||||
|
|
|
@ -160,8 +160,6 @@ public:
|
|||
|
||||
// Gets a bitmask for the decorations which are applied to ID.
|
||||
// I.e. (1ull << spv::DecorationFoo) | (1ull << spv::DecorationBar)
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_decoration_bitset instead.")
|
||||
uint64_t get_decoration_mask(uint32_t id) const;
|
||||
const Bitset &get_decoration_bitset(uint32_t id) const;
|
||||
|
||||
// Returns whether the decoration has been applied to the ID.
|
||||
|
@ -215,8 +213,6 @@ public:
|
|||
void set_member_qualified_name(uint32_t type_id, uint32_t index, const std::string &name);
|
||||
|
||||
// Gets the decoration mask for a member of a struct, similar to get_decoration_mask.
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_member_decoration_bitset instead.")
|
||||
uint64_t get_member_decoration_mask(uint32_t id, uint32_t index) const;
|
||||
const Bitset &get_member_decoration_bitset(uint32_t id, uint32_t index) const;
|
||||
|
||||
// Returns whether the decoration has been applied to a member of a struct.
|
||||
|
@ -260,9 +256,6 @@ public:
|
|||
// Returns the effective size of a buffer block struct member.
|
||||
virtual size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const;
|
||||
|
||||
// Legacy GLSL compatibility method. Deprecated in favor of CompilerGLSL::flatten_buffer_block
|
||||
SPIRV_CROSS_DEPRECATED("Please use flatten_buffer_block instead.") void flatten_interface_block(uint32_t id);
|
||||
|
||||
// Returns a set of all global variables which are statically accessed
|
||||
// by the control flow graph from the current entry point.
|
||||
// Only variables which change the interface for a shader are returned, that is,
|
||||
|
@ -303,24 +296,6 @@ public:
|
|||
// Entry points should be set right after the constructor completes as some reflection functions traverse the graph from the entry point.
|
||||
// Resource reflection also depends on the entry point.
|
||||
// By default, the current entry point is set to the first OpEntryPoint which appears in the SPIR-V module.
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_entry_points_and_stages instead.")
|
||||
std::vector<std::string> get_entry_points() const;
|
||||
SPIRV_CROSS_DEPRECATED("Please use set_entry_point(const std::string &, spv::ExecutionModel) instead.")
|
||||
void set_entry_point(const std::string &name);
|
||||
|
||||
// Renames an entry point from old_name to new_name.
|
||||
// If old_name is currently selected as the current entry point, it will continue to be the current entry point,
|
||||
// albeit with a new name.
|
||||
// get_entry_points() is essentially invalidated at this point.
|
||||
SPIRV_CROSS_DEPRECATED(
|
||||
"Please use rename_entry_point(const std::string&, const std::string&, spv::ExecutionModel) instead.")
|
||||
void rename_entry_point(const std::string &old_name, const std::string &new_name);
|
||||
|
||||
// Returns the internal data structure for entry points to allow poking around.
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_entry_point(const std::string &, spv::ExecutionModel instead.")
|
||||
const SPIREntryPoint &get_entry_point(const std::string &name) const;
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_entry_point(const std::string &, spv::ExecutionModel instead.")
|
||||
SPIREntryPoint &get_entry_point(const std::string &name);
|
||||
|
||||
// Some shader languages restrict the names that can be given to entry points, and the
|
||||
// corresponding backend will automatically rename an entry point name, during the call
|
||||
|
@ -330,15 +305,17 @@ public:
|
|||
// the name, as updated by the backend during the call to compile(). If the name is not
|
||||
// illegal, and has not been renamed, or if this function is called before compile(),
|
||||
// this function will simply return the same name.
|
||||
SPIRV_CROSS_DEPRECATED(
|
||||
"Please use get_cleansed_entry_point_name(const std::string &, spv::ExecutionModel) instead.")
|
||||
const std::string &get_cleansed_entry_point_name(const std::string &name) const;
|
||||
|
||||
// New variants of entry point query and reflection.
|
||||
// Names for entry points in the SPIR-V module may alias if they belong to different execution models.
|
||||
// To disambiguate, we must pass along with the entry point names the execution model.
|
||||
std::vector<EntryPoint> get_entry_points_and_stages() const;
|
||||
void set_entry_point(const std::string &entry, spv::ExecutionModel execution_model);
|
||||
|
||||
// Renames an entry point from old_name to new_name.
|
||||
// If old_name is currently selected as the current entry point, it will continue to be the current entry point,
|
||||
// albeit with a new name.
|
||||
// get_entry_points() is essentially invalidated at this point.
|
||||
void rename_entry_point(const std::string &old_name, const std::string &new_name,
|
||||
spv::ExecutionModel execution_model);
|
||||
const SPIREntryPoint &get_entry_point(const std::string &name, spv::ExecutionModel execution_model) const;
|
||||
|
@ -347,8 +324,6 @@ public:
|
|||
spv::ExecutionModel execution_model) const;
|
||||
|
||||
// Query and modify OpExecutionMode.
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_execution_mode_bitset instead.")
|
||||
uint64_t get_execution_mode_mask() const;
|
||||
const Bitset &get_execution_mode_bitset() const;
|
||||
|
||||
void unset_execution_mode(spv::ExecutionMode mode);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,697 @@
|
|||
/*
|
||||
* Copyright 2019 Hans-Kristian Arntzen
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_C_API_H
|
||||
#define SPIRV_CROSS_C_API_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "spirv.h"
|
||||
|
||||
/*
|
||||
* C89-compatible wrapper for SPIRV-Cross' API.
|
||||
* Documentation here is sparse unless the behavior does not map 1:1 with C++ API.
|
||||
* It is recommended to look at the canonical C++ API for more detailed information.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Bumped if ABI or API breaks backwards compatibility. */
|
||||
#define SPVC_C_API_VERSION_MAJOR 0
|
||||
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
|
||||
#define SPVC_C_API_VERSION_MINOR 1
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
#if !defined(SPVC_PUBLIC_API)
|
||||
#if defined(SPVC_EXPORT_SYMBOLS)
|
||||
/* Exports symbols. Standard C calling convention is used. */
|
||||
#if defined(__GNUC__)
|
||||
#define SPVC_PUBLIC_API __attribute__((visibility("default")))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SPVC_PUBLIC_API __declspec(dllexport)
|
||||
#else
|
||||
#define SPVC_PUBLIC_API
|
||||
#endif
|
||||
#else
|
||||
#define SPVC_PUBLIC_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Gets the SPVC_C_API_VERSION_* used to build this library.
|
||||
* Can be used to check for ABI mismatch if so-versioning did not catch it.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_get_version(unsigned *major, unsigned *minor, unsigned *patch);
|
||||
|
||||
/* These types are opaque to the user. */
|
||||
typedef struct spvc_context_s *spvc_context;
|
||||
typedef struct spvc_parsed_ir_s *spvc_parsed_ir;
|
||||
typedef struct spvc_compiler_s *spvc_compiler;
|
||||
typedef struct spvc_compiler_options_s *spvc_compiler_options;
|
||||
typedef struct spvc_resources_s *spvc_resources;
|
||||
struct spvc_type_s;
|
||||
typedef const struct spvc_type_s *spvc_type;
|
||||
typedef struct spvc_constant_s *spvc_constant;
|
||||
struct spvc_set_s;
|
||||
typedef const struct spvc_set_s *spvc_set;
|
||||
|
||||
/*
|
||||
* Shallow typedefs. All SPIR-V IDs are plain 32-bit numbers, but this helps communicate which data is used.
|
||||
* Maps to a SPIRType.
|
||||
*/
|
||||
typedef SpvId spvc_type_id;
|
||||
/* Maps to a SPIRVariable. */
|
||||
typedef SpvId spvc_variable_id;
|
||||
/* Maps to a SPIRConstant. */
|
||||
typedef SpvId spvc_constant_id;
|
||||
|
||||
/* See C++ API. */
|
||||
typedef struct spvc_reflected_resource
|
||||
{
|
||||
spvc_variable_id id;
|
||||
spvc_type_id base_type_id;
|
||||
spvc_type_id type_id;
|
||||
const char *name;
|
||||
} spvc_reflected_resource;
|
||||
|
||||
/* See C++ API. */
|
||||
typedef struct spvc_entry_point
|
||||
{
|
||||
SpvExecutionModel execution_model;
|
||||
const char *name;
|
||||
} spvc_entry_point;
|
||||
|
||||
/* See C++ API. */
|
||||
typedef struct spvc_combined_image_sampler
|
||||
{
|
||||
spvc_variable_id combined_id;
|
||||
spvc_variable_id image_id;
|
||||
spvc_variable_id sampler_id;
|
||||
} spvc_combined_image_sampler;
|
||||
|
||||
/* See C++ API. */
|
||||
typedef struct spvc_specialization_constant
|
||||
{
|
||||
spvc_constant_id id;
|
||||
unsigned constant_id;
|
||||
} spvc_specialization_constant;
|
||||
|
||||
/* See C++ API. */
|
||||
typedef struct spvc_hlsl_root_constants
|
||||
{
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
unsigned binding;
|
||||
unsigned space;
|
||||
} spvc_hlsl_root_constants;
|
||||
|
||||
/* See C++ API. */
|
||||
typedef struct spvc_hlsl_vertex_attribute_remap
|
||||
{
|
||||
unsigned location;
|
||||
const char *semantic;
|
||||
} spvc_hlsl_vertex_attribute_remap;
|
||||
|
||||
/*
|
||||
* Be compatible with non-C99 compilers, which do not have stdbool.
|
||||
* Only recent MSVC compilers supports this for example, and ideally SPIRV-Cross should be linkable
|
||||
* from a wide range of compilers in its C wrapper.
|
||||
*/
|
||||
typedef unsigned char spvc_bool;
|
||||
#define SPVC_TRUE ((spvc_bool)1)
|
||||
#define SPVC_FALSE ((spvc_bool)0)
|
||||
|
||||
typedef enum spvc_result
|
||||
{
|
||||
/* Success. */
|
||||
SPVC_SUCCESS = 0,
|
||||
|
||||
/* The SPIR-V is invalid. Should have been caught by validation ideally. */
|
||||
SPVC_ERROR_INVALID_SPIRV = -1,
|
||||
|
||||
/* The SPIR-V might be valid or invalid, but SPIRV-Cross currently cannot correctly translate this to your target language. */
|
||||
SPVC_ERROR_UNSUPPORTED_SPIRV = -2,
|
||||
|
||||
/* If for some reason we hit this, new or malloc failed. */
|
||||
SPVC_ERROR_OUT_OF_MEMORY = -3,
|
||||
|
||||
/* Invalid API argument. */
|
||||
SPVC_ERROR_INVALID_ARGUMENT = -4,
|
||||
|
||||
SPVC_ERROR_INT_MAX = 0x7fffffff
|
||||
} spvc_result;
|
||||
|
||||
typedef enum spvc_capture_mode
|
||||
{
|
||||
/* The Parsed IR payload will be copied, and the handle can be reused to create other compiler instances. */
|
||||
SPVC_CAPTURE_MODE_COPY = 0,
|
||||
|
||||
/*
|
||||
* The payload will now be owned by the compiler.
|
||||
* parsed_ir should now be considered a dead blob and must not be used further.
|
||||
* This is optimal for performance and should be the go-to option.
|
||||
*/
|
||||
SPVC_CAPTURE_MODE_TAKE_OWNERSHIP = 1,
|
||||
|
||||
SPVC_CAPTURE_MODE_INT_MAX = 0x7fffffff
|
||||
} spvc_capture_mode;
|
||||
|
||||
typedef enum spvc_backend
|
||||
{
|
||||
/* This backend can only perform reflection, no compiler options are supported. Maps to spirv_cross::Compiler. */
|
||||
SPVC_BACKEND_NONE = 0,
|
||||
SPVC_BACKEND_GLSL = 1, /* spirv_cross::CompilerGLSL */
|
||||
SPVC_BACKEND_HLSL = 2, /* CompilerHLSL */
|
||||
SPVC_BACKEND_MSL = 3, /* CompilerMSL */
|
||||
SPVC_BACKEND_CPP = 4, /* CompilerCPP */
|
||||
SPVC_BACKEND_JSON = 5, /* CompilerReflection w/ JSON backend */
|
||||
SPVC_BACKEND_INT_MAX = 0x7fffffff
|
||||
} spvc_backend;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_resource_type
|
||||
{
|
||||
SPVC_RESOURCE_TYPE_UNKNOWN = 0,
|
||||
SPVC_RESOURCE_TYPE_UNIFORM_BUFFER = 1,
|
||||
SPVC_RESOURCE_TYPE_STORAGE_BUFFER = 2,
|
||||
SPVC_RESOURCE_TYPE_STAGE_INPUT = 3,
|
||||
SPVC_RESOURCE_TYPE_STAGE_OUTPUT = 4,
|
||||
SPVC_RESOURCE_TYPE_SUBPASS_INPUT = 5,
|
||||
SPVC_RESOURCE_TYPE_STORAGE_IMAGE = 6,
|
||||
SPVC_RESOURCE_TYPE_SAMPLED_IMAGE = 7,
|
||||
SPVC_RESOURCE_TYPE_ATOMIC_COUNTER = 8,
|
||||
SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9,
|
||||
SPVC_RESOURCE_TYPE_SEPARATE_IMAGE = 10,
|
||||
SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS = 11,
|
||||
SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff
|
||||
} spvc_resource_type;
|
||||
|
||||
/* Maps to spirv_cross::SPIRType::BaseType. */
|
||||
typedef enum spvc_basetype
|
||||
{
|
||||
SPVC_BASETYPE_UNKNOWN = 0,
|
||||
SPVC_BASETYPE_VOID = 1,
|
||||
SPVC_BASETYPE_BOOLEAN = 2,
|
||||
SPVC_BASETYPE_INT8 = 3,
|
||||
SPVC_BASETYPE_UINT8 = 4,
|
||||
SPVC_BASETYPE_INT16 = 5,
|
||||
SPVC_BASETYPE_UINT16 = 6,
|
||||
SPVC_BASETYPE_INT32 = 7,
|
||||
SPVC_BASETYPE_UINT32 = 8,
|
||||
SPVC_BASETYPE_INT64 = 9,
|
||||
SPVC_BASETYPE_UINT64 = 10,
|
||||
SPVC_BASETYPE_ATOMIC_COUNTER = 11,
|
||||
SPVC_BASETYPE_FP16 = 12,
|
||||
SPVC_BASETYPE_FP32 = 13,
|
||||
SPVC_BASETYPE_FP64 = 14,
|
||||
SPVC_BASETYPE_STRUCT = 15,
|
||||
SPVC_BASETYPE_IMAGE = 16,
|
||||
SPVC_BASETYPE_SAMPLED_IMAGE = 17,
|
||||
SPVC_BASETYPE_SAMPLER = 18,
|
||||
|
||||
SPVC_BASETYPE_INT_MAX = 0x7fffffff
|
||||
} spvc_basetype;
|
||||
|
||||
#define SPVC_COMPILER_OPTION_COMMON_BIT 0x1000000
|
||||
#define SPVC_COMPILER_OPTION_GLSL_BIT 0x2000000
|
||||
#define SPVC_COMPILER_OPTION_HLSL_BIT 0x4000000
|
||||
#define SPVC_COMPILER_OPTION_MSL_BIT 0x8000000
|
||||
#define SPVC_COMPILER_OPTION_LANG_BITS 0x0f000000
|
||||
#define SPVC_COMPILER_OPTION_ENUM_BITS 0xffffff
|
||||
|
||||
#define SPVC_MAKE_MSL_VERSION(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch))
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_platform
|
||||
{
|
||||
SPVC_MSL_PLATFORM_IOS = 0,
|
||||
SPVC_MSL_PLATFORM_MACOS = 1,
|
||||
SPVC_MSL_PLATFORM_MAX_INT = 0x7fffffff
|
||||
} spvc_msl_platform;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_vertex_format
|
||||
{
|
||||
SPVC_MSL_VERTEX_FORMAT_OTHER = 0,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT8 = 1,
|
||||
SPVC_MSL_VERTEX_FORMAT_UINT16 = 2
|
||||
} spvc_msl_vertex_format;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_vertex_attribute
|
||||
{
|
||||
unsigned location;
|
||||
unsigned msl_buffer;
|
||||
unsigned msl_offset;
|
||||
unsigned msl_stride;
|
||||
spvc_bool per_instance;
|
||||
spvc_msl_vertex_format format;
|
||||
SpvBuiltIn builtin;
|
||||
} spvc_msl_vertex_attribute;
|
||||
|
||||
/*
|
||||
* Initializes the vertex attribute struct.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_resource_binding
|
||||
{
|
||||
SpvExecutionModel stage;
|
||||
unsigned desc_set;
|
||||
unsigned binding;
|
||||
unsigned msl_buffer;
|
||||
unsigned msl_texture;
|
||||
unsigned msl_sampler;
|
||||
} spvc_msl_resource_binding;
|
||||
|
||||
/*
|
||||
* Initializes the resource binding struct.
|
||||
* The defaults are non-zero.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_resource_binding_init(spvc_msl_resource_binding *binding);
|
||||
|
||||
#define SPVC_MSL_PUSH_CONSTANT_DESC_SET (~(0u))
|
||||
#define SPVC_MSL_PUSH_CONSTANT_BINDING (0)
|
||||
#define SPVC_MSL_AUX_BUFFER_STRUCT_VERSION 1
|
||||
|
||||
/* Runtime check for incompatibility. */
|
||||
SPVC_PUBLIC_API unsigned spvc_msl_get_aux_buffer_struct_version(void);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_coord
|
||||
{
|
||||
SPVC_MSL_SAMPLER_COORD_NORMALIZED = 0,
|
||||
SPVC_MSL_SAMPLER_COORD_PIXEL = 1,
|
||||
SPVC_MSL_SAMPLER_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_coord;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_filter
|
||||
{
|
||||
SPVC_MSL_SAMPLER_FILTER_NEAREST = 0,
|
||||
SPVC_MSL_SAMPLER_FILTER_LINEAR = 1,
|
||||
SPVC_MSL_SAMPLER_FILTER_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_filter;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_mip_filter
|
||||
{
|
||||
SPVC_MSL_SAMPLER_MIP_FILTER_NONE = 0,
|
||||
SPVC_MSL_SAMPLER_MIP_FILTER_NEAREST = 1,
|
||||
SPVC_MSL_SAMPLER_MIP_FILTER_LINEAR = 2,
|
||||
SPVC_MSL_SAMPLER_MIP_FILTER_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_mip_filter;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_address
|
||||
{
|
||||
SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_ZERO = 0,
|
||||
SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE = 1,
|
||||
SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_BORDER = 2,
|
||||
SPVC_MSL_SAMPLER_ADDRESS_REPEAT = 3,
|
||||
SPVC_MSL_SAMPLER_ADDRESS_MIRRORED_REPEAT = 4,
|
||||
SPVC_MSL_SAMPLER_ADDRESS_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_address;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_compare_func
|
||||
{
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_NEVER = 0,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_LESS = 1,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_LESS_EQUAL = 2,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_GREATER = 3,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_GREATER_EQUAL = 4,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_EQUAL = 5,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_NOT_EQUAL = 6,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_ALWAYS = 7,
|
||||
SPVC_MSL_SAMPLER_COMPARE_FUNC_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_compare_func;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_sampler_border_color
|
||||
{
|
||||
SPVC_MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK = 0,
|
||||
SPVC_MSL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK = 1,
|
||||
SPVC_MSL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE = 2,
|
||||
SPVC_MSL_SAMPLER_BORDER_COLOR_INT_MAX = 0x7fffffff
|
||||
} spvc_msl_sampler_border_color;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_constexpr_sampler
|
||||
{
|
||||
spvc_msl_sampler_coord coord;
|
||||
spvc_msl_sampler_filter min_filter;
|
||||
spvc_msl_sampler_filter mag_filter;
|
||||
spvc_msl_sampler_mip_filter mip_filter;
|
||||
spvc_msl_sampler_address s_address;
|
||||
spvc_msl_sampler_address t_address;
|
||||
spvc_msl_sampler_address r_address;
|
||||
spvc_msl_sampler_compare_func compare_func;
|
||||
spvc_msl_sampler_border_color border_color;
|
||||
float lod_clamp_min;
|
||||
float lod_clamp_max;
|
||||
int max_anisotropy;
|
||||
|
||||
spvc_bool compare_enable;
|
||||
spvc_bool lod_clamp_enable;
|
||||
spvc_bool anisotropy_enable;
|
||||
} spvc_msl_constexpr_sampler;
|
||||
|
||||
/*
|
||||
* Initializes the constexpr sampler struct.
|
||||
* The defaults are non-zero.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler *sampler);
|
||||
|
||||
/* Maps to the various spirv_cross::Compiler*::Option structures. See C++ API for defaults and details. */
|
||||
typedef enum spvc_compiler_option
|
||||
{
|
||||
SPVC_COMPILER_OPTION_UNKNOWN = 0,
|
||||
|
||||
SPVC_COMPILER_OPTION_FORCE_TEMPORARY = 1 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
SPVC_COMPILER_OPTION_FLATTEN_MULTIDIMENSIONAL_ARRAYS = 2 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
SPVC_COMPILER_OPTION_FIXUP_DEPTH_CONVENTION = 3 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
SPVC_COMPILER_OPTION_FLIP_VERTEX_Y = 4 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_SUPPORT_NONZERO_BASE_INSTANCE = 5 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_SEPARATE_SHADER_OBJECTS = 6 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION = 7 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_VERSION = 8 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_ES = 9 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS = 10 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_FLOAT_PRECISION_HIGHP = 11 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_INT_PRECISION_HIGHP = 12 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL = 13 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT = 14 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_HLSL_POINT_COORD_COMPAT = 15 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
SPVC_COMPILER_OPTION_HLSL_SUPPORT_NONZERO_BASE_VERTEX_BASE_INSTANCE = 16 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_VERSION = 17 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_TEXEL_BUFFER_TEXTURE_WIDTH = 18 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_AUX_BUFFER_INDEX = 19 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_INDIRECT_PARAMS_BUFFER_INDEX = 20 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_OUTPUT_BUFFER_INDEX = 21 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_OUTPUT_BUFFER_INDEX = 22 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_TESS_FACTOR_OUTPUT_BUFFER_INDEX = 23 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_WORKGROUP_INDEX = 24 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_ENABLE_POINT_SIZE_BUILTIN = 25 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_DISABLE_RASTERIZATION = 26 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_CAPTURE_OUTPUT_TO_BUFFER = 27 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SWIZZLE_TEXTURE_SAMPLES = 28 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_PAD_FRAGMENT_OUTPUT_COMPONENTS = 29 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_TESS_DOMAIN_ORIGIN_LOWER_LEFT = 30 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_PLATFORM = 31 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
/*
|
||||
* Context is the highest-level API construct.
|
||||
* The context owns all memory allocations made by its child object hierarchy, including various non-opaque structs and strings.
|
||||
* This means that the API user only has to care about one "destroy" call ever when using the C API.
|
||||
* All pointers handed out by the APIs are only valid as long as the context
|
||||
* is alive and spvc_context_release_allocations has not been called.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_context_create(spvc_context *context);
|
||||
|
||||
/* Frees all memory allocations and objects associated with the context and its child objects. */
|
||||
SPVC_PUBLIC_API void spvc_context_destroy(spvc_context context);
|
||||
|
||||
/* Frees all memory allocations and objects associated with the context and its child objects, but keeps the context alive. */
|
||||
SPVC_PUBLIC_API void spvc_context_release_allocations(spvc_context context);
|
||||
|
||||
/* Get the string for the last error which was logged. */
|
||||
SPVC_PUBLIC_API const char *spvc_context_get_last_error_string(spvc_context context);
|
||||
|
||||
/* Get notified in a callback when an error triggers. Useful for debugging. */
|
||||
typedef void (*spvc_error_callback)(void *userdata, const char *error);
|
||||
SPVC_PUBLIC_API void spvc_context_set_error_callback(spvc_context context, spvc_error_callback cb, void *userdata);
|
||||
|
||||
/* SPIR-V parsing interface. Maps to Parser which then creates a ParsedIR, and that IR is extracted into the handle. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_context_parse_spirv(spvc_context context, const SpvId *spirv, size_t word_count,
|
||||
spvc_parsed_ir *parsed_ir);
|
||||
|
||||
/*
|
||||
* Create a compiler backend. Capture mode controls if we construct by copy or move semantics.
|
||||
* It is always recommended to use SPVC_CAPTURE_MODE_TAKE_OWNERSHIP if you only intend to cross-compile the IR once.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend backend,
|
||||
spvc_parsed_ir parsed_ir, spvc_capture_mode mode,
|
||||
spvc_compiler *compiler);
|
||||
|
||||
/* Maps directly to C++ API. */
|
||||
SPVC_PUBLIC_API unsigned spvc_compiler_get_current_id_bound(spvc_compiler compiler);
|
||||
|
||||
/* Create compiler options, which will initialize defaults. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_create_compiler_options(spvc_compiler compiler,
|
||||
spvc_compiler_options *options);
|
||||
/* Override options. Will return error if e.g. MSL options are used for the HLSL backend, etc. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_options_set_bool(spvc_compiler_options options,
|
||||
spvc_compiler_option option, spvc_bool value);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options,
|
||||
spvc_compiler_option option, unsigned value);
|
||||
/* Set compiler options. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_install_compiler_options(spvc_compiler compiler,
|
||||
spvc_compiler_options options);
|
||||
|
||||
/* Compile IR into a string. *source is owned by the context, and caller must not free it themselves. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_compile(spvc_compiler compiler, const char **source);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_add_header_line(spvc_compiler compiler, const char *line);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *ext);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id);
|
||||
|
||||
/*
|
||||
* HLSL specifics.
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_set_root_constants_layout(spvc_compiler compiler,
|
||||
const spvc_hlsl_root_constants *constant_info,
|
||||
size_t count);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_compiler compiler,
|
||||
const spvc_hlsl_vertex_attribute_remap *remap,
|
||||
size_t remaps);
|
||||
SPVC_PUBLIC_API spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler);
|
||||
|
||||
/*
|
||||
* MSL specifics.
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_patch_output_buffer(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_input_threadgroup_mem(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler,
|
||||
const spvc_msl_vertex_attribute *attrs);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,
|
||||
const spvc_msl_resource_binding *binding);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler,
|
||||
SpvExecutionModel model,
|
||||
unsigned set,
|
||||
unsigned binding);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location, unsigned components);
|
||||
|
||||
/*
|
||||
* Reflect resources.
|
||||
* Maps almost 1:1 to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_active_interface_variables(spvc_compiler compiler, spvc_set *set);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_set_enabled_interface_variables(spvc_compiler compiler, spvc_set set);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_create_shader_resources(spvc_compiler compiler, spvc_resources *resources);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_create_shader_resources_for_active_variables(spvc_compiler compiler,
|
||||
spvc_resources *resources,
|
||||
spvc_set active);
|
||||
SPVC_PUBLIC_API spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources, spvc_resource_type type,
|
||||
const spvc_reflected_resource **resource_list,
|
||||
size_t *resource_size);
|
||||
|
||||
/*
|
||||
* Decorations.
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration,
|
||||
unsigned argument);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_decoration_string(spvc_compiler compiler, SpvId id, SpvDecoration decoration,
|
||||
const char *argument);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_name(spvc_compiler compiler, SpvId id, const char *argument);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
|
||||
SpvDecoration decoration, unsigned argument);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_member_decoration_string(spvc_compiler compiler, spvc_type_id id,
|
||||
unsigned member_index, SpvDecoration decoration,
|
||||
const char *argument);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index,
|
||||
const char *argument);
|
||||
SPVC_PUBLIC_API void spvc_compiler_unset_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration);
|
||||
SPVC_PUBLIC_API void spvc_compiler_unset_member_decoration(spvc_compiler compiler, spvc_type_id id,
|
||||
unsigned member_index, SpvDecoration decoration);
|
||||
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_has_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_has_member_decoration(spvc_compiler compiler, spvc_type_id id,
|
||||
unsigned member_index, SpvDecoration decoration);
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_get_name(spvc_compiler compiler, SpvId id);
|
||||
SPVC_PUBLIC_API unsigned spvc_compiler_get_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration);
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_get_decoration_string(spvc_compiler compiler, SpvId id,
|
||||
SpvDecoration decoration);
|
||||
SPVC_PUBLIC_API unsigned spvc_compiler_get_member_decoration(spvc_compiler compiler, spvc_type_id id,
|
||||
unsigned member_index, SpvDecoration decoration);
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_get_member_decoration_string(spvc_compiler compiler, spvc_type_id id,
|
||||
unsigned member_index, SpvDecoration decoration);
|
||||
|
||||
/*
|
||||
* Entry points.
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_entry_points(spvc_compiler compiler,
|
||||
const spvc_entry_point **entry_points,
|
||||
size_t *num_entry_points);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_set_entry_point(spvc_compiler compiler, const char *name,
|
||||
SpvExecutionModel model);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_rename_entry_point(spvc_compiler compiler, const char *old_name,
|
||||
const char *new_name, SpvExecutionModel model);
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_get_cleansed_entry_point_name(spvc_compiler compiler, const char *name,
|
||||
SpvExecutionModel model);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_execution_mode(spvc_compiler compiler, SpvExecutionMode mode);
|
||||
SPVC_PUBLIC_API void spvc_compiler_unset_execution_mode(spvc_compiler compiler, SpvExecutionMode mode);
|
||||
SPVC_PUBLIC_API void spvc_compiler_set_execution_mode_with_arguments(spvc_compiler compiler, SpvExecutionMode mode,
|
||||
unsigned arg0, unsigned arg1, unsigned arg2);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_execution_modes(spvc_compiler compiler, const SpvExecutionMode **modes,
|
||||
size_t *num_modes);
|
||||
SPVC_PUBLIC_API unsigned spvc_compiler_get_execution_mode_argument(spvc_compiler compiler, SpvExecutionMode mode);
|
||||
SPVC_PUBLIC_API unsigned spvc_compiler_get_execution_mode_argument_by_index(spvc_compiler compiler,
|
||||
SpvExecutionMode mode, unsigned index);
|
||||
SPVC_PUBLIC_API SpvExecutionModel spvc_compiler_get_execution_model(spvc_compiler compiler);
|
||||
|
||||
/*
|
||||
* Type query interface.
|
||||
* Maps to C++ API, except it's read-only.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_type spvc_compiler_get_type_handle(spvc_compiler compiler, spvc_type_id id);
|
||||
|
||||
SPVC_PUBLIC_API spvc_basetype spvc_type_get_basetype(spvc_type type);
|
||||
SPVC_PUBLIC_API unsigned spvc_type_get_bit_width(spvc_type type);
|
||||
SPVC_PUBLIC_API unsigned spvc_type_get_vector_size(spvc_type type);
|
||||
SPVC_PUBLIC_API unsigned spvc_type_get_columns(spvc_type type);
|
||||
SPVC_PUBLIC_API unsigned spvc_type_get_num_array_dimensions(spvc_type type);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_type_array_dimension_is_literal(spvc_type type, unsigned dimension);
|
||||
SPVC_PUBLIC_API SpvId spvc_type_get_array_dimension(spvc_type type, unsigned dimension);
|
||||
SPVC_PUBLIC_API unsigned spvc_type_get_num_member_types(spvc_type type);
|
||||
SPVC_PUBLIC_API spvc_type_id spvc_type_get_member_type(spvc_type type, unsigned index);
|
||||
SPVC_PUBLIC_API SpvStorageClass spvc_type_get_storage_class(spvc_type type);
|
||||
|
||||
/* Image type query. */
|
||||
SPVC_PUBLIC_API spvc_type_id spvc_type_get_image_sampled_type(spvc_type type);
|
||||
SPVC_PUBLIC_API SpvDim spvc_type_get_image_dimension(spvc_type type);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_type_get_image_is_depth(spvc_type type);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_type_get_image_arrayed(spvc_type type);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_type_get_image_multisampled(spvc_type type);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_type_get_image_is_storage(spvc_type type);
|
||||
SPVC_PUBLIC_API SpvImageFormat spvc_type_get_image_storage_format(spvc_type type);
|
||||
SPVC_PUBLIC_API SpvAccessQualifier spvc_type_get_image_access_qualifier(spvc_type type);
|
||||
|
||||
/*
|
||||
* Buffer layout query.
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_struct_size(spvc_compiler compiler, spvc_type struct_type, size_t *size);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_struct_size_runtime_array(spvc_compiler compiler,
|
||||
spvc_type struct_type, size_t array_size, size_t *size);
|
||||
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_type_struct_member_offset(spvc_compiler compiler,
|
||||
spvc_type type, unsigned index, unsigned *offset);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_type_struct_member_array_stride(spvc_compiler compiler,
|
||||
spvc_type type, unsigned index, unsigned *stride);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_type_struct_member_matrix_stride(spvc_compiler compiler,
|
||||
spvc_type type, unsigned index, unsigned *stride);
|
||||
|
||||
/*
|
||||
* Workaround helper functions.
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_build_dummy_sampler_for_combined_images(spvc_compiler compiler, spvc_variable_id *id);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_build_combined_image_samplers(spvc_compiler compiler);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_combined_image_samplers(spvc_compiler compiler,
|
||||
const spvc_combined_image_sampler **samplers,
|
||||
size_t *num_samplers);
|
||||
|
||||
/*
|
||||
* Constants
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_specialization_constants(spvc_compiler compiler,
|
||||
const spvc_specialization_constant **constants,
|
||||
size_t *num_constants);
|
||||
SPVC_PUBLIC_API spvc_constant spvc_compiler_get_constant_handle(spvc_compiler compiler,
|
||||
spvc_constant_id id);
|
||||
|
||||
SPVC_PUBLIC_API spvc_constant_id spvc_compiler_get_work_group_size_specialization_constants(spvc_compiler compiler,
|
||||
spvc_specialization_constant *x,
|
||||
spvc_specialization_constant *y,
|
||||
spvc_specialization_constant *z);
|
||||
|
||||
/*
|
||||
* No stdint.h until C99, sigh :(
|
||||
* For smaller types, the result is sign or zero-extended as appropriate.
|
||||
* Maps to C++ API.
|
||||
* TODO: The SPIRConstant query interface and modification interface is not quite complete.
|
||||
*/
|
||||
SPVC_PUBLIC_API float spvc_constant_get_scalar_fp16(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API float spvc_constant_get_scalar_fp32(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API double spvc_constant_get_scalar_fp64(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API unsigned spvc_constant_get_scalar_u32(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API int spvc_constant_get_scalar_i32(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API unsigned spvc_constant_get_scalar_u16(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API int spvc_constant_get_scalar_i16(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API unsigned spvc_constant_get_scalar_u8(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned column, unsigned row);
|
||||
SPVC_PUBLIC_API void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count);
|
||||
SPVC_PUBLIC_API spvc_type_id spvc_constant_get_type(spvc_constant constant);
|
||||
|
||||
/*
|
||||
* Misc reflection
|
||||
* Maps to C++ API.
|
||||
*/
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler,
|
||||
spvc_variable_id id,
|
||||
SpvDecoration decoration,
|
||||
unsigned *word_offset);
|
||||
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_buffer_is_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id);
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_buffer_get_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id,
|
||||
spvc_variable_id *counter_id);
|
||||
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_capabilities(spvc_compiler compiler,
|
||||
const SpvCapability **capabilities,
|
||||
size_t *num_capabilities);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_extensions(spvc_compiler compiler, const char ***extensions,
|
||||
size_t *num_extensions);
|
||||
|
||||
SPVC_PUBLIC_API const char *spvc_compiler_get_remapped_declared_block_name(spvc_compiler compiler, spvc_variable_id id);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_get_buffer_block_decorations(spvc_compiler compiler, spvc_variable_id id,
|
||||
const SpvDecoration **decorations,
|
||||
size_t *num_decorations);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -10205,7 +10205,7 @@ void CompilerGLSL::propagate_loop_dominators(const SPIRBlock &block)
|
|||
// FIXME: This currently cannot handle complex continue blocks
|
||||
// as in do-while.
|
||||
// This should be seen as a "trivial" continue block.
|
||||
string CompilerGLSL::emit_continue_block(uint32_t continue_block)
|
||||
string CompilerGLSL::emit_continue_block(uint32_t continue_block, bool follow_true_block, bool follow_false_block)
|
||||
{
|
||||
auto *block = &get<SPIRBlock>(continue_block);
|
||||
|
||||
|
@ -10233,11 +10233,20 @@ string CompilerGLSL::emit_continue_block(uint32_t continue_block)
|
|||
block = &get<SPIRBlock>(block->next_block);
|
||||
}
|
||||
// For do while blocks. The last block will be a select block.
|
||||
else if (block->true_block)
|
||||
else if (block->true_block && follow_true_block)
|
||||
{
|
||||
flush_phi(continue_block, block->true_block);
|
||||
block = &get<SPIRBlock>(block->true_block);
|
||||
}
|
||||
else if (block->false_block && follow_false_block)
|
||||
{
|
||||
flush_phi(continue_block, block->false_block);
|
||||
block = &get<SPIRBlock>(block->false_block);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW("Invalid continue block detected!");
|
||||
}
|
||||
}
|
||||
|
||||
// Restore old pointer.
|
||||
|
@ -10392,10 +10401,15 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
|
|||
// emitting the continue block can invalidate the condition expression.
|
||||
auto initializer = emit_for_loop_initializers(block);
|
||||
auto condition = to_expression(block.condition);
|
||||
|
||||
// Condition might have to be inverted.
|
||||
if (execution_is_noop(get<SPIRBlock>(block.true_block), get<SPIRBlock>(block.merge_block)))
|
||||
condition = join("!", enclose_expression(condition));
|
||||
|
||||
emit_block_hints(block);
|
||||
if (method != SPIRBlock::MergeToSelectContinueForLoop)
|
||||
{
|
||||
auto continue_block = emit_continue_block(block.continue_block);
|
||||
auto continue_block = emit_continue_block(block.continue_block, false, false);
|
||||
statement("for (", initializer, "; ", condition, "; ", continue_block, ")");
|
||||
}
|
||||
else
|
||||
|
@ -10404,12 +10418,20 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
|
|||
}
|
||||
|
||||
case SPIRBlock::WhileLoop:
|
||||
{
|
||||
// This block may be a dominating block, so make sure we flush undeclared variables before building the while loop header.
|
||||
flush_undeclared_variables(block);
|
||||
emit_while_loop_initializers(block);
|
||||
emit_block_hints(block);
|
||||
statement("while (", to_expression(block.condition), ")");
|
||||
|
||||
auto condition = to_expression(block.condition);
|
||||
// Condition might have to be inverted.
|
||||
if (execution_is_noop(get<SPIRBlock>(block.true_block), get<SPIRBlock>(block.merge_block)))
|
||||
condition = join("!", enclose_expression(condition));
|
||||
|
||||
statement("while (", condition, ")");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
|
||||
|
@ -10445,6 +10467,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
|
|||
if (current_count == statement_count && condition_is_temporary)
|
||||
{
|
||||
propagate_loop_dominators(child);
|
||||
uint32_t target_block = child.true_block;
|
||||
|
||||
switch (continue_type)
|
||||
{
|
||||
|
@ -10454,24 +10477,43 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
|
|||
// emitting the continue block can invalidate the condition expression.
|
||||
auto initializer = emit_for_loop_initializers(block);
|
||||
auto condition = to_expression(child.condition);
|
||||
auto continue_block = emit_continue_block(block.continue_block);
|
||||
|
||||
// Condition might have to be inverted.
|
||||
if (execution_is_noop(get<SPIRBlock>(child.true_block), get<SPIRBlock>(block.merge_block)))
|
||||
{
|
||||
condition = join("!", enclose_expression(condition));
|
||||
target_block = child.false_block;
|
||||
}
|
||||
|
||||
auto continue_block = emit_continue_block(block.continue_block, false, false);
|
||||
emit_block_hints(block);
|
||||
statement("for (", initializer, "; ", condition, "; ", continue_block, ")");
|
||||
break;
|
||||
}
|
||||
|
||||
case SPIRBlock::WhileLoop:
|
||||
{
|
||||
emit_while_loop_initializers(block);
|
||||
emit_block_hints(block);
|
||||
statement("while (", to_expression(child.condition), ")");
|
||||
|
||||
auto condition = to_expression(child.condition);
|
||||
// Condition might have to be inverted.
|
||||
if (execution_is_noop(get<SPIRBlock>(child.true_block), get<SPIRBlock>(block.merge_block)))
|
||||
{
|
||||
condition = join("!", enclose_expression(condition));
|
||||
target_block = child.false_block;
|
||||
}
|
||||
|
||||
statement("while (", condition, ")");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
|
||||
}
|
||||
|
||||
begin_scope();
|
||||
branch(child.self, child.true_block);
|
||||
branch(child.self, target_block);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -10521,8 +10563,9 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
propagate_loop_dominators(block);
|
||||
|
||||
bool select_branch_to_true_block = false;
|
||||
bool select_branch_to_false_block = false;
|
||||
bool skip_direct_branch = false;
|
||||
bool emitted_for_loop_header = false;
|
||||
bool emitted_loop_header_variables = false;
|
||||
bool force_complex_continue_block = false;
|
||||
|
||||
emit_hoisted_temporaries(block.declare_temporary);
|
||||
|
@ -10544,8 +10587,12 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
flush_undeclared_variables(block);
|
||||
if (attempt_emit_loop_header(block, SPIRBlock::MergeToSelectContinueForLoop))
|
||||
{
|
||||
select_branch_to_true_block = true;
|
||||
emitted_for_loop_header = true;
|
||||
if (execution_is_noop(get<SPIRBlock>(block.true_block), get<SPIRBlock>(block.merge_block)))
|
||||
select_branch_to_false_block = true;
|
||||
else
|
||||
select_branch_to_true_block = true;
|
||||
|
||||
emitted_loop_header_variables = true;
|
||||
force_complex_continue_block = true;
|
||||
}
|
||||
}
|
||||
|
@ -10555,9 +10602,13 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
flush_undeclared_variables(block);
|
||||
if (attempt_emit_loop_header(block, SPIRBlock::MergeToSelectForLoop))
|
||||
{
|
||||
// The body of while, is actually just the true block, so always branch there unconditionally.
|
||||
select_branch_to_true_block = true;
|
||||
emitted_for_loop_header = true;
|
||||
// The body of while, is actually just the true (or false) block, so always branch there unconditionally.
|
||||
if (execution_is_noop(get<SPIRBlock>(block.true_block), get<SPIRBlock>(block.merge_block)))
|
||||
select_branch_to_false_block = true;
|
||||
else
|
||||
select_branch_to_true_block = true;
|
||||
|
||||
emitted_loop_header_variables = true;
|
||||
}
|
||||
}
|
||||
// This is the newer loop behavior in glslang which branches from Loop header directly to
|
||||
|
@ -10568,13 +10619,14 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
if (attempt_emit_loop_header(block, SPIRBlock::MergeToDirectForLoop))
|
||||
{
|
||||
skip_direct_branch = true;
|
||||
emitted_for_loop_header = true;
|
||||
emitted_loop_header_variables = true;
|
||||
}
|
||||
}
|
||||
else if (continue_type == SPIRBlock::DoWhileLoop)
|
||||
{
|
||||
flush_undeclared_variables(block);
|
||||
emit_while_loop_initializers(block);
|
||||
emitted_loop_header_variables = true;
|
||||
// We have some temporaries where the loop header is the dominator.
|
||||
// We risk a case where we have code like:
|
||||
// for (;;) { create-temporary; break; } consume-temporary;
|
||||
|
@ -10589,6 +10641,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
{
|
||||
flush_undeclared_variables(block);
|
||||
emit_while_loop_initializers(block);
|
||||
emitted_loop_header_variables = true;
|
||||
|
||||
// We have a generic loop without any distinguishable pattern like for, while or do while.
|
||||
get<SPIRBlock>(block.continue_block).complex_continue = true;
|
||||
|
@ -10611,7 +10664,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
|
||||
// If we didn't successfully emit a loop header and we had loop variable candidates, we have a problem
|
||||
// as writes to said loop variables might have been masked out, we need a recompile.
|
||||
if (!emitted_for_loop_header && !block.loop_variables.empty())
|
||||
if (!emitted_loop_header_variables && !block.loop_variables.empty())
|
||||
{
|
||||
force_recompile = true;
|
||||
for (auto var : block.loop_variables)
|
||||
|
@ -10660,6 +10713,22 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
else
|
||||
branch(block.self, block.true_block);
|
||||
}
|
||||
else if (select_branch_to_false_block)
|
||||
{
|
||||
if (force_complex_continue_block)
|
||||
{
|
||||
assert(block.false_block == block.continue_block);
|
||||
|
||||
// We're going to emit a continue block directly here, so make sure it's marked as complex.
|
||||
auto &complex_continue = get<SPIRBlock>(block.continue_block).complex_continue;
|
||||
bool old_complex = complex_continue;
|
||||
complex_continue = true;
|
||||
branch(block.self, block.false_block);
|
||||
complex_continue = old_complex;
|
||||
}
|
||||
else
|
||||
branch(block.self, block.false_block);
|
||||
}
|
||||
else
|
||||
branch(block.self, block.condition, block.true_block, block.false_block);
|
||||
break;
|
||||
|
@ -10850,7 +10919,11 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
// Make sure that we run the continue block to get the expressions set, but this
|
||||
// should become an empty string.
|
||||
// We have no fallbacks if we cannot forward everything to temporaries ...
|
||||
auto statements = emit_continue_block(block.continue_block);
|
||||
const auto &continue_block = get<SPIRBlock>(block.continue_block);
|
||||
bool positive_test = execution_is_noop(get<SPIRBlock>(continue_block.true_block),
|
||||
get<SPIRBlock>(continue_block.loop_dominator));
|
||||
|
||||
auto statements = emit_continue_block(block.continue_block, positive_test, !positive_test);
|
||||
if (!statements.empty())
|
||||
{
|
||||
// The DoWhile block has side effects, force ComplexLoop pattern next pass.
|
||||
|
@ -10858,7 +10931,12 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||
force_recompile = true;
|
||||
}
|
||||
|
||||
end_scope_decl(join("while (", to_expression(get<SPIRBlock>(block.continue_block).condition), ")"));
|
||||
// Might have to invert the do-while test here.
|
||||
auto condition = to_expression(continue_block.condition);
|
||||
if (!positive_test)
|
||||
condition = join("!", enclose_expression(condition));
|
||||
|
||||
end_scope_decl(join("while (", condition, ")"));
|
||||
}
|
||||
else
|
||||
end_scope();
|
||||
|
|
|
@ -161,27 +161,11 @@ public:
|
|||
init();
|
||||
}
|
||||
|
||||
// Deprecate this interface because it doesn't overload properly with subclasses.
|
||||
// Requires awkward static casting, which was a mistake.
|
||||
SPIRV_CROSS_DEPRECATED("get_options() is obsolete, use get_common_options() instead.")
|
||||
const Options &get_options() const
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
const Options &get_common_options() const
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
// Deprecate this interface because it doesn't overload properly with subclasses.
|
||||
// Requires awkward static casting, which was a mistake.
|
||||
SPIRV_CROSS_DEPRECATED("set_options() is obsolete, use set_common_options() instead.")
|
||||
void set_options(Options &opts)
|
||||
{
|
||||
options = opts;
|
||||
}
|
||||
|
||||
void set_common_options(const Options &opts)
|
||||
{
|
||||
options = opts;
|
||||
|
@ -419,7 +403,7 @@ protected:
|
|||
std::string constant_value_macro_name(uint32_t id);
|
||||
void emit_constant(const SPIRConstant &constant);
|
||||
void emit_specialization_constant_op(const SPIRConstantOp &constant);
|
||||
std::string emit_continue_block(uint32_t continue_block);
|
||||
std::string emit_continue_block(uint32_t continue_block, bool follow_true_block, bool follow_false_block);
|
||||
bool attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method method);
|
||||
void propagate_loop_dominators(const SPIRBlock &block);
|
||||
|
||||
|
|
|
@ -4558,10 +4558,14 @@ void CompilerHLSL::require_texture_query_variant(const SPIRType &type)
|
|||
}
|
||||
}
|
||||
|
||||
string CompilerHLSL::compile(std::vector<HLSLVertexAttributeRemap> vertex_attributes)
|
||||
void CompilerHLSL::set_root_constant_layouts(vector<RootConstants> layout)
|
||||
{
|
||||
remap_vertex_attributes = move(vertex_attributes);
|
||||
return compile();
|
||||
root_constants_layout = move(layout);
|
||||
}
|
||||
|
||||
void CompilerHLSL::add_vertex_attribute_remap(const HLSLVertexAttributeRemap &vertex_attributes)
|
||||
{
|
||||
remap_vertex_attributes.push_back(vertex_attributes);
|
||||
}
|
||||
|
||||
uint32_t CompilerHLSL::remap_num_workgroups_builtin()
|
||||
|
|
|
@ -82,23 +82,11 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
SPIRV_CROSS_DEPRECATED("CompilerHLSL::get_options() is obsolete, use get_hlsl_options() instead.")
|
||||
const Options &get_options() const
|
||||
{
|
||||
return hlsl_options;
|
||||
}
|
||||
|
||||
const Options &get_hlsl_options() const
|
||||
{
|
||||
return hlsl_options;
|
||||
}
|
||||
|
||||
SPIRV_CROSS_DEPRECATED("CompilerHLSL::get_options() is obsolete, use set_hlsl_options() instead.")
|
||||
void set_options(Options &opts)
|
||||
{
|
||||
hlsl_options = opts;
|
||||
}
|
||||
|
||||
void set_hlsl_options(const Options &opts)
|
||||
{
|
||||
hlsl_options = opts;
|
||||
|
@ -108,16 +96,13 @@ public:
|
|||
//
|
||||
// Push constants ranges will be split up according to the
|
||||
// layout specified.
|
||||
void set_root_constant_layouts(std::vector<RootConstants> layout)
|
||||
{
|
||||
root_constants_layout = std::move(layout);
|
||||
}
|
||||
void set_root_constant_layouts(std::vector<RootConstants> layout);
|
||||
|
||||
// Compiles and remaps vertex attributes at specific locations to a fixed semantic.
|
||||
// The default is TEXCOORD# where # denotes location.
|
||||
// Matrices are unrolled to vectors with notation ${SEMANTIC}_#, where # denotes row.
|
||||
// $SEMANTIC is either TEXCOORD# or a semantic name specified here.
|
||||
std::string compile(std::vector<HLSLVertexAttributeRemap> vertex_attributes);
|
||||
void add_vertex_attribute_remap(const HLSLVertexAttributeRemap &vertex_attributes);
|
||||
std::string compile() override;
|
||||
|
||||
// This is a special HLSL workaround for the NumWorkGroups builtin.
|
||||
|
|
|
@ -30,75 +30,51 @@ static const uint32_t k_unknown_component = ~0u;
|
|||
|
||||
static const uint32_t k_aux_mbr_idx_swizzle_const = 0u;
|
||||
|
||||
CompilerMSL::CompilerMSL(vector<uint32_t> spirv_, vector<MSLVertexAttr> *p_vtx_attrs,
|
||||
vector<MSLResourceBinding> *p_res_bindings)
|
||||
CompilerMSL::CompilerMSL(vector<uint32_t> spirv_)
|
||||
: CompilerGLSL(move(spirv_))
|
||||
{
|
||||
if (p_vtx_attrs)
|
||||
for (auto &va : *p_vtx_attrs)
|
||||
{
|
||||
vtx_attrs_by_location[va.location] = &va;
|
||||
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
|
||||
vtx_attrs_by_builtin[va.builtin] = &va;
|
||||
}
|
||||
|
||||
if (p_res_bindings)
|
||||
for (auto &rb : *p_res_bindings)
|
||||
resource_bindings.push_back(&rb);
|
||||
}
|
||||
|
||||
CompilerMSL::CompilerMSL(const uint32_t *ir_, size_t word_count, MSLVertexAttr *p_vtx_attrs, size_t vtx_attrs_count,
|
||||
MSLResourceBinding *p_res_bindings, size_t res_bindings_count)
|
||||
CompilerMSL::CompilerMSL(const uint32_t *ir_, size_t word_count)
|
||||
: CompilerGLSL(ir_, word_count)
|
||||
{
|
||||
if (p_vtx_attrs)
|
||||
for (size_t i = 0; i < vtx_attrs_count; i++)
|
||||
{
|
||||
auto &va = p_vtx_attrs[i];
|
||||
vtx_attrs_by_location[va.location] = &va;
|
||||
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
|
||||
vtx_attrs_by_builtin[va.builtin] = &va;
|
||||
}
|
||||
|
||||
if (p_res_bindings)
|
||||
for (size_t i = 0; i < res_bindings_count; i++)
|
||||
resource_bindings.push_back(&p_res_bindings[i]);
|
||||
}
|
||||
|
||||
CompilerMSL::CompilerMSL(const ParsedIR &ir_, MSLVertexAttr *p_vtx_attrs, size_t vtx_attrs_count,
|
||||
MSLResourceBinding *p_res_bindings, size_t res_bindings_count)
|
||||
CompilerMSL::CompilerMSL(const ParsedIR &ir_)
|
||||
: CompilerGLSL(ir_)
|
||||
{
|
||||
if (p_vtx_attrs)
|
||||
for (size_t i = 0; i < vtx_attrs_count; i++)
|
||||
{
|
||||
auto &va = p_vtx_attrs[i];
|
||||
vtx_attrs_by_location[va.location] = &va;
|
||||
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
|
||||
vtx_attrs_by_builtin[va.builtin] = &va;
|
||||
}
|
||||
|
||||
if (p_res_bindings)
|
||||
for (size_t i = 0; i < res_bindings_count; i++)
|
||||
resource_bindings.push_back(&p_res_bindings[i]);
|
||||
}
|
||||
|
||||
CompilerMSL::CompilerMSL(ParsedIR &&ir_, MSLVertexAttr *p_vtx_attrs, size_t vtx_attrs_count,
|
||||
MSLResourceBinding *p_res_bindings, size_t res_bindings_count)
|
||||
CompilerMSL::CompilerMSL(ParsedIR &&ir_)
|
||||
: CompilerGLSL(std::move(ir_))
|
||||
{
|
||||
if (p_vtx_attrs)
|
||||
for (size_t i = 0; i < vtx_attrs_count; i++)
|
||||
{
|
||||
auto &va = p_vtx_attrs[i];
|
||||
vtx_attrs_by_location[va.location] = &va;
|
||||
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
|
||||
vtx_attrs_by_builtin[va.builtin] = &va;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_res_bindings)
|
||||
for (size_t i = 0; i < res_bindings_count; i++)
|
||||
resource_bindings.push_back(&p_res_bindings[i]);
|
||||
void CompilerMSL::add_msl_vertex_attribute(const MSLVertexAttr &va)
|
||||
{
|
||||
vtx_attrs_by_location[va.location] = va;
|
||||
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
|
||||
vtx_attrs_by_builtin[va.builtin] = va;
|
||||
}
|
||||
|
||||
void CompilerMSL::add_msl_resource_binding(const MSLResourceBinding &binding)
|
||||
{
|
||||
resource_bindings.push_back({ binding, false });
|
||||
}
|
||||
|
||||
bool CompilerMSL::is_msl_vertex_attribute_used(uint32_t location)
|
||||
{
|
||||
return vtx_attrs_in_use.count(location) != 0;
|
||||
}
|
||||
|
||||
bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t desc_set, uint32_t binding)
|
||||
{
|
||||
auto itr = find_if(begin(resource_bindings), end(resource_bindings),
|
||||
[&](const std::pair<MSLResourceBinding, bool> &resource) -> bool {
|
||||
return model == resource.first.stage && desc_set == resource.first.desc_set &&
|
||||
binding == resource.first.binding;
|
||||
});
|
||||
return itr != end(resource_bindings) && itr->second;
|
||||
}
|
||||
|
||||
void CompilerMSL::set_fragment_output_components(uint32_t location, uint32_t components)
|
||||
|
@ -662,7 +638,10 @@ string CompilerMSL::compile()
|
|||
|
||||
reset();
|
||||
|
||||
next_metal_resource_index = MSLResourceBinding(); // Start bindings at zero
|
||||
// Start bindings at zero.
|
||||
next_metal_resource_index_buffer = 0;
|
||||
next_metal_resource_index_texture = 0;
|
||||
next_metal_resource_index_sampler = 0;
|
||||
|
||||
// Move constructor for this type is broken on GCC 4.9 ...
|
||||
buffer = unique_ptr<ostringstream>(new ostringstream());
|
||||
|
@ -679,36 +658,6 @@ string CompilerMSL::compile()
|
|||
return buffer->str();
|
||||
}
|
||||
|
||||
string CompilerMSL::compile(vector<MSLVertexAttr> *p_vtx_attrs, vector<MSLResourceBinding> *p_res_bindings)
|
||||
{
|
||||
if (p_vtx_attrs)
|
||||
{
|
||||
vtx_attrs_by_location.clear();
|
||||
for (auto &va : *p_vtx_attrs)
|
||||
{
|
||||
vtx_attrs_by_location[va.location] = &va;
|
||||
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
|
||||
vtx_attrs_by_builtin[va.builtin] = &va;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_res_bindings)
|
||||
{
|
||||
resource_bindings.clear();
|
||||
for (auto &rb : *p_res_bindings)
|
||||
resource_bindings.push_back(&rb);
|
||||
}
|
||||
|
||||
return compile();
|
||||
}
|
||||
|
||||
string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_vtx_attrs,
|
||||
vector<MSLResourceBinding> *p_res_bindings)
|
||||
{
|
||||
msl_options = msl_cfg;
|
||||
return compile(p_vtx_attrs, p_res_bindings);
|
||||
}
|
||||
|
||||
// Register the need to output any custom functions.
|
||||
void CompilerMSL::preprocess_op_codes()
|
||||
{
|
||||
|
@ -1030,10 +979,8 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
|
|||
// If a vertex attribute exists at the location, it is marked as being used by this shader
|
||||
void CompilerMSL::mark_location_as_used_by_shader(uint32_t location, StorageClass storage)
|
||||
{
|
||||
MSLVertexAttr *p_va;
|
||||
if ((get_execution_model() == ExecutionModelVertex || is_tessellation_shader()) && (storage == StorageClassInput) &&
|
||||
(p_va = vtx_attrs_by_location[location]))
|
||||
p_va->used_by_shader = true;
|
||||
if ((get_execution_model() == ExecutionModelVertex || is_tessellation_shader()) && (storage == StorageClassInput))
|
||||
vtx_attrs_in_use.insert(location);
|
||||
}
|
||||
|
||||
uint32_t CompilerMSL::get_target_components_for_fragment_location(uint32_t location) const
|
||||
|
@ -1141,7 +1088,7 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
|
|||
}
|
||||
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin]->location;
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin].location;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, storage);
|
||||
}
|
||||
|
@ -1268,7 +1215,7 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage
|
|||
}
|
||||
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin]->location + i;
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin].location + i;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, storage);
|
||||
}
|
||||
|
@ -1417,7 +1364,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
|
|||
}
|
||||
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin]->location + i;
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin].location + i;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, storage);
|
||||
}
|
||||
|
@ -1553,7 +1500,10 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor
|
|||
}
|
||||
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin]->location;
|
||||
uint32_t locn = 0;
|
||||
auto builtin_itr = vtx_attrs_by_builtin.find(builtin);
|
||||
if (builtin_itr != end(vtx_attrs_by_builtin))
|
||||
locn = builtin_itr->second.location;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, storage);
|
||||
}
|
||||
|
@ -1635,7 +1585,7 @@ void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_
|
|||
}
|
||||
else if (vtx_attrs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin]->location;
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin].location;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, StorageClassInput);
|
||||
}
|
||||
|
@ -1696,7 +1646,7 @@ void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_
|
|||
}
|
||||
else if (vtx_attrs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin]->location;
|
||||
uint32_t locn = vtx_attrs_by_builtin[builtin].location;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, StorageClassInput);
|
||||
}
|
||||
|
@ -2119,11 +2069,11 @@ uint32_t CompilerMSL::ensure_correct_attribute_type(uint32_t type_id, uint32_t l
|
|||
{
|
||||
auto &type = get<SPIRType>(type_id);
|
||||
|
||||
MSLVertexAttr *p_va = vtx_attrs_by_location[location];
|
||||
if (!p_va)
|
||||
auto p_va = vtx_attrs_by_location.find(location);
|
||||
if (p_va == end(vtx_attrs_by_location))
|
||||
return type_id;
|
||||
|
||||
switch (p_va->format)
|
||||
switch (p_va->second.format)
|
||||
{
|
||||
case MSL_VERTEX_FORMAT_UINT8:
|
||||
{
|
||||
|
@ -2157,6 +2107,7 @@ uint32_t CompilerMSL::ensure_correct_attribute_type(uint32_t type_id, uint32_t l
|
|||
ptr_type.parent_type = base_type_id;
|
||||
return ptr_type_id;
|
||||
}
|
||||
|
||||
case MSL_VERTEX_FORMAT_UINT16:
|
||||
{
|
||||
switch (type.basetype)
|
||||
|
@ -2188,6 +2139,7 @@ uint32_t CompilerMSL::ensure_correct_attribute_type(uint32_t type_id, uint32_t l
|
|||
return ptr_type_id;
|
||||
}
|
||||
|
||||
default:
|
||||
case MSL_VERTEX_FORMAT_OTHER:
|
||||
break;
|
||||
}
|
||||
|
@ -5792,24 +5744,25 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base
|
|||
uint32_t var_binding = (var.storage == StorageClassPushConstant) ? kPushConstBinding : var_dec.binding;
|
||||
|
||||
// If a matching binding has been specified, find and use it
|
||||
for (auto p_res_bind : resource_bindings)
|
||||
{
|
||||
if (p_res_bind->stage == execution.model && p_res_bind->desc_set == var_desc_set &&
|
||||
p_res_bind->binding == var_binding)
|
||||
{
|
||||
auto itr = find_if(begin(resource_bindings), end(resource_bindings),
|
||||
[&](const pair<MSLResourceBinding, bool> &resource) -> bool {
|
||||
return var_desc_set == resource.first.desc_set && var_binding == resource.first.binding &&
|
||||
execution.model == resource.first.stage;
|
||||
});
|
||||
|
||||
p_res_bind->used_by_shader = true;
|
||||
switch (basetype)
|
||||
{
|
||||
case SPIRType::Struct:
|
||||
return p_res_bind->msl_buffer;
|
||||
case SPIRType::Image:
|
||||
return p_res_bind->msl_texture;
|
||||
case SPIRType::Sampler:
|
||||
return p_res_bind->msl_sampler;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (itr != end(resource_bindings))
|
||||
{
|
||||
itr->second = true;
|
||||
switch (basetype)
|
||||
{
|
||||
case SPIRType::Struct:
|
||||
return itr->first.msl_buffer;
|
||||
case SPIRType::Image:
|
||||
return itr->first.msl_texture;
|
||||
case SPIRType::Sampler:
|
||||
return itr->first.msl_sampler;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5827,16 +5780,16 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base
|
|||
switch (basetype)
|
||||
{
|
||||
case SPIRType::Struct:
|
||||
resource_index = next_metal_resource_index.msl_buffer;
|
||||
next_metal_resource_index.msl_buffer += binding_stride;
|
||||
resource_index = next_metal_resource_index_buffer;
|
||||
next_metal_resource_index_buffer += binding_stride;
|
||||
break;
|
||||
case SPIRType::Image:
|
||||
resource_index = next_metal_resource_index.msl_texture;
|
||||
next_metal_resource_index.msl_texture += binding_stride;
|
||||
resource_index = next_metal_resource_index_texture;
|
||||
next_metal_resource_index_texture += binding_stride;
|
||||
break;
|
||||
case SPIRType::Sampler:
|
||||
resource_index = next_metal_resource_index.msl_sampler;
|
||||
next_metal_resource_index.msl_sampler += binding_stride;
|
||||
resource_index = next_metal_resource_index_sampler;
|
||||
next_metal_resource_index_sampler += binding_stride;
|
||||
break;
|
||||
default:
|
||||
resource_index = 0;
|
||||
|
|
|
@ -32,14 +32,14 @@ namespace spirv_cross
|
|||
// some other format.
|
||||
enum MSLVertexFormat
|
||||
{
|
||||
MSL_VERTEX_FORMAT_OTHER,
|
||||
MSL_VERTEX_FORMAT_UINT8,
|
||||
MSL_VERTEX_FORMAT_UINT16
|
||||
MSL_VERTEX_FORMAT_OTHER = 0,
|
||||
MSL_VERTEX_FORMAT_UINT8 = 1,
|
||||
MSL_VERTEX_FORMAT_UINT16 = 2,
|
||||
MSL_VERTEX_FORMAT_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
// Defines MSL characteristics of a vertex attribute at a particular location.
|
||||
// The used_by_shader flag is set to true during compilation of SPIR-V to MSL
|
||||
// if the shader makes use of this vertex attribute.
|
||||
// After compilation, it is possible to query whether or not this location was used.
|
||||
struct MSLVertexAttr
|
||||
{
|
||||
uint32_t location = 0;
|
||||
|
@ -49,72 +49,72 @@ struct MSLVertexAttr
|
|||
bool per_instance = false;
|
||||
MSLVertexFormat format = MSL_VERTEX_FORMAT_OTHER;
|
||||
spv::BuiltIn builtin = spv::BuiltInMax;
|
||||
bool used_by_shader = false;
|
||||
};
|
||||
|
||||
// Matches the binding index of a MSL resource for a binding within a descriptor set.
|
||||
// Taken together, the stage, desc_set and binding combine to form a reference to a resource
|
||||
// descriptor used in a particular shading stage. Generally, only one of the buffer, texture,
|
||||
// or sampler elements will be populated. The used_by_shader flag is set to true during
|
||||
// compilation of SPIR-V to MSL if the shader makes use of this vertex attribute.
|
||||
// descriptor used in a particular shading stage.
|
||||
struct MSLResourceBinding
|
||||
{
|
||||
spv::ExecutionModel stage;
|
||||
spv::ExecutionModel stage = spv::ExecutionModelMax;
|
||||
uint32_t desc_set = 0;
|
||||
uint32_t binding = 0;
|
||||
|
||||
uint32_t msl_buffer = 0;
|
||||
uint32_t msl_texture = 0;
|
||||
uint32_t msl_sampler = 0;
|
||||
|
||||
bool used_by_shader = false;
|
||||
};
|
||||
|
||||
enum MSLSamplerCoord
|
||||
{
|
||||
MSL_SAMPLER_COORD_NORMALIZED,
|
||||
MSL_SAMPLER_COORD_PIXEL
|
||||
MSL_SAMPLER_COORD_NORMALIZED = 0,
|
||||
MSL_SAMPLER_COORD_PIXEL = 1,
|
||||
MSL_SAMPLER_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerFilter
|
||||
{
|
||||
MSL_SAMPLER_FILTER_NEAREST,
|
||||
MSL_SAMPLER_FILTER_LINEAR
|
||||
MSL_SAMPLER_FILTER_NEAREST = 0,
|
||||
MSL_SAMPLER_FILTER_LINEAR = 1,
|
||||
MSL_SAMPLER_FILTER_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerMipFilter
|
||||
{
|
||||
MSL_SAMPLER_MIP_FILTER_NONE,
|
||||
MSL_SAMPLER_MIP_FILTER_NEAREST,
|
||||
MSL_SAMPLER_MIP_FILTER_LINEAR,
|
||||
MSL_SAMPLER_MIP_FILTER_NONE = 0,
|
||||
MSL_SAMPLER_MIP_FILTER_NEAREST = 1,
|
||||
MSL_SAMPLER_MIP_FILTER_LINEAR = 2,
|
||||
MSL_SAMPLER_MIP_FILTER_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerAddress
|
||||
{
|
||||
MSL_SAMPLER_ADDRESS_CLAMP_TO_ZERO,
|
||||
MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE,
|
||||
MSL_SAMPLER_ADDRESS_CLAMP_TO_BORDER,
|
||||
MSL_SAMPLER_ADDRESS_REPEAT,
|
||||
MSL_SAMPLER_ADDRESS_MIRRORED_REPEAT
|
||||
MSL_SAMPLER_ADDRESS_CLAMP_TO_ZERO = 0,
|
||||
MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE = 1,
|
||||
MSL_SAMPLER_ADDRESS_CLAMP_TO_BORDER = 2,
|
||||
MSL_SAMPLER_ADDRESS_REPEAT = 3,
|
||||
MSL_SAMPLER_ADDRESS_MIRRORED_REPEAT = 4,
|
||||
MSL_SAMPLER_ADDRESS_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerCompareFunc
|
||||
{
|
||||
MSL_SAMPLER_COMPARE_FUNC_NEVER,
|
||||
MSL_SAMPLER_COMPARE_FUNC_LESS,
|
||||
MSL_SAMPLER_COMPARE_FUNC_LESS_EQUAL,
|
||||
MSL_SAMPLER_COMPARE_FUNC_GREATER,
|
||||
MSL_SAMPLER_COMPARE_FUNC_GREATER_EQUAL,
|
||||
MSL_SAMPLER_COMPARE_FUNC_EQUAL,
|
||||
MSL_SAMPLER_COMPARE_FUNC_NOT_EQUAL,
|
||||
MSL_SAMPLER_COMPARE_FUNC_ALWAYS
|
||||
MSL_SAMPLER_COMPARE_FUNC_NEVER = 0,
|
||||
MSL_SAMPLER_COMPARE_FUNC_LESS = 1,
|
||||
MSL_SAMPLER_COMPARE_FUNC_LESS_EQUAL = 2,
|
||||
MSL_SAMPLER_COMPARE_FUNC_GREATER = 3,
|
||||
MSL_SAMPLER_COMPARE_FUNC_GREATER_EQUAL = 4,
|
||||
MSL_SAMPLER_COMPARE_FUNC_EQUAL = 5,
|
||||
MSL_SAMPLER_COMPARE_FUNC_NOT_EQUAL = 6,
|
||||
MSL_SAMPLER_COMPARE_FUNC_ALWAYS = 7,
|
||||
MSL_SAMPLER_COMPARE_FUNC_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
enum MSLSamplerBorderColor
|
||||
{
|
||||
MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK,
|
||||
MSL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK,
|
||||
MSL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE
|
||||
MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK = 0,
|
||||
MSL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK = 1,
|
||||
MSL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE = 2,
|
||||
MSL_SAMPLER_BORDER_COLOR_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
struct MSLConstexprSampler
|
||||
|
@ -161,8 +161,8 @@ public:
|
|||
{
|
||||
typedef enum
|
||||
{
|
||||
iOS,
|
||||
macOS,
|
||||
iOS = 0,
|
||||
macOS = 1
|
||||
} Platform;
|
||||
|
||||
Platform platform = macOS;
|
||||
|
@ -210,23 +210,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
SPIRV_CROSS_DEPRECATED("CompilerMSL::get_options() is obsolete, use get_msl_options() instead.")
|
||||
const Options &get_options() const
|
||||
{
|
||||
return msl_options;
|
||||
}
|
||||
|
||||
const Options &get_msl_options() const
|
||||
{
|
||||
return msl_options;
|
||||
}
|
||||
|
||||
SPIRV_CROSS_DEPRECATED("CompilerMSL::set_options() is obsolete, use set_msl_options() instead.")
|
||||
void set_options(Options &opts)
|
||||
{
|
||||
msl_options = opts;
|
||||
}
|
||||
|
||||
void set_msl_options(const Options &opts)
|
||||
{
|
||||
msl_options = opts;
|
||||
|
@ -269,6 +257,44 @@ public:
|
|||
return capture_output_to_buffer && stage_in_var_id != 0;
|
||||
}
|
||||
|
||||
explicit CompilerMSL(std::vector<uint32_t> spirv);
|
||||
CompilerMSL(const uint32_t *ir, size_t word_count);
|
||||
explicit CompilerMSL(const ParsedIR &ir);
|
||||
explicit CompilerMSL(ParsedIR &&ir);
|
||||
|
||||
// attr is a vertex attribute binding used to match
|
||||
// vertex content locations to MSL attributes. If vertex attributes are provided,
|
||||
// is_msl_vertex_attribute_used() will return true after calling ::compile() if
|
||||
// the location was used by the MSL code.
|
||||
void add_msl_vertex_attribute(const MSLVertexAttr &attr);
|
||||
|
||||
// resource is a resource binding to indicate the MSL buffer,
|
||||
// texture or sampler index to use for a particular SPIR-V description set
|
||||
// and binding. If resource bindings are provided,
|
||||
// is_msl_resource_binding_used() will return true after calling ::compile() if
|
||||
// the set/binding combination was used by the MSL code.
|
||||
void add_msl_resource_binding(const MSLResourceBinding &resource);
|
||||
|
||||
// Query after compilation is done. This allows you to check if a location or set/binding combination was used by the shader.
|
||||
bool is_msl_vertex_attribute_used(uint32_t location);
|
||||
bool is_msl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding);
|
||||
|
||||
// Compiles the SPIR-V code into Metal Shading Language.
|
||||
std::string compile() override;
|
||||
|
||||
// Remap a sampler with ID to a constexpr sampler.
|
||||
// Older iOS targets must use constexpr samplers in certain cases (PCF),
|
||||
// so a static sampler must be used.
|
||||
// The sampler will not consume a binding, but be declared in the entry point as a constexpr sampler.
|
||||
// This can be used on both combined image/samplers (sampler2D) or standalone samplers.
|
||||
// The remapped sampler must not be an array of samplers.
|
||||
void remap_constexpr_sampler(uint32_t id, const MSLConstexprSampler &sampler);
|
||||
|
||||
// If using CompilerMSL::Options::pad_fragment_output_components, override the number of components we expect
|
||||
// to use for a particular location. The default is 4 if number of components is not overridden.
|
||||
void set_fragment_output_components(uint32_t location, uint32_t components);
|
||||
|
||||
protected:
|
||||
// An enum of SPIR-V functions that are implemented in additional
|
||||
// source code that is added to the shader if necessary.
|
||||
enum SPVFuncImpl
|
||||
|
@ -304,58 +330,6 @@ public:
|
|||
SPVFuncImplArrayCopyMultidimMax = 6
|
||||
};
|
||||
|
||||
// Constructs an instance to compile the SPIR-V code into Metal Shading Language,
|
||||
// using the configuration parameters, if provided:
|
||||
// - p_vtx_attrs is an optional list of vertex attribute bindings used to match
|
||||
// vertex content locations to MSL attributes. If vertex attributes are provided,
|
||||
// the compiler will set the used_by_shader flag to true in any vertex attribute
|
||||
// actually used by the MSL code.
|
||||
// - p_res_bindings is a list of resource bindings to indicate the MSL buffer,
|
||||
// texture or sampler index to use for a particular SPIR-V description set
|
||||
// and binding. If resource bindings are provided, the compiler will set the
|
||||
// used_by_shader flag to true in any resource binding actually used by the MSL code.
|
||||
CompilerMSL(std::vector<uint32_t> spirv, std::vector<MSLVertexAttr> *p_vtx_attrs = nullptr,
|
||||
std::vector<MSLResourceBinding> *p_res_bindings = nullptr);
|
||||
|
||||
// Alternate constructor avoiding use of std::vectors.
|
||||
CompilerMSL(const uint32_t *ir, size_t word_count, MSLVertexAttr *p_vtx_attrs = nullptr, size_t vtx_attrs_count = 0,
|
||||
MSLResourceBinding *p_res_bindings = nullptr, size_t res_bindings_count = 0);
|
||||
|
||||
// Alternate constructors taking pre-parsed IR directly.
|
||||
CompilerMSL(const ParsedIR &ir, MSLVertexAttr *p_vtx_attrs = nullptr, size_t vtx_attrs_count = 0,
|
||||
MSLResourceBinding *p_res_bindings = nullptr, size_t res_bindings_count = 0);
|
||||
|
||||
CompilerMSL(ParsedIR &&ir, MSLVertexAttr *p_vtx_attrs = nullptr, size_t vtx_attrs_count = 0,
|
||||
MSLResourceBinding *p_res_bindings = nullptr, size_t res_bindings_count = 0);
|
||||
|
||||
// Compiles the SPIR-V code into Metal Shading Language.
|
||||
std::string compile() override;
|
||||
|
||||
// Compiles the SPIR-V code into Metal Shading Language, overriding configuration parameters.
|
||||
// Any of the parameters here may be null to indicate that the configuration provided in the
|
||||
// constructor should be used. They are not declared as optional to avoid a conflict with the
|
||||
// inherited and overridden zero-parameter compile() function.
|
||||
std::string compile(std::vector<MSLVertexAttr> *p_vtx_attrs, std::vector<MSLResourceBinding> *p_res_bindings);
|
||||
|
||||
// This legacy method is deprecated.
|
||||
typedef Options MSLConfiguration;
|
||||
SPIRV_CROSS_DEPRECATED("Please use get_msl_options() and set_msl_options() instead.")
|
||||
std::string compile(MSLConfiguration &msl_cfg, std::vector<MSLVertexAttr> *p_vtx_attrs = nullptr,
|
||||
std::vector<MSLResourceBinding> *p_res_bindings = nullptr);
|
||||
|
||||
// Remap a sampler with ID to a constexpr sampler.
|
||||
// Older iOS targets must use constexpr samplers in certain cases (PCF),
|
||||
// so a static sampler must be used.
|
||||
// The sampler will not consume a binding, but be declared in the entry point as a constexpr sampler.
|
||||
// This can be used on both combined image/samplers (sampler2D) or standalone samplers.
|
||||
// The remapped sampler must not be an array of samplers.
|
||||
void remap_constexpr_sampler(uint32_t id, const MSLConstexprSampler &sampler);
|
||||
|
||||
// If using CompilerMSL::Options::pad_fragment_output_components, override the number of components we expect
|
||||
// to use for a particular location. The default is 4 if number of components is not overridden.
|
||||
void set_fragment_output_components(uint32_t location, uint32_t components);
|
||||
|
||||
protected:
|
||||
void emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op);
|
||||
void emit_instruction(const Instruction &instr) override;
|
||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
|
@ -495,15 +469,20 @@ protected:
|
|||
|
||||
Options msl_options;
|
||||
std::set<SPVFuncImpl> spv_function_implementations;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_location;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_builtin;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr> vtx_attrs_by_location;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr> vtx_attrs_by_builtin;
|
||||
std::unordered_set<uint32_t> vtx_attrs_in_use;
|
||||
std::unordered_map<uint32_t, uint32_t> fragment_output_components;
|
||||
std::unordered_map<MSLStructMemberKey, uint32_t> struct_member_padding;
|
||||
std::set<std::string> pragma_lines;
|
||||
std::set<std::string> typedef_lines;
|
||||
std::vector<uint32_t> vars_needing_early_declaration;
|
||||
std::vector<MSLResourceBinding *> resource_bindings;
|
||||
MSLResourceBinding next_metal_resource_index;
|
||||
|
||||
std::vector<std::pair<MSLResourceBinding, bool>> resource_bindings;
|
||||
uint32_t next_metal_resource_index_buffer = 0;
|
||||
uint32_t next_metal_resource_index_texture = 0;
|
||||
uint32_t next_metal_resource_index_sampler = 0;
|
||||
|
||||
uint32_t stage_in_var_id = 0;
|
||||
uint32_t stage_out_var_id = 0;
|
||||
uint32_t patch_stage_in_var_id = 0;
|
||||
|
|
|
@ -16,6 +16,13 @@ import multiprocessing
|
|||
import errno
|
||||
from functools import partial
|
||||
|
||||
class Paths():
|
||||
def __init__(self, glslang, spirv_as, spirv_val, spirv_opt):
|
||||
self.glslang = glslang
|
||||
self.spirv_as = spirv_as
|
||||
self.spirv_val = spirv_val
|
||||
self.spirv_opt = spirv_opt
|
||||
|
||||
def remove_file(path):
|
||||
#print('Removing file:', path)
|
||||
os.remove(path)
|
||||
|
@ -131,21 +138,21 @@ def validate_shader_msl(shader, opt):
|
|||
print('Error compiling Metal shader: ' + msl_path)
|
||||
raise RuntimeError('Failed to compile Metal shader')
|
||||
|
||||
def cross_compile_msl(shader, spirv, opt):
|
||||
def cross_compile_msl(shader, spirv, opt, paths):
|
||||
spirv_path = create_temporary()
|
||||
msl_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
|
||||
spirv_cmd = [paths.spirv_as, '-o', spirv_path, shader]
|
||||
if '.preserve.' in shader:
|
||||
spirv_cmd.append('--preserve-numeric-ids')
|
||||
|
||||
if spirv:
|
||||
subprocess.check_call(spirv_cmd)
|
||||
else:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
subprocess.check_call([paths.glslang, '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
|
||||
if opt:
|
||||
subprocess.check_call(['spirv-opt', '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
subprocess.check_call([paths.spirv_opt, '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
|
||||
spirv_cross_path = './spirv-cross'
|
||||
|
||||
|
@ -166,7 +173,7 @@ def cross_compile_msl(shader, spirv, opt):
|
|||
subprocess.check_call(msl_args)
|
||||
|
||||
if not shader_is_invalid_spirv(msl_path):
|
||||
subprocess.check_call(['spirv-val', '--target-env', 'vulkan1.1', spirv_path])
|
||||
subprocess.check_call([paths.spirv_val, '--target-env', 'vulkan1.1', spirv_path])
|
||||
|
||||
return (spirv_path, msl_path)
|
||||
|
||||
|
@ -201,8 +208,8 @@ def shader_to_win_path(shader):
|
|||
return shader
|
||||
|
||||
ignore_fxc = False
|
||||
def validate_shader_hlsl(shader, force_no_external_validation):
|
||||
subprocess.check_call(['glslangValidator', '-e', 'main', '-D', '--target-env', 'vulkan1.1', '-V', shader])
|
||||
def validate_shader_hlsl(shader, force_no_external_validation, paths):
|
||||
subprocess.check_call([paths.glslang, '-e', 'main', '-D', '--target-env', 'vulkan1.1', '-V', shader])
|
||||
is_no_fxc = '.nofxc.' in shader
|
||||
global ignore_fxc
|
||||
if (not ignore_fxc) and (not force_no_external_validation) and (not is_no_fxc):
|
||||
|
@ -231,21 +238,21 @@ def shader_to_sm(shader):
|
|||
else:
|
||||
return '50'
|
||||
|
||||
def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation):
|
||||
def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation, paths):
|
||||
spirv_path = create_temporary()
|
||||
hlsl_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
|
||||
spirv_cmd = [paths.spirv_as, '-o', spirv_path, shader]
|
||||
if '.preserve.' in shader:
|
||||
spirv_cmd.append('--preserve-numeric-ids')
|
||||
|
||||
if spirv:
|
||||
subprocess.check_call(spirv_cmd)
|
||||
else:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
subprocess.check_call([paths.glslang, '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
|
||||
if opt:
|
||||
subprocess.check_call(['spirv-opt', '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
subprocess.check_call([paths.spirv_opt, '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
|
||||
spirv_cross_path = './spirv-cross'
|
||||
|
||||
|
@ -253,27 +260,27 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation):
|
|||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', sm])
|
||||
|
||||
if not shader_is_invalid_spirv(hlsl_path):
|
||||
subprocess.check_call(['spirv-val', '--target-env', 'vulkan1.1', spirv_path])
|
||||
subprocess.check_call([paths.spirv_val, '--target-env', 'vulkan1.1', spirv_path])
|
||||
|
||||
validate_shader_hlsl(hlsl_path, force_no_external_validation)
|
||||
validate_shader_hlsl(hlsl_path, force_no_external_validation, paths)
|
||||
|
||||
return (spirv_path, hlsl_path)
|
||||
|
||||
def cross_compile_reflect(shader, spirv, opt):
|
||||
def cross_compile_reflect(shader, spirv, opt, paths):
|
||||
spirv_path = create_temporary()
|
||||
reflect_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
|
||||
spirv_cmd = [paths.spirv_as, '-o', spirv_path, shader]
|
||||
if '.preserve.' in shader:
|
||||
spirv_cmd.append('--preserve-numeric-ids')
|
||||
|
||||
if spirv:
|
||||
subprocess.check_call(spirv_cmd)
|
||||
else:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
subprocess.check_call([paths.glslang, '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
|
||||
if opt:
|
||||
subprocess.check_call(['spirv-opt', '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
subprocess.check_call([paths.spirv_opt, '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
|
||||
spirv_cross_path = './spirv-cross'
|
||||
|
||||
|
@ -281,33 +288,33 @@ def cross_compile_reflect(shader, spirv, opt):
|
|||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', reflect_path, spirv_path, '--reflect'])
|
||||
return (spirv_path, reflect_path)
|
||||
|
||||
def validate_shader(shader, vulkan):
|
||||
def validate_shader(shader, vulkan, paths):
|
||||
if vulkan:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', shader])
|
||||
subprocess.check_call([paths.glslang, '--target-env', 'vulkan1.1', '-V', shader])
|
||||
else:
|
||||
subprocess.check_call(['glslangValidator', shader])
|
||||
subprocess.check_call([paths.glslang, shader])
|
||||
|
||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt):
|
||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt, paths):
|
||||
spirv_path = create_temporary()
|
||||
glsl_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
if vulkan or spirv:
|
||||
vulkan_glsl_path = create_temporary('vk' + os.path.basename(shader))
|
||||
|
||||
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
|
||||
spirv_cmd = [paths.spirv_as, '-o', spirv_path, shader]
|
||||
if '.preserve.' in shader:
|
||||
spirv_cmd.append('--preserve-numeric-ids')
|
||||
|
||||
if spirv:
|
||||
subprocess.check_call(spirv_cmd)
|
||||
else:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
subprocess.check_call([paths.glslang, '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
|
||||
if opt and (not invalid_spirv):
|
||||
subprocess.check_call(['spirv-opt', '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
subprocess.check_call([paths.spirv_opt, '--skip-validation', '-O', '-o', spirv_path, spirv_path])
|
||||
|
||||
if not invalid_spirv:
|
||||
subprocess.check_call(['spirv-val', '--target-env', 'vulkan1.1', spirv_path])
|
||||
subprocess.check_call([paths.spirv_val, '--target-env', 'vulkan1.1', spirv_path])
|
||||
|
||||
extra_args = []
|
||||
if eliminate:
|
||||
|
@ -326,14 +333,14 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
|||
# A shader might not be possible to make valid GLSL from, skip validation for this case.
|
||||
if not ('nocompat' in glsl_path):
|
||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', glsl_path, spirv_path] + extra_args)
|
||||
validate_shader(glsl_path, False)
|
||||
validate_shader(glsl_path, False, paths)
|
||||
else:
|
||||
remove_file(glsl_path)
|
||||
glsl_path = None
|
||||
|
||||
if vulkan or spirv:
|
||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--vulkan-semantics', '--output', vulkan_glsl_path, spirv_path] + extra_args)
|
||||
validate_shader(vulkan_glsl_path, True)
|
||||
validate_shader(vulkan_glsl_path, True, paths)
|
||||
# SPIR-V shaders might just want to validate Vulkan GLSL output, we don't always care about the output.
|
||||
if not vulkan:
|
||||
remove_file(vulkan_glsl_path)
|
||||
|
@ -481,7 +488,7 @@ def shader_is_flatten_dimensions(shader):
|
|||
def shader_is_noopt(shader):
|
||||
return '.noopt.' in shader
|
||||
|
||||
def test_shader(stats, shader, update, keep, opt):
|
||||
def test_shader(stats, shader, update, keep, opt, paths):
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
vulkan = shader_is_vulkan(shader[1])
|
||||
desktop = shader_is_desktop(shader[1])
|
||||
|
@ -495,7 +502,7 @@ def test_shader(stats, shader, update, keep, opt):
|
|||
noopt = shader_is_noopt(shader[1])
|
||||
|
||||
print('Testing shader:', joined_path)
|
||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt and (not noopt))
|
||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt and (not noopt), paths)
|
||||
|
||||
# Only test GLSL stats if we have a shader following GL semantics.
|
||||
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
||||
|
@ -519,12 +526,12 @@ def test_shader(stats, shader, update, keep, opt):
|
|||
a.append(str(i))
|
||||
print(','.join(a), file = stats)
|
||||
|
||||
def test_shader_msl(stats, shader, update, keep, opt, force_no_external_validation):
|
||||
def test_shader_msl(stats, shader, update, keep, opt, force_no_external_validation, paths):
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
print('\nTesting MSL shader:', joined_path)
|
||||
is_spirv = shader_is_spirv(shader[1])
|
||||
noopt = shader_is_noopt(shader[1])
|
||||
spirv, msl = cross_compile_msl(joined_path, is_spirv, opt and (not noopt))
|
||||
spirv, msl = cross_compile_msl(joined_path, is_spirv, opt and (not noopt), paths)
|
||||
regression_check(shader, msl, update, keep, opt)
|
||||
|
||||
# Uncomment the following line to print the temp SPIR-V file path.
|
||||
|
@ -540,34 +547,35 @@ def test_shader_msl(stats, shader, update, keep, opt, force_no_external_validati
|
|||
|
||||
remove_file(spirv)
|
||||
|
||||
def test_shader_hlsl(stats, shader, update, keep, opt, force_no_external_validation):
|
||||
def test_shader_hlsl(stats, shader, update, keep, opt, force_no_external_validation, paths):
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
print('Testing HLSL shader:', joined_path)
|
||||
is_spirv = shader_is_spirv(shader[1])
|
||||
noopt = shader_is_noopt(shader[1])
|
||||
spirv, hlsl = cross_compile_hlsl(joined_path, is_spirv, opt and (not noopt), force_no_external_validation)
|
||||
spirv, hlsl = cross_compile_hlsl(joined_path, is_spirv, opt and (not noopt), force_no_external_validation, paths)
|
||||
regression_check(shader, hlsl, update, keep, opt)
|
||||
remove_file(spirv)
|
||||
|
||||
def test_shader_reflect(stats, shader, update, keep, opt):
|
||||
def test_shader_reflect(stats, shader, update, keep, opt, paths):
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
print('Testing shader reflection:', joined_path)
|
||||
is_spirv = shader_is_spirv(shader[1])
|
||||
noopt = shader_is_noopt(shader[1])
|
||||
spirv, reflect = cross_compile_reflect(joined_path, is_spirv, opt and (not noopt))
|
||||
spirv, reflect = cross_compile_reflect(joined_path, is_spirv, opt and (not noopt), paths)
|
||||
regression_check_reflect(shader, reflect, update, keep, opt)
|
||||
remove_file(spirv)
|
||||
|
||||
def test_shader_file(relpath, stats, shader_dir, update, keep, opt, force_no_external_validation, backend):
|
||||
def test_shader_file(relpath, stats, args, backend):
|
||||
paths = Paths(args.glslang, args.spirv_as, args.spirv_val, args.spirv_opt)
|
||||
try:
|
||||
if backend == 'msl':
|
||||
test_shader_msl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation)
|
||||
test_shader_msl(stats, (args.folder, relpath), args.update, args.keep, args.opt, args.force_no_external_validation, paths)
|
||||
elif backend == 'hlsl':
|
||||
test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation)
|
||||
test_shader_hlsl(stats, (args.folder, relpath), args.update, args.keep, args.opt, args.force_no_external_validation, paths)
|
||||
elif backend == 'reflect':
|
||||
test_shader_reflect(stats, (shader_dir, relpath), update, keep, opt)
|
||||
test_shader_reflect(stats, (args.folder, relpath), args.update, args.keep, args.opt, paths)
|
||||
else:
|
||||
test_shader(stats, (shader_dir, relpath), update, keep, opt)
|
||||
test_shader(stats, (args.folder, relpath), args.update, args.keep, args.opt, paths)
|
||||
return None
|
||||
except Exception as e:
|
||||
return e
|
||||
|
@ -589,9 +597,7 @@ def test_shaders_helper(stats, backend, args):
|
|||
results = []
|
||||
for f in all_files:
|
||||
results.append(pool.apply_async(test_shader_file,
|
||||
args = (f, stats,
|
||||
args.folder, args.update, args.keep, args.opt, args.force_no_external_validation,
|
||||
backend)))
|
||||
args = (f, stats, args, backend)))
|
||||
|
||||
for res in results:
|
||||
error = res.get()
|
||||
|
@ -602,7 +608,7 @@ def test_shaders_helper(stats, backend, args):
|
|||
sys.exit(1)
|
||||
else:
|
||||
for i in all_files:
|
||||
e = test_shader_file(i, stats, args.folder, args.update, args.keep, args.opt, args.force_no_external_validation, backend)
|
||||
e = test_shader_file(i, stats, args, backend)
|
||||
if e is not None:
|
||||
print('Error:', e)
|
||||
sys.exit(1)
|
||||
|
@ -649,6 +655,18 @@ def main():
|
|||
parser.add_argument('--parallel',
|
||||
action = 'store_true',
|
||||
help = 'Execute tests in parallel. Useful for doing regression quickly, but bad for debugging and stat output.')
|
||||
parser.add_argument('--glslang',
|
||||
default = 'glslangValidator',
|
||||
help = 'Explicit path to glslangValidator')
|
||||
parser.add_argument('--spirv-as',
|
||||
default = 'spirv-as',
|
||||
help = 'Explicit path to spirv-as')
|
||||
parser.add_argument('--spirv-val',
|
||||
default = 'spirv-val',
|
||||
help = 'Explicit path to spirv-val')
|
||||
parser.add_argument('--spirv-opt',
|
||||
default = 'spirv-opt',
|
||||
help = 'Explicit path to spirv-opt')
|
||||
|
||||
args = parser.parse_args()
|
||||
if not args.folder:
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/* Smoke test for the C API. */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <spirv_cross_c.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define SPVC_CHECKED_CALL(x) do { \
|
||||
if ((x) != SPVC_SUCCESS) { \
|
||||
fprintf(stderr, "Failed at line %d.\n", __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while(0)
|
||||
#define SPVC_CHECKED_CALL_NEGATIVE(x) do { \
|
||||
g_fail_on_error = SPVC_FALSE; \
|
||||
if ((x) == SPVC_SUCCESS) { \
|
||||
fprintf(stderr, "Failed at line %d.\n", __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
g_fail_on_error = SPVC_TRUE; \
|
||||
} while(0)
|
||||
|
||||
static int read_file(const char *path, SpvId **buffer, size_t *word_count)
|
||||
{
|
||||
long len;
|
||||
FILE *file = fopen(path, "rb");
|
||||
|
||||
if (!file)
|
||||
return -1;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
len = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
*buffer = malloc(len);
|
||||
if (fread(*buffer, 1, len, file) != (size_t)len)
|
||||
{
|
||||
fclose(file);
|
||||
free(*buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
*word_count = len / sizeof(SpvId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static spvc_bool g_fail_on_error = SPVC_TRUE;
|
||||
|
||||
static void error_callback(void *userdata, const char *error)
|
||||
{
|
||||
(void)userdata;
|
||||
if (g_fail_on_error)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", error);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
printf("Expected error hit: %s.\n", error);
|
||||
}
|
||||
|
||||
static void dump_resource_list(spvc_compiler compiler, spvc_resources resources, spvc_resource_type type, const char *tag)
|
||||
{
|
||||
const spvc_reflected_resource *list = NULL;
|
||||
size_t count = 0;
|
||||
size_t i;
|
||||
SPVC_CHECKED_CALL(spvc_resources_get_resource_list_for_type(resources, type, &list, &count));
|
||||
printf("%s\n", tag);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
printf("ID: %u, BaseTypeID: %u, TypeID: %u, Name: %s\n", list[i].id, list[i].base_type_id, list[i].type_id,
|
||||
list[i].name);
|
||||
printf(" Set: %u, Binding: %u\n",
|
||||
spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationDescriptorSet),
|
||||
spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationBinding));
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_resources(spvc_compiler compiler, spvc_resources resources)
|
||||
{
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, "UBO");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_STORAGE_BUFFER, "SSBO");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, "Push");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS, "Samplers");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_SEPARATE_IMAGE, "Image");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE, "Combined image samplers");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_STAGE_INPUT, "Stage input");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_STAGE_OUTPUT, "Stage output");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_STORAGE_IMAGE, "Storage image");
|
||||
dump_resource_list(compiler, resources, SPVC_RESOURCE_TYPE_SUBPASS_INPUT, "Subpass input");
|
||||
}
|
||||
|
||||
static void compile(spvc_compiler compiler, const char *tag)
|
||||
{
|
||||
const char *result = NULL;
|
||||
SPVC_CHECKED_CALL(spvc_compiler_compile(compiler, &result));
|
||||
printf("\n%s\n=======\n", tag);
|
||||
printf("%s\n=======\n", result);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
spvc_context context = NULL;
|
||||
spvc_parsed_ir ir = NULL;
|
||||
spvc_compiler compiler_glsl = NULL;
|
||||
spvc_compiler compiler_hlsl = NULL;
|
||||
spvc_compiler compiler_msl = NULL;
|
||||
spvc_compiler compiler_cpp = NULL;
|
||||
spvc_compiler compiler_json = NULL;
|
||||
spvc_compiler compiler_none = NULL;
|
||||
spvc_compiler_options options = NULL;
|
||||
spvc_resources resources = NULL;
|
||||
SpvId *buffer = NULL;
|
||||
size_t word_count = 0;
|
||||
|
||||
if (argc != 2)
|
||||
return 1;
|
||||
|
||||
if (read_file(argv[1], &buffer, &word_count) < 0)
|
||||
return 1;
|
||||
|
||||
SPVC_CHECKED_CALL(spvc_context_create(&context));
|
||||
spvc_context_set_error_callback(context, error_callback, NULL);
|
||||
SPVC_CHECKED_CALL(spvc_context_parse_spirv(context, buffer, word_count, &ir));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler_glsl));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(context, SPVC_BACKEND_HLSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler_hlsl));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(context, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler_msl));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(context, SPVC_BACKEND_CPP, ir, SPVC_CAPTURE_MODE_COPY, &compiler_cpp));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(context, SPVC_BACKEND_JSON, ir, SPVC_CAPTURE_MODE_COPY, &compiler_json));
|
||||
SPVC_CHECKED_CALL(spvc_context_create_compiler(context, SPVC_BACKEND_NONE, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler_none));
|
||||
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler_none, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler_none, options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler_json, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler_json, options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler_cpp, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler_cpp, options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler_msl, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler_msl, options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler_hlsl, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL, 50));
|
||||
SPVC_CHECKED_CALL_NEGATIVE(spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_PLATFORM, 1));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler_hlsl, options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_compiler_options(compiler_glsl, &options));
|
||||
SPVC_CHECKED_CALL(spvc_compiler_install_compiler_options(compiler_glsl, options));
|
||||
|
||||
SPVC_CHECKED_CALL(spvc_compiler_create_shader_resources(compiler_none, &resources));
|
||||
dump_resources(compiler_none, resources);
|
||||
compile(compiler_glsl, "GLSL");
|
||||
compile(compiler_hlsl, "HLSL");
|
||||
compile(compiler_msl, "MSL");
|
||||
compile(compiler_json, "JSON");
|
||||
compile(compiler_cpp, "CPP");
|
||||
|
||||
spvc_context_destroy(context);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue