New SPIRV Shader toolchain

This commit is contained in:
Brad Davis 2018-08-27 08:14:37 -07:00
parent 8ce2081349
commit c8e664a0a1
175 changed files with 2316 additions and 1697 deletions

View file

@ -24,7 +24,6 @@ android {
'-DANDROID_STL=c++_shared', '-DANDROID_STL=c++_shared',
'-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake', '-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake',
'-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX, '-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX,
'-DNATIVE_SHREFLECT=' + HIFI_ANDROID_PRECOMPILED + '/shreflect' + EXEC_SUFFIX,
'-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED, '-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED,
'-DRELEASE_NUMBER=' + RELEASE_NUMBER, '-DRELEASE_NUMBER=' + RELEASE_NUMBER,
'-DRELEASE_TYPE=' + RELEASE_TYPE, '-DRELEASE_TYPE=' + RELEASE_TYPE,

View file

@ -161,31 +161,19 @@ def packages = [
] ]
] ]
def scribeLocalFile='scribe' + EXEC_SUFFIX def scribeLocalFile='scribe' + EXEC_SUFFIX
def scribeFile='scribe_linux_x86_64' def scribeFile='scribe_linux_x86_64'
def scribeChecksum='ca4b904f52f4f993c29175ba96798fa6' def scribeChecksum='4635c28192724281d2367ce9e94380ab'
def scribeVersion='u_iTrJDaE95i2abTPXOpPZckGBIim53G' def scribeVersion='mPAY_N846oZH1tPY1bwChB_hzqkiYyoC'
def shreflectLocalFile='shreflect' + EXEC_SUFFIX
def shreflectFile='shreflect_linux_x86_64'
def shreflectChecksum='d6094a8580066c0b6f4e80b5adfb1d98'
def shreflectVersion='jnrpudh6fptIg6T2.Z6fgKP2ultAdKmE'
if (Os.isFamily(Os.FAMILY_MAC)) { if (Os.isFamily(Os.FAMILY_MAC)) {
scribeFile = 'scribe_osx_x86_64' scribeFile = 'scribe_osx_x86_64'
scribeChecksum='72db9d32d4e1e50add755570ac5eb749' scribeChecksum='1ead61c285d265eba9a5ef91ae3b7c26'
scribeVersion='DAW0DmnjCRib4MD8x93bgc2Z2MpPojZC' scribeVersion='4TAXWdo9fviw60N2wUA8HNyQ9TabjZa3'
shreflectFile='shreflect_osx_x86_64'
shreflectChecksum='d613ef0703c21371fee93fd2e54b964f'
shreflectVersion='.rYNzjSFq6WtWDnE5KIKRIAGyJtr__ad'
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) { } else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
scribeFile = 'scribe_win32_x86_64.exe' scribeFile = 'scribe_win32_x86_64.exe'
scribeChecksum='678e43d290c90fda670c6fefe038a06d' scribeChecksum='9c29a62595daf4844f95f6744d568c15'
scribeVersion='PuullrA_bPlO9kXZRt8rLe536X1UI.m7' scribeVersion='DUoxjufeX8ZAIVRBKRczWTuZwT13enTv'
shreflectFile='shreflect_win32_x86_64.exe'
shreflectChecksum='6f4a77b8cceb3f1bbc655132c3665060'
shreflectVersion='iIyCyza1nelkbI7ihybF59bBlwrfAC3D'
} }
def options = [ def options = [
@ -461,27 +449,11 @@ task fixScribePermissions(type: Exec, dependsOn: verifyScribe) {
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + scribeLocalFile commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + scribeLocalFile
} }
task downloadShreflect(type: Download) { task setupScribe(dependsOn: [verifyScribe]) { }
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]) { }
// On Windows, we don't need to set the executable bit, but on OSX and Unix we do // On Windows, we don't need to set the executable bit, but on OSX and Unix we do
if (!Os.isFamily(Os.FAMILY_WINDOWS)) { if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
setupScribe.dependsOn fixScribePermissions setupScribe.dependsOn fixScribePermissions
setupScribe.dependsOn fixShreflectPermissions
} }
task extractGvrBinaries(dependsOn: extractDependencies) { task extractGvrBinaries(dependsOn: extractDependencies) {

42
cmake/externals/glslang/CMakeLists.txt vendored Normal file
View 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")

View 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")

View 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")

View 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")

View 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")

View file

@ -10,6 +10,10 @@ if (POLICY CMP0042)
cmake_policy(SET CMP0042 NEW) cmake_policy(SET CMP0042 NEW)
endif () endif ()
if (POLICY CMP0074)
cmake_policy(SET CMP0074 OLD)
endif ()
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets") set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
# Hide automoc folders (for IDEs) # Hide automoc folders (for IDEs)

View file

@ -8,34 +8,132 @@
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # 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) 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) unset(SHADER_INCLUDE_FILES)
# Grab include files
foreach(includeFile ${ARGN}) foreach(includeFile ${ARGN})
list(APPEND SHADER_INCLUDE_FILES ${includeFile}) list(APPEND SHADER_INCLUDE_FILES ${includeFile})
endforeach() endforeach()
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES}) foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH) get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR}) list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
endforeach() endforeach()
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
#Extract the unique include shader paths
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES}) set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES}) foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE}) list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
endforeach() endforeach()
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS) list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
#message(ready for includes ${SHADER_INCLUDES_PATHS}) unset(SCRIBE_INCLUDES)
# make the scribe include arguments
set(SCRIBE_INCLUDES)
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS}) foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS})
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/) set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/)
endforeach() endforeach()
#
# Figure out the various output names
#
# Define the final name of the generated shader file # Define the final name of the generated shader file
get_filename_component(SHADER_NAME ${SHADER_FILE} NAME_WE) get_filename_component(SHADER_NAME ${SHADER_FILE} NAME_WE)
get_filename_component(SHADER_EXT ${SHADER_FILE} EXT) get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
@ -46,38 +144,36 @@ macro(AUTOSCRIBE_SHADER)
elseif(${SHADER_EXT} STREQUAL .slg) elseif(${SHADER_EXT} STREQUAL .slg)
set(SHADER_TYPE geom) set(SHADER_TYPE geom)
endif() 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 # SHADER_SCRIBED -> the output of scribe
add_custom_command( set(SHADER_SCRIBED "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
OUTPUT ${SHADER_TARGET}
COMMAND ${SCRIBE_COMMAND} ${SCRIBE_ARGS}
DEPENDS ${SHADER_FILE} ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES})
# Generate the json reflection # SHADER_NAME_FILE -> a file containing the shader name and extension (useful for debugging and for
# FIXME move to spirv-cross for this task after we have spirv compatible shaders # determining the type of shader from the filename)
add_custom_command( set(SHADER_NAME_FILE "${SHADER_SCRIBED}.name")
OUTPUT ${REFLECTED_SHADER} file(TO_CMAKE_PATH "${SHADER_SCRIBED}" SHADER_SCRIBED)
COMMAND ${SHREFLECT_COMMAND} ${COMPILED_SHADER} file(WRITE "${SHADER_SCRIBED}.name" "${SHADER_NAME}.${SHADER_TYPE}")
DEPENDS ${SHREFLECT_DEPENDENCY} ${COMPILED_SHADER}) AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/name" "${SHADER_NAME_FILE}")
#output the generated file name if (USE_GLES)
source_group("Compiled/${SHADER_LIB}" FILES ${COMPILED_SHADER}) set(SPIRV_CROSS_ARGS --version 310es)
set_property(SOURCE ${COMPILED_SHADER} PROPERTY SKIP_AUTOMOC ON) AUTOSCRIBE_PLATFORM_SHADER("310es")
list(APPEND COMPILED_SHADERS ${COMPILED_SHADER}) 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_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") MATH(EXPR SHADER_COUNT "${SHADER_COUNT}+1")
endmacro() endmacro()
@ -86,6 +182,8 @@ macro(AUTOSCRIBE_SHADER_LIB)
message(FATAL_ERROR "AUTOSCRIBE_SHADER_LIB can only be used by the shaders library") message(FATAL_ERROR "AUTOSCRIBE_SHADER_LIB can only be used by the shaders library")
endif() endif()
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES "${CMAKE_SOURCE_DIR}/libraries/${SHADER_LIB}/src") list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES "${CMAKE_SOURCE_DIR}/libraries/${SHADER_LIB}/src")
string(REGEX REPLACE "[-]" "_" SHADER_NAMESPACE ${SHADER_LIB}) string(REGEX REPLACE "[-]" "_" SHADER_NAMESPACE ${SHADER_LIB})
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace ${SHADER_NAMESPACE} {\n") string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace ${SHADER_NAMESPACE} {\n")
@ -165,66 +263,103 @@ macro(AUTOSCRIBE_SHADER_LIB)
# Finish the shader enums # Finish the shader enums
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "} // namespace ${SHADER_NAMESPACE}\n") 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() endmacro()
macro(AUTOSCRIBE_SHADER_LIBS) macro(AUTOSCRIBE_SHADER_LIBS)
set(SCRIBE_COMMAND scribe) message(STATUS "Shader processing start")
set(SHREFLECT_COMMAND shreflect) set(AUTOSCRIBE_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/headers)
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()
# Start the shader IDs # Start the shader IDs
set(SHADER_COUNT 1)
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders") set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
set(SHADER_ENUMS "")
file(MAKE_DIRECTORY ${SHADERS_DIR}) file(MAKE_DIRECTORY ${SHADERS_DIR})
set(SHADER_ENUMS "")
set(SHADER_COUNT 1)
# #
# Scribe generation & program defintiion # Scribe generation & program defintiion
# #
foreach(SHADER_LIB ${ARGN}) foreach(SHADER_LIB ${ARGN})
list(APPEND AUTOSCRIBE_SHADER_SEEN_LIBS ${SHADER_LIB})
AUTOSCRIBE_SHADER_LIB(${SHADER_LIB}) AUTOSCRIBE_SHADER_LIB(${SHADER_LIB})
endforeach() endforeach()
# Generate the library files # Generate the library files
configure_file( configure_file(
ShaderEnums.cpp.in ShaderEnums.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp) ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
configure_file( configure_file(
ShaderEnums.h.in ShaderEnums.h.in
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h) ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h)
configure_file(
shaders.qrc.in
${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
set(AUTOSCRIBE_SHADER_LIB_SRC "${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h;${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp") configure_file(shaders.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
set(QT_RESOURCES_FILE ${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 # Custom targets required to force generation of the shaders via scribe
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS}) add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS} ${AUTOSCRIBE_SHADER_HEADERS})
add_custom_target(compiled_shaders SOURCES ${COMPILED_SHADERS})
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
set_target_properties(scribe_shaders PROPERTIES FOLDER "Shaders") 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") set_target_properties(reflected_shaders PROPERTIES FOLDER "Shaders")
add_dependencies(reflected_shaders shadergen)
message(STATUS "Shader processing end")
endmacro() endmacro()

View file

@ -15,8 +15,8 @@ macro(TARGET_PYTHON)
set(HIFI_PYTHON_EXEC ${Python3_EXECUTABLE}) set(HIFI_PYTHON_EXEC ${Python3_EXECUTABLE})
endif() endif()
if ((NOT HIFI_PYTHON_EXEC) OR (HIFI_PYTHON_VERSION VERSION_LESS 3.6)) if ((NOT HIFI_PYTHON_EXEC) OR (HIFI_PYTHON_VERSION VERSION_LESS 3.5))
message(FATAL_ERROR "Unable to locate Python interpreter 3.6 or higher") message(FATAL_ERROR "Unable to locate Python interpreter 3.5 or higher")
endif() endif()
endif() endif()
endmacro() endmacro()

View 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()

View 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()

View 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()

View file

@ -1,6 +1,6 @@
set(TARGET_NAME avatars-renderer) set(TARGET_NAME avatars-renderer)
setup_hifi_library(Network Script) 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(avatars)
include_hifi_library_headers(networking) include_hifi_library_headers(networking)
include_hifi_library_headers(fbx) include_hifi_library_headers(fbx)

View file

@ -2,11 +2,11 @@ struct TextureData {
ivec2 textureSize; ivec2 textureSize;
}; };
layout(std140, binding=0) uniform textureDataBuffer { LAYOUT_STD140(binding=0) uniform textureDataBuffer {
TextureData textureData; TextureData textureData;
}; };
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;

View file

@ -363,56 +363,35 @@ void OpenGLDisplayPlugin::customizeContext() {
} }
if (!_presentPipeline) { 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::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); _simplePipeline = gpu::Pipeline::create(program, scissorState);
state->setDepthTest(gpu::State::DepthTest(false)); _hudPipeline = gpu::Pipeline::create(program, blendState);
state->setScissorEnable(true);
_simplePipeline = gpu::Pipeline::create(program, state);
} }
{ {
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::SrgbToLinear); gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::SrgbToLinear);
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); _presentPipeline = gpu::Pipeline::create(program, scissorState);
state->setDepthTest(gpu::State::DepthTest(false));
state->setScissorEnable(true);
_presentPipeline = gpu::Pipeline::create(program, state);
} }
{ {
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord); gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX);
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture); _mirrorHUDPipeline = gpu::Pipeline::create(program, blendState);
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);
} }
{ {
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord); gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTransformedTexture);
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTextureMirroredX); _cursorPipeline = gpu::Pipeline::create(program, blendState);
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);
} }
} }
updateCompositeFramebuffer(); updateCompositeFramebuffer();

View file

@ -1,10 +1,10 @@
// OpenGLDisplayPlugin_present.frag // 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) { float sRGBFloatToLinear(float value) {
const float SRGB_ELBOW = 0.04045; const float SRGB_ELBOW = 0.04045;

View file

@ -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. // 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 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) { ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
_procedural._vertexSource = gpu::Shader::getVertexShaderSource(shader::render_utils::vertex::simple); _procedural._vertexSource = gpu::Shader::getVertexShaderSource(shader::render_utils::vertex::simple);
// FIXME: Setup proper uniform slots and use correct pipelines for forward rendering // FIXME: Setup proper uniform slots and use correct pipelines for forward rendering
_procedural._opaquefragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple); _procedural._opaqueFragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::simple);
_procedural._transparentfragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple_transparent); _procedural._transparentFragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::simple_transparent);
_procedural._opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
_procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); _procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState); PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);

View file

@ -15,7 +15,7 @@
<@include DeferredBufferWrite.slh@> <@include DeferredBufferWrite.slh@>
// the albedo texture // the albedo texture
layout(binding=0) uniform sampler2D originalTexture; LAYOUT(binding=0) uniform sampler2D originalTexture;
// the interpolated normal // the interpolated normal
layout(location=0) in vec3 interpolatedNormal; layout(location=0) in vec3 interpolatedNormal;

View file

@ -18,7 +18,7 @@
<$declareFadeFragment()$> <$declareFadeFragment()$>
// the albedo texture // the albedo texture
layout(binding=0) uniform sampler2D originalTexture; LAYOUT(binding=0) uniform sampler2D originalTexture;
// the interpolated normal // the interpolated normal
layout(location=0) in vec3 interpolatedNormal; layout(location=0) in vec3 interpolatedNormal;
@ -30,7 +30,7 @@ struct PolyLineUniforms {
vec3 color; vec3 color;
}; };
layout(binding=0) uniform polyLineBuffer { LAYOUT(binding=0) uniform polyLineBuffer {
PolyLineUniforms polyline; PolyLineUniforms polyline;
}; };

View file

@ -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_MS) in vec4 _position;
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition; layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition;
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap; LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
struct PolyvoxParams { struct PolyvoxParams {
vec4 voxelVolumeSize; vec4 voxelVolumeSize;
}; };
layout(binding=0) uniform polyvoxParamsBuffer { LAYOUT(binding=0) uniform polyvoxParamsBuffer {
PolyvoxParams params; PolyvoxParams params;
}; };

View file

@ -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_WS) in vec4 _worldPosition;
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _worldFadePosition; layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _worldFadePosition;
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap; LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
struct PolyvoxParams { struct PolyvoxParams {
vec4 voxelVolumeSize; vec4 voxelVolumeSize;
}; };
layout(binding=0) uniform polyvoxParamsBuffer { LAYOUT(binding=0) uniform polyvoxParamsBuffer {
PolyvoxParams params; PolyvoxParams params;
}; };

View file

@ -10,7 +10,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // 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=0) in vec4 varColor;
layout(location=1) in vec2 varTexcoord; layout(location=1) in vec2 varTexcoord;

View file

@ -43,7 +43,7 @@ struct ParticleUniforms {
vec2 spare; vec2 spare;
}; };
layout(std140, binding=0) uniform particleBuffer { LAYOUT_STD140(binding=0) uniform particleBuffer {
ParticleUniforms particle; ParticleUniforms particle;
}; };

View file

@ -5,4 +5,4 @@ include_hifi_library_headers(fbx)
include_hifi_library_headers(gpu) include_hifi_library_headers(gpu)
include_hifi_library_headers(image) include_hifi_library_headers(image)
include_hifi_library_headers(ktx) 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)

View file

@ -1,6 +1,6 @@
set(TARGET_NAME gpu-gl-common) set(TARGET_NAME gpu-gl-common)
setup_hifi_library(Concurrent) setup_hifi_library(Concurrent)
link_hifi_libraries(shared gl gpu) link_hifi_libraries(shared gl gpu shaders)
GroupSources("src") GroupSources("src")
target_opengl() target_opengl()

View file

@ -643,18 +643,21 @@ protected:
} }
} _pipeline; } _pipeline;
// Backend dependant compilation of the shader // Backend dependent compilation of the shader
virtual void postLinkProgram(ShaderObject& programObject, const Shader& program) const; virtual void postLinkProgram(ShaderObject& programObject, const Shader& program) const;
virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler); virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler);
virtual GLShader* compileBackendShader(const Shader& shader, 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 // 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 // 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 // return the fully customized shader with all the version and backend specific
// preprocessor directives // preprocessor directives
// The program string returned can be used as a key for a cache of shader binaries // 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 // 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 { class ElementResource {
public: public:
gpu::Element _element; gpu::Element _element;

View file

@ -54,7 +54,7 @@ void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) {
// check the program cache // check the program cache
// pick the program version // pick the program version
#ifdef GPU_STEREO_CAMERA_BUFFER #ifdef GPU_STEREO_CAMERA_BUFFER
GLuint glprogram = pipelineObject->_program->getProgram((GLShader::Version)isStereo()); GLuint glprogram = pipelineObject->_program->getProgram(getShaderVariant());
#else #else
GLuint glprogram = pipelineObject->_program->getProgram(); GLuint glprogram = pipelineObject->_program->getProgram();
#endif #endif

View file

@ -25,120 +25,53 @@ static const std::array<GLenum, NUM_SHADER_DOMAINS> SHADER_DOMAINS{ {
GL_GEOMETRY_SHADER, GL_GEOMETRY_SHADER,
} }; } };
// Domain specific defines std::string GLBackend::getShaderSource(const Shader& shader, shader::Variant variant) {
// 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) {
if (shader.isProgram()) { if (shader.isProgram()) {
std::string result; std::string result;
result.append("// VERSION " + std::to_string(version));
for (const auto& subShader : shader.getShaders()) { for (const auto& subShader : shader.getShaders()) {
result.append("//-------- "); if (subShader) {
result.append(getShaderTypeString(subShader->getType())); result += subShader->getSource().getSource(getShaderDialect(), variant);
result.append("\n"); }
result.append(subShader->getSource().getCode());
} }
return result; return result;
} }
return shader.getSource().getSource(getShaderDialect(), variant);
std::string shaderDefines = getBackendShaderHeader() + "\n"
+ (supportsBindless() ? textureTableVersion : "\n")
+ DOMAIN_DEFINES[shader.getType()] + "\n"
+ VERSION_DEFINES[version];
return shaderDefines + "\n" + shader.getSource().getCode();
} }
GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler) { GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler) {
// Any GLSLprogram ? normally yes... // Any GLSLprogram ? normally yes...
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()]; GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
GLShader::ShaderObjects shaderObjects; GLShader::ShaderObjects shaderObjects;
Shader::CompilationLogs compilationLogs(GLShader::NumVersions); const auto& variants = shader::allVariants();
Shader::CompilationLogs compilationLogs(variants.size());
shader.incrementCompilationAttempt(); shader.incrementCompilationAttempt();
for (const auto& variant : variants) {
for (int version = 0; version < GLShader::NumVersions; version++) { auto index = static_cast<uint32_t>(variant);
auto& shaderObject = shaderObjects[version]; auto shaderSource = getShaderSource(shader, variant);
auto shaderSource = getShaderSource(shader, version); auto& shaderObject = shaderObjects[index];
if (handler) { if (handler) {
bool retest = true; bool retest = true;
std::string currentSrc = shaderSource; 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. // 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. // The handler tells us if we should retry or not while returning a modified version of the source.
while (retest) { while (retest) {
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[version].message); bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[index].message);
compilationLogs[version].compiled = result; compilationLogs[index].compiled = result;
if (!result) { if (!result) {
std::string newSrc; std::string newSrc;
retest = handler(shader, currentSrc, compilationLogs[version], newSrc); retest = handler(shader, currentSrc, compilationLogs[index], newSrc);
currentSrc = newSrc; currentSrc = newSrc;
} else { } else {
retest = false; retest = false;
} }
} }
} else { } 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) { if (!compilationLogs[index].compiled) {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[version].message.c_str(); qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[index].message.c_str();
shader.setCompilationLogs(compilationLogs); shader.setCompilationLogs(compilationLogs);
return nullptr; return nullptr;
} }
@ -162,11 +95,13 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
GLShader::ShaderObjects programObjects; GLShader::ShaderObjects programObjects;
program.incrementCompilationAttempt(); 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++) { for (const auto& variant : variants) {
auto& programObject = programObjects[version]; auto index = static_cast<uint32_t>(variant);
auto programSource = getShaderSource(program, version); auto& programObject = programObjects[index];
auto programSource = getShaderSource(program, variant);
auto hash = ::gl::getShaderHash(programSource); auto hash = ::gl::getShaderHash(programSource);
CachedShader cachedBinary; CachedShader cachedBinary;
@ -199,11 +134,11 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
for (auto subShader : program.getShaders()) { for (auto subShader : program.getShaders()) {
auto object = GLShader::sync((*this), *subShader, handler); auto object = GLShader::sync((*this), *subShader, handler);
if (object) { if (object) {
shaderGLObjects.push_back(object->_shaderObjects[version].glshader); shaderGLObjects.push_back(object->_shaderObjects[index].glshader);
} else { } else {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?"; qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?";
compilationLogs[version].compiled = false; compilationLogs[index].compiled = false;
compilationLogs[version].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?"); compilationLogs[index].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
program.setCompilationLogs(compilationLogs); program.setCompilationLogs(compilationLogs);
return nullptr; return nullptr;
} }
@ -211,9 +146,9 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
glprogram = ::gl::buildProgram(shaderGLObjects); glprogram = ::gl::buildProgram(shaderGLObjects);
if (!::gl::linkProgram(glprogram, compilationLogs[version].message)) { if (!::gl::linkProgram(glprogram, compilationLogs[index].message)) {
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();
compilationLogs[version].compiled = false; compilationLogs[index].compiled = false;
glDeleteProgram(glprogram); glDeleteProgram(glprogram);
glprogram = 0; glprogram = 0;
return nullptr; return nullptr;
@ -228,12 +163,12 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
} }
if (glprogram == 0) { 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); program.setCompilationLogs(compilationLogs);
return nullptr; return nullptr;
} }
compilationLogs[version].compiled = true; compilationLogs[index].compiled = true;
programObject.glprogram = glprogram; programObject.glprogram = glprogram;
postLinkProgram(programObject, program); postLinkProgram(programObject, program);
} }
@ -249,7 +184,10 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
static const GLint INVALID_UNIFORM_INDEX = -1; static const GLint INVALID_UNIFORM_INDEX = -1;
GLint GLBackend::getRealUniformLocation(GLint location) const { 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); auto itr = shader.uniformRemap.find(location);
if (itr == shader.uniformRemap.end()) { if (itr == shader.uniformRemap.end()) {
// This shouldn't happen, because we use reflection to determine all the possible // 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 { void GLBackend::postLinkProgram(ShaderObject& shaderObject, const Shader& program) const {
const auto& glprogram = shaderObject.glprogram; const auto& glprogram = shaderObject.glprogram;
const auto& expectedUniforms = program.getUniforms(); const auto& expectedUniforms = program.getReflection().uniforms;
const auto expectedLocationsByName = expectedUniforms.getLocationsByName();
const auto uniforms = ::gl::Uniform::load(glprogram, expectedUniforms.getNames());
auto& uniformRemap = shaderObject.uniformRemap;
// Pre-initialize all the uniforms with an invalid location auto& uniformRemap = shaderObject.uniformRemap;
for (const auto& entry : expectedLocationsByName) { // initialize all the uniforms with an invalid location
for (const auto& entry : expectedUniforms) {
uniformRemap[entry.second] = INVALID_UNIFORM_INDEX; 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) { for (const auto& uniform : uniforms) {
const auto& name = uniform.name; const auto& name = uniform.name;
const auto& expectedLocation = expectedLocationsByName.at(name); const auto& expectedLocation = expectedUniforms.at(name);
const auto& location = uniform.binding; const auto& location = uniform.binding;
uniformRemap[expectedLocation] = location; uniformRemap[expectedLocation] = location;
} }
@ -462,3 +403,4 @@ void GLBackend::initShaderBinaryCache() {
void GLBackend::killShaderBinaryCache() { void GLBackend::killShaderBinaryCache() {
::gl::saveShaderCache(_shaderBinaryCache._binaries); ::gl::saveShaderCache(_shaderBinaryCache._binaries);
} }

View file

@ -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 // Special case for view correction matrices, any pipeline that declares the correction buffer
// uniform will automatically have it provided without any client code necessary. // uniform will automatically have it provided without any client code necessary.
// Required for stable lighting in the HMD. // 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->_program = programObject;
object->_state = stateObject; object->_state = stateObject;

View file

@ -14,43 +14,45 @@
namespace gpu { namespace gl { namespace gpu { namespace gl {
struct ShaderObject { struct ShaderObject {
GLuint glshader { 0 }; enum class BindingType
GLuint glprogram { 0 }; {
INPUT,
OUTPUT,
TEXTURE,
SAMPLER,
UNIFORM_BUFFER,
RESOURCE_BUFFER,
UNIFORM,
};
using LocationMap = std::unordered_map <GLuint, GLuint>; using LocationMap = std::unordered_map<std::string, int32_t>;
LocationMap uniformRemap; 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 { class GLShader : public GPUObject {
public: public:
static GLShader* sync(GLBackend& backend, const Shader& shader, const Shader::CompilationHandler& handler = nullptr); 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 ShaderObject = gpu::gl::ShaderObject;
using ShaderObjects = std::array< ShaderObject, NumVersions >; using ShaderObjects = std::array<ShaderObject, shader::NUM_VARIANTS>;
using UniformMapping = std::map<GLint, GLint>;
using UniformMappingVersions = std::vector<UniformMapping>;
GLShader(const std::weak_ptr<GLBackend>& backend); GLShader(const std::weak_ptr<GLBackend>& backend);
~GLShader(); ~GLShader();
ShaderObjects _shaderObjects; ShaderObjects _shaderObjects;
GLuint getProgram(Version version = Mono) const { GLuint getProgram(shader::Variant version = shader::Variant::Mono) const {
return _shaderObjects[version].glprogram; return _shaderObjects[static_cast<uint32_t>(version)].glprogram;
} }
const std::weak_ptr<GLBackend> _backend; const std::weak_ptr<GLBackend> _backend;
}; };
} } }} // namespace gpu::gl
#endif #endif

View file

@ -1,6 +1,6 @@
set(TARGET_NAME gpu-gl) set(TARGET_NAME gpu-gl)
setup_hifi_library(Concurrent) 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) if (UNIX)
target_link_libraries(${TARGET_NAME} pthread) target_link_libraries(${TARGET_NAME} pthread)
endif(UNIX) endif(UNIX)

View file

@ -170,8 +170,7 @@ protected:
// Output stage // Output stage
void do_blit(const Batch& batch, size_t paramOffset) override; 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; void postLinkProgram(ShaderObject& programObject, const Shader& program) const override;
}; };

View file

@ -12,22 +12,13 @@ using namespace gpu;
using namespace gpu::gl; using namespace gpu::gl;
using namespace gpu::gl41; 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 { void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& program) const {
Parent::postLinkProgram(programObject, program); Parent::postLinkProgram(programObject, program);
const auto& glprogram = programObject.glprogram; const auto& glprogram = programObject.glprogram;
const auto& reflection = program.getReflection();
// For the UBOs, use glUniformBlockBinding to fixup the locations based on the reflection // 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); auto ubos = ::gl::UniformBlock::load(glprogram);
for (const auto& ubo : ubos) { for (const auto& ubo : ubos) {
const auto& name = ubo.name; 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 // 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) { for (const auto& expectedTexture : expectedTextures) {
auto location = glGetUniformLocation(glprogram, expectedTexture.first.c_str()); auto location = glGetUniformLocation(glprogram, expectedTexture.first.c_str());
if (location < 0) { 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 // 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& expectedResourceBuffers = reflection.resourceBuffers;
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, program.getResourceBuffers().getNames()); const auto names = Shader::Reflection::getNames(expectedResourceBuffers);
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names);
for (const auto& resourceBuffer : resourceBufferUniforms) { for (const auto& resourceBuffer : resourceBufferUniforms) {
const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name); const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name);
glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding + GL41Backend::RESOURCE_BUFFER_SLOT0_TEX_UNIT); glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding + GL41Backend::RESOURCE_BUFFER_SLOT0_TEX_UNIT);

View file

@ -23,7 +23,7 @@
#define GPU_BINDLESS_TEXTURES 0 #define GPU_BINDLESS_TEXTURES 0
namespace gpu { namespace gl45 { namespace gpu { namespace gl45 {
using namespace gpu::gl; using namespace gpu::gl;
using TextureWeakPointer = std::weak_ptr<Texture>; using TextureWeakPointer = std::weak_ptr<Texture>;
@ -56,6 +56,7 @@ public:
using Parent = GLTexture; using Parent = GLTexture;
friend class GL45Backend; friend class GL45Backend;
static GLuint allocate(const Texture& texture); static GLuint allocate(const Texture& texture);
protected: protected:
GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture); GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
void generateMips() const override; void generateMips() const override;
@ -88,6 +89,7 @@ public:
virtual const Bindless& getBindless() const; virtual const Bindless& getBindless() const;
void releaseBindless() const; void releaseBindless() const;
void recreateBindless() const; void recreateBindless() const;
private: private:
mutable Bindless _bindless; mutable Bindless _bindless;
#endif #endif
@ -98,10 +100,11 @@ public:
mutable Sampler _cachedSampler{ getInvalidSampler() }; mutable Sampler _cachedSampler{ getInvalidSampler() };
}; };
#if GPU_BINDLESS_TEXTURES #if GPU_BINDLESS_TEXTURES
class GL45TextureTable : public GLObject<TextureTable> { class GL45TextureTable : public GLObject<TextureTable> {
static GLuint allocate(); static GLuint allocate();
using Parent = GLObject<TextureTable>; using Parent = GLObject<TextureTable>;
public: public:
using BindlessArray = std::array<GL45Texture::Bindless, TextureTable::COUNT>; using BindlessArray = std::array<GL45Texture::Bindless, TextureTable::COUNT>;
@ -116,7 +119,6 @@ public:
}; };
#endif #endif
// //
// Textures that have fixed allocation sizes and cannot be managed at runtime // Textures that have fixed allocation sizes and cannot be managed at runtime
// //
@ -134,12 +136,13 @@ public:
void allocateStorage() const; void allocateStorage() const;
void syncSampler() const override; void syncSampler() const override;
const Size _size { 0 }; const Size _size{ 0 };
}; };
class GL45AttachmentTexture : public GL45FixedAllocationTexture { class GL45AttachmentTexture : public GL45FixedAllocationTexture {
using Parent = GL45FixedAllocationTexture; using Parent = GL45FixedAllocationTexture;
friend class GL45Backend; friend class GL45Backend;
protected: protected:
GL45AttachmentTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture); GL45AttachmentTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
~GL45AttachmentTexture(); ~GL45AttachmentTexture();
@ -148,6 +151,7 @@ public:
class GL45StrictResourceTexture : public GL45FixedAllocationTexture { class GL45StrictResourceTexture : public GL45FixedAllocationTexture {
using Parent = GL45FixedAllocationTexture; using Parent = GL45FixedAllocationTexture;
friend class GL45Backend; friend class GL45Backend;
protected: protected:
GL45StrictResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture); GL45StrictResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
~GL45StrictResourceTexture(); ~GL45StrictResourceTexture();
@ -179,6 +183,7 @@ public:
class GL45ResourceTexture : public GL45VariableAllocationTexture { class GL45ResourceTexture : public GL45VariableAllocationTexture {
using Parent = GL45VariableAllocationTexture; using Parent = GL45VariableAllocationTexture;
friend class GL45Backend; friend class GL45Backend;
protected: protected:
GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture); GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
@ -186,7 +191,6 @@ public:
size_t promote() override; size_t promote() override;
size_t demote() override; size_t demote() override;
void populateTransferQueue(TransferQueue& pendingTransfers) override; void populateTransferQueue(TransferQueue& pendingTransfers) override;
void allocateStorage(uint16 mip); void allocateStorage(uint16 mip);
Size copyMipsFromTexture(); Size copyMipsFromTexture();
@ -226,7 +230,6 @@ public:
}; };
#endif #endif
protected: protected:
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override; void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
@ -244,7 +247,6 @@ protected:
GLuint getQueryID(const QueryPointer& query) override; GLuint getQueryID(const QueryPointer& query) override;
GLQuery* syncGPUObject(const Query& query) override; GLQuery* syncGPUObject(const Query& query) override;
// Draw Stage // Draw Stage
void do_draw(const Batch& batch, size_t paramOffset) override; void do_draw(const Batch& batch, size_t paramOffset) override;
void do_drawIndexed(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; void do_blit(const Batch& batch, size_t paramOffset) override;
// Shader Stage // Shader Stage
std::string getBackendShaderHeader() const override; shader::Dialect getShaderDialect() const override;
// Texture Management Stage // Texture Management Stage
void initTextureManagementStage() override; void initTextureManagementStage() override;
@ -282,9 +284,8 @@ protected:
#endif #endif
}; };
} } }} // namespace gpu::gl45
Q_DECLARE_LOGGING_CATEGORY(gpugl45logging) Q_DECLARE_LOGGING_CATEGORY(gpugl45logging)
#endif #endif

View file

@ -7,22 +7,16 @@
// //
#include "GL45Backend.h" #include "GL45Backend.h"
#include <gpu/gl/GLShader.h> #include <gpu/gl/GLShader.h>
//#include <gl/GLShaders.h>
using namespace gpu; using namespace gpu;
using namespace gpu::gl; using namespace gpu::gl;
using namespace gpu::gl45; using namespace gpu::gl45;
// GLSL version shader::Dialect GL45Backend::getShaderDialect() const {
std::string GL45Backend::getBackendShaderHeader() const { #if defined(Q_OS_MAC)
static const std::string header( // We build, but don't actually use GL 4.5 on OSX
R"SHADER(#version 450 core throw std::runtime_error("GL 4.5 unavailable on OSX");
#define GPU_GL450 #else
#define BITFIELD int return shader::Dialect::glsl450;
)SHADER"
#ifdef GPU_SSBO_TRANSFORM_OBJECT
R"SHADER(#define GPU_SSBO_TRANSFORM_OBJECT)SHADER"
#endif #endif
);
return header;
} }

View file

@ -1,5 +1,5 @@
set(TARGET_NAME gpu-gles) set(TARGET_NAME gpu-gles)
setup_hifi_library(Gui Concurrent) 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") GroupSources("src")
target_opengl() target_opengl()

View file

@ -27,11 +27,7 @@ class GLESBackend : public GLBackend {
friend class Context; friend class Context;
public: public:
static const GLint TRANSFORM_OBJECT_SLOT { 31 };
static const GLint RESOURCE_TRANSFER_TEX_UNIT { 32 }; 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) {} explicit GLESBackend(bool syncCache) : Parent(syncCache) {}
GLESBackend() : Parent() {} GLESBackend() : Parent() {}
virtual ~GLESBackend() { virtual ~GLESBackend() {
@ -166,7 +162,7 @@ protected:
// Output stage // Output stage
void do_blit(const Batch& batch, size_t paramOffset) override; void do_blit(const Batch& batch, size_t paramOffset) override;
std::string getBackendShaderHeader() const override; shader::Dialect getShaderDialect() const override { return shader::Dialect::glsl310es; }
}; };
} } } }

View file

@ -12,15 +12,3 @@ using namespace gpu;
using namespace gpu::gl; using namespace gpu::gl;
using namespace gpu::gles; 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;
}

View file

@ -60,12 +60,11 @@ void GLESBackend::transferTransformState(const Batch& batch) const {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
glActiveTexture(GL_TEXTURE0 + GLESBackend::TRANSFORM_OBJECT_SLOT); glActiveTexture(GL_TEXTURE0 + slot::texture::ObjectTransforms);
glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture); glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture);
if (!batch._objects.empty()) { if (!batch._objects.empty()) {
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer);
} }
CHECK_GL_ERROR(); CHECK_GL_ERROR();
// Make sure the current Camera offset is unknown before render Draw // Make sure the current Camera offset is unknown before render Draw

View file

@ -17,7 +17,7 @@ struct DrawColorParams {
vec4 color; vec4 color;
}; };
layout(binding=0) uniform drawColorParamsBuffer { LAYOUT(binding=0) uniform drawColorParamsBuffer {
DrawColorParams params; DrawColorParams params;
}; };

View file

@ -13,13 +13,13 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // 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 { struct DrawColorParams {
vec4 color; vec4 color;
}; };
layout(binding=0) uniform drawColorParams { LAYOUT(binding=0) uniform drawColorParams {
DrawColorParams params; DrawColorParams params;
}; };

View file

@ -25,7 +25,7 @@ struct TexCoordRectParams {
vec4 texcoordRect; vec4 texcoordRect;
}; };
layout(binding=0) uniform texcoordRectBuffer { LAYOUT(binding=0) uniform texcoordRectBuffer {
TexCoordRectParams params; TexCoordRectParams params;
}; };

View file

@ -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) in vec2 varTexCoord0;
layout(location=0) out vec4 outFragColor; layout(location=0) out vec4 outFragColor;

View file

@ -1,2 +1 @@
VERTEX DrawUnitQuadTexcoord VERTEX DrawUnitQuadTexcoord
FRAGMENT DrawTexture

View file

@ -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) in vec2 varTexCoord0;
layout(location=0) out vec4 outFragColor; layout(location=0) out vec4 outFragColor;

View file

@ -0,0 +1 @@
VERTEX DrawUnitQuadTexcoord

View file

@ -16,7 +16,7 @@
<@include gpu/ShaderConstants.h@> <@include gpu/ShaderConstants.h@>
layout(binding=0) uniform sampler2D colorMap; LAYOUT(binding=0) uniform sampler2D colorMap;
layout(location=0) in vec2 varTexCoord0; layout(location=0) in vec2 varTexCoord0;

View file

@ -0,0 +1,2 @@
VERTEX DrawTransformUnitQuad
FRAGMENT DrawTexture

View file

@ -10,44 +10,49 @@
// //
#include "Shader.h" #include "Shader.h"
#include <math.h>
#include <QDebug>
#include <set>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <shaders/Shaders.h>
#include "Context.h" #include "Context.h"
using namespace gpu; using namespace gpu;
std::atomic<uint32_t> Shader::_nextShaderID( 1 );
Shader::DomainShaderMaps Shader::_domainShaderMaps;
Shader::ProgramMap Shader::_programMap; Shader::ProgramMap Shader::_programMap;
Shader::Shader(Type type, const Source& source) : Shader::Shader(Type type, const Source& source, bool dynamic) :
_source(source), _type(type)
_type(type),
_ID(_nextShaderID++)
{ {
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): Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel) :
_type(type), _type(type)
_ID(_nextShaderID++)
{ {
auto& shaders = const_cast<Shaders&>(_shaders);
if (geometry) { if (geometry) {
_shaders.resize(3); shaders.resize(3);
_shaders[VERTEX] = vertex; shaders[VERTEX] = vertex;
_shaders[GEOMETRY] = geometry; shaders[GEOMETRY] = geometry;
_shaders[PIXEL] = pixel; shaders[PIXEL] = pixel;
} else { } else {
_shaders.resize(2); shaders.resize(2);
_shaders[VERTEX] = vertex; shaders[VERTEX] = vertex;
_shaders[PIXEL] = pixel; 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) { static std::unordered_map<uint32_t, std::weak_ptr<Shader>> _shaderCache;
for (const auto& entry : map) {
const auto& name = entry.first; Shader::ID Shader::getID() const {
const auto& location = entry.second; if (isProgram()) {
slotSet.insert({ name, location, Element() }); return (_shaders[VERTEX]->getID() << 16) | (_shaders[PIXEL]->getID());
} }
return _source.id;
} }
Shader::Pointer Shader::createOrReuseDomainShader(Type type, const Source& source) { Shader::Pointer Shader::createOrReuseDomainShader(Type type, uint32_t sourceId) {
auto found = _domainShaderMaps[type].find(source); // Don't attempt to cache non-static shaders
if (found != _domainShaderMaps[type].end()) { auto found = _shaderCache.find(sourceId);
if (found != _shaderCache.end()) {
auto sharedShader = (*found).second.lock(); auto sharedShader = (*found).second.lock();
if (sharedShader) { if (sharedShader) {
return sharedShader; return sharedShader;
} }
} }
auto shader = Pointer(new Shader(type, source)); auto shader = Pointer(new Shader(type, getShaderSource(sourceId), false));
const auto& reflection = source.getReflection(); _shaderCache.insert({ sourceId, shader });
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));
return shader; return shader;
} }
@ -137,28 +123,6 @@ ShaderPointer Shader::createOrReuseProgramShader(Type type, const Pointer& verte
// Program is a new one, let's create it // Program is a new one, let's create it
auto program = Pointer(new Shader(type, vertexShader, geometryShader, pixelShader)); 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)); _programMap.emplace(key, std::weak_ptr<Shader>(program));
return program; return program;
} }
@ -175,24 +139,21 @@ void Shader::incrementCompilationAttempt() const {
} }
Shader::Pointer Shader::createVertex(const Source& source) { 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) { 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) { Shader::Pointer Shader::createVertex(uint32_t id) {
return createVertex(getShaderSource(id)); return createOrReuseDomainShader(VERTEX, id);
} }
Shader::Pointer Shader::createPixel(uint32_t 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) { Shader::Pointer Shader::createProgram(uint32_t programId) {
auto vertexShader = createVertex(shader::getVertexId(programId)); auto vertexShader = createVertex(shader::getVertexId(programId));
@ -200,98 +161,15 @@ Shader::Pointer Shader::createProgram(uint32_t programId) {
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, fragmentShader); 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) { 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"; const Shader::Source& Shader::getShaderSource(uint32_t id) {
return shader::Source::get(id);
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 };
} }

View file

@ -19,6 +19,7 @@
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <functional> #include <functional>
#include <shaders/Shaders.h>
#include <QUrl> #include <QUrl>
namespace gpu { namespace gpu {
@ -42,58 +43,10 @@ public:
typedef std::shared_ptr<Shader> Pointer; typedef std::shared_ptr<Shader> Pointer;
typedef std::vector<Pointer> Shaders; typedef std::vector<Pointer> Shaders;
// Needs to match values in shaders/Shaders.h using Source = shader::Source;
enum class BindingType using Reflection = shader::Reflection;
{ using Dialect = shader::Dialect;
INVALID = -1, using Variant = shader::Variant;
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;
};
struct CompilationLog { struct CompilationLog {
std::string message; std::string message;
@ -112,85 +65,13 @@ public:
bool operator()(const T& x, const T& y) const { return x._name < y._name; } bool operator()(const T& x, const T& y) const { return x._name < y._name; }
}; };
class Slot { static const Source& getShaderSource(uint32_t id);
public: static const Source& getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
std::string _name; static const Source& getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
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 Pointer createVertex(const Source& source); static Pointer createVertex(const Source& source);
static Pointer createPixel(const Source& source); static Pointer createPixel(const Source& source);
static Pointer createGeometry(const Source& source); static Pointer createGeometry(const Source& source);
static Pointer createVertex(uint32_t shaderId); static Pointer createVertex(uint32_t shaderId);
static Pointer createPixel(uint32_t shaderId); static Pointer createPixel(uint32_t shaderId);
static Pointer createGeometry(uint32_t shaderId); static Pointer createGeometry(uint32_t shaderId);
@ -201,8 +82,7 @@ public:
~Shader(); ~Shader();
ID getID() const { return _ID; } ID getID() const;
Type getType() const { return _type; } Type getType() const { return _type; }
bool isProgram() const { return getType() > NUM_DOMAINS; } bool isProgram() const { return getType() > NUM_DOMAINS; }
bool isDomain() const { return getType() < NUM_DOMAINS; } bool isDomain() const { return getType() < NUM_DOMAINS; }
@ -211,17 +91,12 @@ public:
const Shaders& getShaders() const { return _shaders; } const Shaders& getShaders() const { return _shaders; }
// Access the exposed uniform, input and output slot const Reflection& getReflection() const { return _source.reflection; }
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; }
// Compilation Handler can be passed while compiling a shader (in the makeProgram call) to be able to give the hand to // 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 // @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 // @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 // @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 // @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{}; const GPUObjectPointer gpuObject{};
protected: 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(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel);
Shader(const Shader& shader); // deep copy of the sysmem shader Shader(const Shader& shader); // deep copy of the sysmem shader
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture 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 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 // if shader is composed of sub shaders, here they are
Shaders _shaders; const Shaders _shaders;
// List of exposed uniform, input and output slots
SlotSet _uniforms;
SlotSet _uniformBuffers;
SlotSet _resourceBuffers;
SlotSet _textures;
SlotSet _samplers;
SlotSet _inputs;
SlotSet _outputs;
// The type of the shader, the master key // The type of the shader, the master key
Type _type; const Type _type;
// The unique identifier of a shader in the GPU lib
uint32_t _ID{ 0 };
// Number of attempts to compile the shader // Number of attempts to compile the shader
mutable uint32_t _numCompilationAttempts{ 0 }; mutable uint32_t _numCompilationAttempts{ 0 };
@ -277,13 +141,9 @@ protected:
// Global maps of the shaders // Global maps of the shaders
// Unique shader ID // Unique shader ID
static std::atomic<ID> _nextShaderID; //static std::atomic<ID> _nextShaderID;
using ShaderMap = std::map<Source, std::weak_ptr<Shader>, Source::Less>; static ShaderPointer createOrReuseDomainShader(Type type, uint32_t sourceId);
using DomainShaderMaps = std::array<ShaderMap, NUM_DOMAINS>;
static DomainShaderMaps _domainShaderMaps;
static ShaderPointer createOrReuseDomainShader(Type type, const Source& source);
using ProgramMapKey = glm::uvec3; // The IDs of the shaders in a program make its key using ProgramMapKey = glm::uvec3; // The IDs of the shaders in a program make its key
class ProgramKeyLess { class ProgramKeyLess {

View file

@ -98,21 +98,6 @@ enum Attribute {
}; };
} // namespace attr } // 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 } } // namespace gpu::slot
// !> // !>

View file

@ -16,7 +16,7 @@
#define TransformCamera _TransformCamera #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_IS_STEREO
#ifdef GPU_TRANSFORM_STEREO_CAMERA #ifdef GPU_TRANSFORM_STEREO_CAMERA
TransformCamera _camera[2]; TransformCamera _camera[2];
@ -26,7 +26,7 @@ layout(std140, binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffe
#else #else
TransformCamera _camera; TransformCamera _camera;
#endif #endif
}; } _cameraBlock;
#ifdef GPU_VERTEX_SHADER #ifdef GPU_VERTEX_SHADER
#ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_IS_STEREO
@ -76,12 +76,12 @@ TransformCamera getTransformCamera() {
_stereoSide = gl_InstanceID % 2; _stereoSide = gl_InstanceID % 2;
#endif #endif
#endif #endif
return _camera[_stereoSide]; return _cameraBlock._camera[_stereoSide];
#else #else
return _camera; return _cameraBlock._camera;
#endif #endif
#else #else
return _camera; return _cameraBlock._camera;
#endif #endif
} }
@ -93,7 +93,7 @@ bool cam_isStereo() {
#ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_IS_STEREO
return getTransformCamera()._stereoInfo.x > 0.0; return getTransformCamera()._stereoInfo.x > 0.0;
#else #else
return _camera._stereoInfo.x > 0.0; return _cameraBlock._camera._stereoInfo.x > 0.0;
#endif #endif
} }
@ -102,10 +102,10 @@ float cam_getStereoSide() {
#ifdef GPU_TRANSFORM_STEREO_CAMERA #ifdef GPU_TRANSFORM_STEREO_CAMERA
return getTransformCamera()._stereoInfo.y; return getTransformCamera()._stereoInfo.y;
#else #else
return _camera._stereoInfo.y; return _cameraBlock._camera._stereoInfo.y;
#endif #endif
#else #else
return _camera._stereoInfo.y; return _cameraBlock._camera._stereoInfo.y;
#endif #endif
} }
@ -120,7 +120,7 @@ struct TransformObject {
layout(location=GPU_ATTR_DRAW_CALL_INFO) in ivec2 _drawCallInfo; layout(location=GPU_ATTR_DRAW_CALL_INFO) in ivec2 _drawCallInfo;
#if defined(GPU_SSBO_TRANSFORM_OBJECT) #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 _object[];
}; };
TransformObject getTransformObject() { TransformObject getTransformObject() {
@ -128,7 +128,7 @@ TransformObject getTransformObject() {
return transformObject; return transformObject;
} }
#else #else
layout(binding=GPU_TEXTURE_TRANSFORM_OBJECT) uniform samplerBuffer transformObjectBuffer; LAYOUT(binding=GPU_TEXTURE_TRANSFORM_OBJECT) uniform samplerBuffer transformObjectBuffer;
TransformObject getTransformObject() { TransformObject getTransformObject() {
int offset = 8 * _drawCallInfo.x; 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)); vec4 eyeClipEdge[2]= vec4[2](vec4(-1,0,0,1), vec4(1,0,0,1));
vec2 eyeOffsetScale = vec2(-0.5, +0.5); vec2 eyeOffsetScale = vec2(-0.5, +0.5);
uint eyeIndex = uint(_stereoSide); uint eyeIndex = uint(_stereoSide);
#ifndef GPU_GLES
gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]); gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]);
#endif
float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w; float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w;
<$clipPos$>.x = newClipPosX; <$clipPos$>.x = newClipPosX;
#endif #endif

View file

@ -51,7 +51,7 @@ float getLightAmbientMapNumMips(LightAmbient l) { return l._ambient.y; }
<@if N@> <@if N@>
layout(binding=GRAPHICS_BUFFER_LIGHT) uniform lightBuffer { LAYOUT(binding=GRAPHICS_BUFFER_LIGHT) uniform lightBuffer {
Light lightArray[<$N$>]; Light lightArray[<$N$>];
}; };
Light getLight(int index) { Light getLight(int index) {
@ -59,7 +59,7 @@ Light getLight(int index) {
} }
<@else@> <@else@>
layout(binding=GRAPHICS_BUFFER_KEY_LIGHT) uniform keyLightBuffer { LAYOUT(binding=GRAPHICS_BUFFER_KEY_LIGHT) uniform keyLightBuffer {
Light light; Light light;
}; };
Light getKeyLight() { Light getKeyLight() {
@ -79,7 +79,7 @@ Light getKeyLight() {
<@if N@> <@if N@>
layout(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer { LAYOUT(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
LightAmbient lightAmbientArray[<$N$>]; LightAmbient lightAmbientArray[<$N$>];
}; };
@ -88,7 +88,7 @@ LightAmbient getLightAmbient(int index) {
} }
<@else@> <@else@>
layout(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer { LAYOUT(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
LightAmbient lightAmbient; LightAmbient lightAmbient;
}; };

View file

@ -48,7 +48,7 @@ struct Material {
vec4 _scatteringSpare2Key; vec4 _scatteringSpare2Key;
}; };
layout(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer { LAYOUT(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
Material _mat; Material _mat;
TexMapArray _texMapArray; TexMapArray _texMapArray;
}; };

View file

@ -11,6 +11,7 @@
<@if not MODEL_MATERIAL_TEXTURES_SLH@> <@if not MODEL_MATERIAL_TEXTURES_SLH@>
<@def MODEL_MATERIAL_TEXTURES_SLH@> <@def MODEL_MATERIAL_TEXTURES_SLH@>
<@include graphics/ShaderConstants.h@>
<@include graphics/Material.slh@> <@include graphics/Material.slh@>
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@> <@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
@ -91,21 +92,21 @@ float fetchScatteringMap(vec2 uv) {
#else #else
<@if withAlbedo@> <@if withAlbedo@>
layout(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap; LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
vec4 fetchAlbedoMap(vec2 uv) { vec4 fetchAlbedoMap(vec2 uv) {
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS); return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
} }
<@endif@> <@endif@>
<@if withRoughness@> <@if withRoughness@>
layout(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap; LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
float fetchRoughnessMap(vec2 uv) { float fetchRoughnessMap(vec2 uv) {
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r); return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
} }
<@endif@> <@endif@>
<@if withNormal@> <@if withNormal@>
layout(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap; LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
vec3 fetchNormalMap(vec2 uv) { vec3 fetchNormalMap(vec2 uv) {
// unpack normal, swizzle to get into hifi tangent space with Y axis pointing out // 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)); 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@> <@endif@>
<@if withMetallic@> <@if withMetallic@>
layout(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap; LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap;
float fetchMetallicMap(vec2 uv) { float fetchMetallicMap(vec2 uv) {
return (texture(metallicMap, uv, TAA_TEXTURE_LOD_BIAS).r); return (texture(metallicMap, uv, TAA_TEXTURE_LOD_BIAS).r);
} }
<@endif@> <@endif@>
<@if withEmissive@> <@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) { vec3 fetchEmissiveMap(vec2 uv) {
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb; return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
} }
<@endif@> <@endif@>
<@if withOcclusion@> <@if withOcclusion@>
layout(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap; LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
float fetchOcclusionMap(vec2 uv) { float fetchOcclusionMap(vec2 uv) {
return texture(occlusionMap, uv).r; return texture(occlusionMap, uv).r;
} }
<@endif@> <@endif@>
<@if withScattering@> <@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 fetchScatteringMap(vec2 uv) {
float scattering = texture(scatteringMap, uv, TAA_TEXTURE_LOD_BIAS).r; // boolean scattering for now float scattering = texture(scatteringMap, uv, TAA_TEXTURE_LOD_BIAS).r; // boolean scattering for now
return max(((scattering - 0.1) / 0.9), 0.0); return max(((scattering - 0.1) / 0.9), 0.0);
@ -185,7 +186,7 @@ float fetchScatteringMap(vec2 uv) {
<$declareMaterialTexMapArrayBuffer()$> <$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) { vec3 fetchLightmapMap(vec2 uv) {
vec2 lightmapParams = getTexMapArray()._lightmapParams.xy; vec2 lightmapParams = getTexMapArray()._lightmapParams.xy;
return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb); return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb);

View file

@ -12,13 +12,13 @@
// //
<@include graphics/ShaderConstants.h@> <@include graphics/ShaderConstants.h@>
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap; LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
struct Skybox { struct Skybox {
vec4 color; vec4 color;
}; };
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer { LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
Skybox skybox; Skybox skybox;
}; };

View file

@ -1,4 +1,4 @@
set(TARGET_NAME model-networking) set(TARGET_NAME model-networking)
setup_hifi_library() 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) include_hifi_library_headers(gpu)

View file

@ -27,7 +27,7 @@
Q_LOGGING_CATEGORY(proceduralLog, "hifi.gpu.procedural") 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 PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
static const QString URL_KEY = "shaderUrl"; static const QString URL_KEY = "shaderUrl";
static const QString VERSION_KEY = "version"; 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"; static const std::string PROCEDURAL_VERSION = "//PROCEDURAL_VERSION";
bool operator==(const ProceduralData& a, const ProceduralData& b) { bool operator==(const ProceduralData& a, const ProceduralData& b) {
return ( return ((a.version == b.version) && (a.shaderUrl == b.shaderUrl) && (a.uniforms == b.uniforms) &&
(a.version == b.version) && (a.channels == b.channels));
(a.shaderUrl == b.shaderUrl) &&
(a.uniforms == b.uniforms) &&
(a.channels == b.channels));
} }
QJsonValue ProceduralData::getProceduralData(const QString& proceduralJson) { QJsonValue ProceduralData::getProceduralData(const QString& proceduralJson) {
@ -109,6 +106,8 @@ Procedural::Procedural() {
_transparentState->setDepthTest(true, true, gpu::LESS_EQUAL); _transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
_transparentState->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, _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); 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) { void Procedural::setProceduralData(const ProceduralData& proceduralData) {
@ -119,7 +118,7 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
_dirty = true; _dirty = true;
_enabled = false; _enabled = false;
if (proceduralData.version != _data.version ) { if (proceduralData.version != _data.version) {
_data.version = proceduralData.version; _data.version = proceduralData.version;
_shaderDirty = true; _shaderDirty = true;
} }
@ -144,7 +143,6 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
_channels[channel] = textureCache->getTexture(QUrl()); _channels[channel] = textureCache->getTexture(QUrl());
} }
} }
_channelsDirty = true;
} }
if (proceduralData.shaderUrl != _data.shaderUrl) { if (proceduralData.shaderUrl != _data.shaderUrl) {
@ -212,23 +210,6 @@ bool Procedural::isReady() const {
return true; 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, void Procedural::prepare(gpu::Batch& batch,
const glm::vec3& position, const glm::vec3& position,
const glm::vec3& size, const glm::vec3& size,
@ -256,19 +237,21 @@ void Procedural::prepare(gpu::Batch& batch,
} }
// Build the fragment shader // Build the fragment shader
std::string opaqueShaderSource = replaceProceduralBlock(_opaquefragmentSource.getCode()); _opaqueFragmentSource.replacements.clear();
auto opaqueReflection = _opaquefragmentSource.getReflection(); if (_data.version == 1) {
auto& opaqueUniforms = opaqueReflection[gpu::Shader::BindingType::UNIFORM]; _opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V1 1";
std::string transparentShaderSource = replaceProceduralBlock(_transparentfragmentSource.getCode()); } else if (_data.version == 2) {
auto transparentReflection = _transparentfragmentSource.getReflection(); _opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V2 1";
auto& transparentUniforms = transparentReflection[gpu::Shader::BindingType::UNIFORM]; }
_opaqueFragmentSource.replacements[PROCEDURAL_BLOCK] = _shaderSource.toStdString();
_transparentFragmentSource.replacements = _opaqueFragmentSource.replacements;
// Set any userdata specified uniforms // Set any userdata specified uniforms
int customSlot = procedural::slot::uniform::Custom; int customSlot = procedural::slot::uniform::Custom;
for (const auto& key : _data.uniforms.keys()) { for (const auto& key : _data.uniforms.keys()) {
std::string uniformName = key.toLocal8Bit().data(); std::string uniformName = key.toLocal8Bit().data();
opaqueUniforms[uniformName] = customSlot; _opaqueFragmentSource.reflection.uniforms[uniformName] = customSlot;
transparentUniforms[uniformName] = customSlot; _transparentFragmentSource.reflection.uniforms[uniformName] = customSlot;
++customSlot; ++customSlot;
} }
@ -276,18 +259,18 @@ void Procedural::prepare(gpu::Batch& batch,
// qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str(); // 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. // 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); _opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader);
if (!transparentShaderSource.empty() && transparentShaderSource != opaqueShaderSource) { _opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
_transparentFragmentShader = gpu::Shader::createPixel({ transparentShaderSource, transparentReflection }); if (_transparentFragmentSource.valid()) {
_transparentFragmentShader = gpu::Shader::createPixel(_transparentFragmentSource);
_transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader); _transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader);
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
} else { } else {
_transparentFragmentShader = _opaqueFragmentShader; _transparentFragmentShader = _opaqueFragmentShader;
_transparentShader = _opaqueShader; _transparentShader = _opaqueShader;
_transparentPipeline = _opaquePipeline;
} }
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
_start = usecTimestampNow(); _start = usecTimestampNow();
_frameCount = 0; _frameCount = 0;
} }
@ -299,12 +282,8 @@ void Procedural::prepare(gpu::Batch& batch,
setupUniforms(transparent); setupUniforms(transparent);
} }
if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) {
setupChannels(_shaderDirty || _uniformsDirty, transparent);
}
_prevTransparent = transparent; _prevTransparent = transparent;
_shaderDirty = _uniformsDirty = _channelsDirty = false; _shaderDirty = _uniformsDirty = false;
for (auto lambda : _uniforms) { for (auto lambda : _uniforms) {
lambda(batch); lambda(batch);
@ -331,16 +310,10 @@ void Procedural::prepare(gpu::Batch& batch,
void Procedural::setupUniforms(bool transparent) { void Procedural::setupUniforms(bool transparent) {
_uniforms.clear(); _uniforms.clear();
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
const auto& uniformSlots = pipeline->getUniforms();
auto customUniformCount = _data.uniforms.keys().size(); auto customUniformCount = _data.uniforms.keys().size();
// Set any userdata specified uniforms // Set any userdata specified uniforms
for (int i = 0; i < customUniformCount; ++i) { for (int i = 0; i < customUniformCount; ++i) {
int slot = procedural::slot::uniform::Custom + i; int slot = procedural::slot::uniform::Custom + i;
if (!uniformSlots.isValid(slot)) {
continue;
}
QString key = _data.uniforms.keys().at(i); QString key = _data.uniforms.keys().at(i);
std::string uniformName = key.toLocal8Bit().data(); std::string uniformName = key.toLocal8Bit().data();
QJsonValue value = _data.uniforms[key]; 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 // 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; 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)) { // Date
_uniforms.push_back([=](gpu::Batch& batch) { {
QDateTime now = QDateTime::currentDateTimeUtc(); QDateTime now = QDateTime::currentDateTimeUtc();
QDate date = now.date(); QDate date = now.date();
QTime time = now.time(); QTime time = now.time();
vec4 v; _standardInputs.date.x = date.year();
v.x = date.year();
// Shadertoy month is 0 based // Shadertoy month is 0 based
v.y = date.month() - 1; _standardInputs.date.y = date.month() - 1;
// But not the day... go figure // But not the day... go figure
v.z = date.day(); _standardInputs.date.z = date.day();
float fractSeconds = (time.msec() / 1000.0f); float fractSeconds = (time.msec() / 1000.0f);
v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds; _standardInputs.date.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();
} }
_uniforms.push_back([=](gpu::Batch& batch) {
vec3 channelSizes[MAX_PROCEDURAL_TEXTURE_CHANNELS]; _standardInputs.scaleAndCount = vec4(_entityDimensions, ++_frameCount);
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) { _standardInputs.orientation = mat4(_entityOrientation);
if (_channels[i]) {
channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0); 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) { glm::vec4 Procedural::getColor(const glm::vec4& entityColor) {

View file

@ -65,14 +65,22 @@ public:
void setDoesFade(bool doesFade) { _doesFade = doesFade; } void setDoesFade(bool doesFade) { _doesFade = doesFade; }
gpu::Shader::Source _vertexSource; gpu::Shader::Source _vertexSource;
gpu::Shader::Source _opaquefragmentSource; gpu::Shader::Source _opaqueFragmentSource;
gpu::Shader::Source _transparentfragmentSource; gpu::Shader::Source _transparentFragmentSource;
gpu::StatePointer _opaqueState { std::make_shared<gpu::State>() }; gpu::StatePointer _opaqueState { std::make_shared<gpu::State>() };
gpu::StatePointer _transparentState { std::make_shared<gpu::State>() }; gpu::StatePointer _transparentState { std::make_shared<gpu::State>() };
protected: protected:
struct StandardInputs {
vec4 date;
vec4 posAndTime;
vec4 scaleAndCount;
mat4 orientation;
vec4 resolution[4];
};
// Procedural metadata // Procedural metadata
ProceduralData _data; ProceduralData _data;
@ -88,13 +96,14 @@ protected:
bool _dirty { false }; bool _dirty { false };
bool _shaderDirty { true }; bool _shaderDirty { true };
bool _uniformsDirty { true }; bool _uniformsDirty { true };
bool _channelsDirty { true };
// Rendering objects // Rendering objects
UniformLambdas _uniforms; UniformLambdas _uniforms;
NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS]; NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS];
gpu::PipelinePointer _opaquePipeline; gpu::PipelinePointer _opaquePipeline;
gpu::PipelinePointer _transparentPipeline; gpu::PipelinePointer _transparentPipeline;
StandardInputs _standardInputs;
gpu::BufferPointer _standardInputsBuffer;
gpu::ShaderPointer _vertexShader; gpu::ShaderPointer _vertexShader;
gpu::ShaderPointer _opaqueFragmentShader; gpu::ShaderPointer _opaqueFragmentShader;
gpu::ShaderPointer _transparentFragmentShader; gpu::ShaderPointer _transparentFragmentShader;
@ -109,9 +118,6 @@ protected:
private: private:
// This should only be called from the render thread, as it shares data with Procedural::prepare // This should only be called from the render thread, as it shares data with Procedural::prepare
void setupUniforms(bool transparent); void setupUniforms(bool transparent);
void setupChannels(bool shouldCreate, bool transparent);
std::string replaceProceduralBlock(const std::string& fragmentSource);
mutable quint64 _fadeStartTime { 0 }; mutable quint64 _fadeStartTime { 0 };
mutable bool _hasStartedFade { false }; mutable bool _hasStartedFade { false };

View file

@ -14,18 +14,51 @@
<$declareStandardCameraTransform()$> <$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) // shader playback time (in seconds)
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime; float iGlobalTime = params.posAndTime.w;
// the dimensions of the object being rendered
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale; 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 // Unimplemented uniforms
// Resolution doesn't make sense in the VR context // Resolution doesn't make sense in the VR context
@ -37,20 +70,9 @@ const float iSampleRate = 1.0;
// No support for video input // No support for video input
const vec4 iChannelTime = vec4(0.0); const vec4 iChannelTime = vec4(0.0);
#define PROCEDURAL 1
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime; // shader playback time (in seconds) //PROCEDURAL_VERSION
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
// hack comment for extra whitespace // hack comment for extra whitespace

View file

@ -19,7 +19,7 @@
ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() { ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() {
_procedural._vertexSource = gpu::Shader::createVertex(shader::graphics::vertex::skybox)->getSource(); _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 // Adjust the pipeline state for background using the stencil test
_procedural.setDoesFade(false); _procedural.setDoesFade(false);
// Must match PrepareStencil::STENCIL_BACKGROUND // Must match PrepareStencil::STENCIL_BACKGROUND

View file

@ -14,14 +14,6 @@
#ifndef PROCEDURAL_SHADER_CONSTANTS_H #ifndef PROCEDURAL_SHADER_CONSTANTS_H
#define 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_UNIFORM_CUSTOM 220
#define PROCEDURAL_TEXTURE_CHANNEL0 0 #define PROCEDURAL_TEXTURE_CHANNEL0 0
@ -33,15 +25,9 @@
namespace procedural { namespace slot { namespace procedural { namespace slot {
namespace uniform { namespace uniform {
enum 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, Custom = PROCEDURAL_UNIFORM_CUSTOM,
}; };
} }

View file

@ -12,13 +12,13 @@
// //
<@include graphics/ShaderConstants.h@> <@include graphics/ShaderConstants.h@>
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap; LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
struct Skybox { struct Skybox {
vec4 color; vec4 color;
}; };
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer { LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
Skybox skybox; Skybox skybox;
}; };
@ -28,9 +28,13 @@ layout(location=0) out vec4 _fragColor;
<@include procedural/ProceduralCommon.slh@> <@include procedural/ProceduralCommon.slh@>
#line 1001 #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) { void main(void) {
vec3 color = getSkyboxColor(); vec3 color = getSkyboxColor();
// Protect from NaNs and negative values // Protect from NaNs and negative values

View file

@ -0,0 +1 @@
VERTEX graphics::vertex::skybox

View file

@ -10,13 +10,13 @@
<@func declareBlendshape(USE_NORMAL, USE_TANGENT)@> <@func declareBlendshape(USE_NORMAL, USE_TANGENT)@>
#if defined(GPU_GL410) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer; LAYOUT(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
uvec4 getPackedBlendshapeOffset(int i) { uvec4 getPackedBlendshapeOffset(int i) {
return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i)); return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
} }
#else #else
layout(std140, binding=0) buffer blendshapeOffsetsBuffer { LAYOUT_STD140(binding=0) buffer blendshapeOffsetsBuffer {
uvec4 _packedBlendshapeOffsets[]; uvec4 _packedBlendshapeOffsets[];
}; };
uvec4 getPackedBlendshapeOffset(int i) { uvec4 getPackedBlendshapeOffset(int i) {

View file

@ -12,11 +12,11 @@
<@include BloomApply.shared.slh@> <@include BloomApply.shared.slh@>
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
layout(binding=0) uniform sampler2D blurMap0; LAYOUT(binding=0) uniform sampler2D blurMap0;
layout(binding=1) uniform sampler2D blurMap1; LAYOUT(binding=1) uniform sampler2D blurMap1;
layout(binding=2) uniform sampler2D blurMap2; 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; Parameters parameters;
}; };

View file

@ -12,8 +12,8 @@
<@include BloomThreshold.shared.slh@> <@include BloomThreshold.shared.slh@>
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
layout(binding=RENDER_UTILS_TEXTURE_BLOOM_COLOR) uniform sampler2D colorMap; LAYOUT(binding=RENDER_UTILS_TEXTURE_BLOOM_COLOR) uniform sampler2D colorMap;
layout(std140, binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer { LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
Parameters parameters; Parameters parameters;
}; };

View file

@ -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)); QFile customFile(QString::fromStdString(fileName));
if (customFile.open(QIODevice::ReadOnly)) { if (customFile.open(QIODevice::ReadOnly)) {
return customFile.readAll().toStdString(); 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) { switch (mode) {
case AlbedoMode: case AlbedoMode:
return DEFAULT_ALBEDO_SHADER; return DEFAULT_ALBEDO_SHADER;
@ -334,7 +334,7 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
return std::string(); 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) { if (mode != CustomMode) {
return !_pipelines[mode]; return !_pipelines[mode];
} }
@ -351,19 +351,17 @@ bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile)
return true; 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)) { if (pipelineNeedsUpdate(mode, customFile)) {
static const auto FRAGMENT_SHADER_SOURCE = static_assert(shader::render_utils::program::debug_deferred_buffer != 0, "Validate debug deferred program");
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 bakedFragmentShader = FRAGMENT_SHADER_SOURCE.getCode(); static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), getShaderSourceCode(mode, customFile)); 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 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); const auto program = gpu::Shader::createProgram(vs, ps);
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>()); auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>());

View file

@ -112,9 +112,9 @@ private:
using StandardPipelines = std::array<gpu::PipelinePointer, NumModes>; using StandardPipelines = std::array<gpu::PipelinePointer, NumModes>;
using CustomPipelines = std::unordered_map<std::string, CustomPipeline>; using CustomPipelines = std::unordered_map<std::string, CustomPipeline>;
bool pipelineNeedsUpdate(Mode mode, std::string customFile = std::string()) const; bool pipelineNeedsUpdate(Mode mode, const std::string& customFile = std::string()) const;
const gpu::PipelinePointer& getPipeline(Mode mode, std::string customFile = std::string()); const gpu::PipelinePointer& getPipeline(Mode mode, const std::string& customFile = std::string());
std::string getShaderSourceCode(Mode mode, std::string customFile = std::string()); std::string getShaderSourceCode(Mode mode, const std::string& customFile = std::string());
ParametersBuffer _parameters; ParametersBuffer _parameters;
StandardPipelines _pipelines; StandardPipelines _pipelines;

View file

@ -17,23 +17,23 @@
// See DeferredShader_MapSlot in DeferredLightingEffect.cpp for constants // See DeferredShader_MapSlot in DeferredLightingEffect.cpp for constants
// the albedo texture // 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 // 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 // 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 // the depth texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap; 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_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
// the obscurance texture // 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 // 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 { struct DeferredFragment {
@ -170,14 +170,14 @@ DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform
<@func declareDeferredCurvature()@> <@func declareDeferredCurvature()@>
// the curvature texture // 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) { vec4 fetchCurvature(vec2 texcoord) {
return texture(curvatureMap, texcoord); return texture(curvatureMap, texcoord);
} }
// the curvature texture // 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) { vec4 fetchDiffusedCurvature(vec2 texcoord) {
return texture(diffusedCurvatureMap, texcoord); return texture(diffusedCurvatureMap, texcoord);

View file

@ -44,7 +44,7 @@ using namespace render;
struct LightLocations { struct LightLocations {
bool shadowTransform{ false }; bool shadowTransform{ false };
void initialize(const gpu::ShaderPointer& program) { void initialize(const gpu::ShaderPointer& program) {
shadowTransform = program->getUniformBuffers().isValid(ru::Buffer::ShadowParams); shadowTransform = program->getReflection().validUniformBuffer(ru::Buffer::ShadowParams);
} }
}; };

View file

@ -24,7 +24,7 @@ struct CameraCorrection {
mat4 _prevViewInverse; mat4 _prevViewInverse;
}; };
layout(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer { LAYOUT(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
CameraCorrection cameraCorrection; CameraCorrection cameraCorrection;
}; };
@ -42,7 +42,7 @@ struct DeferredFrameTransform {
mat4 _invProjectionUnJittered[2]; 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; DeferredFrameTransform frameTransform;
}; };

View file

@ -19,12 +19,12 @@
<@include FadeObjectParams.shared.slh@> <@include FadeObjectParams.shared.slh@>
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h // 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]; FadeParameters fadeParameters[CATEGORY_COUNT];
}; };
// See ShapePipeline::Slot::MAP in ShapePipeline.h // 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) { vec3 getNoiseInverseSize(int category) {
return fadeParameters[category]._noiseInvSizeAndLevel.xyz; return fadeParameters[category]._noiseInvSizeAndLevel.xyz;
@ -117,7 +117,7 @@ void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) {
<@func declareFadeFragmentUniform()@> <@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; FadeObjectParams fadeObjectParams;
}; };

View file

@ -21,7 +21,7 @@
<@include Haze.slh@> <@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) { vec4 unpackPositionFromZeye(vec2 texcoord) {
float Zeye = -texture(linearDepthMap, texcoord).x; float Zeye = -texture(linearDepthMap, texcoord).x;

View file

@ -39,7 +39,7 @@ struct HazeParams {
}; };
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h // 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; HazeParams hazeParams;
}; };

View file

@ -15,12 +15,12 @@
<@include Highlight_shared.slh@> <@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; HighlightParameters params;
}; };
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap; 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_DEPTH) uniform sampler2D highlightedDepthMap;
layout(location=0) in vec2 varTexCoord0; layout(location=0) in vec2 varTexCoord0;
layout(location=0) out vec4 outFragColor; layout(location=0) out vec4 outFragColor;

View file

@ -402,36 +402,31 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
} }
void DebugHighlight::initializePipelines() { void DebugHighlight::initializePipelines() {
static const auto FRAGMENT_SHADER_SOURCE = gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource(); static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
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);
// Depth shader // Depth shader
{ static const std::string DEPTH_SHADER{ R"SHADER(
static const std::string DEPTH_SHADER{ R"SHADER(
vec4 getFragmentColor() { vec4 getFragmentColor() {
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
Zdb = 1.0-(1.0-Zdb)*100; Zdb = 1.0-(1.0-Zdb)*100;
return vec4(Zdb, Zdb, Zdb, 1.0); return vec4(Zdb, Zdb, Zdb, 1.0);
} }
)SHADER" }; )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() }); gpu::Shader::Source fragmentSource;
const auto program = gpu::Shader::createProgram(vs, ps); fragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
_depthPipeline = gpu::Pipeline::create(program, state); 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() { const gpu::PipelinePointer& DebugHighlight::getDepthPipeline() {

View file

@ -22,8 +22,8 @@ struct ItemBound {
vec4 boundDim_s; vec4 boundDim_s;
}; };
#if defined(GPU_GL410) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
layout(binding=0) uniform samplerBuffer ssbo0Buffer; LAYOUT(binding=0) uniform samplerBuffer ssbo0Buffer;
ItemBound getItemBound(int i) { ItemBound getItemBound(int i) {
int offset = 2 * i; int offset = 2 * i;
ItemBound bound; ItemBound bound;
@ -32,7 +32,7 @@ ItemBound getItemBound(int i) {
return bound; return bound;
} }
#else #else
layout(std140, binding=0) buffer ssbo0Buffer { LAYOUT_STD140(binding=0) buffer ssbo0Buffer {
ItemBound bounds[]; ItemBound bounds[];
}; };
ItemBound getItemBound(int i) { ItemBound getItemBound(int i) {
@ -45,7 +45,7 @@ struct HighlightParameters {
vec2 outlineWidth; vec2 outlineWidth;
}; };
layout(std140, binding=0) uniform parametersBuffer { LAYOUT_STD140(binding=0) uniform parametersBuffer {
HighlightParameters _parameters; HighlightParameters _parameters;
}; };

View file

@ -9,7 +9,7 @@
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
<@func declareSkyboxMap()@> <@func declareSkyboxMap()@>
// 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) { vec4 evalSkyboxLight(vec3 direction, float lod) {
// textureQueryLevels is not available until #430, so we require explicit lod // textureQueryLevels is not available until #430, so we require explicit lod

View file

@ -24,7 +24,7 @@ struct FrustumGrid {
mat4 eyeToWorldMat; 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; FrustumGrid frustumGrid;
}; };
@ -60,11 +60,11 @@ float projection_getFar(mat4 projection) {
#define GRID_FETCH_BUFFER(i) i!> #define GRID_FETCH_BUFFER(i) i!>
<@endif@> <@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]; 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]; GRID_INDEX_TYPE _clusterGridContent[GRID_NUM_ELEMENTS];
}; };

View file

@ -23,7 +23,7 @@ struct LightingModel {
}; };
// See DeferredShader_BufferSlot in DeferredLightingEffect.cpp // 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; LightingModel lightingModel;
}; };

View file

@ -229,7 +229,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
} }
void initForwardPipelines(ShapePlumber& plumber) { void initForwardPipelines(ShapePlumber& plumber) {
using namespace shader::render_utils::program; using namespace shader::render_utils;
using Key = render::ShapeKey; using Key = render::ShapeKey;
auto addPipelineBind = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4); auto addPipelineBind = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4);
@ -244,33 +244,33 @@ void initForwardPipelines(ShapePlumber& plumber) {
forceLightBatchSetter = true; forceLightBatchSetter = true;
// Simple Opaques // Simple Opaques
addPipeline(Key::Builder(), simple); addPipeline(Key::Builder(), program::forward_simple_textured);
addPipeline(Key::Builder().withUnlit(), simpleUnlit); addPipeline(Key::Builder().withUnlit(), program::forward_simple_textured_unlit);
// Simple Translucents // Simple Translucents
addPipeline(Key::Builder().withTranslucent(), simpleTranslucent); addPipeline(Key::Builder().withTranslucent(), program::forward_simple_textured_transparent);
addPipeline(Key::Builder().withTranslucent().withUnlit(), simpleTranslucentUnlit); addPipeline(Key::Builder().withTranslucent().withUnlit(), program::simple_transparent_textured_unlit);
// Opaques // Opaques
addPipeline(Key::Builder().withMaterial(), forward_model); addPipeline(Key::Builder().withMaterial(), program::forward_model);
addPipeline(Key::Builder().withMaterial().withUnlit(), forward_model_unlit); addPipeline(Key::Builder().withMaterial().withUnlit(), program::forward_model_unlit);
addPipeline(Key::Builder().withMaterial().withTangents(), forward_model_translucent); addPipeline(Key::Builder().withMaterial().withTangents(), program::forward_model_translucent);
// Deformed Opaques // Deformed Opaques
addPipeline(Key::Builder().withMaterial().withDeformed(), forward_deformed_model); addPipeline(Key::Builder().withMaterial().withDeformed(), program::forward_deformed_model);
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), forward_deformed_model_normal_map); addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), program::forward_deformed_model_normal_map);
addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), forward_deformed_model_dq); addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), program::forward_deformed_model_dq);
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), forward_deformed_model_normal_map_dq); addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), program::forward_deformed_model_normal_map_dq);
// Translucents // Translucents
addPipeline(Key::Builder().withMaterial().withTranslucent(), forward_model_translucent); addPipeline(Key::Builder().withMaterial().withTranslucent(), program::forward_model_translucent);
addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), forward_model_normal_map_translucent); addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), program::forward_model_normal_map_translucent);
// Deformed Translucents // Deformed Translucents
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), forward_deformed_translucent); addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), program::forward_deformed_translucent);
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), forward_deformed_translucent_normal_map); addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), program::forward_deformed_translucent_normal_map);
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), forward_deformed_translucent_dq); addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), program::forward_deformed_translucent_dq);
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), forward_deformed_translucent_normal_map_dq); addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), program::forward_deformed_translucent_normal_map_dq);
forceLightBatchSetter = false; forceLightBatchSetter = false;
} }

View file

@ -15,7 +15,7 @@
<@func declareBeckmannSpecular()@> <@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) { float fetchSpecularBeckmann(float ndoth, float roughness) {
return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0); return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);

View file

@ -19,7 +19,7 @@
#define SHADOW_SCREEN_SPACE_DITHER 1 #define SHADOW_SCREEN_SPACE_DITHER 1
// the shadow texture // 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) // Sample the shadowMap with PCF (built-in)
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) { float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {

View file

@ -13,7 +13,7 @@
<@include Shadows_shared.slh@> <@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; ShadowParameters shadow;
}; };

View file

@ -18,7 +18,7 @@
const int MAX_CLUSTERS = 128; const int MAX_CLUSTERS = 128;
const int INDICES_PER_VERTEX = 4; 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]; mat4 clusterMatrices[MAX_CLUSTERS];
}; };

View file

@ -421,6 +421,10 @@ void DebugSubsurfaceScattering::configure(const Config& config) {
_showSpecularTable = config.showSpecularTable; _showSpecularTable = config.showSpecularTable;
_showCursorPixel = config.showCursorPixel; _showCursorPixel = config.showCursorPixel;
_debugCursorTexcoord = config.debugCursorTexcoord; _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); assert(lightStage);
// const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0); // const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0);
const auto light = lightStage->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) { gpu::doInBatch("DebugSubsurfaceScattering::run", args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false); 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::DeferredNormal, deferredFramebuffer->getDeferredNormalTexture());
batch.setResourceTexture(ru::Texture::DeferredColor, deferredFramebuffer->getDeferredColorTexture()); batch.setResourceTexture(ru::Texture::DeferredColor, deferredFramebuffer->getDeferredColorTexture());
batch.setResourceTexture(ru::Texture::DeferredDepth, linearDepthTexture); batch.setResourceTexture(ru::Texture::DeferredDepth, linearDepthTexture);
batch.setUniformBuffer(1, _debugParams);
batch._glUniform2f(gpu::slot::uniform::Extra0, _debugCursorTexcoord.x, _debugCursorTexcoord.y);
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
} }
} }

View file

@ -179,6 +179,7 @@ private:
gpu::PipelinePointer _showLUTPipeline; gpu::PipelinePointer _showLUTPipeline;
gpu::PipelinePointer getShowLUTPipeline(); gpu::PipelinePointer getShowLUTPipeline();
gpu::BufferPointer _debugParams;
bool _showProfile{ false }; bool _showProfile{ false };
bool _showLUT{ false }; bool _showLUT{ false };
bool _showSpecularTable{ false }; bool _showSpecularTable{ false };

View file

@ -56,7 +56,7 @@ vec3 generateProfile(vec2 uv) {
<@func declareSubsurfaceScatteringProfileMap()@> <@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) { vec3 scatter(float r) {
return texture(scatteringProfile, vec2(r * 0.5, 0.5)).rgb; return texture(scatteringProfile, vec2(r * 0.5, 0.5)).rgb;
@ -104,7 +104,7 @@ vec3 integrate(float cosTheta, float skinRadius) {
<@func declareSubsurfaceScatteringResource()@> <@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) { 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; 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; vec4 debugFlags;
}; };
layout(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer { LAYOUT(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
ScatteringParameters parameters; ScatteringParameters parameters;
}; };

View file

@ -25,8 +25,8 @@ struct WorkloadProxy {
vec4 region; vec4 region;
}; };
#if defined(GPU_GL410) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
layout(binding=0) uniform samplerBuffer workloadProxiesBuffer; LAYOUT(binding=0) uniform samplerBuffer workloadProxiesBuffer;
WorkloadProxy getWorkloadProxy(int i) { WorkloadProxy getWorkloadProxy(int i) {
int offset = 2 * i; int offset = 2 * i;
WorkloadProxy proxy; WorkloadProxy proxy;
@ -35,7 +35,7 @@ WorkloadProxy getWorkloadProxy(int i) {
return proxy; return proxy;
} }
#else #else
layout(std140, binding=0) buffer workloadProxiesBuffer { LAYOUT_STD140(binding=0) buffer workloadProxiesBuffer {
WorkloadProxy _proxies[]; WorkloadProxy _proxies[];
}; };
WorkloadProxy getWorkloadProxy(int i) { WorkloadProxy getWorkloadProxy(int i) {
@ -57,17 +57,23 @@ struct WorkloadView {
vec4 regions[3]; vec4 regions[3];
}; };
#if defined(GPU_GL410) #if !defined(GPU_SSBO_TRANSFORM_OBJECT)
layout(binding=1) uniform samplerBuffer workloadViewsBuffer; LAYOUT(binding=1) uniform samplerBuffer workloadViewsBuffer;
WorkloadView getWorkloadView(int i) { WorkloadView getWorkloadView(int i) {
int offset = 2 * i; int offset = 8 * i;
WorkloadView view; WorkloadView view;
view.origin = texelFetch(workloadViewsBuffer, offset); view.direction_far = texelFetch(workloadViewsBuffer, offset + 0);
view.radiuses = texelFetch(workloadViewsBuffer, offset + 1); 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; return view;
} }
#else #else
layout(std140, binding=1) buffer workloadViewsBuffer { LAYOUT_STD140(binding=1) buffer workloadViewsBuffer {
WorkloadView _views[]; WorkloadView _views[];
}; };
WorkloadView getWorkloadView(int i) { WorkloadView getWorkloadView(int i) {

View file

@ -16,8 +16,8 @@
<@include gpu/Color.slh@> <@include gpu/Color.slh@>
<$declareColorWheel()$> <$declareColorWheel()$>
layout(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0; LAYOUT(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps; LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
<@include ShadowCore.slh@> <@include ShadowCore.slh@>
@ -36,7 +36,13 @@ float curvatureAO(float k) {
layout(location=0) in vec2 uv; layout(location=0) in vec2 uv;
layout(location=0) out vec4 outFragColor; 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) { void main(void) {
outFragColor = getFragmentColor(); outFragColor = getFragmentColor();

View file

@ -22,7 +22,7 @@
<$declareLightBuffer(256)$> <$declareLightBuffer(256)$>
layout(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer { LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
int lightIndex[256]; int lightIndex[256];
}; };

View file

@ -21,7 +21,7 @@
<$declareLightBuffer(256)$> <$declareLightBuffer(256)$>
layout(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer { LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
int lightIndex[256]; int lightIndex[256];
}; };
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord0; layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord0;

View file

@ -32,7 +32,7 @@ struct DrawMesh {
vec4 verts[NUM_SEGMENT_PER_VIEW_REGION]; vec4 verts[NUM_SEGMENT_PER_VIEW_REGION];
}; };
layout(std140, binding=0) uniform DrawMeshBuffer { LAYOUT_STD140(binding=0) uniform DrawMeshBuffer {
DrawMesh _drawMeshBuffer; DrawMesh _drawMeshBuffer;
}; };

View file

@ -14,8 +14,10 @@
<@include DefaultMaterials.slh@> <@include DefaultMaterials.slh@>
<@include ForwardGlobalLight.slh@> <@include ForwardGlobalLight.slh@>
<$declareEvalSkyboxGlobalColor()$> <@include gpu/Transform.slh@>
<$declareEvalSkyboxGlobalColor()$>
<$declareStandardCameraTransform()$>
// the interpolated normal // the interpolated normal
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; 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; layout(location=0) out vec4 _fragColor0;
<@include procedural/ProceduralCommon.slh@>
#line 1001
//PROCEDURAL_BLOCK
#line 2030
void main(void) { void main(void) {
vec3 normal = normalize(_normalWS.xyz); vec3 normal = normalize(_normalWS.xyz);
vec3 diffuse = _color.rgb; vec3 diffuse = _color.rgb;
@ -48,45 +44,18 @@ void main(void) {
float shininess = DEFAULT_SHININESS; float shininess = DEFAULT_SHININESS;
float emissiveAmount = 0.0; 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(); TransformCamera cam = getTransformCamera();
vec3 fragPosition = _positionES.xyz; vec3 fragPosition = _positionES.xyz;
if (emissiveAmount > 0.0) { _fragColor0 = vec4(evalSkyboxGlobalColor(
_fragColor0 = vec4(evalSkyboxGlobalColor( cam._viewInverse,
cam._viewInverse, 1.0,
1.0, DEFAULT_OCCLUSION,
DEFAULT_OCCLUSION, fragPosition,
fragPosition, normal,
normal, diffuse,
diffuse, DEFAULT_FRESNEL,
specular, length(specular),
DEFAULT_METALLIC, max(0.0, 1.0 - shininess / 128.0)),
max(0.0, 1.0 - shininess / 128.0)), 1.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);
}
} }

View file

@ -22,7 +22,7 @@
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
// the albedo texture // the albedo texture
layout(binding=0) uniform sampler2D originalTexture; LAYOUT(binding=0) uniform sampler2D originalTexture;
// the interpolated normal // the interpolated normal
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;

View file

@ -22,7 +22,7 @@
<@include render-utils/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@>
// the albedo texture // the albedo texture
layout(binding=0) uniform sampler2D originalTexture; LAYOUT(binding=0) uniform sampler2D originalTexture;
// the interpolated normal // the interpolated normal
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;

View file

@ -20,7 +20,7 @@
layout(location=0) out vec4 _fragColor0; layout(location=0) out vec4 _fragColor0;
// the albedo texture // 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_COLOR) in vec4 _color;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;

View file

@ -22,7 +22,7 @@ precision mediump float;
precision mediump int; precision mediump int;
#endif #endif
layout(binding=0) uniform sampler2D colorTexture; LAYOUT(binding=0) uniform sampler2D colorTexture;
//uniform sampler2D historyTexture; //uniform sampler2D historyTexture;
// FIXME make into a uniform buffer or push constant if this shader ever comes into use // 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