mirror of
https://github.com/overte-org/overte.git
synced 2025-04-05 21:12:25 +02:00
New SPIRV Shader toolchain
This commit is contained in:
parent
8ce2081349
commit
c8e664a0a1
175 changed files with 2316 additions and 1697 deletions
|
@ -24,7 +24,6 @@ android {
|
|||
'-DANDROID_STL=c++_shared',
|
||||
'-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake',
|
||||
'-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX,
|
||||
'-DNATIVE_SHREFLECT=' + HIFI_ANDROID_PRECOMPILED + '/shreflect' + EXEC_SUFFIX,
|
||||
'-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED,
|
||||
'-DRELEASE_NUMBER=' + RELEASE_NUMBER,
|
||||
'-DRELEASE_TYPE=' + RELEASE_TYPE,
|
||||
|
|
|
@ -161,31 +161,19 @@ def packages = [
|
|||
]
|
||||
]
|
||||
|
||||
|
||||
def scribeLocalFile='scribe' + EXEC_SUFFIX
|
||||
def scribeFile='scribe_linux_x86_64'
|
||||
def scribeChecksum='ca4b904f52f4f993c29175ba96798fa6'
|
||||
def scribeVersion='u_iTrJDaE95i2abTPXOpPZckGBIim53G'
|
||||
|
||||
def shreflectLocalFile='shreflect' + EXEC_SUFFIX
|
||||
def shreflectFile='shreflect_linux_x86_64'
|
||||
def shreflectChecksum='d6094a8580066c0b6f4e80b5adfb1d98'
|
||||
def shreflectVersion='jnrpudh6fptIg6T2.Z6fgKP2ultAdKmE'
|
||||
def scribeChecksum='4635c28192724281d2367ce9e94380ab'
|
||||
def scribeVersion='mPAY_N846oZH1tPY1bwChB_hzqkiYyoC'
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
scribeFile = 'scribe_osx_x86_64'
|
||||
scribeChecksum='72db9d32d4e1e50add755570ac5eb749'
|
||||
scribeVersion='DAW0DmnjCRib4MD8x93bgc2Z2MpPojZC'
|
||||
shreflectFile='shreflect_osx_x86_64'
|
||||
shreflectChecksum='d613ef0703c21371fee93fd2e54b964f'
|
||||
shreflectVersion='.rYNzjSFq6WtWDnE5KIKRIAGyJtr__ad'
|
||||
scribeChecksum='1ead61c285d265eba9a5ef91ae3b7c26'
|
||||
scribeVersion='4TAXWdo9fviw60N2wUA8HNyQ9TabjZa3'
|
||||
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
scribeFile = 'scribe_win32_x86_64.exe'
|
||||
scribeChecksum='678e43d290c90fda670c6fefe038a06d'
|
||||
scribeVersion='PuullrA_bPlO9kXZRt8rLe536X1UI.m7'
|
||||
shreflectFile='shreflect_win32_x86_64.exe'
|
||||
shreflectChecksum='6f4a77b8cceb3f1bbc655132c3665060'
|
||||
shreflectVersion='iIyCyza1nelkbI7ihybF59bBlwrfAC3D'
|
||||
scribeChecksum='9c29a62595daf4844f95f6744d568c15'
|
||||
scribeVersion='DUoxjufeX8ZAIVRBKRczWTuZwT13enTv'
|
||||
}
|
||||
|
||||
def options = [
|
||||
|
@ -461,27 +449,11 @@ task fixScribePermissions(type: Exec, dependsOn: verifyScribe) {
|
|||
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + scribeLocalFile
|
||||
}
|
||||
|
||||
task downloadShreflect(type: Download) {
|
||||
src baseUrl + shreflectFile + '?versionId=' + shreflectVersion
|
||||
dest new File(baseFolder, shreflectLocalFile)
|
||||
onlyIfNewer true
|
||||
}
|
||||
|
||||
task verifyShreflect(type: Verify, dependsOn: downloadShreflect) {
|
||||
src new File(baseFolder, shreflectLocalFile);
|
||||
checksum shreflectChecksum
|
||||
}
|
||||
|
||||
task fixShreflectPermissions(type: Exec, dependsOn: verifyShreflect) {
|
||||
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + shreflectLocalFile
|
||||
}
|
||||
|
||||
task setupScribe(dependsOn: [verifyScribe, verifyShreflect]) { }
|
||||
task setupScribe(dependsOn: [verifyScribe]) { }
|
||||
|
||||
// On Windows, we don't need to set the executable bit, but on OSX and Unix we do
|
||||
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
setupScribe.dependsOn fixScribePermissions
|
||||
setupScribe.dependsOn fixShreflectPermissions
|
||||
}
|
||||
|
||||
task extractGvrBinaries(dependsOn: extractDependencies) {
|
||||
|
|
42
cmake/externals/glslang/CMakeLists.txt
vendored
Normal file
42
cmake/externals/glslang/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
set(EXTERNAL_NAME glslang)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/glslang/archive/7.8.2853.zip
|
||||
URL_MD5 4f93e3818528176c622c137fba05cbf8
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG>
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
# includes
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$<CONFIG>")
|
||||
|
||||
list(APPEND INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include)
|
||||
#list(APPEND INCLUDE_DIRS ${INSTALL_DIR}/include)
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INCLUDE_DIRS} CACHE PATH "List of glslang include directories")
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${${EXTERNAL_NAME_UPPER}_INCLUDE_DIR} CACHE PATH "List of glslang include directories")
|
||||
|
||||
|
||||
set(LIB_DIR ${SUFFIXED_INSTALL_DIR}/lib)
|
||||
list(APPEND LIB_NAMES glslang HLSL OGLCompiler OSDependent SPIRV SPVRemapper)
|
||||
include(SelectLibraryConfigurations)
|
||||
|
||||
foreach(BASE_LIB ${LIB_NAMES})
|
||||
string(TOUPPER ${BASE_LIB} BASE_LIB_UPPER)
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${LIB_DIR}/${BASE_LIB}.lib")
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "${LIB_DIR}/${BASE_LIB}d.lib")
|
||||
endforeach()
|
||||
|
||||
select_library_configurations(${EXTERNAL_NAME_UPPER})
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of glslang libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of glslang libraries")
|
34
cmake/externals/spirv_binaries/CMakeLists.txt
vendored
Normal file
34
cmake/externals/spirv_binaries/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
set(EXTERNAL_NAME spirv_binaries)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/vulkan/vulkansdk-win32-1.1.82.1.tar.gz)
|
||||
set(DOWNLOAD_MD5 3a83ef490bce248b1a4d6726a3e5893e)
|
||||
set(BIN_DIR "Bin")
|
||||
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/vulkan/vulkansdk-macos-1.1.82.1.tar.gz)
|
||||
set(DOWNLOAD_MD5 a57d37275b2c5db023ba8e84a63461ff)
|
||||
set(BIN_DIR "macOS/bin")
|
||||
else ()
|
||||
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/vulkan/vulkansdk-linux-x86_64-1.1.82.1.tar.gz)
|
||||
set(DOWNLOAD_MD5 5a7c9eeda8cee6b36724da7f7cbe5ec6)
|
||||
set(BIN_DIR "x86_64/bin")
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL ${DOWNLOAD_URL}
|
||||
URL_MD5 ${DOWNLOAD_MD5}
|
||||
BUILD_COMMAND ""
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
LOG_DOWNLOAD ON
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_DIR "${SOURCE_DIR}/${BIN_DIR}" CACHE FILEPATH "SPIRV binary tools location")
|
||||
|
35
cmake/externals/spirv_cross/CMakeLists.txt
vendored
Normal file
35
cmake/externals/spirv_cross/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
set(EXTERNAL_NAME spirv_cross)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/SPIRV-Cross/archive/2018-08-07.zip
|
||||
URL_MD5 11198e4dc6a815ffbdb7a0a56d2d9261
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$<CONFIG>")
|
||||
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include CACHE PATH "List of Draco include directories")
|
||||
|
||||
if (UNIX)
|
||||
set(LIB_PREFIX "lib")
|
||||
set(LIB_EXT "a")
|
||||
elseif (WIN32)
|
||||
set(LIB_EXT "lib")
|
||||
endif ()
|
||||
|
||||
foreach(lib glsl msl cpp hlsl reflect util core)
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/spirv-cross-${lib}.${LIB_EXT})
|
||||
endforeach()
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Path to SPIRV-Cross libraries")
|
18
cmake/externals/spirv_headers/CMakeLists.txt
vendored
Normal file
18
cmake/externals/spirv_headers/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
set(EXTERNAL_NAME spirv_headers)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/SPIRV-Headers/archive/2c512180ca03b5d4f56283efc85745775b45fdc4.zip
|
||||
URL_MD5 83e652221b5f21d5fdb61c45f5b4d9f9
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EXTRA_CMAKE_FLAGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(${EXTERNAL_NAME_UPPER}_ROOT ${INSTALL_DIR} CACHE PATH "List of include directories")
|
33
cmake/externals/spirv_tools/CMakeLists.txt
vendored
Normal file
33
cmake/externals/spirv_tools/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
set(EXTERNAL_NAME spirv_tools)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/SPIRV-Tools/archive/v2018.4.zip
|
||||
URL_MD5 7a7c69cf6ff0318910b4bfbdf30bcfc9
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DSPIRV-Headers_SOURCE_DIR=${SPIRV_HEADERS_ROOT} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$<CONFIG>")
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include CACHE PATH "List of SPIRV-Tools include directories")
|
||||
|
||||
if (UNIX)
|
||||
set(LIB_PREFIX "lib")
|
||||
set(LIB_EXT "a")
|
||||
elseif (WIN32)
|
||||
set(LIB_EXT "lib")
|
||||
endif ()
|
||||
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/SPIRV-Tools-opt.${LIB_EXT})
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/SPIRV-Tools-link.${LIB_EXT})
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/SPIRV-Tools.${LIB_EXT})
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Path to SPIRV-Tool libraries")
|
|
@ -10,6 +10,10 @@ if (POLICY CMP0042)
|
|||
cmake_policy(SET CMP0042 NEW)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 OLD)
|
||||
endif ()
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
|
||||
# Hide automoc folders (for IDEs)
|
||||
|
|
|
@ -8,34 +8,132 @@
|
|||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
# FIXME use the built tools
|
||||
|
||||
macro(AUTOSCRIBE_APPEND_QRC)
|
||||
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${ARGV0}\">${ARGV1}</file>\n")
|
||||
endmacro()
|
||||
|
||||
set(VULKAN_DIR $ENV{VULKAN_SDK})
|
||||
set(GLSLANG_EXEC "${VULKAN_DIR}/Bin/glslangValidator.exe")
|
||||
set(SPIRV_CROSS_EXEC "${VULKAN_DIR}/Bin/spirv-cross.exe")
|
||||
set(SPIRV_OPT_EXEC "${VULKAN_DIR}/Bin/spirv-opt.exe")
|
||||
set(GLSLC_EXEC "${VULKAN_DIR}/Bin/glslc.exe")
|
||||
set(SCRIBE_EXEC "D:/scribe.exe")
|
||||
|
||||
macro(AUTOSCRIBE_PLATFORM_SHADER)
|
||||
set(AUTOSCRIBE_PLATFORM_PATH "${ARGV0}")
|
||||
string(REGEX MATCH "([0-9]+(es)?)(/stereo)?" PLATFORM_PATH_REGEX ${AUTOSCRIBE_PLATFORM_PATH})
|
||||
set(AUTOSCRIBE_DIALECT "${CMAKE_MATCH_1}")
|
||||
if (CMAKE_MATCH_3)
|
||||
set(AUTOSCRIBE_VARIANT "stereo")
|
||||
else()
|
||||
set(AUTOSCRIBE_VARIANT "mono")
|
||||
endif()
|
||||
string(REGEX REPLACE "/" "\\\\" SOURCE_GROUP_PATH ${AUTOSCRIBE_PLATFORM_PATH})
|
||||
set(SOURCE_GROUP_PATH "${SHADER_LIB}\\${SOURCE_GROUP_PATH}")
|
||||
set(AUTOSCRIBE_DIALECT_HEADER "${AUTOSCRIBE_HEADER_DIR}/${AUTOSCRIBE_DIALECT}/header.glsl")
|
||||
set(AUTOSCRIBE_VARIANT_HEADER "${AUTOSCRIBE_HEADER_DIR}/${AUTOSCRIBE_VARIANT}.glsl")
|
||||
|
||||
set(AUTOSCRIBE_OUTPUT_FILE "${SHADERS_DIR}/${SHADER_LIB}/${AUTOSCRIBE_PLATFORM_PATH}/${SHADER_NAME}.${SHADER_TYPE}")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/scribe" "${AUTOSCRIBE_OUTPUT_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_OUTPUT_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_OUTPUT_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SCRIBED_SHADERS ${AUTOSCRIBE_OUTPUT_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_FILE "${AUTOSCRIBE_OUTPUT_FILE}.spv")
|
||||
# don't add unoptimized spirv to the QRC
|
||||
#AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/spirv_unopt" "${AUTOSCRIBE_SPIRV_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_OPT_FILE "${AUTOSCRIBE_OUTPUT_FILE}.opt.spv")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/spirv" "${AUTOSCRIBE_SPIRV_OPT_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_OPT_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_OPT_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_OPT_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_GLSL_FILE "${AUTOSCRIBE_OUTPUT_FILE}.glsl")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/glsl" "${AUTOSCRIBE_SPIRV_GLSL_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_GLSL_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_GLSL_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_GLSL_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_JSON_FILE "${AUTOSCRIBE_OUTPUT_FILE}.json")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/json" "${AUTOSCRIBE_SPIRV_JSON_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_JSON_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_JSON_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND REFLECTED_SHADERS ${AUTOSCRIBE_SPIRV_JSON_FILE})
|
||||
|
||||
unset(SHADER_GEN_LINE)
|
||||
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_DIALECT})
|
||||
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_VARIANT})
|
||||
file(RELATIVE_PATH TEMP_PATH ${CMAKE_SOURCE_DIR} ${SHADER_FILE})
|
||||
list(APPEND SHADER_GEN_LINE ${TEMP_PATH})
|
||||
file(RELATIVE_PATH TEMP_PATH ${CMAKE_SOURCE_DIR} ${AUTOSCRIBE_OUTPUT_FILE})
|
||||
list(APPEND SHADER_GEN_LINE ${TEMP_PATH})
|
||||
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_SHADER_SEEN_LIBS})
|
||||
string(CONCAT AUTOSCRIBE_SHADERGEN_COMMANDS "${AUTOSCRIBE_SHADERGEN_COMMANDS}" "${SHADER_GEN_LINE}\n")
|
||||
|
||||
# # FIXME need better mechanism for determining the include files
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_OUTPUT_FILE}
|
||||
# COMMAND ${SCRIBE_COMMAND} ${SHADER_FILE} ${SCRIBE_ARGS} -o ${AUTOSCRIBE_OUTPUT_FILE} -h ${AUTOSCRIBE_DIALECT_HEADER} -h ${AUTOSCRIBE_VARIANT_HEADER}
|
||||
# DEPENDS ${SCRIBE_COMMAND} ${SHADER_FILE} ${AUTOSCRIBE_DIALECT_HEADER} ${AUTOSCRIBE_VARIANT_HEADER})
|
||||
|
||||
# # Generate the spirv file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_FILE}
|
||||
# COMMAND ${GLSLANG_EXEC} -V110 -o ${AUTOSCRIBE_SPIRV_FILE} ${AUTOSCRIBE_OUTPUT_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_OUTPUT_FILE} ${GLSLANG_EXEC})
|
||||
|
||||
# # Generate the optimized spirv file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_OPT_FILE}
|
||||
# COMMAND ${SPIRV_OPT_EXEC} -O ${AUTOSCRIBE_SPIRV_FILE} -o ${AUTOSCRIBE_SPIRV_OPT_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_SPIRV_FILE} ${SPIRV_OPT_EXEC})
|
||||
|
||||
# # Generate the optimized GLSL file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_GLSL_FILE}
|
||||
# COMMAND ${SPIRV_CROSS_EXEC} ${SPIRV_CROSS_ARGS} ${AUTOSCRIBE_SPIRV_OPT_FILE} --output ${AUTOSCRIBE_SPIRV_GLSL_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_SPIRV_OPT_FILE} ${SPIRV_CROSS_EXEC})
|
||||
|
||||
# # Generate the optimized spirv file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_JSON_FILE}
|
||||
# COMMAND ${SPIRV_CROSS_EXEC} --reflect json ${AUTOSCRIBE_SPIRV_OPT_FILE} --output ${AUTOSCRIBE_SPIRV_JSON_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_SPIRV_OPT_FILE} ${SPIRV_CROSS_EXEC})
|
||||
endmacro()
|
||||
|
||||
macro(AUTOSCRIBE_SHADER)
|
||||
#
|
||||
# Set the include paths
|
||||
#
|
||||
# FIXME base the include paths off of output from the scribe tool,
|
||||
# instead of treating every previously seen shader as a possible header
|
||||
unset(SHADER_INCLUDE_FILES)
|
||||
# Grab include files
|
||||
foreach(includeFile ${ARGN})
|
||||
list(APPEND SHADER_INCLUDE_FILES ${includeFile})
|
||||
endforeach()
|
||||
|
||||
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
|
||||
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
|
||||
#Extract the unique include shader paths
|
||||
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
|
||||
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
|
||||
#message(ready for includes ${SHADER_INCLUDES_PATHS})
|
||||
|
||||
# make the scribe include arguments
|
||||
set(SCRIBE_INCLUDES)
|
||||
unset(SCRIBE_INCLUDES)
|
||||
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS})
|
||||
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/)
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# Figure out the various output names
|
||||
#
|
||||
# Define the final name of the generated shader file
|
||||
get_filename_component(SHADER_NAME ${SHADER_FILE} NAME_WE)
|
||||
get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
|
||||
|
@ -46,38 +144,36 @@ macro(AUTOSCRIBE_SHADER)
|
|||
elseif(${SHADER_EXT} STREQUAL .slg)
|
||||
set(SHADER_TYPE geom)
|
||||
endif()
|
||||
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
|
||||
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
|
||||
file(TO_CMAKE_PATH "${SHADER_TARGET}" COMPILED_SHADER)
|
||||
set(REFLECTED_SHADER "${COMPILED_SHADER}.json")
|
||||
|
||||
set(SCRIBE_ARGS -T ${SHADER_TYPE} -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
|
||||
set(SCRIBE_ARGS -D GLPROFILE ${GLPROFILE} -T ${SHADER_TYPE} ${SCRIBE_INCLUDES} )
|
||||
|
||||
# Generate the frag/vert file
|
||||
add_custom_command(
|
||||
OUTPUT ${SHADER_TARGET}
|
||||
COMMAND ${SCRIBE_COMMAND} ${SCRIBE_ARGS}
|
||||
DEPENDS ${SHADER_FILE} ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES})
|
||||
# SHADER_SCRIBED -> the output of scribe
|
||||
set(SHADER_SCRIBED "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
|
||||
|
||||
# Generate the json reflection
|
||||
# FIXME move to spirv-cross for this task after we have spirv compatible shaders
|
||||
add_custom_command(
|
||||
OUTPUT ${REFLECTED_SHADER}
|
||||
COMMAND ${SHREFLECT_COMMAND} ${COMPILED_SHADER}
|
||||
DEPENDS ${SHREFLECT_DEPENDENCY} ${COMPILED_SHADER})
|
||||
# SHADER_NAME_FILE -> a file containing the shader name and extension (useful for debugging and for
|
||||
# determining the type of shader from the filename)
|
||||
set(SHADER_NAME_FILE "${SHADER_SCRIBED}.name")
|
||||
file(TO_CMAKE_PATH "${SHADER_SCRIBED}" SHADER_SCRIBED)
|
||||
file(WRITE "${SHADER_SCRIBED}.name" "${SHADER_NAME}.${SHADER_TYPE}")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/name" "${SHADER_NAME_FILE}")
|
||||
|
||||
#output the generated file name
|
||||
source_group("Compiled/${SHADER_LIB}" FILES ${COMPILED_SHADER})
|
||||
set_property(SOURCE ${COMPILED_SHADER} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND COMPILED_SHADERS ${COMPILED_SHADER})
|
||||
if (USE_GLES)
|
||||
set(SPIRV_CROSS_ARGS --version 310es)
|
||||
AUTOSCRIBE_PLATFORM_SHADER("310es")
|
||||
AUTOSCRIBE_PLATFORM_SHADER("310es/stereo")
|
||||
else()
|
||||
set(SPIRV_CROSS_ARGS --version 410 --no-420pack-extension)
|
||||
AUTOSCRIBE_PLATFORM_SHADER("410")
|
||||
AUTOSCRIBE_PLATFORM_SHADER("410/stereo")
|
||||
if (NOT APPLE)
|
||||
set(SPIRV_CROSS_ARGS --version 450)
|
||||
AUTOSCRIBE_PLATFORM_SHADER("450")
|
||||
AUTOSCRIBE_PLATFORM_SHADER("450/stereo")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
source_group("Reflected/${SHADER_LIB}" FILES ${REFLECTED_SHADER})
|
||||
list(APPEND REFLECTED_SHADERS ${REFLECTED_SHADER})
|
||||
|
||||
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}\">${COMPILED_SHADER}</file>\n")
|
||||
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}_reflection\">${REFLECTED_SHADER}</file>\n")
|
||||
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "${SHADER_NAME} = ${SHADER_COUNT},\n")
|
||||
|
||||
string(CONCAT SHADER_SHADERS_ARRAY "${SHADER_SHADERS_ARRAY}" "${SHADER_COUNT},\n")
|
||||
MATH(EXPR SHADER_COUNT "${SHADER_COUNT}+1")
|
||||
endmacro()
|
||||
|
||||
|
@ -86,6 +182,8 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
|||
message(FATAL_ERROR "AUTOSCRIBE_SHADER_LIB can only be used by the shaders library")
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
|
||||
|
||||
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES "${CMAKE_SOURCE_DIR}/libraries/${SHADER_LIB}/src")
|
||||
string(REGEX REPLACE "[-]" "_" SHADER_NAMESPACE ${SHADER_LIB})
|
||||
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace ${SHADER_NAMESPACE} {\n")
|
||||
|
@ -165,66 +263,103 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
|||
|
||||
# Finish the shader enums
|
||||
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "} // namespace ${SHADER_NAMESPACE}\n")
|
||||
#file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
|
||||
#foreach(HIFI_LIBRARY ${ARGN})
|
||||
#list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src)
|
||||
#endforeach()
|
||||
#endif()
|
||||
endmacro()
|
||||
|
||||
macro(AUTOSCRIBE_SHADER_LIBS)
|
||||
set(SCRIBE_COMMAND scribe)
|
||||
set(SHREFLECT_COMMAND shreflect)
|
||||
set(SHREFLECT_DEPENDENCY shreflect)
|
||||
|
||||
# Target dependant Custom rule on the SHADER_FILE
|
||||
if (ANDROID)
|
||||
set(GLPROFILE LINUX_GL)
|
||||
set(SCRIBE_COMMAND ${NATIVE_SCRIBE})
|
||||
set(SHREFLECT_COMMAND ${NATIVE_SHREFLECT})
|
||||
unset(SHREFLECT_DEPENDENCY)
|
||||
else()
|
||||
if (APPLE)
|
||||
set(GLPROFILE MAC_GL)
|
||||
elseif(UNIX)
|
||||
set(GLPROFILE LINUX_GL)
|
||||
else()
|
||||
set(GLPROFILE PC_GL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Shader processing start")
|
||||
set(AUTOSCRIBE_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/headers)
|
||||
# Start the shader IDs
|
||||
set(SHADER_COUNT 1)
|
||||
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
|
||||
set(SHADER_ENUMS "")
|
||||
file(MAKE_DIRECTORY ${SHADERS_DIR})
|
||||
set(SHADER_ENUMS "")
|
||||
set(SHADER_COUNT 1)
|
||||
|
||||
#
|
||||
# Scribe generation & program defintiion
|
||||
#
|
||||
foreach(SHADER_LIB ${ARGN})
|
||||
list(APPEND AUTOSCRIBE_SHADER_SEEN_LIBS ${SHADER_LIB})
|
||||
AUTOSCRIBE_SHADER_LIB(${SHADER_LIB})
|
||||
endforeach()
|
||||
|
||||
# Generate the library files
|
||||
configure_file(
|
||||
ShaderEnums.cpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
|
||||
configure_file(
|
||||
ShaderEnums.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h)
|
||||
configure_file(
|
||||
shaders.qrc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h)
|
||||
|
||||
set(AUTOSCRIBE_SHADER_LIB_SRC "${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h;${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp")
|
||||
set(QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
configure_file(shaders.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
list(APPEND QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
|
||||
list(APPEND AUTOSCRIBE_SHADER_HEADERS ${AUTOSCRIBE_HEADER_DIR}/mono.glsl ${AUTOSCRIBE_HEADER_DIR}/stereo.glsl)
|
||||
list(APPEND AUTOSCRIBE_SHADER_HEADERS ${AUTOSCRIBE_HEADER_DIR}/450/header.glsl ${AUTOSCRIBE_HEADER_DIR}/410/header.glsl ${AUTOSCRIBE_HEADER_DIR}/310es/header.glsl)
|
||||
source_group("Shader Headers" FILES ${AUTOSCRIBE_HEADER_DIR}/mono.glsl ${AUTOSCRIBE_HEADER_DIR}/stereo.glsl)
|
||||
source_group("Shader Headers\\450" FILES ${AUTOSCRIBE_HEADER_DIR}/450/header.glsl)
|
||||
source_group("Shader Headers\\410" FILES ${AUTOSCRIBE_HEADER_DIR}/410/header.glsl)
|
||||
source_group("Shader Headers\\310es" FILES ${AUTOSCRIBE_HEADER_DIR}/310es/header.glsl)
|
||||
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${AUTOSCRIBE_SHADER_HEADERS})
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
|
||||
|
||||
# Write the shadergen command list
|
||||
set(AUTOSCRIBE_SHADERGEN_COMMANDS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shadergen.txt)
|
||||
file(WRITE ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE} "${AUTOSCRIBE_SHADERGEN_COMMANDS}")
|
||||
|
||||
# grab the SPIRV binaries we require
|
||||
# note we don't use the normal ADD_DEPENDENCY_EXTERNAL_PROJECTS macro because only a custom command
|
||||
# depends on these, not any of our build artifacts, so there's no valid target for the add_dependencies
|
||||
# call in ADD_DEPENDENCY_EXTERNAL_PROJECTS to use
|
||||
add_subdirectory(${EXTERNAL_PROJECT_DIR}/spirv_binaries ${EXTERNALS_BINARY_DIR}/spirv_binaries)
|
||||
|
||||
target_python()
|
||||
|
||||
# A custom python script which will generate
|
||||
if (ANDROID)
|
||||
add_custom_command(
|
||||
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
|
||||
COMMENT "Generating/updating shaders"
|
||||
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_SOURCE_DIR}/tools/shadergen.py
|
||||
--commands ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE}
|
||||
--spirv-binaries ${SPIRV_BINARIES_DIR}
|
||||
--scribe ${NATIVE_SCRIBE}
|
||||
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
|
||||
--source-dir ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} spirv_binaries ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
|
||||
COMMENT "Generating/updating shaders"
|
||||
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_SOURCE_DIR}/tools/shadergen.py
|
||||
--commands ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE}
|
||||
--spirv-binaries ${SPIRV_BINARIES_DIR}
|
||||
--scribe $<TARGET_FILE:scribe>
|
||||
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
|
||||
--source-dir ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} scribe spirv_binaries ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
|
||||
endif()
|
||||
|
||||
add_custom_target(shadergen DEPENDS ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS})
|
||||
set_target_properties(shadergen PROPERTIES FOLDER "Shaders")
|
||||
|
||||
# Custom targets required to force generation of the shaders via scribe
|
||||
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS})
|
||||
add_custom_target(compiled_shaders SOURCES ${COMPILED_SHADERS})
|
||||
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
|
||||
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS} ${AUTOSCRIBE_SHADER_HEADERS})
|
||||
set_target_properties(scribe_shaders PROPERTIES FOLDER "Shaders")
|
||||
set_target_properties(compiled_shaders PROPERTIES FOLDER "Shaders")
|
||||
|
||||
add_custom_target(scribed_shaders SOURCES ${SCRIBED_SHADERS})
|
||||
set_target_properties(scribed_shaders PROPERTIES FOLDER "Shaders")
|
||||
add_dependencies(scribed_shaders shadergen)
|
||||
|
||||
add_custom_target(spirv_shaders SOURCES ${SPIRV_SHADERS})
|
||||
set_target_properties(spirv_shaders PROPERTIES FOLDER "Shaders")
|
||||
add_dependencies(spirv_shaders shadergen)
|
||||
|
||||
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
|
||||
set_target_properties(reflected_shaders PROPERTIES FOLDER "Shaders")
|
||||
add_dependencies(reflected_shaders shadergen)
|
||||
|
||||
message(STATUS "Shader processing end")
|
||||
endmacro()
|
||||
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ macro(TARGET_PYTHON)
|
|||
set(HIFI_PYTHON_EXEC ${Python3_EXECUTABLE})
|
||||
endif()
|
||||
|
||||
if ((NOT HIFI_PYTHON_EXEC) OR (HIFI_PYTHON_VERSION VERSION_LESS 3.6))
|
||||
message(FATAL_ERROR "Unable to locate Python interpreter 3.6 or higher")
|
||||
if ((NOT HIFI_PYTHON_EXEC) OR (HIFI_PYTHON_VERSION VERSION_LESS 3.5))
|
||||
message(FATAL_ERROR "Unable to locate Python interpreter 3.5 or higher")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
15
cmake/macros/TargetSPIRV.cmake
Normal file
15
cmake/macros/TargetSPIRV.cmake
Normal file
|
@ -0,0 +1,15 @@
|
|||
macro(TARGET_SPIRV)
|
||||
add_dependency_external_projects(spirv_cross)
|
||||
target_link_libraries(${TARGET_NAME} ${SPIRV_CROSS_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SPIRV_CROSS_INCLUDE_DIRS})
|
||||
|
||||
# spirv-tools requires spirv-headers
|
||||
add_dependency_external_projects(spirv_headers)
|
||||
add_dependency_external_projects(spirv_tools)
|
||||
target_link_libraries(${TARGET_NAME} ${SPIRV_TOOLS_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SPIRV_TOOLS_INCLUDE_DIRS})
|
||||
|
||||
add_dependency_external_projects(glslang)
|
||||
target_link_libraries(${TARGET_NAME} ${GLSLANG_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${GLSLANG_INCLUDE_DIRS})
|
||||
endmacro()
|
10
cmake/macros/TargetSpirvBinaries.cmake
Normal file
10
cmake/macros/TargetSpirvBinaries.cmake
Normal file
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Created by Bradley Austin Davis on 2016/02/16
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
macro(TARGET_SPIRV_BINARIES)
|
||||
add_dependency_external_projects(spirv_binaries)
|
||||
endmacro()
|
||||
|
19
cmake/macros/TargetVulkan.cmake
Normal file
19
cmake/macros/TargetVulkan.cmake
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Created by Bradley Austin Davis on 2016/02/16
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
macro(TARGET_VULKAN)
|
||||
find_package(Vulkan)
|
||||
|
||||
if (Vulkan_FOUND)
|
||||
add_definitions(-DHAVE_VULKAN)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${Vulkan_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${Vulkan_LIBRARIES})
|
||||
|
||||
add_dependency_external_projects(glslang)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${GLSLANG_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${GLSLANG_LIBRARIES})
|
||||
endif()
|
||||
endmacro()
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME avatars-renderer)
|
||||
setup_hifi_library(Network Script)
|
||||
link_hifi_libraries(shared gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
|
||||
link_hifi_libraries(shared shaders gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
|
||||
include_hifi_library_headers(avatars)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(fbx)
|
||||
|
|
|
@ -2,11 +2,11 @@ struct TextureData {
|
|||
ivec2 textureSize;
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform textureDataBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform textureDataBuffer {
|
||||
TextureData textureData;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
|
|
|
@ -363,56 +363,35 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
}
|
||||
|
||||
if (!_presentPipeline) {
|
||||
gpu::StatePointer blendState = gpu::StatePointer(new gpu::State());
|
||||
blendState->setDepthTest(gpu::State::DepthTest(false));
|
||||
blendState->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
gpu::StatePointer scissorState = gpu::StatePointer(new gpu::State());
|
||||
scissorState->setDepthTest(gpu::State::DepthTest(false));
|
||||
scissorState->setScissorEnable(true);
|
||||
|
||||
{
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::drawTexture);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setScissorEnable(true);
|
||||
_simplePipeline = gpu::Pipeline::create(program, state);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
|
||||
_simplePipeline = gpu::Pipeline::create(program, scissorState);
|
||||
_hudPipeline = gpu::Pipeline::create(program, blendState);
|
||||
}
|
||||
|
||||
{
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::SrgbToLinear);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setScissorEnable(true);
|
||||
_presentPipeline = gpu::Pipeline::create(program, state);
|
||||
_presentPipeline = gpu::Pipeline::create(program, scissorState);
|
||||
}
|
||||
|
||||
{
|
||||
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord);
|
||||
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_hudPipeline = gpu::Pipeline::create(program, state);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX);
|
||||
_mirrorHUDPipeline = gpu::Pipeline::create(program, blendState);
|
||||
}
|
||||
|
||||
{
|
||||
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord);
|
||||
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTextureMirroredX);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_mirrorHUDPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
{
|
||||
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawTransformUnitQuad);
|
||||
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_cursorPipeline = gpu::Pipeline::create(program, state);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTransformedTexture);
|
||||
_cursorPipeline = gpu::Pipeline::create(program, blendState);
|
||||
}
|
||||
}
|
||||
updateCompositeFramebuffer();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// OpenGLDisplayPlugin_present.frag
|
||||
|
||||
layout(binding = 0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location = 0) in vec2 varTexCoord0;
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
float sRGBFloatToLinear(float value) {
|
||||
const float SRGB_ELBOW = 0.04045;
|
||||
|
|
|
@ -30,12 +30,14 @@ using namespace render::entities;
|
|||
// is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down.
|
||||
static const float SPHERE_ENTITY_SCALE = 0.5f;
|
||||
|
||||
static_assert(shader::render_utils::program::simple != 0, "Validate simple program exists");
|
||||
static_assert(shader::render_utils::program::simple_transparent != 0, "Validate simple transparent program exists");
|
||||
|
||||
ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
|
||||
_procedural._vertexSource = gpu::Shader::getVertexShaderSource(shader::render_utils::vertex::simple);
|
||||
// FIXME: Setup proper uniform slots and use correct pipelines for forward rendering
|
||||
_procedural._opaquefragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple);
|
||||
_procedural._transparentfragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple_transparent);
|
||||
_procedural._opaqueFragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::simple);
|
||||
_procedural._transparentFragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::simple_transparent);
|
||||
_procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
|
||||
_procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=0) in vec3 interpolatedNormal;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<$declareFadeFragment()$>
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=0) in vec3 interpolatedNormal;
|
||||
|
@ -30,7 +30,7 @@ struct PolyLineUniforms {
|
|||
vec3 color;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform polyLineBuffer {
|
||||
LAYOUT(binding=0) uniform polyLineBuffer {
|
||||
PolyLineUniforms polyline;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,15 +20,15 @@ layout(location=RENDER_UTILS_ATTR_NORMAL_MS) in vec3 _normal;
|
|||
layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec4 _position;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition;
|
||||
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
|
||||
struct PolyvoxParams {
|
||||
vec4 voxelVolumeSize;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform polyvoxParamsBuffer {
|
||||
LAYOUT(binding=0) uniform polyvoxParamsBuffer {
|
||||
PolyvoxParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@ layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec4 _position;
|
|||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _worldFadePosition;
|
||||
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
|
||||
struct PolyvoxParams {
|
||||
vec4 voxelVolumeSize;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform polyvoxParamsBuffer {
|
||||
LAYOUT(binding=0) uniform polyvoxParamsBuffer {
|
||||
PolyvoxParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec4 varColor;
|
||||
layout(location=1) in vec2 varTexcoord;
|
||||
|
|
|
@ -43,7 +43,7 @@ struct ParticleUniforms {
|
|||
vec2 spare;
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform particleBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform particleBuffer {
|
||||
ParticleUniforms particle;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,4 +5,4 @@ include_hifi_library_headers(fbx)
|
|||
include_hifi_library_headers(gpu)
|
||||
include_hifi_library_headers(image)
|
||||
include_hifi_library_headers(ktx)
|
||||
link_hifi_libraries(shared networking octree avatars graphics model-networking)
|
||||
link_hifi_libraries(shared shaders networking octree avatars graphics model-networking)
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME gpu-gl-common)
|
||||
setup_hifi_library(Concurrent)
|
||||
link_hifi_libraries(shared gl gpu)
|
||||
link_hifi_libraries(shared gl gpu shaders)
|
||||
GroupSources("src")
|
||||
target_opengl()
|
||||
|
||||
|
|
|
@ -643,18 +643,21 @@ protected:
|
|||
}
|
||||
} _pipeline;
|
||||
|
||||
// Backend dependant compilation of the shader
|
||||
// Backend dependent compilation of the shader
|
||||
virtual void postLinkProgram(ShaderObject& programObject, const Shader& program) const;
|
||||
virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler);
|
||||
virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler);
|
||||
virtual std::string getBackendShaderHeader() const = 0;
|
||||
// For a program, this will return a string containing all the source files (without any
|
||||
// backend headers or defines). For a vertex, fragment or geometry shader, this will
|
||||
// return the fully customized shader with all the version and backend specific
|
||||
|
||||
// For a program, this will return a string containing all the source files (without any
|
||||
// backend headers or defines). For a vertex, fragment or geometry shader, this will
|
||||
// return the fully customized shader with all the version and backend specific
|
||||
// preprocessor directives
|
||||
// The program string returned can be used as a key for a cache of shader binaries
|
||||
// The shader strings can be reliably sent to the low level `compileShader` functions
|
||||
virtual std::string getShaderSource(const Shader& shader, int version) final;
|
||||
virtual std::string getShaderSource(const Shader& shader, shader::Variant version) final;
|
||||
shader::Variant getShaderVariant() const { return isStereo() ? shader::Variant::Stereo : shader::Variant::Mono; }
|
||||
virtual shader::Dialect getShaderDialect() const = 0;
|
||||
|
||||
class ElementResource {
|
||||
public:
|
||||
gpu::Element _element;
|
||||
|
|
|
@ -54,7 +54,7 @@ void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) {
|
|||
// check the program cache
|
||||
// pick the program version
|
||||
#ifdef GPU_STEREO_CAMERA_BUFFER
|
||||
GLuint glprogram = pipelineObject->_program->getProgram((GLShader::Version)isStereo());
|
||||
GLuint glprogram = pipelineObject->_program->getProgram(getShaderVariant());
|
||||
#else
|
||||
GLuint glprogram = pipelineObject->_program->getProgram();
|
||||
#endif
|
||||
|
|
|
@ -25,120 +25,53 @@ static const std::array<GLenum, NUM_SHADER_DOMAINS> SHADER_DOMAINS{ {
|
|||
GL_GEOMETRY_SHADER,
|
||||
} };
|
||||
|
||||
// Domain specific defines
|
||||
// Must match the order of type specified in gpu::Shader::Type
|
||||
static const std::array<std::string, NUM_SHADER_DOMAINS> DOMAIN_DEFINES{ {
|
||||
"#define GPU_VERTEX_SHADER",
|
||||
"#define GPU_PIXEL_SHADER",
|
||||
"#define GPU_GEOMETRY_SHADER",
|
||||
} };
|
||||
|
||||
// Stereo specific defines
|
||||
static const std::string stereoVersion{
|
||||
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
||||
R"SHADER(
|
||||
#define GPU_TRANSFORM_IS_STEREO
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA_INSTANCED
|
||||
#define GPU_TRANSFORM_STEREO_SPLIT_SCREEN
|
||||
)SHADER"
|
||||
#endif
|
||||
#ifdef GPU_STEREO_DRAWCALL_DOUBLED
|
||||
#ifdef GPU_STEREO_CAMERA_BUFFER
|
||||
R"SHADER(
|
||||
#define GPU_TRANSFORM_IS_STEREO
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA_ATTRIBUTED
|
||||
)SHADER"
|
||||
#else
|
||||
R"SHADER(
|
||||
#define GPU_TRANSFORM_IS_STEREO
|
||||
)SHADER"
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
// TextureTable specific defines
|
||||
static const std::string textureTableVersion {
|
||||
"#extension GL_ARB_bindless_texture : require\n#define GPU_TEXTURE_TABLE_BINDLESS\n"
|
||||
};
|
||||
|
||||
// Versions specific of the shader
|
||||
static const std::array<std::string, GLShader::NumVersions> VERSION_DEFINES { {
|
||||
"",
|
||||
stereoVersion
|
||||
} };
|
||||
|
||||
static std::string getShaderTypeString(Shader::Type type) {
|
||||
switch (type) {
|
||||
case Shader::Type::VERTEX:
|
||||
return "vertex";
|
||||
case Shader::Type::PIXEL:
|
||||
return "pixel";
|
||||
case Shader::Type::GEOMETRY:
|
||||
return "geometry";
|
||||
case Shader::Type::PROGRAM:
|
||||
return "program";
|
||||
default:
|
||||
qFatal("Unexpected shader type %d", type);
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GLBackend::getShaderSource(const Shader& shader, int version) {
|
||||
std::string GLBackend::getShaderSource(const Shader& shader, shader::Variant variant) {
|
||||
if (shader.isProgram()) {
|
||||
std::string result;
|
||||
result.append("// VERSION " + std::to_string(version));
|
||||
for (const auto& subShader : shader.getShaders()) {
|
||||
result.append("//-------- ");
|
||||
result.append(getShaderTypeString(subShader->getType()));
|
||||
result.append("\n");
|
||||
result.append(subShader->getSource().getCode());
|
||||
if (subShader) {
|
||||
result += subShader->getSource().getSource(getShaderDialect(), variant);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string shaderDefines = getBackendShaderHeader() + "\n"
|
||||
+ (supportsBindless() ? textureTableVersion : "\n")
|
||||
+ DOMAIN_DEFINES[shader.getType()] + "\n"
|
||||
+ VERSION_DEFINES[version];
|
||||
|
||||
return shaderDefines + "\n" + shader.getSource().getCode();
|
||||
}
|
||||
return shader.getSource().getSource(getShaderDialect(), variant);
|
||||
}
|
||||
|
||||
GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler) {
|
||||
// Any GLSLprogram ? normally yes...
|
||||
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
|
||||
GLShader::ShaderObjects shaderObjects;
|
||||
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
|
||||
const auto& variants = shader::allVariants();
|
||||
Shader::CompilationLogs compilationLogs(variants.size());
|
||||
shader.incrementCompilationAttempt();
|
||||
|
||||
for (int version = 0; version < GLShader::NumVersions; version++) {
|
||||
auto& shaderObject = shaderObjects[version];
|
||||
auto shaderSource = getShaderSource(shader, version);
|
||||
for (const auto& variant : variants) {
|
||||
auto index = static_cast<uint32_t>(variant);
|
||||
auto shaderSource = getShaderSource(shader, variant);
|
||||
auto& shaderObject = shaderObjects[index];
|
||||
if (handler) {
|
||||
bool retest = true;
|
||||
std::string currentSrc = shaderSource;
|
||||
// When a Handler is specified, we can try multiple times to build the shader and let the handler change the source if the compilation fails.
|
||||
// The retest bool is set to false as soon as the compilation succeed to wexit the while loop.
|
||||
// The retest bool is set to false as soon as the compilation succeed to exit the while loop.
|
||||
// The handler tells us if we should retry or not while returning a modified version of the source.
|
||||
while (retest) {
|
||||
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[version].message);
|
||||
compilationLogs[version].compiled = result;
|
||||
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[index].message);
|
||||
compilationLogs[index].compiled = result;
|
||||
if (!result) {
|
||||
std::string newSrc;
|
||||
retest = handler(shader, currentSrc, compilationLogs[version], newSrc);
|
||||
retest = handler(shader, currentSrc, compilationLogs[index], newSrc);
|
||||
currentSrc = newSrc;
|
||||
} else {
|
||||
retest = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
compilationLogs[version].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderObject.glshader, compilationLogs[version].message);
|
||||
compilationLogs[index].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderObject.glshader, compilationLogs[index].message);
|
||||
}
|
||||
|
||||
if (!compilationLogs[version].compiled) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[version].message.c_str();
|
||||
if (!compilationLogs[index].compiled) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[index].message.c_str();
|
||||
shader.setCompilationLogs(compilationLogs);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -162,11 +95,13 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
|
||||
GLShader::ShaderObjects programObjects;
|
||||
program.incrementCompilationAttempt();
|
||||
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
|
||||
const auto& variants = shader::allVariants();
|
||||
Shader::CompilationLogs compilationLogs(variants.size());
|
||||
|
||||
for (int version = 0; version < GLShader::NumVersions; version++) {
|
||||
auto& programObject = programObjects[version];
|
||||
auto programSource = getShaderSource(program, version);
|
||||
for (const auto& variant : variants) {
|
||||
auto index = static_cast<uint32_t>(variant);
|
||||
auto& programObject = programObjects[index];
|
||||
auto programSource = getShaderSource(program, variant);
|
||||
auto hash = ::gl::getShaderHash(programSource);
|
||||
|
||||
CachedShader cachedBinary;
|
||||
|
@ -199,11 +134,11 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
for (auto subShader : program.getShaders()) {
|
||||
auto object = GLShader::sync((*this), *subShader, handler);
|
||||
if (object) {
|
||||
shaderGLObjects.push_back(object->_shaderObjects[version].glshader);
|
||||
shaderGLObjects.push_back(object->_shaderObjects[index].glshader);
|
||||
} else {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?";
|
||||
compilationLogs[version].compiled = false;
|
||||
compilationLogs[version].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
|
||||
compilationLogs[index].compiled = false;
|
||||
compilationLogs[index].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
|
||||
program.setCompilationLogs(compilationLogs);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -211,9 +146,9 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
|
||||
glprogram = ::gl::buildProgram(shaderGLObjects);
|
||||
|
||||
if (!::gl::linkProgram(glprogram, compilationLogs[version].message)) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str();
|
||||
compilationLogs[version].compiled = false;
|
||||
if (!::gl::linkProgram(glprogram, compilationLogs[index].message)) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[index].message.c_str();
|
||||
compilationLogs[index].compiled = false;
|
||||
glDeleteProgram(glprogram);
|
||||
glprogram = 0;
|
||||
return nullptr;
|
||||
|
@ -228,12 +163,12 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
}
|
||||
|
||||
if (glprogram == 0) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str();
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[index].message.c_str();
|
||||
program.setCompilationLogs(compilationLogs);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
compilationLogs[version].compiled = true;
|
||||
compilationLogs[index].compiled = true;
|
||||
programObject.glprogram = glprogram;
|
||||
postLinkProgram(programObject, program);
|
||||
}
|
||||
|
@ -249,7 +184,10 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
static const GLint INVALID_UNIFORM_INDEX = -1;
|
||||
|
||||
GLint GLBackend::getRealUniformLocation(GLint location) const {
|
||||
auto& shader = _pipeline._programShader->_shaderObjects[(GLShader::Version)isStereo()];
|
||||
auto variant = isStereo() ? shader::Variant::Stereo : shader::Variant::Mono;
|
||||
auto index = static_cast<uint32_t>(variant);
|
||||
|
||||
auto& shader = _pipeline._programShader->_shaderObjects[index];
|
||||
auto itr = shader.uniformRemap.find(location);
|
||||
if (itr == shader.uniformRemap.end()) {
|
||||
// This shouldn't happen, because we use reflection to determine all the possible
|
||||
|
@ -264,20 +202,23 @@ GLint GLBackend::getRealUniformLocation(GLint location) const {
|
|||
|
||||
void GLBackend::postLinkProgram(ShaderObject& shaderObject, const Shader& program) const {
|
||||
const auto& glprogram = shaderObject.glprogram;
|
||||
const auto& expectedUniforms = program.getUniforms();
|
||||
const auto expectedLocationsByName = expectedUniforms.getLocationsByName();
|
||||
const auto uniforms = ::gl::Uniform::load(glprogram, expectedUniforms.getNames());
|
||||
auto& uniformRemap = shaderObject.uniformRemap;
|
||||
const auto& expectedUniforms = program.getReflection().uniforms;
|
||||
|
||||
// Pre-initialize all the uniforms with an invalid location
|
||||
for (const auto& entry : expectedLocationsByName) {
|
||||
auto& uniformRemap = shaderObject.uniformRemap;
|
||||
// initialize all the uniforms with an invalid location
|
||||
for (const auto& entry : expectedUniforms) {
|
||||
uniformRemap[entry.second] = INVALID_UNIFORM_INDEX;
|
||||
}
|
||||
|
||||
// Now load up all the actual found uniform location
|
||||
|
||||
// Get the actual uniform locations from the shader
|
||||
const auto names = Shader::Reflection::getNames(expectedUniforms);
|
||||
const auto uniforms = ::gl::Uniform::load(glprogram, names);
|
||||
|
||||
// Now populate the remapping with the found locations
|
||||
for (const auto& uniform : uniforms) {
|
||||
const auto& name = uniform.name;
|
||||
const auto& expectedLocation = expectedLocationsByName.at(name);
|
||||
const auto& expectedLocation = expectedUniforms.at(name);
|
||||
const auto& location = uniform.binding;
|
||||
uniformRemap[expectedLocation] = location;
|
||||
}
|
||||
|
@ -462,3 +403,4 @@ void GLBackend::initShaderBinaryCache() {
|
|||
void GLBackend::killShaderBinaryCache() {
|
||||
::gl::saveShaderCache(_shaderBinaryCache._binaries);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ GLPipeline* GLPipeline::sync(GLBackend& backend, const Pipeline& pipeline) {
|
|||
// Special case for view correction matrices, any pipeline that declares the correction buffer
|
||||
// uniform will automatically have it provided without any client code necessary.
|
||||
// Required for stable lighting in the HMD.
|
||||
object->_cameraCorrection = shader->getUniformBuffers().isValid(gpu::slot::buffer::CameraCorrection);
|
||||
object->_cameraCorrection = shader->getReflection().validUniformBuffer(gpu::slot::buffer::CameraCorrection);
|
||||
object->_program = programObject;
|
||||
object->_state = stateObject;
|
||||
|
||||
|
|
|
@ -14,43 +14,45 @@
|
|||
namespace gpu { namespace gl {
|
||||
|
||||
struct ShaderObject {
|
||||
GLuint glshader { 0 };
|
||||
GLuint glprogram { 0 };
|
||||
enum class BindingType
|
||||
{
|
||||
INPUT,
|
||||
OUTPUT,
|
||||
TEXTURE,
|
||||
SAMPLER,
|
||||
UNIFORM_BUFFER,
|
||||
RESOURCE_BUFFER,
|
||||
UNIFORM,
|
||||
};
|
||||
|
||||
using LocationMap = std::unordered_map <GLuint, GLuint>;
|
||||
LocationMap uniformRemap;
|
||||
using LocationMap = std::unordered_map<std::string, int32_t>;
|
||||
using ReflectionMap = std::map<BindingType, LocationMap>;
|
||||
using UniformMap = std::unordered_map<GLuint, GLuint>;
|
||||
|
||||
GLuint glshader{ 0 };
|
||||
GLuint glprogram{ 0 };
|
||||
|
||||
UniformMap uniformRemap;
|
||||
};
|
||||
|
||||
class GLShader : public GPUObject {
|
||||
public:
|
||||
static GLShader* sync(GLBackend& backend, const Shader& shader, const Shader::CompilationHandler& handler = nullptr);
|
||||
|
||||
enum Version {
|
||||
Mono = 0,
|
||||
Stereo,
|
||||
|
||||
NumVersions
|
||||
};
|
||||
|
||||
using ShaderObject = gpu::gl::ShaderObject;
|
||||
using ShaderObjects = std::array< ShaderObject, NumVersions >;
|
||||
|
||||
using UniformMapping = std::map<GLint, GLint>;
|
||||
using UniformMappingVersions = std::vector<UniformMapping>;
|
||||
using ShaderObjects = std::array<ShaderObject, shader::NUM_VARIANTS>;
|
||||
|
||||
GLShader(const std::weak_ptr<GLBackend>& backend);
|
||||
~GLShader();
|
||||
|
||||
ShaderObjects _shaderObjects;
|
||||
|
||||
GLuint getProgram(Version version = Mono) const {
|
||||
return _shaderObjects[version].glprogram;
|
||||
GLuint getProgram(shader::Variant version = shader::Variant::Mono) const {
|
||||
return _shaderObjects[static_cast<uint32_t>(version)].glprogram;
|
||||
}
|
||||
|
||||
const std::weak_ptr<GLBackend> _backend;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
}} // namespace gpu::gl
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME gpu-gl)
|
||||
setup_hifi_library(Concurrent)
|
||||
link_hifi_libraries(shared gl gpu gpu-gl-common)
|
||||
link_hifi_libraries(shared gl gpu gpu-gl-common shaders)
|
||||
if (UNIX)
|
||||
target_link_libraries(${TARGET_NAME} pthread)
|
||||
endif(UNIX)
|
||||
|
|
|
@ -170,8 +170,7 @@ protected:
|
|||
// Output stage
|
||||
void do_blit(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
std::string getBackendShaderHeader() const override;
|
||||
|
||||
shader::Dialect getShaderDialect() const override { return shader::Dialect::glsl410; }
|
||||
void postLinkProgram(ShaderObject& programObject, const Shader& program) const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,22 +12,13 @@ using namespace gpu;
|
|||
using namespace gpu::gl;
|
||||
using namespace gpu::gl41;
|
||||
|
||||
// GLSL version
|
||||
std::string GL41Backend::getBackendShaderHeader() const {
|
||||
static const std::string header(
|
||||
R"SHADER(#version 410 core
|
||||
#define GPU_GL410
|
||||
#define BITFIELD int
|
||||
)SHADER");
|
||||
return header;
|
||||
}
|
||||
|
||||
void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& program) const {
|
||||
Parent::postLinkProgram(programObject, program);
|
||||
const auto& glprogram = programObject.glprogram;
|
||||
const auto& reflection = program.getReflection();
|
||||
// For the UBOs, use glUniformBlockBinding to fixup the locations based on the reflection
|
||||
{
|
||||
const auto expectedUbos = program.getUniformBuffers().getLocationsByName();
|
||||
const auto& expectedUbos = reflection.uniformBuffers;
|
||||
auto ubos = ::gl::UniformBlock::load(glprogram);
|
||||
for (const auto& ubo : ubos) {
|
||||
const auto& name = ubo.name;
|
||||
|
@ -41,7 +32,7 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
|
|||
|
||||
// For the Textures, use glUniform1i to fixup the active texture slots based on the reflection
|
||||
{
|
||||
const auto expectedTextures = program.getTextures().getLocationsByName();
|
||||
const auto& expectedTextures = reflection.textures;
|
||||
for (const auto& expectedTexture : expectedTextures) {
|
||||
auto location = glGetUniformLocation(glprogram, expectedTexture.first.c_str());
|
||||
if (location < 0) {
|
||||
|
@ -53,8 +44,9 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
|
|||
|
||||
// For the resource buffers, do the same as for the textures, since in GL 4.1 that's how they're implemented
|
||||
{
|
||||
const auto expectedResourceBuffers = program.getResourceBuffers().getLocationsByName();
|
||||
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, program.getResourceBuffers().getNames());
|
||||
const auto& expectedResourceBuffers = reflection.resourceBuffers;
|
||||
const auto names = Shader::Reflection::getNames(expectedResourceBuffers);
|
||||
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names);
|
||||
for (const auto& resourceBuffer : resourceBufferUniforms) {
|
||||
const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name);
|
||||
glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding + GL41Backend::RESOURCE_BUFFER_SLOT0_TEX_UNIT);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define GPU_BINDLESS_TEXTURES 0
|
||||
|
||||
namespace gpu { namespace gl45 {
|
||||
|
||||
|
||||
using namespace gpu::gl;
|
||||
using TextureWeakPointer = std::weak_ptr<Texture>;
|
||||
|
||||
|
@ -56,6 +56,7 @@ public:
|
|||
using Parent = GLTexture;
|
||||
friend class GL45Backend;
|
||||
static GLuint allocate(const Texture& texture);
|
||||
|
||||
protected:
|
||||
GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
void generateMips() const override;
|
||||
|
@ -88,6 +89,7 @@ public:
|
|||
virtual const Bindless& getBindless() const;
|
||||
void releaseBindless() const;
|
||||
void recreateBindless() const;
|
||||
|
||||
private:
|
||||
mutable Bindless _bindless;
|
||||
#endif
|
||||
|
@ -98,10 +100,11 @@ public:
|
|||
mutable Sampler _cachedSampler{ getInvalidSampler() };
|
||||
};
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
class GL45TextureTable : public GLObject<TextureTable> {
|
||||
static GLuint allocate();
|
||||
using Parent = GLObject<TextureTable>;
|
||||
|
||||
public:
|
||||
using BindlessArray = std::array<GL45Texture::Bindless, TextureTable::COUNT>;
|
||||
|
||||
|
@ -116,7 +119,6 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Textures that have fixed allocation sizes and cannot be managed at runtime
|
||||
//
|
||||
|
@ -134,12 +136,13 @@ public:
|
|||
|
||||
void allocateStorage() const;
|
||||
void syncSampler() const override;
|
||||
const Size _size { 0 };
|
||||
const Size _size{ 0 };
|
||||
};
|
||||
|
||||
class GL45AttachmentTexture : public GL45FixedAllocationTexture {
|
||||
using Parent = GL45FixedAllocationTexture;
|
||||
friend class GL45Backend;
|
||||
|
||||
protected:
|
||||
GL45AttachmentTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
~GL45AttachmentTexture();
|
||||
|
@ -148,6 +151,7 @@ public:
|
|||
class GL45StrictResourceTexture : public GL45FixedAllocationTexture {
|
||||
using Parent = GL45FixedAllocationTexture;
|
||||
friend class GL45Backend;
|
||||
|
||||
protected:
|
||||
GL45StrictResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
~GL45StrictResourceTexture();
|
||||
|
@ -179,6 +183,7 @@ public:
|
|||
class GL45ResourceTexture : public GL45VariableAllocationTexture {
|
||||
using Parent = GL45VariableAllocationTexture;
|
||||
friend class GL45Backend;
|
||||
|
||||
protected:
|
||||
GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
|
||||
|
@ -186,7 +191,6 @@ public:
|
|||
size_t promote() override;
|
||||
size_t demote() override;
|
||||
void populateTransferQueue(TransferQueue& pendingTransfers) override;
|
||||
|
||||
|
||||
void allocateStorage(uint16 mip);
|
||||
Size copyMipsFromTexture();
|
||||
|
@ -226,7 +230,6 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||
|
@ -244,7 +247,6 @@ protected:
|
|||
GLuint getQueryID(const QueryPointer& query) override;
|
||||
GLQuery* syncGPUObject(const Query& query) override;
|
||||
|
||||
|
||||
// Draw Stage
|
||||
void do_draw(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawIndexed(const Batch& batch, size_t paramOffset) override;
|
||||
|
@ -270,7 +272,7 @@ protected:
|
|||
void do_blit(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
// Shader Stage
|
||||
std::string getBackendShaderHeader() const override;
|
||||
shader::Dialect getShaderDialect() const override;
|
||||
|
||||
// Texture Management Stage
|
||||
void initTextureManagementStage() override;
|
||||
|
@ -282,9 +284,8 @@ protected:
|
|||
#endif
|
||||
};
|
||||
|
||||
} }
|
||||
}} // namespace gpu::gl45
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(gpugl45logging)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,22 +7,16 @@
|
|||
//
|
||||
#include "GL45Backend.h"
|
||||
#include <gpu/gl/GLShader.h>
|
||||
//#include <gl/GLShaders.h>
|
||||
|
||||
using namespace gpu;
|
||||
using namespace gpu::gl;
|
||||
using namespace gpu::gl45;
|
||||
|
||||
// GLSL version
|
||||
std::string GL45Backend::getBackendShaderHeader() const {
|
||||
static const std::string header(
|
||||
R"SHADER(#version 450 core
|
||||
#define GPU_GL450
|
||||
#define BITFIELD int
|
||||
)SHADER"
|
||||
#ifdef GPU_SSBO_TRANSFORM_OBJECT
|
||||
R"SHADER(#define GPU_SSBO_TRANSFORM_OBJECT)SHADER"
|
||||
shader::Dialect GL45Backend::getShaderDialect() const {
|
||||
#if defined(Q_OS_MAC)
|
||||
// We build, but don't actually use GL 4.5 on OSX
|
||||
throw std::runtime_error("GL 4.5 unavailable on OSX");
|
||||
#else
|
||||
return shader::Dialect::glsl450;
|
||||
#endif
|
||||
);
|
||||
return header;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
set(TARGET_NAME gpu-gles)
|
||||
setup_hifi_library(Gui Concurrent)
|
||||
link_hifi_libraries(shared gl gpu gpu-gl-common)
|
||||
link_hifi_libraries(shared shaders gl gpu gpu-gl-common)
|
||||
GroupSources("src")
|
||||
target_opengl()
|
||||
|
|
|
@ -27,11 +27,7 @@ class GLESBackend : public GLBackend {
|
|||
friend class Context;
|
||||
|
||||
public:
|
||||
static const GLint TRANSFORM_OBJECT_SLOT { 31 };
|
||||
static const GLint RESOURCE_TRANSFER_TEX_UNIT { 32 };
|
||||
static const GLint RESOURCE_TRANSFER_EXTRA_TEX_UNIT { 33 };
|
||||
static const GLint RESOURCE_BUFFER_TEXBUF_TEX_UNIT { 34 };
|
||||
static const GLint RESOURCE_BUFFER_SLOT0_TEX_UNIT { 35 };
|
||||
explicit GLESBackend(bool syncCache) : Parent(syncCache) {}
|
||||
GLESBackend() : Parent() {}
|
||||
virtual ~GLESBackend() {
|
||||
|
@ -166,7 +162,7 @@ protected:
|
|||
// Output stage
|
||||
void do_blit(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
std::string getBackendShaderHeader() const override;
|
||||
shader::Dialect getShaderDialect() const override { return shader::Dialect::glsl310es; }
|
||||
};
|
||||
|
||||
} }
|
||||
|
|
|
@ -12,15 +12,3 @@ using namespace gpu;
|
|||
using namespace gpu::gl;
|
||||
using namespace gpu::gles;
|
||||
|
||||
// GLSL version
|
||||
std::string GLESBackend::getBackendShaderHeader() const {
|
||||
static const std::string header(
|
||||
R"SHADER(#version 310 es
|
||||
#extension GL_EXT_texture_buffer : enable
|
||||
precision highp float;
|
||||
precision highp samplerBuffer;
|
||||
precision highp sampler2DShadow;
|
||||
#define BITFIELD highp int
|
||||
)SHADER");
|
||||
return header;
|
||||
}
|
||||
|
|
|
@ -60,12 +60,11 @@ void GLESBackend::transferTransformState(const Batch& batch) const {
|
|||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + GLESBackend::TRANSFORM_OBJECT_SLOT);
|
||||
glActiveTexture(GL_TEXTURE0 + slot::texture::ObjectTransforms);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture);
|
||||
if (!batch._objects.empty()) {
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer);
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
// Make sure the current Camera offset is unknown before render Draw
|
||||
|
|
|
@ -17,7 +17,7 @@ struct DrawColorParams {
|
|||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform drawColorParamsBuffer {
|
||||
LAYOUT(binding=0) uniform drawColorParamsBuffer {
|
||||
DrawColorParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
struct DrawColorParams {
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform drawColorParams {
|
||||
LAYOUT(binding=0) uniform drawColorParams {
|
||||
DrawColorParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ struct TexCoordRectParams {
|
|||
vec4 texcoordRect;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform texcoordRectBuffer {
|
||||
LAYOUT(binding=0) uniform texcoordRectBuffer {
|
||||
TexCoordRectParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
VERTEX DrawUnitQuadTexcoord
|
||||
FRAGMENT DrawTexture
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
|
1
libraries/gpu/src/gpu/DrawTextureMirroredX.slp
Normal file
1
libraries/gpu/src/gpu/DrawTextureMirroredX.slp
Normal file
|
@ -0,0 +1 @@
|
|||
VERTEX DrawUnitQuadTexcoord
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<@include gpu/ShaderConstants.h@>
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
|
||||
|
|
2
libraries/gpu/src/gpu/DrawTransformedTexture.slp
Normal file
2
libraries/gpu/src/gpu/DrawTransformedTexture.slp
Normal file
|
@ -0,0 +1,2 @@
|
|||
VERTEX DrawTransformUnitQuad
|
||||
FRAGMENT DrawTexture
|
|
@ -10,44 +10,49 @@
|
|||
//
|
||||
|
||||
#include "Shader.h"
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
#include <set>
|
||||
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
#include <shaders/Shaders.h>
|
||||
|
||||
#include "Context.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
std::atomic<uint32_t> Shader::_nextShaderID( 1 );
|
||||
Shader::DomainShaderMaps Shader::_domainShaderMaps;
|
||||
Shader::ProgramMap Shader::_programMap;
|
||||
|
||||
|
||||
Shader::Shader(Type type, const Source& source) :
|
||||
_source(source),
|
||||
_type(type),
|
||||
_ID(_nextShaderID++)
|
||||
Shader::Shader(Type type, const Source& source, bool dynamic) :
|
||||
_type(type)
|
||||
{
|
||||
auto& thisSource = const_cast<Source&>(_source);
|
||||
thisSource = source;
|
||||
if (!dynamic) {
|
||||
thisSource.id = source.id;
|
||||
}
|
||||
}
|
||||
|
||||
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel):
|
||||
_type(type),
|
||||
_ID(_nextShaderID++)
|
||||
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel) :
|
||||
_type(type)
|
||||
{
|
||||
|
||||
auto& shaders = const_cast<Shaders&>(_shaders);
|
||||
if (geometry) {
|
||||
_shaders.resize(3);
|
||||
_shaders[VERTEX] = vertex;
|
||||
_shaders[GEOMETRY] = geometry;
|
||||
_shaders[PIXEL] = pixel;
|
||||
shaders.resize(3);
|
||||
shaders[VERTEX] = vertex;
|
||||
shaders[GEOMETRY] = geometry;
|
||||
shaders[PIXEL] = pixel;
|
||||
} else {
|
||||
_shaders.resize(2);
|
||||
_shaders[VERTEX] = vertex;
|
||||
_shaders[PIXEL] = pixel;
|
||||
shaders.resize(2);
|
||||
shaders[VERTEX] = vertex;
|
||||
shaders[PIXEL] = pixel;
|
||||
}
|
||||
|
||||
auto& reflection = const_cast<Reflection&>(getReflection());
|
||||
for (const auto& subShader : _shaders) {
|
||||
reflection.merge(subShader->getReflection());
|
||||
}
|
||||
if (_shaders[VERTEX]) {
|
||||
reflection.inputs = _shaders[VERTEX]->getReflection().inputs;
|
||||
}
|
||||
if (_shaders[PIXEL]) {
|
||||
reflection.outputs = _shaders[PIXEL]->getReflection().outputs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,46 +60,27 @@ Shader::~Shader()
|
|||
{
|
||||
}
|
||||
|
||||
void populateSlotSet(Shader::SlotSet& slotSet, const Shader::LocationMap& map) {
|
||||
for (const auto& entry : map) {
|
||||
const auto& name = entry.first;
|
||||
const auto& location = entry.second;
|
||||
slotSet.insert({ name, location, Element() });
|
||||
}
|
||||
static std::unordered_map<uint32_t, std::weak_ptr<Shader>> _shaderCache;
|
||||
|
||||
Shader::ID Shader::getID() const {
|
||||
if (isProgram()) {
|
||||
return (_shaders[VERTEX]->getID() << 16) | (_shaders[PIXEL]->getID());
|
||||
}
|
||||
|
||||
return _source.id;
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createOrReuseDomainShader(Type type, const Source& source) {
|
||||
auto found = _domainShaderMaps[type].find(source);
|
||||
if (found != _domainShaderMaps[type].end()) {
|
||||
Shader::Pointer Shader::createOrReuseDomainShader(Type type, uint32_t sourceId) {
|
||||
// Don't attempt to cache non-static shaders
|
||||
auto found = _shaderCache.find(sourceId);
|
||||
if (found != _shaderCache.end()) {
|
||||
auto sharedShader = (*found).second.lock();
|
||||
if (sharedShader) {
|
||||
return sharedShader;
|
||||
}
|
||||
}
|
||||
auto shader = Pointer(new Shader(type, source));
|
||||
const auto& reflection = source.getReflection();
|
||||
if (0 != reflection.count(BindingType::INPUT)) {
|
||||
populateSlotSet(shader->_inputs, reflection.find(BindingType::INPUT)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::OUTPUT)) {
|
||||
populateSlotSet(shader->_outputs, reflection.find(BindingType::OUTPUT)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::UNIFORM_BUFFER)) {
|
||||
populateSlotSet(shader->_uniformBuffers, reflection.find(BindingType::UNIFORM_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::RESOURCE_BUFFER)) {
|
||||
populateSlotSet(shader->_resourceBuffers, reflection.find(BindingType::RESOURCE_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::TEXTURE)) {
|
||||
populateSlotSet(shader->_textures, reflection.find(BindingType::TEXTURE)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::SAMPLER)) {
|
||||
populateSlotSet(shader->_samplers, reflection.find(BindingType::SAMPLER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::UNIFORM)) {
|
||||
populateSlotSet(shader->_uniforms, reflection.find(BindingType::UNIFORM)->second);
|
||||
}
|
||||
_domainShaderMaps[type].emplace(source, std::weak_ptr<Shader>(shader));
|
||||
auto shader = Pointer(new Shader(type, getShaderSource(sourceId), false));
|
||||
_shaderCache.insert({ sourceId, shader });
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
@ -137,28 +123,6 @@ ShaderPointer Shader::createOrReuseProgramShader(Type type, const Pointer& verte
|
|||
|
||||
// Program is a new one, let's create it
|
||||
auto program = Pointer(new Shader(type, vertexShader, geometryShader, pixelShader));
|
||||
|
||||
// Combine the slots from the sub-shaders
|
||||
for (const auto& shader : program->_shaders) {
|
||||
const auto& reflection = shader->_source.getReflection();
|
||||
if (0 != reflection.count(BindingType::UNIFORM_BUFFER)) {
|
||||
populateSlotSet(program->_uniformBuffers, reflection.find(BindingType::UNIFORM_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::RESOURCE_BUFFER)) {
|
||||
populateSlotSet(program->_resourceBuffers, reflection.find(BindingType::RESOURCE_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::TEXTURE)) {
|
||||
populateSlotSet(program->_textures, reflection.find(BindingType::TEXTURE)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::SAMPLER)) {
|
||||
populateSlotSet(program->_samplers, reflection.find(BindingType::SAMPLER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::UNIFORM)) {
|
||||
populateSlotSet(program->_uniforms, reflection.find(BindingType::UNIFORM)->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_programMap.emplace(key, std::weak_ptr<Shader>(program));
|
||||
return program;
|
||||
}
|
||||
|
@ -175,24 +139,21 @@ void Shader::incrementCompilationAttempt() const {
|
|||
}
|
||||
|
||||
Shader::Pointer Shader::createVertex(const Source& source) {
|
||||
return createOrReuseDomainShader(VERTEX, source);
|
||||
return Pointer(new Shader(VERTEX, source, true));
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createPixel(const Source& source) {
|
||||
return createOrReuseDomainShader(FRAGMENT, source);
|
||||
return Pointer(new Shader(FRAGMENT, source, true));
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createVertex(uint32_t id) {
|
||||
return createVertex(getShaderSource(id));
|
||||
return createOrReuseDomainShader(VERTEX, id);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createPixel(uint32_t id) {
|
||||
return createPixel(getShaderSource(id));
|
||||
return createOrReuseDomainShader(FRAGMENT, id);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
|
||||
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, pixelShader);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createProgram(uint32_t programId) {
|
||||
auto vertexShader = createVertex(shader::getVertexId(programId));
|
||||
|
@ -200,98 +161,15 @@ Shader::Pointer Shader::createProgram(uint32_t programId) {
|
|||
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, fragmentShader);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
|
||||
return Pointer(new Shader(PROGRAM, vertexShader, nullptr, pixelShader));
|
||||
}
|
||||
|
||||
// Dynamic program, bypass caching
|
||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& geometryShader, const Pointer& pixelShader) {
|
||||
return createOrReuseProgramShader(PROGRAM, vertexShader, geometryShader, pixelShader);
|
||||
return Pointer(new Shader(PROGRAM, vertexShader, geometryShader, pixelShader));
|
||||
}
|
||||
|
||||
static const std::string IGNORED_BINDING = "transformObjectBuffer";
|
||||
|
||||
void updateBindingsFromJsonObject(Shader::LocationMap& inOutSet, const QJsonObject& json) {
|
||||
for (const auto& key : json.keys()) {
|
||||
auto keyStr = key.toStdString();
|
||||
if (IGNORED_BINDING == keyStr) {
|
||||
continue;
|
||||
}
|
||||
inOutSet[keyStr] = json[key].toInt();
|
||||
}
|
||||
}
|
||||
|
||||
void updateTextureAndResourceBuffersFromJsonObjects(Shader::LocationMap& inOutTextures, Shader::LocationMap& inOutResourceBuffers,
|
||||
const QJsonObject& json, const QJsonObject& types) {
|
||||
static const std::string RESOURCE_BUFFER_TEXTURE_TYPE = "samplerBuffer";
|
||||
for (const auto& key : json.keys()) {
|
||||
auto keyStr = key.toStdString();
|
||||
if (keyStr == IGNORED_BINDING) {
|
||||
continue;
|
||||
}
|
||||
auto location = json[key].toInt();
|
||||
auto type = types[key].toString().toStdString();
|
||||
if (type == RESOURCE_BUFFER_TEXTURE_TYPE) {
|
||||
inOutResourceBuffers[keyStr] = location;
|
||||
} else {
|
||||
inOutTextures[key.toStdString()] = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shader::ReflectionMap getShaderReflection(const std::string& reflectionJson) {
|
||||
if (reflectionJson.empty() && reflectionJson != std::string("null")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
#define REFLECT_KEY_INPUTS "inputs"
|
||||
#define REFLECT_KEY_OUTPUTS "outputs"
|
||||
#define REFLECT_KEY_UBOS "uniformBuffers"
|
||||
#define REFLECT_KEY_SSBOS "storageBuffers"
|
||||
#define REFLECT_KEY_UNIFORMS "uniforms"
|
||||
#define REFLECT_KEY_TEXTURES "textures"
|
||||
#define REFLECT_KEY_TEXTURE_TYPES "textureTypes"
|
||||
|
||||
auto doc = QJsonDocument::fromJson(reflectionJson.c_str());
|
||||
if (doc.isNull()) {
|
||||
qWarning() << "Invalid shader reflection JSON" << reflectionJson.c_str();
|
||||
return {};
|
||||
}
|
||||
|
||||
Shader::ReflectionMap result;
|
||||
auto json = doc.object();
|
||||
if (json.contains(REFLECT_KEY_INPUTS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::INPUT], json[REFLECT_KEY_INPUTS].toObject());
|
||||
}
|
||||
if (json.contains(REFLECT_KEY_OUTPUTS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::OUTPUT], json[REFLECT_KEY_OUTPUTS].toObject());
|
||||
}
|
||||
// FIXME eliminate the last of the uniforms
|
||||
if (json.contains(REFLECT_KEY_UNIFORMS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::UNIFORM], json[REFLECT_KEY_UNIFORMS].toObject());
|
||||
}
|
||||
if (json.contains(REFLECT_KEY_UBOS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::UNIFORM_BUFFER], json[REFLECT_KEY_UBOS].toObject());
|
||||
}
|
||||
|
||||
// SSBOs need to come BEFORE the textures. In GL 4.5 the reflection slots aren't really used, but in 4.1 the slots
|
||||
// are used to explicitly setup bindings after shader linkage, so we want the resource buffer slots to contain the
|
||||
// texture locations, not the SSBO locations
|
||||
if (json.contains(REFLECT_KEY_SSBOS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::RESOURCE_BUFFER], json[REFLECT_KEY_SSBOS].toObject());
|
||||
}
|
||||
|
||||
// samplerBuffer textures map to gpu ResourceBuffer, while all other textures map to regular gpu Texture
|
||||
if (json.contains(REFLECT_KEY_TEXTURES)) {
|
||||
updateTextureAndResourceBuffersFromJsonObjects(
|
||||
result[Shader::BindingType::TEXTURE],
|
||||
result[Shader::BindingType::RESOURCE_BUFFER],
|
||||
json[REFLECT_KEY_TEXTURES].toObject(),
|
||||
json[REFLECT_KEY_TEXTURE_TYPES].toObject());
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Shader::Source Shader::getShaderSource(uint32_t id) {
|
||||
auto source = shader::loadShaderSource(id);
|
||||
auto reflectionJson = shader::loadShaderReflection(id);
|
||||
auto reflection = getShaderReflection(reflectionJson);
|
||||
return { source, reflection };
|
||||
const Shader::Source& Shader::getShaderSource(uint32_t id) {
|
||||
return shader::Source::get(id);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <shaders/Shaders.h>
|
||||
#include <QUrl>
|
||||
|
||||
namespace gpu {
|
||||
|
@ -42,58 +43,10 @@ public:
|
|||
typedef std::shared_ptr<Shader> Pointer;
|
||||
typedef std::vector<Pointer> Shaders;
|
||||
|
||||
// Needs to match values in shaders/Shaders.h
|
||||
enum class BindingType
|
||||
{
|
||||
INVALID = -1,
|
||||
INPUT = 0,
|
||||
OUTPUT,
|
||||
TEXTURE,
|
||||
SAMPLER,
|
||||
UNIFORM_BUFFER,
|
||||
RESOURCE_BUFFER,
|
||||
UNIFORM,
|
||||
};
|
||||
|
||||
using LocationMap = std::unordered_map<std::string, int32_t>;
|
||||
using ReflectionMap = std::map<BindingType, LocationMap>;
|
||||
|
||||
class Source {
|
||||
public:
|
||||
enum Language
|
||||
{
|
||||
INVALID = -1,
|
||||
GLSL = 0,
|
||||
SPIRV = 1,
|
||||
MSL = 2,
|
||||
HLSL = 3,
|
||||
};
|
||||
|
||||
Source() {}
|
||||
Source(const std::string& code, const ReflectionMap& reflection, Language lang = GLSL) :
|
||||
_code(code), _reflection(reflection), _lang(lang) {}
|
||||
Source(const Source& source) : _code(source._code), _reflection(source._reflection), _lang(source._lang) {}
|
||||
virtual ~Source() {}
|
||||
|
||||
virtual const std::string& getCode() const { return _code; }
|
||||
virtual const ReflectionMap& getReflection() const { return _reflection; }
|
||||
|
||||
class Less {
|
||||
public:
|
||||
bool operator()(const Source& x, const Source& y) const {
|
||||
if (x._lang == y._lang) {
|
||||
return x._code < y._code;
|
||||
} else {
|
||||
return (x._lang < y._lang);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
std::string _code;
|
||||
ReflectionMap _reflection;
|
||||
Language _lang;
|
||||
};
|
||||
using Source = shader::Source;
|
||||
using Reflection = shader::Reflection;
|
||||
using Dialect = shader::Dialect;
|
||||
using Variant = shader::Variant;
|
||||
|
||||
struct CompilationLog {
|
||||
std::string message;
|
||||
|
@ -112,85 +65,13 @@ public:
|
|||
bool operator()(const T& x, const T& y) const { return x._name < y._name; }
|
||||
};
|
||||
|
||||
class Slot {
|
||||
public:
|
||||
std::string _name;
|
||||
int32 _location{ INVALID_LOCATION };
|
||||
Element _element;
|
||||
uint16 _resourceType{ Resource::BUFFER };
|
||||
uint32 _size{ 0 };
|
||||
|
||||
Slot(const Slot& s) :
|
||||
_name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType), _size(s._size) {}
|
||||
Slot(Slot&& s) :
|
||||
_name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType), _size(s._size) {}
|
||||
Slot(const std::string& name,
|
||||
int32 location,
|
||||
const Element& element,
|
||||
uint16 resourceType = Resource::BUFFER,
|
||||
uint32 size = 0) :
|
||||
_name(name),
|
||||
_location(location), _element(element), _resourceType(resourceType), _size(size) {}
|
||||
Slot(const std::string& name) : _name(name) {}
|
||||
|
||||
Slot& operator=(const Slot& s) {
|
||||
_name = s._name;
|
||||
_location = s._location;
|
||||
_element = s._element;
|
||||
_resourceType = s._resourceType;
|
||||
_size = s._size;
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
|
||||
class SlotSet : protected std::set<Slot, Less<Slot>> {
|
||||
using Parent = std::set<Slot, Less<Slot>>;
|
||||
|
||||
public:
|
||||
void insert(const Parent::value_type& value) {
|
||||
Parent::insert(value);
|
||||
if (value._location != INVALID_LOCATION) {
|
||||
_validSlots.insert(value._location);
|
||||
}
|
||||
}
|
||||
|
||||
using Parent::begin;
|
||||
using Parent::empty;
|
||||
using Parent::end;
|
||||
using Parent::size;
|
||||
|
||||
using LocationMap = std::unordered_map<std::string, int32>;
|
||||
using NameVector = std::vector<std::string>;
|
||||
|
||||
NameVector getNames() const {
|
||||
NameVector result;
|
||||
for (const auto& entry : *this) {
|
||||
result.push_back(entry._name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LocationMap getLocationsByName() const {
|
||||
LocationMap result;
|
||||
for (const auto& entry : *this) {
|
||||
result.insert({ entry._name, entry._location });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isValid(int32 slot) const { return 0 != _validSlots.count(slot); }
|
||||
|
||||
protected:
|
||||
std::unordered_set<int> _validSlots;
|
||||
};
|
||||
|
||||
static Source getShaderSource(uint32_t id);
|
||||
static Source getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
static Source getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
|
||||
static const Source& getShaderSource(uint32_t id);
|
||||
static const Source& getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
static const Source& getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
static Pointer createVertex(const Source& source);
|
||||
static Pointer createPixel(const Source& source);
|
||||
static Pointer createGeometry(const Source& source);
|
||||
|
||||
static Pointer createVertex(uint32_t shaderId);
|
||||
static Pointer createPixel(uint32_t shaderId);
|
||||
static Pointer createGeometry(uint32_t shaderId);
|
||||
|
@ -201,8 +82,7 @@ public:
|
|||
|
||||
~Shader();
|
||||
|
||||
ID getID() const { return _ID; }
|
||||
|
||||
ID getID() const;
|
||||
Type getType() const { return _type; }
|
||||
bool isProgram() const { return getType() > NUM_DOMAINS; }
|
||||
bool isDomain() const { return getType() < NUM_DOMAINS; }
|
||||
|
@ -211,17 +91,12 @@ public:
|
|||
|
||||
const Shaders& getShaders() const { return _shaders; }
|
||||
|
||||
// Access the exposed uniform, input and output slot
|
||||
const SlotSet& getUniforms() const { return _uniforms; }
|
||||
const SlotSet& getUniformBuffers() const { return _uniformBuffers; }
|
||||
const SlotSet& getResourceBuffers() const { return _resourceBuffers; }
|
||||
const SlotSet& getTextures() const { return _textures; }
|
||||
const SlotSet& getSamplers() const { return _samplers; }
|
||||
const Reflection& getReflection() const { return _source.reflection; }
|
||||
|
||||
// Compilation Handler can be passed while compiling a shader (in the makeProgram call) to be able to give the hand to
|
||||
// the caller thread if the comilation fails and to prvide a different version of the source for it
|
||||
// the caller thread if the compilation fails and to provide a different version of the source for it
|
||||
// @param0 the Shader object that just failed to compile
|
||||
// @param1 the original source code as submited to the compiler
|
||||
// @param1 the original source code as submitted to the compiler
|
||||
// @param2 the compilation log containing the error message
|
||||
// @param3 a new string ready to be filled with the new version of the source that could be proposed from the handler functor
|
||||
// @return boolean true if the backend should keep trying to compile the shader with the new source returned or false to stop and fail that shader compilation
|
||||
|
@ -240,32 +115,21 @@ public:
|
|||
const GPUObjectPointer gpuObject{};
|
||||
|
||||
protected:
|
||||
Shader(Type type, const Source& source);
|
||||
Shader(Type type, const Source& source, bool dynamic);
|
||||
Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel);
|
||||
|
||||
Shader(const Shader& shader); // deep copy of the sysmem shader
|
||||
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture
|
||||
|
||||
// Source contains the actual source code or nothing if the shader is a program
|
||||
Source _source;
|
||||
const Source _source;
|
||||
|
||||
// if shader is composed of sub shaders, here they are
|
||||
Shaders _shaders;
|
||||
|
||||
// List of exposed uniform, input and output slots
|
||||
SlotSet _uniforms;
|
||||
SlotSet _uniformBuffers;
|
||||
SlotSet _resourceBuffers;
|
||||
SlotSet _textures;
|
||||
SlotSet _samplers;
|
||||
SlotSet _inputs;
|
||||
SlotSet _outputs;
|
||||
const Shaders _shaders;
|
||||
|
||||
|
||||
// The type of the shader, the master key
|
||||
Type _type;
|
||||
|
||||
// The unique identifier of a shader in the GPU lib
|
||||
uint32_t _ID{ 0 };
|
||||
const Type _type;
|
||||
|
||||
// Number of attempts to compile the shader
|
||||
mutable uint32_t _numCompilationAttempts{ 0 };
|
||||
|
@ -277,13 +141,9 @@ protected:
|
|||
|
||||
// Global maps of the shaders
|
||||
// Unique shader ID
|
||||
static std::atomic<ID> _nextShaderID;
|
||||
//static std::atomic<ID> _nextShaderID;
|
||||
|
||||
using ShaderMap = std::map<Source, std::weak_ptr<Shader>, Source::Less>;
|
||||
using DomainShaderMaps = std::array<ShaderMap, NUM_DOMAINS>;
|
||||
static DomainShaderMaps _domainShaderMaps;
|
||||
|
||||
static ShaderPointer createOrReuseDomainShader(Type type, const Source& source);
|
||||
static ShaderPointer createOrReuseDomainShader(Type type, uint32_t sourceId);
|
||||
|
||||
using ProgramMapKey = glm::uvec3; // The IDs of the shaders in a program make its key
|
||||
class ProgramKeyLess {
|
||||
|
|
|
@ -98,21 +98,6 @@ enum Attribute {
|
|||
};
|
||||
} // namespace attr
|
||||
|
||||
namespace uniform {
|
||||
enum Uniform {
|
||||
Extra0 = GPU_UNIFORM_EXTRA0,
|
||||
Extra1 = GPU_UNIFORM_EXTRA1,
|
||||
Extra2 = GPU_UNIFORM_EXTRA2,
|
||||
Extra3 = GPU_UNIFORM_EXTRA3,
|
||||
Extra4 = GPU_UNIFORM_EXTRA4,
|
||||
Extra5 = GPU_UNIFORM_EXTRA5,
|
||||
Extra6 = GPU_UNIFORM_EXTRA6,
|
||||
Extra7 = GPU_UNIFORM_EXTRA7,
|
||||
Extra8 = GPU_UNIFORM_EXTRA8,
|
||||
Extra9 = GPU_UNIFORM_EXTRA9,
|
||||
};
|
||||
} // namespace uniform
|
||||
|
||||
} } // namespace gpu::slot
|
||||
|
||||
// !>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define TransformCamera _TransformCamera
|
||||
|
||||
layout(std140, binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffer {
|
||||
LAYOUT_STD140(binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffer {
|
||||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
#ifdef GPU_TRANSFORM_STEREO_CAMERA
|
||||
TransformCamera _camera[2];
|
||||
|
@ -26,7 +26,7 @@ layout(std140, binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffe
|
|||
#else
|
||||
TransformCamera _camera;
|
||||
#endif
|
||||
};
|
||||
} _cameraBlock;
|
||||
|
||||
#ifdef GPU_VERTEX_SHADER
|
||||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
|
@ -76,12 +76,12 @@ TransformCamera getTransformCamera() {
|
|||
_stereoSide = gl_InstanceID % 2;
|
||||
#endif
|
||||
#endif
|
||||
return _camera[_stereoSide];
|
||||
return _cameraBlock._camera[_stereoSide];
|
||||
#else
|
||||
return _camera;
|
||||
return _cameraBlock._camera;
|
||||
#endif
|
||||
#else
|
||||
return _camera;
|
||||
return _cameraBlock._camera;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ bool cam_isStereo() {
|
|||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
return getTransformCamera()._stereoInfo.x > 0.0;
|
||||
#else
|
||||
return _camera._stereoInfo.x > 0.0;
|
||||
return _cameraBlock._camera._stereoInfo.x > 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,10 @@ float cam_getStereoSide() {
|
|||
#ifdef GPU_TRANSFORM_STEREO_CAMERA
|
||||
return getTransformCamera()._stereoInfo.y;
|
||||
#else
|
||||
return _camera._stereoInfo.y;
|
||||
return _cameraBlock._camera._stereoInfo.y;
|
||||
#endif
|
||||
#else
|
||||
return _camera._stereoInfo.y;
|
||||
return _cameraBlock._camera._stereoInfo.y;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ struct TransformObject {
|
|||
layout(location=GPU_ATTR_DRAW_CALL_INFO) in ivec2 _drawCallInfo;
|
||||
|
||||
#if defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
layout(std140, binding=GPU_STORAGE_TRANSFORM_OBJECT) buffer transformObjectBuffer {
|
||||
LAYOUT_STD140(binding=GPU_STORAGE_TRANSFORM_OBJECT) buffer transformObjectBuffer {
|
||||
TransformObject _object[];
|
||||
};
|
||||
TransformObject getTransformObject() {
|
||||
|
@ -128,7 +128,7 @@ TransformObject getTransformObject() {
|
|||
return transformObject;
|
||||
}
|
||||
#else
|
||||
layout(binding=GPU_TEXTURE_TRANSFORM_OBJECT) uniform samplerBuffer transformObjectBuffer;
|
||||
LAYOUT(binding=GPU_TEXTURE_TRANSFORM_OBJECT) uniform samplerBuffer transformObjectBuffer;
|
||||
|
||||
TransformObject getTransformObject() {
|
||||
int offset = 8 * _drawCallInfo.x;
|
||||
|
@ -167,7 +167,9 @@ TransformObject getTransformObject() {
|
|||
vec4 eyeClipEdge[2]= vec4[2](vec4(-1,0,0,1), vec4(1,0,0,1));
|
||||
vec2 eyeOffsetScale = vec2(-0.5, +0.5);
|
||||
uint eyeIndex = uint(_stereoSide);
|
||||
#ifndef GPU_GLES
|
||||
gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]);
|
||||
#endif
|
||||
float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w;
|
||||
<$clipPos$>.x = newClipPosX;
|
||||
#endif
|
||||
|
|
|
@ -51,7 +51,7 @@ float getLightAmbientMapNumMips(LightAmbient l) { return l._ambient.y; }
|
|||
|
||||
|
||||
<@if N@>
|
||||
layout(binding=GRAPHICS_BUFFER_LIGHT) uniform lightBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_LIGHT) uniform lightBuffer {
|
||||
Light lightArray[<$N$>];
|
||||
};
|
||||
Light getLight(int index) {
|
||||
|
@ -59,7 +59,7 @@ Light getLight(int index) {
|
|||
}
|
||||
|
||||
<@else@>
|
||||
layout(binding=GRAPHICS_BUFFER_KEY_LIGHT) uniform keyLightBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_KEY_LIGHT) uniform keyLightBuffer {
|
||||
Light light;
|
||||
};
|
||||
Light getKeyLight() {
|
||||
|
@ -79,7 +79,7 @@ Light getKeyLight() {
|
|||
|
||||
<@if N@>
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LightAmbient lightAmbientArray[<$N$>];
|
||||
};
|
||||
|
||||
|
@ -88,7 +88,7 @@ LightAmbient getLightAmbient(int index) {
|
|||
}
|
||||
|
||||
<@else@>
|
||||
layout(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LightAmbient lightAmbient;
|
||||
};
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ struct Material {
|
|||
vec4 _scatteringSpare2Key;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
|
||||
Material _mat;
|
||||
TexMapArray _texMapArray;
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<@if not MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
<@def MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
@ -91,21 +92,21 @@ float fetchScatteringMap(vec2 uv) {
|
|||
#else
|
||||
|
||||
<@if withAlbedo@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
// unpack normal, swizzle to get into hifi tangent space with Y axis pointing out
|
||||
vec2 t = 2.0 * (texture(normalMap, uv, TAA_TEXTURE_LOD_BIAS).rg - vec2(0.5, 0.5));
|
||||
|
@ -115,28 +116,28 @@ vec3 fetchNormalMap(vec2 uv) {
|
|||
<@endif@>
|
||||
|
||||
<@if withMetallic@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap;
|
||||
float fetchMetallicMap(vec2 uv) {
|
||||
return (texture(metallicMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withEmissive@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withOcclusion@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
|
||||
float fetchOcclusionMap(vec2 uv) {
|
||||
return texture(occlusionMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withScattering@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_SCATTERING) uniform sampler2D scatteringMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SCATTERING) uniform sampler2D scatteringMap;
|
||||
float fetchScatteringMap(vec2 uv) {
|
||||
float scattering = texture(scatteringMap, uv, TAA_TEXTURE_LOD_BIAS).r; // boolean scattering for now
|
||||
return max(((scattering - 0.1) / 0.9), 0.0);
|
||||
|
@ -185,7 +186,7 @@ float fetchScatteringMap(vec2 uv) {
|
|||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
vec3 fetchLightmapMap(vec2 uv) {
|
||||
vec2 lightmapParams = getTexMapArray()._lightmapParams.xy;
|
||||
return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb);
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
//
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
|
||||
struct Skybox {
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
Skybox skybox;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
set(TARGET_NAME model-networking)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared networking graphics fbx ktx image gl)
|
||||
link_hifi_libraries(shared shaders networking graphics fbx ktx image gl)
|
||||
include_hifi_library_headers(gpu)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(proceduralLog, "hifi.gpu.procedural")
|
||||
|
||||
// Userdata parsing constants
|
||||
// User-data parsing constants
|
||||
static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
|
||||
static const QString URL_KEY = "shaderUrl";
|
||||
static const QString VERSION_KEY = "version";
|
||||
|
@ -39,11 +39,8 @@ static const std::string PROCEDURAL_BLOCK = "//PROCEDURAL_BLOCK";
|
|||
static const std::string PROCEDURAL_VERSION = "//PROCEDURAL_VERSION";
|
||||
|
||||
bool operator==(const ProceduralData& a, const ProceduralData& b) {
|
||||
return (
|
||||
(a.version == b.version) &&
|
||||
(a.shaderUrl == b.shaderUrl) &&
|
||||
(a.uniforms == b.uniforms) &&
|
||||
(a.channels == b.channels));
|
||||
return ((a.version == b.version) && (a.shaderUrl == b.shaderUrl) && (a.uniforms == b.uniforms) &&
|
||||
(a.channels == b.channels));
|
||||
}
|
||||
|
||||
QJsonValue ProceduralData::getProceduralData(const QString& proceduralJson) {
|
||||
|
@ -109,6 +106,8 @@ Procedural::Procedural() {
|
|||
_transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
_transparentState->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
_standardInputsBuffer = std::make_shared<gpu::Buffer>(sizeof(StandardInputs), nullptr);
|
||||
}
|
||||
|
||||
void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
||||
|
@ -119,7 +118,7 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
|||
_dirty = true;
|
||||
_enabled = false;
|
||||
|
||||
if (proceduralData.version != _data.version ) {
|
||||
if (proceduralData.version != _data.version) {
|
||||
_data.version = proceduralData.version;
|
||||
_shaderDirty = true;
|
||||
}
|
||||
|
@ -144,7 +143,6 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
|||
_channels[channel] = textureCache->getTexture(QUrl());
|
||||
}
|
||||
}
|
||||
_channelsDirty = true;
|
||||
}
|
||||
|
||||
if (proceduralData.shaderUrl != _data.shaderUrl) {
|
||||
|
@ -212,23 +210,6 @@ bool Procedural::isReady() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string Procedural::replaceProceduralBlock(const std::string& fragmentSource) {
|
||||
std::string result = fragmentSource;
|
||||
auto replaceIndex = result.find(PROCEDURAL_VERSION);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
if (_data.version == 1) {
|
||||
result.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1");
|
||||
} else if (_data.version == 2) {
|
||||
result.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1");
|
||||
}
|
||||
}
|
||||
replaceIndex = result.find(PROCEDURAL_BLOCK);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
result.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Procedural::prepare(gpu::Batch& batch,
|
||||
const glm::vec3& position,
|
||||
const glm::vec3& size,
|
||||
|
@ -256,19 +237,21 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
}
|
||||
|
||||
// Build the fragment shader
|
||||
std::string opaqueShaderSource = replaceProceduralBlock(_opaquefragmentSource.getCode());
|
||||
auto opaqueReflection = _opaquefragmentSource.getReflection();
|
||||
auto& opaqueUniforms = opaqueReflection[gpu::Shader::BindingType::UNIFORM];
|
||||
std::string transparentShaderSource = replaceProceduralBlock(_transparentfragmentSource.getCode());
|
||||
auto transparentReflection = _transparentfragmentSource.getReflection();
|
||||
auto& transparentUniforms = transparentReflection[gpu::Shader::BindingType::UNIFORM];
|
||||
_opaqueFragmentSource.replacements.clear();
|
||||
if (_data.version == 1) {
|
||||
_opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V1 1";
|
||||
} else if (_data.version == 2) {
|
||||
_opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V2 1";
|
||||
}
|
||||
_opaqueFragmentSource.replacements[PROCEDURAL_BLOCK] = _shaderSource.toStdString();
|
||||
_transparentFragmentSource.replacements = _opaqueFragmentSource.replacements;
|
||||
|
||||
// Set any userdata specified uniforms
|
||||
int customSlot = procedural::slot::uniform::Custom;
|
||||
for (const auto& key : _data.uniforms.keys()) {
|
||||
std::string uniformName = key.toLocal8Bit().data();
|
||||
opaqueUniforms[uniformName] = customSlot;
|
||||
transparentUniforms[uniformName] = customSlot;
|
||||
_opaqueFragmentSource.reflection.uniforms[uniformName] = customSlot;
|
||||
_transparentFragmentSource.reflection.uniforms[uniformName] = customSlot;
|
||||
++customSlot;
|
||||
}
|
||||
|
||||
|
@ -276,18 +259,18 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
// qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str();
|
||||
|
||||
// TODO: THis is a simple fix, we need a cleaner way to provide the "hosting" program for procedural custom shaders to be defined together with the required bindings.
|
||||
_opaqueFragmentShader = gpu::Shader::createPixel({ opaqueShaderSource, opaqueReflection });
|
||||
_opaqueFragmentShader = gpu::Shader::createPixel(_opaqueFragmentSource);
|
||||
_opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader);
|
||||
if (!transparentShaderSource.empty() && transparentShaderSource != opaqueShaderSource) {
|
||||
_transparentFragmentShader = gpu::Shader::createPixel({ transparentShaderSource, transparentReflection });
|
||||
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
|
||||
if (_transparentFragmentSource.valid()) {
|
||||
_transparentFragmentShader = gpu::Shader::createPixel(_transparentFragmentSource);
|
||||
_transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader);
|
||||
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
|
||||
} else {
|
||||
_transparentFragmentShader = _opaqueFragmentShader;
|
||||
_transparentShader = _opaqueShader;
|
||||
_transparentPipeline = _opaquePipeline;
|
||||
}
|
||||
|
||||
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
|
||||
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
|
||||
_start = usecTimestampNow();
|
||||
_frameCount = 0;
|
||||
}
|
||||
|
@ -299,12 +282,8 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
setupUniforms(transparent);
|
||||
}
|
||||
|
||||
if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) {
|
||||
setupChannels(_shaderDirty || _uniformsDirty, transparent);
|
||||
}
|
||||
|
||||
_prevTransparent = transparent;
|
||||
_shaderDirty = _uniformsDirty = _channelsDirty = false;
|
||||
_shaderDirty = _uniformsDirty = false;
|
||||
|
||||
for (auto lambda : _uniforms) {
|
||||
lambda(batch);
|
||||
|
@ -331,16 +310,10 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
|
||||
void Procedural::setupUniforms(bool transparent) {
|
||||
_uniforms.clear();
|
||||
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
|
||||
const auto& uniformSlots = pipeline->getUniforms();
|
||||
auto customUniformCount = _data.uniforms.keys().size();
|
||||
|
||||
// Set any userdata specified uniforms
|
||||
for (int i = 0; i < customUniformCount; ++i) {
|
||||
int slot = procedural::slot::uniform::Custom + i;
|
||||
if (!uniformSlots.isValid(slot)) {
|
||||
continue;
|
||||
}
|
||||
QString key = _data.uniforms.keys().at(i);
|
||||
std::string uniformName = key.toLocal8Bit().data();
|
||||
QJsonValue value = _data.uniforms[key];
|
||||
|
@ -390,73 +363,42 @@ void Procedural::setupUniforms(bool transparent) {
|
|||
}
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Time)) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
// Time and position
|
||||
{
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
batch._glUniform(procedural::slot::uniform::Time, time);
|
||||
});
|
||||
}
|
||||
_standardInputs.posAndTime = vec4(_entityPosition, time);
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Date)) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
// Date
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||
QDate date = now.date();
|
||||
QTime time = now.time();
|
||||
vec4 v;
|
||||
v.x = date.year();
|
||||
_standardInputs.date.x = date.year();
|
||||
// Shadertoy month is 0 based
|
||||
v.y = date.month() - 1;
|
||||
_standardInputs.date.y = date.month() - 1;
|
||||
// But not the day... go figure
|
||||
v.z = date.day();
|
||||
_standardInputs.date.z = date.day();
|
||||
float fractSeconds = (time.msec() / 1000.0f);
|
||||
v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
|
||||
batch._glUniform(procedural::slot::uniform::Date, v);
|
||||
});
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::FrameCount)) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::FrameCount, ++_frameCount); });
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Scale)) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Scale, _entityDimensions); });
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Orientation)) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back(
|
||||
[=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Orientation, _entityOrientation); });
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Position)) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back(
|
||||
[=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Orientation, _entityPosition); });
|
||||
}
|
||||
}
|
||||
|
||||
void Procedural::setupChannels(bool shouldCreate, bool transparent) {
|
||||
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
|
||||
const auto& uniformSlots = pipeline->getUniforms();
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::ChannelResolution)) {
|
||||
if (!shouldCreate) {
|
||||
// Instead of modifying the last element, just remove and recreate it.
|
||||
_uniforms.pop_back();
|
||||
_standardInputs.date.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
|
||||
}
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
vec3 channelSizes[MAX_PROCEDURAL_TEXTURE_CHANNELS];
|
||||
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
|
||||
if (_channels[i]) {
|
||||
channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0);
|
||||
}
|
||||
|
||||
_standardInputs.scaleAndCount = vec4(_entityDimensions, ++_frameCount);
|
||||
_standardInputs.orientation = mat4(_entityOrientation);
|
||||
|
||||
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
|
||||
if (_channels[i]) {
|
||||
_standardInputs.resolution[i] = vec4(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0f, 1.0f);
|
||||
} else {
|
||||
_standardInputs.resolution[i] = vec4(1.0f);
|
||||
}
|
||||
batch._glUniform3fv(procedural::slot::uniform::ChannelResolution, MAX_PROCEDURAL_TEXTURE_CHANNELS,
|
||||
&channelSizes[0].x);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_standardInputsBuffer->setSubData(0, _standardInputs);
|
||||
batch.setUniformBuffer(0, _standardInputsBuffer, 0, sizeof(StandardInputs));
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec4 Procedural::getColor(const glm::vec4& entityColor) {
|
||||
|
|
|
@ -65,14 +65,22 @@ public:
|
|||
void setDoesFade(bool doesFade) { _doesFade = doesFade; }
|
||||
|
||||
gpu::Shader::Source _vertexSource;
|
||||
gpu::Shader::Source _opaquefragmentSource;
|
||||
gpu::Shader::Source _transparentfragmentSource;
|
||||
gpu::Shader::Source _opaqueFragmentSource;
|
||||
gpu::Shader::Source _transparentFragmentSource;
|
||||
|
||||
gpu::StatePointer _opaqueState { std::make_shared<gpu::State>() };
|
||||
gpu::StatePointer _transparentState { std::make_shared<gpu::State>() };
|
||||
|
||||
|
||||
protected:
|
||||
struct StandardInputs {
|
||||
vec4 date;
|
||||
vec4 posAndTime;
|
||||
vec4 scaleAndCount;
|
||||
mat4 orientation;
|
||||
vec4 resolution[4];
|
||||
};
|
||||
|
||||
// Procedural metadata
|
||||
ProceduralData _data;
|
||||
|
||||
|
@ -88,13 +96,14 @@ protected:
|
|||
bool _dirty { false };
|
||||
bool _shaderDirty { true };
|
||||
bool _uniformsDirty { true };
|
||||
bool _channelsDirty { true };
|
||||
|
||||
// Rendering objects
|
||||
UniformLambdas _uniforms;
|
||||
NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS];
|
||||
gpu::PipelinePointer _opaquePipeline;
|
||||
gpu::PipelinePointer _transparentPipeline;
|
||||
StandardInputs _standardInputs;
|
||||
gpu::BufferPointer _standardInputsBuffer;
|
||||
gpu::ShaderPointer _vertexShader;
|
||||
gpu::ShaderPointer _opaqueFragmentShader;
|
||||
gpu::ShaderPointer _transparentFragmentShader;
|
||||
|
@ -109,9 +118,6 @@ protected:
|
|||
private:
|
||||
// This should only be called from the render thread, as it shares data with Procedural::prepare
|
||||
void setupUniforms(bool transparent);
|
||||
void setupChannels(bool shouldCreate, bool transparent);
|
||||
|
||||
std::string replaceProceduralBlock(const std::string& fragmentSource);
|
||||
|
||||
mutable quint64 _fadeStartTime { 0 };
|
||||
mutable bool _hasStartedFade { false };
|
||||
|
|
|
@ -14,18 +14,51 @@
|
|||
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
#define PROCEDURAL 1
|
||||
#ifdef GL_EXT_shader_non_constant_global_initializers
|
||||
#extension GL_EXT_shader_non_constant_global_initializers : enable
|
||||
#endif
|
||||
|
||||
//PROCEDURAL_VERSION
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL0) uniform sampler2D iChannel0;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
struct StandardInputs {
|
||||
vec4 date;
|
||||
vec4 posAndTime;
|
||||
vec4 scaleAndCount;
|
||||
mat4 orientation;
|
||||
vec4 resolution[4];
|
||||
};
|
||||
|
||||
|
||||
LAYOUT(binding=0) uniform standardInputsBuffer {
|
||||
StandardInputs params;
|
||||
};
|
||||
|
||||
// shader playback time (in seconds)
|
||||
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime;
|
||||
// the dimensions of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale;
|
||||
float iGlobalTime = params.posAndTime.w;
|
||||
|
||||
vec4 iDate = params.date;
|
||||
|
||||
int iFrameCount = int(params.scaleAndCount.w);
|
||||
|
||||
// the position of the object being rendered
|
||||
vec3 iWorldPosition = params.posAndTime.xyz;
|
||||
|
||||
// the dimensions of the object being rendered
|
||||
vec3 iWorldScale = params.scaleAndCount.xyz;
|
||||
|
||||
// the orientation of the object being rendered
|
||||
mat3 iWorldOrientation = mat3(params.orientation);
|
||||
|
||||
vec3 iChannelResolution[4] = vec3[4](
|
||||
params.resolution[0].xyz,
|
||||
params.resolution[1].xyz,
|
||||
params.resolution[2].xyz,
|
||||
params.resolution[3].xyz
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
// Unimplemented uniforms
|
||||
// Resolution doesn't make sense in the VR context
|
||||
|
@ -37,20 +70,9 @@ const float iSampleRate = 1.0;
|
|||
// No support for video input
|
||||
const vec4 iChannelTime = vec4(0.0);
|
||||
|
||||
#define PROCEDURAL 1
|
||||
|
||||
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime; // shader playback time (in seconds)
|
||||
layout(location=PROCEDURAL_UNIFORM_DATE) uniform vec4 iDate;
|
||||
layout(location=PROCEDURAL_UNIFORM_FRAME_COUNT) uniform int iFrameCount;
|
||||
layout(location=PROCEDURAL_UNIFORM_POSITION) uniform vec3 iWorldPosition; // the position of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale; // the dimensions of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_ORIENTATION) uniform mat3 iWorldOrientation; // the orientation of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION) uniform vec3 iChannelResolution[4];
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL0) uniform sampler2D iChannel0;
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
|
||||
|
||||
#endif
|
||||
//PROCEDURAL_VERSION
|
||||
|
||||
// hack comment for extra whitespace
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() {
|
||||
_procedural._vertexSource = gpu::Shader::createVertex(shader::graphics::vertex::skybox)->getSource();
|
||||
_procedural._opaquefragmentSource = gpu::Shader::createPixel(shader::procedural::fragment::proceduralSkybox)->getSource();
|
||||
_procedural._opaqueFragmentSource = shader::Source::get(shader::procedural::fragment::proceduralSkybox);
|
||||
// Adjust the pipeline state for background using the stencil test
|
||||
_procedural.setDoesFade(false);
|
||||
// Must match PrepareStencil::STENCIL_BACKGROUND
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
#ifndef PROCEDURAL_SHADER_CONSTANTS_H
|
||||
#define PROCEDURAL_SHADER_CONSTANTS_H
|
||||
|
||||
#define PROCEDURAL_UNIFORM_TIME 200
|
||||
#define PROCEDURAL_UNIFORM_DATE 201
|
||||
#define PROCEDURAL_UNIFORM_FRAME_COUNT 202
|
||||
#define PROCEDURAL_UNIFORM_POSITION 203
|
||||
#define PROCEDURAL_UNIFORM_SCALE 204
|
||||
#define PROCEDURAL_UNIFORM_ORIENTATION 205
|
||||
// Additional space because orientation will take up 3-4 locations, being a matrix
|
||||
#define PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION 209
|
||||
#define PROCEDURAL_UNIFORM_CUSTOM 220
|
||||
|
||||
#define PROCEDURAL_TEXTURE_CHANNEL0 0
|
||||
|
@ -33,15 +25,9 @@
|
|||
|
||||
namespace procedural { namespace slot {
|
||||
|
||||
|
||||
namespace uniform {
|
||||
enum Uniform {
|
||||
Time = PROCEDURAL_UNIFORM_TIME,
|
||||
Date = PROCEDURAL_UNIFORM_DATE,
|
||||
FrameCount = PROCEDURAL_UNIFORM_FRAME_COUNT,
|
||||
Position = PROCEDURAL_UNIFORM_POSITION,
|
||||
Scale = PROCEDURAL_UNIFORM_SCALE,
|
||||
Orientation = PROCEDURAL_UNIFORM_ORIENTATION,
|
||||
ChannelResolution = PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION,
|
||||
Custom = PROCEDURAL_UNIFORM_CUSTOM,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
//
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
|
||||
struct Skybox {
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
Skybox skybox;
|
||||
};
|
||||
|
||||
|
@ -28,9 +28,13 @@ layout(location=0) out vec4 _fragColor;
|
|||
<@include procedural/ProceduralCommon.slh@>
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
//PROCEDURAL_BLOCK_BEGIN
|
||||
vec3 getSkyboxColor() {
|
||||
return vec3(abs(sin(iGlobalTime / 5.0)), 1.0, 0.0);
|
||||
}
|
||||
//PROCEDURAL_BLOCK_END
|
||||
|
||||
#line 2033
|
||||
#line 2038
|
||||
void main(void) {
|
||||
vec3 color = getSkyboxColor();
|
||||
// Protect from NaNs and negative values
|
||||
|
|
1
libraries/procedural/src/procedural/proceduralSkybox.slp
Normal file
1
libraries/procedural/src/procedural/proceduralSkybox.slp
Normal file
|
@ -0,0 +1 @@
|
|||
VERTEX graphics::vertex::skybox
|
|
@ -10,13 +10,13 @@
|
|||
|
||||
<@func declareBlendshape(USE_NORMAL, USE_TANGENT)@>
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
|
||||
uvec4 getPackedBlendshapeOffset(int i) {
|
||||
return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer blendshapeOffsetsBuffer {
|
||||
LAYOUT_STD140(binding=0) buffer blendshapeOffsetsBuffer {
|
||||
uvec4 _packedBlendshapeOffsets[];
|
||||
};
|
||||
uvec4 getPackedBlendshapeOffset(int i) {
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
<@include BloomApply.shared.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(binding=0) uniform sampler2D blurMap0;
|
||||
layout(binding=1) uniform sampler2D blurMap1;
|
||||
layout(binding=2) uniform sampler2D blurMap2;
|
||||
LAYOUT(binding=0) uniform sampler2D blurMap0;
|
||||
LAYOUT(binding=1) uniform sampler2D blurMap1;
|
||||
LAYOUT(binding=2) uniform sampler2D blurMap2;
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
Parameters parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<@include BloomThreshold.shared.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_BLOOM_COLOR) uniform sampler2D colorMap;
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_BLOOM_COLOR) uniform sampler2D colorMap;
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
Parameters parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ static const std::string DEFAULT_CUSTOM_SHADER{
|
|||
" }"
|
||||
};
|
||||
|
||||
static std::string getFileContent(std::string fileName, std::string defaultContent = std::string()) {
|
||||
static std::string getFileContent(const std::string& fileName, const std::string& defaultContent = std::string()) {
|
||||
QFile customFile(QString::fromStdString(fileName));
|
||||
if (customFile.open(QIODevice::ReadOnly)) {
|
||||
return customFile.readAll().toStdString();
|
||||
|
@ -270,7 +270,7 @@ DebugDeferredBuffer::~DebugDeferredBuffer() {
|
|||
}
|
||||
}
|
||||
|
||||
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string customFile) {
|
||||
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, const std::string& customFile) {
|
||||
switch (mode) {
|
||||
case AlbedoMode:
|
||||
return DEFAULT_ALBEDO_SHADER;
|
||||
|
@ -334,7 +334,7 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
|
|||
return std::string();
|
||||
}
|
||||
|
||||
bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile) const {
|
||||
bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, const std::string& customFile) const {
|
||||
if (mode != CustomMode) {
|
||||
return !_pipelines[mode];
|
||||
}
|
||||
|
@ -351,19 +351,17 @@ bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile)
|
|||
return true;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::string customFile) {
|
||||
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, const std::string& customFile) {
|
||||
if (pipelineNeedsUpdate(mode, customFile)) {
|
||||
static const auto FRAGMENT_SHADER_SOURCE =
|
||||
gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource();
|
||||
static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
|
||||
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER_SOURCE.getCode().find(SOURCE_PLACEHOLDER);
|
||||
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO, "Could not find source placeholder");
|
||||
static_assert(shader::render_utils::program::debug_deferred_buffer != 0, "Validate debug deferred program");
|
||||
|
||||
auto bakedFragmentShader = FRAGMENT_SHADER_SOURCE.getCode();
|
||||
bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), getShaderSourceCode(mode, customFile));
|
||||
static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
|
||||
shader::Source resolvedFragmentSource;
|
||||
resolvedFragmentSource = shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
|
||||
resolvedFragmentSource.replacements[REPLACEMENT_MARKER] = getShaderSourceCode(mode, customFile);
|
||||
|
||||
const auto vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
|
||||
const auto ps = gpu::Shader::createPixel({ bakedFragmentShader, FRAGMENT_SHADER_SOURCE.getReflection() });
|
||||
const auto ps = gpu::Shader::createPixel(resolvedFragmentSource);
|
||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>());
|
||||
|
||||
|
|
|
@ -112,9 +112,9 @@ private:
|
|||
using StandardPipelines = std::array<gpu::PipelinePointer, NumModes>;
|
||||
using CustomPipelines = std::unordered_map<std::string, CustomPipeline>;
|
||||
|
||||
bool pipelineNeedsUpdate(Mode mode, std::string customFile = std::string()) const;
|
||||
const gpu::PipelinePointer& getPipeline(Mode mode, std::string customFile = std::string());
|
||||
std::string getShaderSourceCode(Mode mode, std::string customFile = std::string());
|
||||
bool pipelineNeedsUpdate(Mode mode, const std::string& customFile = std::string()) const;
|
||||
const gpu::PipelinePointer& getPipeline(Mode mode, const std::string& customFile = std::string());
|
||||
std::string getShaderSourceCode(Mode mode, const std::string& customFile = std::string());
|
||||
|
||||
ParametersBuffer _parameters;
|
||||
StandardPipelines _pipelines;
|
||||
|
|
|
@ -17,23 +17,23 @@
|
|||
// See DeferredShader_MapSlot in DeferredLightingEffect.cpp for constants
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_COLOR) uniform sampler2D albedoMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_COLOR) uniform sampler2D albedoMap;
|
||||
|
||||
// the normal texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL) uniform sampler2D normalMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL) uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_SPECULAR) uniform sampler2D specularMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_SPECULAR) uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap;
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
|
||||
|
||||
// the obscurance texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_OBSCURANCE) uniform sampler2D obscuranceMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_OBSCURANCE) uniform sampler2D obscuranceMap;
|
||||
|
||||
// the lighting texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING) uniform sampler2D lightingMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING) uniform sampler2D lightingMap;
|
||||
|
||||
|
||||
struct DeferredFragment {
|
||||
|
@ -170,14 +170,14 @@ DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform
|
|||
<@func declareDeferredCurvature()@>
|
||||
|
||||
// the curvature texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE) uniform sampler2D curvatureMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE) uniform sampler2D curvatureMap;
|
||||
|
||||
vec4 fetchCurvature(vec2 texcoord) {
|
||||
return texture(curvatureMap, texcoord);
|
||||
}
|
||||
|
||||
// the curvature texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE) uniform sampler2D diffusedCurvatureMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE) uniform sampler2D diffusedCurvatureMap;
|
||||
|
||||
vec4 fetchDiffusedCurvature(vec2 texcoord) {
|
||||
return texture(diffusedCurvatureMap, texcoord);
|
||||
|
|
|
@ -44,7 +44,7 @@ using namespace render;
|
|||
struct LightLocations {
|
||||
bool shadowTransform{ false };
|
||||
void initialize(const gpu::ShaderPointer& program) {
|
||||
shadowTransform = program->getUniformBuffers().isValid(ru::Buffer::ShadowParams);
|
||||
shadowTransform = program->getReflection().validUniformBuffer(ru::Buffer::ShadowParams);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ struct CameraCorrection {
|
|||
mat4 _prevViewInverse;
|
||||
};
|
||||
|
||||
layout(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
|
||||
LAYOUT(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
|
||||
CameraCorrection cameraCorrection;
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ struct DeferredFrameTransform {
|
|||
mat4 _invProjectionUnJittered[2];
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer {
|
||||
DeferredFrameTransform frameTransform;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
<@include FadeObjectParams.shared.slh@>
|
||||
|
||||
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_FADE_PARAMS) uniform fadeParametersBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_FADE_PARAMS) uniform fadeParametersBuffer {
|
||||
FadeParameters fadeParameters[CATEGORY_COUNT];
|
||||
};
|
||||
|
||||
// See ShapePipeline::Slot::MAP in ShapePipeline.h
|
||||
layout(binding=RENDER_UTILS_TEXTURE_FADE_MASK) uniform sampler2D fadeMaskMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_FADE_MASK) uniform sampler2D fadeMaskMap;
|
||||
|
||||
vec3 getNoiseInverseSize(int category) {
|
||||
return fadeParameters[category]._noiseInvSizeAndLevel.xyz;
|
||||
|
@ -117,7 +117,7 @@ void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) {
|
|||
|
||||
<@func declareFadeFragmentUniform()@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS) uniform fadeObjectParametersBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS) uniform fadeObjectParametersBuffer {
|
||||
FadeObjectParams fadeObjectParams;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<@include Haze.slh@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;
|
||||
|
||||
vec4 unpackPositionFromZeye(vec2 texcoord) {
|
||||
float Zeye = -texture(linearDepthMap, texcoord).x;
|
||||
|
|
|
@ -39,7 +39,7 @@ struct HazeParams {
|
|||
};
|
||||
|
||||
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
|
||||
HazeParams hazeParams;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
<@include Highlight_shared.slh@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuffer {
|
||||
HighlightParameters params;
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap;
|
||||
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
|
|
@ -402,36 +402,31 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
|
|||
}
|
||||
|
||||
void DebugHighlight::initializePipelines() {
|
||||
static const auto FRAGMENT_SHADER_SOURCE = gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource();
|
||||
static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
|
||||
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER_SOURCE.getCode().find(SOURCE_PLACEHOLDER);
|
||||
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO,
|
||||
"Could not find source placeholder");
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setDepthTest(gpu::State::DepthTest(false, false));
|
||||
state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
|
||||
state->setColorWriteMask(true, true, true, true);
|
||||
|
||||
const auto vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
|
||||
|
||||
static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
|
||||
// Depth shader
|
||||
{
|
||||
static const std::string DEPTH_SHADER{ R"SHADER(
|
||||
static const std::string DEPTH_SHADER{ R"SHADER(
|
||||
vec4 getFragmentColor() {
|
||||
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
|
||||
Zdb = 1.0-(1.0-Zdb)*100;
|
||||
return vec4(Zdb, Zdb, Zdb, 1.0);
|
||||
}
|
||||
)SHADER" };
|
||||
static const auto& vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
|
||||
|
||||
auto fragmentShader = FRAGMENT_SHADER_SOURCE.getCode();
|
||||
fragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), DEPTH_SHADER);
|
||||
|
||||
const auto ps = gpu::Shader::createPixel({ fragmentShader, FRAGMENT_SHADER_SOURCE.getReflection() });
|
||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
_depthPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
gpu::Shader::Source fragmentSource;
|
||||
fragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
|
||||
fragmentSource.replacements[REPLACEMENT_MARKER] = DEPTH_SHADER;
|
||||
|
||||
const auto ps = gpu::Shader::createPixel(fragmentSource);
|
||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setDepthTest(gpu::State::DepthTest(false, false));
|
||||
state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
|
||||
state->setColorWriteMask(true, true, true, true);
|
||||
|
||||
_depthPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DebugHighlight::getDepthPipeline() {
|
||||
|
|
|
@ -22,8 +22,8 @@ struct ItemBound {
|
|||
vec4 boundDim_s;
|
||||
};
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer ssbo0Buffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=0) uniform samplerBuffer ssbo0Buffer;
|
||||
ItemBound getItemBound(int i) {
|
||||
int offset = 2 * i;
|
||||
ItemBound bound;
|
||||
|
@ -32,7 +32,7 @@ ItemBound getItemBound(int i) {
|
|||
return bound;
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer ssbo0Buffer {
|
||||
LAYOUT_STD140(binding=0) buffer ssbo0Buffer {
|
||||
ItemBound bounds[];
|
||||
};
|
||||
ItemBound getItemBound(int i) {
|
||||
|
@ -45,7 +45,7 @@ struct HighlightParameters {
|
|||
vec2 outlineWidth;
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform parametersBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform parametersBuffer {
|
||||
HighlightParameters _parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<@include render-utils/ShaderConstants.h@>
|
||||
<@func declareSkyboxMap()@>
|
||||
// declareSkyboxMap
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SKYBOX) uniform samplerCube skyboxMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SKYBOX) uniform samplerCube skyboxMap;
|
||||
|
||||
vec4 evalSkyboxLight(vec3 direction, float lod) {
|
||||
// textureQueryLevels is not available until #430, so we require explicit lod
|
||||
|
|
|
@ -24,7 +24,7 @@ struct FrustumGrid {
|
|||
mat4 eyeToWorldMat;
|
||||
};
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer {
|
||||
FrustumGrid frustumGrid;
|
||||
};
|
||||
|
||||
|
@ -60,11 +60,11 @@ float projection_getFar(mat4 projection) {
|
|||
#define GRID_FETCH_BUFFER(i) i!>
|
||||
<@endif@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer {
|
||||
GRID_INDEX_TYPE _clusterGridTable[GRID_NUM_ELEMENTS];
|
||||
};
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer {
|
||||
GRID_INDEX_TYPE _clusterGridContent[GRID_NUM_ELEMENTS];
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ struct LightingModel {
|
|||
};
|
||||
|
||||
// See DeferredShader_BufferSlot in DeferredLightingEffect.cpp
|
||||
layout(binding=RENDER_UTILS_BUFFER_LIGHT_MODEL) uniform lightingModelBuffer{
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_MODEL) uniform lightingModelBuffer{
|
||||
LightingModel lightingModel;
|
||||
};
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
}
|
||||
|
||||
void initForwardPipelines(ShapePlumber& plumber) {
|
||||
using namespace shader::render_utils::program;
|
||||
using namespace shader::render_utils;
|
||||
|
||||
using Key = render::ShapeKey;
|
||||
auto addPipelineBind = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4);
|
||||
|
@ -244,33 +244,33 @@ void initForwardPipelines(ShapePlumber& plumber) {
|
|||
forceLightBatchSetter = true;
|
||||
|
||||
// Simple Opaques
|
||||
addPipeline(Key::Builder(), simple);
|
||||
addPipeline(Key::Builder().withUnlit(), simpleUnlit);
|
||||
addPipeline(Key::Builder(), program::forward_simple_textured);
|
||||
addPipeline(Key::Builder().withUnlit(), program::forward_simple_textured_unlit);
|
||||
|
||||
// Simple Translucents
|
||||
addPipeline(Key::Builder().withTranslucent(), simpleTranslucent);
|
||||
addPipeline(Key::Builder().withTranslucent().withUnlit(), simpleTranslucentUnlit);
|
||||
addPipeline(Key::Builder().withTranslucent(), program::forward_simple_textured_transparent);
|
||||
addPipeline(Key::Builder().withTranslucent().withUnlit(), program::simple_transparent_textured_unlit);
|
||||
|
||||
// Opaques
|
||||
addPipeline(Key::Builder().withMaterial(), forward_model);
|
||||
addPipeline(Key::Builder().withMaterial().withUnlit(), forward_model_unlit);
|
||||
addPipeline(Key::Builder().withMaterial().withTangents(), forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial(), program::forward_model);
|
||||
addPipeline(Key::Builder().withMaterial().withUnlit(), program::forward_model_unlit);
|
||||
addPipeline(Key::Builder().withMaterial().withTangents(), program::forward_model_translucent);
|
||||
|
||||
// Deformed Opaques
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed(), forward_deformed_model);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), forward_deformed_model_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), forward_deformed_model_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), forward_deformed_model_normal_map_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed(), program::forward_deformed_model);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), program::forward_deformed_model_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), program::forward_deformed_model_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), program::forward_deformed_model_normal_map_dq);
|
||||
|
||||
// Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent(), forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), forward_model_normal_map_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent(), program::forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), program::forward_model_normal_map_translucent);
|
||||
|
||||
// Deformed Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), forward_deformed_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), forward_deformed_translucent_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), forward_deformed_translucent_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), forward_deformed_translucent_normal_map_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), program::forward_deformed_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), program::forward_deformed_translucent_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), program::forward_deformed_translucent_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), program::forward_deformed_translucent_normal_map_dq);
|
||||
|
||||
forceLightBatchSetter = false;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<@func declareBeckmannSpecular()@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSSC_SPECULAR_BECKMANN) uniform sampler2D scatteringSpecularBeckmann;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_SPECULAR_BECKMANN) uniform sampler2D scatteringSpecularBeckmann;
|
||||
|
||||
float fetchSpecularBeckmann(float ndoth, float roughness) {
|
||||
return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define SHADOW_SCREEN_SPACE_DITHER 1
|
||||
|
||||
// the shadow texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
|
||||
// Sample the shadowMap with PCF (built-in)
|
||||
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<@include Shadows_shared.slh@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer {
|
||||
ShadowParameters shadow;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
const int MAX_CLUSTERS = 128;
|
||||
const int INDICES_PER_VERTEX = 4;
|
||||
|
||||
layout(std140, binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
|
||||
LAYOUT_STD140(binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
|
||||
mat4 clusterMatrices[MAX_CLUSTERS];
|
||||
};
|
||||
|
||||
|
|
|
@ -421,6 +421,10 @@ void DebugSubsurfaceScattering::configure(const Config& config) {
|
|||
_showSpecularTable = config.showSpecularTable;
|
||||
_showCursorPixel = config.showCursorPixel;
|
||||
_debugCursorTexcoord = config.debugCursorTexcoord;
|
||||
if (!_debugParams) {
|
||||
_debugParams = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
|
||||
}
|
||||
_debugParams->setSubData(0, _debugCursorTexcoord);
|
||||
}
|
||||
|
||||
|
||||
|
@ -479,6 +483,10 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
|
|||
assert(lightStage);
|
||||
// const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0);
|
||||
const auto light = lightStage->getLight(0);
|
||||
if (!_debugParams) {
|
||||
_debugParams = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
|
||||
_debugParams->setSubData(0, _debugCursorTexcoord);
|
||||
}
|
||||
|
||||
gpu::doInBatch("DebugSubsurfaceScattering::run", args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
@ -521,9 +529,7 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
|
|||
batch.setResourceTexture(ru::Texture::DeferredNormal, deferredFramebuffer->getDeferredNormalTexture());
|
||||
batch.setResourceTexture(ru::Texture::DeferredColor, deferredFramebuffer->getDeferredColorTexture());
|
||||
batch.setResourceTexture(ru::Texture::DeferredDepth, linearDepthTexture);
|
||||
|
||||
|
||||
batch._glUniform2f(gpu::slot::uniform::Extra0, _debugCursorTexcoord.x, _debugCursorTexcoord.y);
|
||||
batch.setUniformBuffer(1, _debugParams);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ private:
|
|||
|
||||
gpu::PipelinePointer _showLUTPipeline;
|
||||
gpu::PipelinePointer getShowLUTPipeline();
|
||||
gpu::BufferPointer _debugParams;
|
||||
bool _showProfile{ false };
|
||||
bool _showLUT{ false };
|
||||
bool _showSpecularTable{ false };
|
||||
|
|
|
@ -56,7 +56,7 @@ vec3 generateProfile(vec2 uv) {
|
|||
|
||||
<@func declareSubsurfaceScatteringProfileMap()@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSSC_PROFILE) uniform sampler2D scatteringProfile;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_PROFILE) uniform sampler2D scatteringProfile;
|
||||
|
||||
vec3 scatter(float r) {
|
||||
return texture(scatteringProfile, vec2(r * 0.5, 0.5)).rgb;
|
||||
|
@ -104,7 +104,7 @@ vec3 integrate(float cosTheta, float skinRadius) {
|
|||
|
||||
<@func declareSubsurfaceScatteringResource()@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSSC_LUT) uniform sampler2D scatteringLUT;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_LUT) uniform sampler2D scatteringLUT;
|
||||
|
||||
vec3 fetchBRDF(float LdotN, float curvature) {
|
||||
return texture(scatteringLUT, vec2( clamp(LdotN * 0.5 + 0.5, 0.0, 1.0), clamp(2.0 * curvature, 0.0, 1.0))).xyz;
|
||||
|
@ -124,7 +124,7 @@ struct ScatteringParameters {
|
|||
vec4 debugFlags;
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
|
||||
ScatteringParameters parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ struct WorkloadProxy {
|
|||
vec4 region;
|
||||
};
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer workloadProxiesBuffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=0) uniform samplerBuffer workloadProxiesBuffer;
|
||||
WorkloadProxy getWorkloadProxy(int i) {
|
||||
int offset = 2 * i;
|
||||
WorkloadProxy proxy;
|
||||
|
@ -35,7 +35,7 @@ WorkloadProxy getWorkloadProxy(int i) {
|
|||
return proxy;
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer workloadProxiesBuffer {
|
||||
LAYOUT_STD140(binding=0) buffer workloadProxiesBuffer {
|
||||
WorkloadProxy _proxies[];
|
||||
};
|
||||
WorkloadProxy getWorkloadProxy(int i) {
|
||||
|
@ -57,17 +57,23 @@ struct WorkloadView {
|
|||
vec4 regions[3];
|
||||
};
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=1) uniform samplerBuffer workloadViewsBuffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=1) uniform samplerBuffer workloadViewsBuffer;
|
||||
WorkloadView getWorkloadView(int i) {
|
||||
int offset = 2 * i;
|
||||
int offset = 8 * i;
|
||||
WorkloadView view;
|
||||
view.origin = texelFetch(workloadViewsBuffer, offset);
|
||||
view.radiuses = texelFetch(workloadViewsBuffer, offset + 1);
|
||||
view.direction_far = texelFetch(workloadViewsBuffer, offset + 0);
|
||||
view.fov = texelFetch(workloadViewsBuffer, offset + 1);
|
||||
view.origin = texelFetch(workloadViewsBuffer, offset + 2);
|
||||
view.backFront[0] = texelFetch(workloadViewsBuffer, offset + 3);
|
||||
view.backFront[1] = texelFetch(workloadViewsBuffer, offset + 4);
|
||||
view.regions[0] = texelFetch(workloadViewsBuffer, offset + 5);
|
||||
view.regions[1] = texelFetch(workloadViewsBuffer, offset + 6);
|
||||
view.regions[2] = texelFetch(workloadViewsBuffer, offset + 7);
|
||||
return view;
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=1) buffer workloadViewsBuffer {
|
||||
LAYOUT_STD140(binding=1) buffer workloadViewsBuffer {
|
||||
WorkloadView _views[];
|
||||
};
|
||||
WorkloadView getWorkloadView(int i) {
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<@include gpu/Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
layout(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
LAYOUT(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
|
||||
<@include ShadowCore.slh@>
|
||||
|
||||
|
@ -36,7 +36,13 @@ float curvatureAO(float k) {
|
|||
layout(location=0) in vec2 uv;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
//SOURCE_PLACEHOLDER
|
||||
//SOURCE_PLACEHOLDER_BEGIN
|
||||
vec4 getFragmentColor() {
|
||||
DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);
|
||||
return vec4(pow(frag.albedo, vec3(1.0 / 2.2)), 1.0);
|
||||
}
|
||||
//SOURCE_PLACEHOLDER_END
|
||||
|
||||
|
||||
void main(void) {
|
||||
outFragColor = getFragmentColor();
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<$declareLightBuffer(256)$>
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
int lightIndex[256];
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<$declareLightBuffer(256)$>
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
int lightIndex[256];
|
||||
};
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord0;
|
||||
|
|
|
@ -32,7 +32,7 @@ struct DrawMesh {
|
|||
vec4 verts[NUM_SEGMENT_PER_VIEW_REGION];
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform DrawMeshBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform DrawMeshBuffer {
|
||||
DrawMesh _drawMeshBuffer;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
<@include DefaultMaterials.slh@>
|
||||
|
||||
<@include ForwardGlobalLight.slh@>
|
||||
<$declareEvalSkyboxGlobalColor()$>
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareEvalSkyboxGlobalColor()$>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||
|
@ -35,12 +37,6 @@ layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
|||
|
||||
layout(location=0) out vec4 _fragColor0;
|
||||
|
||||
<@include procedural/ProceduralCommon.slh@>
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
vec3 normal = normalize(_normalWS.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
|
@ -48,45 +44,18 @@ void main(void) {
|
|||
float shininess = DEFAULT_SHININESS;
|
||||
float emissiveAmount = 0.0;
|
||||
|
||||
#ifdef PROCEDURAL
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
diffuse = getProceduralColor().rgb;
|
||||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
//diffuse = pow(diffuse, vec3(2.2));
|
||||
emissiveAmount = 1.0;
|
||||
#else
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragPosition = _positionES.xyz;
|
||||
|
||||
if (emissiveAmount > 0.0) {
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
specular,
|
||||
DEFAULT_METALLIC,
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
} else {
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
length(specular),
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
}
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
length(specular),
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
layout(location=0) out vec4 _fragColor0;
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||
|
|
|
@ -22,7 +22,7 @@ precision mediump float;
|
|||
precision mediump int;
|
||||
#endif
|
||||
|
||||
layout(binding=0) uniform sampler2D colorTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D colorTexture;
|
||||
//uniform sampler2D historyTexture;
|
||||
|
||||
// FIXME make into a uniform buffer or push constant if this shader ever comes into use
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue