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',
'-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake',
'-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX,
'-DNATIVE_SHREFLECT=' + HIFI_ANDROID_PRECOMPILED + '/shreflect' + EXEC_SUFFIX,
'-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED,
'-DRELEASE_NUMBER=' + RELEASE_NUMBER,
'-DRELEASE_TYPE=' + RELEASE_TYPE,

View file

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

42
cmake/externals/glslang/CMakeLists.txt vendored Normal file
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)
endif ()
if (POLICY CMP0074)
cmake_policy(SET CMP0074 OLD)
endif ()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
# Hide automoc folders (for IDEs)

View file

@ -8,34 +8,132 @@
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
# FIXME use the built tools
macro(AUTOSCRIBE_APPEND_QRC)
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${ARGV0}\">${ARGV1}</file>\n")
endmacro()
set(VULKAN_DIR $ENV{VULKAN_SDK})
set(GLSLANG_EXEC "${VULKAN_DIR}/Bin/glslangValidator.exe")
set(SPIRV_CROSS_EXEC "${VULKAN_DIR}/Bin/spirv-cross.exe")
set(SPIRV_OPT_EXEC "${VULKAN_DIR}/Bin/spirv-opt.exe")
set(GLSLC_EXEC "${VULKAN_DIR}/Bin/glslc.exe")
set(SCRIBE_EXEC "D:/scribe.exe")
macro(AUTOSCRIBE_PLATFORM_SHADER)
set(AUTOSCRIBE_PLATFORM_PATH "${ARGV0}")
string(REGEX MATCH "([0-9]+(es)?)(/stereo)?" PLATFORM_PATH_REGEX ${AUTOSCRIBE_PLATFORM_PATH})
set(AUTOSCRIBE_DIALECT "${CMAKE_MATCH_1}")
if (CMAKE_MATCH_3)
set(AUTOSCRIBE_VARIANT "stereo")
else()
set(AUTOSCRIBE_VARIANT "mono")
endif()
string(REGEX REPLACE "/" "\\\\" SOURCE_GROUP_PATH ${AUTOSCRIBE_PLATFORM_PATH})
set(SOURCE_GROUP_PATH "${SHADER_LIB}\\${SOURCE_GROUP_PATH}")
set(AUTOSCRIBE_DIALECT_HEADER "${AUTOSCRIBE_HEADER_DIR}/${AUTOSCRIBE_DIALECT}/header.glsl")
set(AUTOSCRIBE_VARIANT_HEADER "${AUTOSCRIBE_HEADER_DIR}/${AUTOSCRIBE_VARIANT}.glsl")
set(AUTOSCRIBE_OUTPUT_FILE "${SHADERS_DIR}/${SHADER_LIB}/${AUTOSCRIBE_PLATFORM_PATH}/${SHADER_NAME}.${SHADER_TYPE}")
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/scribe" "${AUTOSCRIBE_OUTPUT_FILE}")
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_OUTPUT_FILE})
set_property(SOURCE ${AUTOSCRIBE_OUTPUT_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND SCRIBED_SHADERS ${AUTOSCRIBE_OUTPUT_FILE})
set(AUTOSCRIBE_SPIRV_FILE "${AUTOSCRIBE_OUTPUT_FILE}.spv")
# don't add unoptimized spirv to the QRC
#AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/spirv_unopt" "${AUTOSCRIBE_SPIRV_FILE}")
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_FILE})
set_property(SOURCE ${AUTOSCRIBE_SPIRV_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_FILE})
set(AUTOSCRIBE_SPIRV_OPT_FILE "${AUTOSCRIBE_OUTPUT_FILE}.opt.spv")
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/spirv" "${AUTOSCRIBE_SPIRV_OPT_FILE}")
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_OPT_FILE})
set_property(SOURCE ${AUTOSCRIBE_SPIRV_OPT_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_OPT_FILE})
set(AUTOSCRIBE_SPIRV_GLSL_FILE "${AUTOSCRIBE_OUTPUT_FILE}.glsl")
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/glsl" "${AUTOSCRIBE_SPIRV_GLSL_FILE}")
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_GLSL_FILE})
set_property(SOURCE ${AUTOSCRIBE_SPIRV_GLSL_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_GLSL_FILE})
set(AUTOSCRIBE_SPIRV_JSON_FILE "${AUTOSCRIBE_OUTPUT_FILE}.json")
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/json" "${AUTOSCRIBE_SPIRV_JSON_FILE}")
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_JSON_FILE})
set_property(SOURCE ${AUTOSCRIBE_SPIRV_JSON_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND REFLECTED_SHADERS ${AUTOSCRIBE_SPIRV_JSON_FILE})
unset(SHADER_GEN_LINE)
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_DIALECT})
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_VARIANT})
file(RELATIVE_PATH TEMP_PATH ${CMAKE_SOURCE_DIR} ${SHADER_FILE})
list(APPEND SHADER_GEN_LINE ${TEMP_PATH})
file(RELATIVE_PATH TEMP_PATH ${CMAKE_SOURCE_DIR} ${AUTOSCRIBE_OUTPUT_FILE})
list(APPEND SHADER_GEN_LINE ${TEMP_PATH})
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_SHADER_SEEN_LIBS})
string(CONCAT AUTOSCRIBE_SHADERGEN_COMMANDS "${AUTOSCRIBE_SHADERGEN_COMMANDS}" "${SHADER_GEN_LINE}\n")
# # FIXME need better mechanism for determining the include files
# add_custom_command(
# OUTPUT ${AUTOSCRIBE_OUTPUT_FILE}
# COMMAND ${SCRIBE_COMMAND} ${SHADER_FILE} ${SCRIBE_ARGS} -o ${AUTOSCRIBE_OUTPUT_FILE} -h ${AUTOSCRIBE_DIALECT_HEADER} -h ${AUTOSCRIBE_VARIANT_HEADER}
# DEPENDS ${SCRIBE_COMMAND} ${SHADER_FILE} ${AUTOSCRIBE_DIALECT_HEADER} ${AUTOSCRIBE_VARIANT_HEADER})
# # Generate the spirv file
# add_custom_command(
# OUTPUT ${AUTOSCRIBE_SPIRV_FILE}
# COMMAND ${GLSLANG_EXEC} -V110 -o ${AUTOSCRIBE_SPIRV_FILE} ${AUTOSCRIBE_OUTPUT_FILE}
# DEPENDS ${AUTOSCRIBE_OUTPUT_FILE} ${GLSLANG_EXEC})
# # Generate the optimized spirv file
# add_custom_command(
# OUTPUT ${AUTOSCRIBE_SPIRV_OPT_FILE}
# COMMAND ${SPIRV_OPT_EXEC} -O ${AUTOSCRIBE_SPIRV_FILE} -o ${AUTOSCRIBE_SPIRV_OPT_FILE}
# DEPENDS ${AUTOSCRIBE_SPIRV_FILE} ${SPIRV_OPT_EXEC})
# # Generate the optimized GLSL file
# add_custom_command(
# OUTPUT ${AUTOSCRIBE_SPIRV_GLSL_FILE}
# COMMAND ${SPIRV_CROSS_EXEC} ${SPIRV_CROSS_ARGS} ${AUTOSCRIBE_SPIRV_OPT_FILE} --output ${AUTOSCRIBE_SPIRV_GLSL_FILE}
# DEPENDS ${AUTOSCRIBE_SPIRV_OPT_FILE} ${SPIRV_CROSS_EXEC})
# # Generate the optimized spirv file
# add_custom_command(
# OUTPUT ${AUTOSCRIBE_SPIRV_JSON_FILE}
# COMMAND ${SPIRV_CROSS_EXEC} --reflect json ${AUTOSCRIBE_SPIRV_OPT_FILE} --output ${AUTOSCRIBE_SPIRV_JSON_FILE}
# DEPENDS ${AUTOSCRIBE_SPIRV_OPT_FILE} ${SPIRV_CROSS_EXEC})
endmacro()
macro(AUTOSCRIBE_SHADER)
#
# Set the include paths
#
# FIXME base the include paths off of output from the scribe tool,
# instead of treating every previously seen shader as a possible header
unset(SHADER_INCLUDE_FILES)
# Grab include files
foreach(includeFile ${ARGN})
list(APPEND SHADER_INCLUDE_FILES ${includeFile})
endforeach()
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
endforeach()
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
#Extract the unique include shader paths
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
endforeach()
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
#message(ready for includes ${SHADER_INCLUDES_PATHS})
# make the scribe include arguments
set(SCRIBE_INCLUDES)
unset(SCRIBE_INCLUDES)
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS})
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/)
endforeach()
#
# Figure out the various output names
#
# Define the final name of the generated shader file
get_filename_component(SHADER_NAME ${SHADER_FILE} NAME_WE)
get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
@ -46,38 +144,36 @@ macro(AUTOSCRIBE_SHADER)
elseif(${SHADER_EXT} STREQUAL .slg)
set(SHADER_TYPE geom)
endif()
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
file(TO_CMAKE_PATH "${SHADER_TARGET}" COMPILED_SHADER)
set(REFLECTED_SHADER "${COMPILED_SHADER}.json")
set(SCRIBE_ARGS -T ${SHADER_TYPE} -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
set(SCRIBE_ARGS -D GLPROFILE ${GLPROFILE} -T ${SHADER_TYPE} ${SCRIBE_INCLUDES} )
# Generate the frag/vert file
add_custom_command(
OUTPUT ${SHADER_TARGET}
COMMAND ${SCRIBE_COMMAND} ${SCRIBE_ARGS}
DEPENDS ${SHADER_FILE} ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES})
# SHADER_SCRIBED -> the output of scribe
set(SHADER_SCRIBED "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
# Generate the json reflection
# FIXME move to spirv-cross for this task after we have spirv compatible shaders
add_custom_command(
OUTPUT ${REFLECTED_SHADER}
COMMAND ${SHREFLECT_COMMAND} ${COMPILED_SHADER}
DEPENDS ${SHREFLECT_DEPENDENCY} ${COMPILED_SHADER})
# SHADER_NAME_FILE -> a file containing the shader name and extension (useful for debugging and for
# determining the type of shader from the filename)
set(SHADER_NAME_FILE "${SHADER_SCRIBED}.name")
file(TO_CMAKE_PATH "${SHADER_SCRIBED}" SHADER_SCRIBED)
file(WRITE "${SHADER_SCRIBED}.name" "${SHADER_NAME}.${SHADER_TYPE}")
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/name" "${SHADER_NAME_FILE}")
#output the generated file name
source_group("Compiled/${SHADER_LIB}" FILES ${COMPILED_SHADER})
set_property(SOURCE ${COMPILED_SHADER} PROPERTY SKIP_AUTOMOC ON)
list(APPEND COMPILED_SHADERS ${COMPILED_SHADER})
if (USE_GLES)
set(SPIRV_CROSS_ARGS --version 310es)
AUTOSCRIBE_PLATFORM_SHADER("310es")
AUTOSCRIBE_PLATFORM_SHADER("310es/stereo")
else()
set(SPIRV_CROSS_ARGS --version 410 --no-420pack-extension)
AUTOSCRIBE_PLATFORM_SHADER("410")
AUTOSCRIBE_PLATFORM_SHADER("410/stereo")
if (NOT APPLE)
set(SPIRV_CROSS_ARGS --version 450)
AUTOSCRIBE_PLATFORM_SHADER("450")
AUTOSCRIBE_PLATFORM_SHADER("450/stereo")
endif()
endif()
source_group("Reflected/${SHADER_LIB}" FILES ${REFLECTED_SHADER})
list(APPEND REFLECTED_SHADERS ${REFLECTED_SHADER})
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}\">${COMPILED_SHADER}</file>\n")
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}_reflection\">${REFLECTED_SHADER}</file>\n")
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "${SHADER_NAME} = ${SHADER_COUNT},\n")
string(CONCAT SHADER_SHADERS_ARRAY "${SHADER_SHADERS_ARRAY}" "${SHADER_COUNT},\n")
MATH(EXPR SHADER_COUNT "${SHADER_COUNT}+1")
endmacro()
@ -86,6 +182,8 @@ macro(AUTOSCRIBE_SHADER_LIB)
message(FATAL_ERROR "AUTOSCRIBE_SHADER_LIB can only be used by the shaders library")
endif()
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES "${CMAKE_SOURCE_DIR}/libraries/${SHADER_LIB}/src")
string(REGEX REPLACE "[-]" "_" SHADER_NAMESPACE ${SHADER_LIB})
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace ${SHADER_NAMESPACE} {\n")
@ -165,66 +263,103 @@ macro(AUTOSCRIBE_SHADER_LIB)
# Finish the shader enums
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "} // namespace ${SHADER_NAMESPACE}\n")
#file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
#foreach(HIFI_LIBRARY ${ARGN})
#list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src)
#endforeach()
#endif()
endmacro()
macro(AUTOSCRIBE_SHADER_LIBS)
set(SCRIBE_COMMAND scribe)
set(SHREFLECT_COMMAND shreflect)
set(SHREFLECT_DEPENDENCY shreflect)
# Target dependant Custom rule on the SHADER_FILE
if (ANDROID)
set(GLPROFILE LINUX_GL)
set(SCRIBE_COMMAND ${NATIVE_SCRIBE})
set(SHREFLECT_COMMAND ${NATIVE_SHREFLECT})
unset(SHREFLECT_DEPENDENCY)
else()
if (APPLE)
set(GLPROFILE MAC_GL)
elseif(UNIX)
set(GLPROFILE LINUX_GL)
else()
set(GLPROFILE PC_GL)
endif()
endif()
message(STATUS "Shader processing start")
set(AUTOSCRIBE_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/headers)
# Start the shader IDs
set(SHADER_COUNT 1)
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
set(SHADER_ENUMS "")
file(MAKE_DIRECTORY ${SHADERS_DIR})
set(SHADER_ENUMS "")
set(SHADER_COUNT 1)
#
# Scribe generation & program defintiion
#
foreach(SHADER_LIB ${ARGN})
list(APPEND AUTOSCRIBE_SHADER_SEEN_LIBS ${SHADER_LIB})
AUTOSCRIBE_SHADER_LIB(${SHADER_LIB})
endforeach()
# Generate the library files
configure_file(
ShaderEnums.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp)
${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
configure_file(
ShaderEnums.h.in
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h)
configure_file(
shaders.qrc.in
${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h)
set(AUTOSCRIBE_SHADER_LIB_SRC "${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h;${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp")
set(QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
configure_file(shaders.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
list(APPEND QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
list(APPEND AUTOSCRIBE_SHADER_HEADERS ${AUTOSCRIBE_HEADER_DIR}/mono.glsl ${AUTOSCRIBE_HEADER_DIR}/stereo.glsl)
list(APPEND AUTOSCRIBE_SHADER_HEADERS ${AUTOSCRIBE_HEADER_DIR}/450/header.glsl ${AUTOSCRIBE_HEADER_DIR}/410/header.glsl ${AUTOSCRIBE_HEADER_DIR}/310es/header.glsl)
source_group("Shader Headers" FILES ${AUTOSCRIBE_HEADER_DIR}/mono.glsl ${AUTOSCRIBE_HEADER_DIR}/stereo.glsl)
source_group("Shader Headers\\450" FILES ${AUTOSCRIBE_HEADER_DIR}/450/header.glsl)
source_group("Shader Headers\\410" FILES ${AUTOSCRIBE_HEADER_DIR}/410/header.glsl)
source_group("Shader Headers\\310es" FILES ${AUTOSCRIBE_HEADER_DIR}/310es/header.glsl)
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${AUTOSCRIBE_SHADER_HEADERS})
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
# Write the shadergen command list
set(AUTOSCRIBE_SHADERGEN_COMMANDS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shadergen.txt)
file(WRITE ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE} "${AUTOSCRIBE_SHADERGEN_COMMANDS}")
# grab the SPIRV binaries we require
# note we don't use the normal ADD_DEPENDENCY_EXTERNAL_PROJECTS macro because only a custom command
# depends on these, not any of our build artifacts, so there's no valid target for the add_dependencies
# call in ADD_DEPENDENCY_EXTERNAL_PROJECTS to use
add_subdirectory(${EXTERNAL_PROJECT_DIR}/spirv_binaries ${EXTERNALS_BINARY_DIR}/spirv_binaries)
target_python()
# A custom python script which will generate
if (ANDROID)
add_custom_command(
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
COMMENT "Generating/updating shaders"
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_SOURCE_DIR}/tools/shadergen.py
--commands ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE}
--spirv-binaries ${SPIRV_BINARIES_DIR}
--scribe ${NATIVE_SCRIBE}
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
--source-dir ${CMAKE_SOURCE_DIR}
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} spirv_binaries ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
else()
add_custom_command(
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
COMMENT "Generating/updating shaders"
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_SOURCE_DIR}/tools/shadergen.py
--commands ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE}
--spirv-binaries ${SPIRV_BINARIES_DIR}
--scribe $<TARGET_FILE:scribe>
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
--source-dir ${CMAKE_SOURCE_DIR}
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} scribe spirv_binaries ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
endif()
add_custom_target(shadergen DEPENDS ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS})
set_target_properties(shadergen PROPERTIES FOLDER "Shaders")
# Custom targets required to force generation of the shaders via scribe
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS})
add_custom_target(compiled_shaders SOURCES ${COMPILED_SHADERS})
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS} ${AUTOSCRIBE_SHADER_HEADERS})
set_target_properties(scribe_shaders PROPERTIES FOLDER "Shaders")
set_target_properties(compiled_shaders PROPERTIES FOLDER "Shaders")
add_custom_target(scribed_shaders SOURCES ${SCRIBED_SHADERS})
set_target_properties(scribed_shaders PROPERTIES FOLDER "Shaders")
add_dependencies(scribed_shaders shadergen)
add_custom_target(spirv_shaders SOURCES ${SPIRV_SHADERS})
set_target_properties(spirv_shaders PROPERTIES FOLDER "Shaders")
add_dependencies(spirv_shaders shadergen)
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
set_target_properties(reflected_shaders PROPERTIES FOLDER "Shaders")
add_dependencies(reflected_shaders shadergen)
message(STATUS "Shader processing end")
endmacro()

View file

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

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)
setup_hifi_library(Network Script)
link_hifi_libraries(shared gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
link_hifi_libraries(shared shaders gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
include_hifi_library_headers(avatars)
include_hifi_library_headers(networking)
include_hifi_library_headers(fbx)

View file

@ -2,11 +2,11 @@ struct TextureData {
ivec2 textureSize;
};
layout(std140, binding=0) uniform textureDataBuffer {
LAYOUT_STD140(binding=0) uniform textureDataBuffer {
TextureData textureData;
};
layout(binding=0) uniform sampler2D colorMap;
LAYOUT(binding=0) uniform sampler2D colorMap;
layout(location=0) in vec2 varTexCoord0;
layout(location=0) out vec4 outFragColor;

View file

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

View file

@ -1,10 +1,10 @@
// OpenGLDisplayPlugin_present.frag
layout(binding = 0) uniform sampler2D colorMap;
LAYOUT(binding=0) uniform sampler2D colorMap;
layout(location = 0) in vec2 varTexCoord0;
layout(location=0) in vec2 varTexCoord0;
layout(location = 0) out vec4 outFragColor;
layout(location=0) out vec4 outFragColor;
float sRGBFloatToLinear(float value) {
const float SRGB_ELBOW = 0.04045;

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

View file

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

View file

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

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

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

View file

@ -10,7 +10,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
layout(binding=0) uniform sampler2D colorMap;
LAYOUT(binding=0) uniform sampler2D colorMap;
layout(location=0) in vec4 varColor;
layout(location=1) in vec2 varTexcoord;

View file

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

View file

@ -5,4 +5,4 @@ include_hifi_library_headers(fbx)
include_hifi_library_headers(gpu)
include_hifi_library_headers(image)
include_hifi_library_headers(ktx)
link_hifi_libraries(shared networking octree avatars graphics model-networking)
link_hifi_libraries(shared shaders networking octree avatars graphics model-networking)

View file

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

View file

@ -643,18 +643,21 @@ protected:
}
} _pipeline;
// Backend dependant compilation of the shader
// Backend dependent compilation of the shader
virtual void postLinkProgram(ShaderObject& programObject, const Shader& program) const;
virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler);
virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler);
virtual std::string getBackendShaderHeader() const = 0;
// For a program, this will return a string containing all the source files (without any
// backend headers or defines). For a vertex, fragment or geometry shader, this will
// return the fully customized shader with all the version and backend specific
// For a program, this will return a string containing all the source files (without any
// backend headers or defines). For a vertex, fragment or geometry shader, this will
// return the fully customized shader with all the version and backend specific
// preprocessor directives
// The program string returned can be used as a key for a cache of shader binaries
// The shader strings can be reliably sent to the low level `compileShader` functions
virtual std::string getShaderSource(const Shader& shader, int version) final;
virtual std::string getShaderSource(const Shader& shader, shader::Variant version) final;
shader::Variant getShaderVariant() const { return isStereo() ? shader::Variant::Stereo : shader::Variant::Mono; }
virtual shader::Dialect getShaderDialect() const = 0;
class ElementResource {
public:
gpu::Element _element;

View file

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

View file

@ -25,120 +25,53 @@ static const std::array<GLenum, NUM_SHADER_DOMAINS> SHADER_DOMAINS{ {
GL_GEOMETRY_SHADER,
} };
// Domain specific defines
// Must match the order of type specified in gpu::Shader::Type
static const std::array<std::string, NUM_SHADER_DOMAINS> DOMAIN_DEFINES{ {
"#define GPU_VERTEX_SHADER",
"#define GPU_PIXEL_SHADER",
"#define GPU_GEOMETRY_SHADER",
} };
// Stereo specific defines
static const std::string stereoVersion{
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
R"SHADER(
#define GPU_TRANSFORM_IS_STEREO
#define GPU_TRANSFORM_STEREO_CAMERA
#define GPU_TRANSFORM_STEREO_CAMERA_INSTANCED
#define GPU_TRANSFORM_STEREO_SPLIT_SCREEN
)SHADER"
#endif
#ifdef GPU_STEREO_DRAWCALL_DOUBLED
#ifdef GPU_STEREO_CAMERA_BUFFER
R"SHADER(
#define GPU_TRANSFORM_IS_STEREO
#define GPU_TRANSFORM_STEREO_CAMERA
#define GPU_TRANSFORM_STEREO_CAMERA_ATTRIBUTED
)SHADER"
#else
R"SHADER(
#define GPU_TRANSFORM_IS_STEREO
)SHADER"
#endif
#endif
};
// TextureTable specific defines
static const std::string textureTableVersion {
"#extension GL_ARB_bindless_texture : require\n#define GPU_TEXTURE_TABLE_BINDLESS\n"
};
// Versions specific of the shader
static const std::array<std::string, GLShader::NumVersions> VERSION_DEFINES { {
"",
stereoVersion
} };
static std::string getShaderTypeString(Shader::Type type) {
switch (type) {
case Shader::Type::VERTEX:
return "vertex";
case Shader::Type::PIXEL:
return "pixel";
case Shader::Type::GEOMETRY:
return "geometry";
case Shader::Type::PROGRAM:
return "program";
default:
qFatal("Unexpected shader type %d", type);
Q_UNREACHABLE();
}
}
std::string GLBackend::getShaderSource(const Shader& shader, int version) {
std::string GLBackend::getShaderSource(const Shader& shader, shader::Variant variant) {
if (shader.isProgram()) {
std::string result;
result.append("// VERSION " + std::to_string(version));
for (const auto& subShader : shader.getShaders()) {
result.append("//-------- ");
result.append(getShaderTypeString(subShader->getType()));
result.append("\n");
result.append(subShader->getSource().getCode());
if (subShader) {
result += subShader->getSource().getSource(getShaderDialect(), variant);
}
}
return result;
}
std::string shaderDefines = getBackendShaderHeader() + "\n"
+ (supportsBindless() ? textureTableVersion : "\n")
+ DOMAIN_DEFINES[shader.getType()] + "\n"
+ VERSION_DEFINES[version];
return shaderDefines + "\n" + shader.getSource().getCode();
}
return shader.getSource().getSource(getShaderDialect(), variant);
}
GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler) {
// Any GLSLprogram ? normally yes...
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
GLShader::ShaderObjects shaderObjects;
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
const auto& variants = shader::allVariants();
Shader::CompilationLogs compilationLogs(variants.size());
shader.incrementCompilationAttempt();
for (int version = 0; version < GLShader::NumVersions; version++) {
auto& shaderObject = shaderObjects[version];
auto shaderSource = getShaderSource(shader, version);
for (const auto& variant : variants) {
auto index = static_cast<uint32_t>(variant);
auto shaderSource = getShaderSource(shader, variant);
auto& shaderObject = shaderObjects[index];
if (handler) {
bool retest = true;
std::string currentSrc = shaderSource;
// When a Handler is specified, we can try multiple times to build the shader and let the handler change the source if the compilation fails.
// The retest bool is set to false as soon as the compilation succeed to wexit the while loop.
// The retest bool is set to false as soon as the compilation succeed to exit the while loop.
// The handler tells us if we should retry or not while returning a modified version of the source.
while (retest) {
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[version].message);
compilationLogs[version].compiled = result;
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[index].message);
compilationLogs[index].compiled = result;
if (!result) {
std::string newSrc;
retest = handler(shader, currentSrc, compilationLogs[version], newSrc);
retest = handler(shader, currentSrc, compilationLogs[index], newSrc);
currentSrc = newSrc;
} else {
retest = false;
}
}
} else {
compilationLogs[version].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderObject.glshader, compilationLogs[version].message);
compilationLogs[index].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderObject.glshader, compilationLogs[index].message);
}
if (!compilationLogs[version].compiled) {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[version].message.c_str();
if (!compilationLogs[index].compiled) {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[index].message.c_str();
shader.setCompilationLogs(compilationLogs);
return nullptr;
}
@ -162,11 +95,13 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
GLShader::ShaderObjects programObjects;
program.incrementCompilationAttempt();
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
const auto& variants = shader::allVariants();
Shader::CompilationLogs compilationLogs(variants.size());
for (int version = 0; version < GLShader::NumVersions; version++) {
auto& programObject = programObjects[version];
auto programSource = getShaderSource(program, version);
for (const auto& variant : variants) {
auto index = static_cast<uint32_t>(variant);
auto& programObject = programObjects[index];
auto programSource = getShaderSource(program, variant);
auto hash = ::gl::getShaderHash(programSource);
CachedShader cachedBinary;
@ -199,11 +134,11 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
for (auto subShader : program.getShaders()) {
auto object = GLShader::sync((*this), *subShader, handler);
if (object) {
shaderGLObjects.push_back(object->_shaderObjects[version].glshader);
shaderGLObjects.push_back(object->_shaderObjects[index].glshader);
} else {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?";
compilationLogs[version].compiled = false;
compilationLogs[version].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
compilationLogs[index].compiled = false;
compilationLogs[index].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
program.setCompilationLogs(compilationLogs);
return nullptr;
}
@ -211,9 +146,9 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
glprogram = ::gl::buildProgram(shaderGLObjects);
if (!::gl::linkProgram(glprogram, compilationLogs[version].message)) {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str();
compilationLogs[version].compiled = false;
if (!::gl::linkProgram(glprogram, compilationLogs[index].message)) {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[index].message.c_str();
compilationLogs[index].compiled = false;
glDeleteProgram(glprogram);
glprogram = 0;
return nullptr;
@ -228,12 +163,12 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
}
if (glprogram == 0) {
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str();
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[index].message.c_str();
program.setCompilationLogs(compilationLogs);
return nullptr;
}
compilationLogs[version].compiled = true;
compilationLogs[index].compiled = true;
programObject.glprogram = glprogram;
postLinkProgram(programObject, program);
}
@ -249,7 +184,10 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
static const GLint INVALID_UNIFORM_INDEX = -1;
GLint GLBackend::getRealUniformLocation(GLint location) const {
auto& shader = _pipeline._programShader->_shaderObjects[(GLShader::Version)isStereo()];
auto variant = isStereo() ? shader::Variant::Stereo : shader::Variant::Mono;
auto index = static_cast<uint32_t>(variant);
auto& shader = _pipeline._programShader->_shaderObjects[index];
auto itr = shader.uniformRemap.find(location);
if (itr == shader.uniformRemap.end()) {
// This shouldn't happen, because we use reflection to determine all the possible
@ -264,20 +202,23 @@ GLint GLBackend::getRealUniformLocation(GLint location) const {
void GLBackend::postLinkProgram(ShaderObject& shaderObject, const Shader& program) const {
const auto& glprogram = shaderObject.glprogram;
const auto& expectedUniforms = program.getUniforms();
const auto expectedLocationsByName = expectedUniforms.getLocationsByName();
const auto uniforms = ::gl::Uniform::load(glprogram, expectedUniforms.getNames());
auto& uniformRemap = shaderObject.uniformRemap;
const auto& expectedUniforms = program.getReflection().uniforms;
// Pre-initialize all the uniforms with an invalid location
for (const auto& entry : expectedLocationsByName) {
auto& uniformRemap = shaderObject.uniformRemap;
// initialize all the uniforms with an invalid location
for (const auto& entry : expectedUniforms) {
uniformRemap[entry.second] = INVALID_UNIFORM_INDEX;
}
// Now load up all the actual found uniform location
// Get the actual uniform locations from the shader
const auto names = Shader::Reflection::getNames(expectedUniforms);
const auto uniforms = ::gl::Uniform::load(glprogram, names);
// Now populate the remapping with the found locations
for (const auto& uniform : uniforms) {
const auto& name = uniform.name;
const auto& expectedLocation = expectedLocationsByName.at(name);
const auto& expectedLocation = expectedUniforms.at(name);
const auto& location = uniform.binding;
uniformRemap[expectedLocation] = location;
}
@ -462,3 +403,4 @@ void GLBackend::initShaderBinaryCache() {
void GLBackend::killShaderBinaryCache() {
::gl::saveShaderCache(_shaderBinaryCache._binaries);
}

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
// uniform will automatically have it provided without any client code necessary.
// Required for stable lighting in the HMD.
object->_cameraCorrection = shader->getUniformBuffers().isValid(gpu::slot::buffer::CameraCorrection);
object->_cameraCorrection = shader->getReflection().validUniformBuffer(gpu::slot::buffer::CameraCorrection);
object->_program = programObject;
object->_state = stateObject;

View file

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

View file

@ -1,6 +1,6 @@
set(TARGET_NAME gpu-gl)
setup_hifi_library(Concurrent)
link_hifi_libraries(shared gl gpu gpu-gl-common)
link_hifi_libraries(shared gl gpu gpu-gl-common shaders)
if (UNIX)
target_link_libraries(${TARGET_NAME} pthread)
endif(UNIX)

View file

@ -170,8 +170,7 @@ protected:
// Output stage
void do_blit(const Batch& batch, size_t paramOffset) override;
std::string getBackendShaderHeader() const override;
shader::Dialect getShaderDialect() const override { return shader::Dialect::glsl410; }
void postLinkProgram(ShaderObject& programObject, const Shader& program) const override;
};

View file

@ -12,22 +12,13 @@ using namespace gpu;
using namespace gpu::gl;
using namespace gpu::gl41;
// GLSL version
std::string GL41Backend::getBackendShaderHeader() const {
static const std::string header(
R"SHADER(#version 410 core
#define GPU_GL410
#define BITFIELD int
)SHADER");
return header;
}
void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& program) const {
Parent::postLinkProgram(programObject, program);
const auto& glprogram = programObject.glprogram;
const auto& reflection = program.getReflection();
// For the UBOs, use glUniformBlockBinding to fixup the locations based on the reflection
{
const auto expectedUbos = program.getUniformBuffers().getLocationsByName();
const auto& expectedUbos = reflection.uniformBuffers;
auto ubos = ::gl::UniformBlock::load(glprogram);
for (const auto& ubo : ubos) {
const auto& name = ubo.name;
@ -41,7 +32,7 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
// For the Textures, use glUniform1i to fixup the active texture slots based on the reflection
{
const auto expectedTextures = program.getTextures().getLocationsByName();
const auto& expectedTextures = reflection.textures;
for (const auto& expectedTexture : expectedTextures) {
auto location = glGetUniformLocation(glprogram, expectedTexture.first.c_str());
if (location < 0) {
@ -53,8 +44,9 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
// For the resource buffers, do the same as for the textures, since in GL 4.1 that's how they're implemented
{
const auto expectedResourceBuffers = program.getResourceBuffers().getLocationsByName();
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, program.getResourceBuffers().getNames());
const auto& expectedResourceBuffers = reflection.resourceBuffers;
const auto names = Shader::Reflection::getNames(expectedResourceBuffers);
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names);
for (const auto& resourceBuffer : resourceBufferUniforms) {
const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name);
glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding + GL41Backend::RESOURCE_BUFFER_SLOT0_TEX_UNIT);

View file

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

View file

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

View file

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

View file

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

View file

@ -12,15 +12,3 @@ using namespace gpu;
using namespace gpu::gl;
using namespace gpu::gles;
// GLSL version
std::string GLESBackend::getBackendShaderHeader() const {
static const std::string header(
R"SHADER(#version 310 es
#extension GL_EXT_texture_buffer : enable
precision highp float;
precision highp samplerBuffer;
precision highp sampler2DShadow;
#define BITFIELD highp int
)SHADER");
return header;
}

View file

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

View file

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

View file

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

View file

@ -25,7 +25,7 @@ struct TexCoordRectParams {
vec4 texcoordRect;
};
layout(binding=0) uniform texcoordRectBuffer {
LAYOUT(binding=0) uniform texcoordRectBuffer {
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) out vec4 outFragColor;

View file

@ -1,2 +1 @@
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) out vec4 outFragColor;

View file

@ -0,0 +1 @@
VERTEX DrawUnitQuadTexcoord

View file

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

View file

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

View file

@ -10,44 +10,49 @@
//
#include "Shader.h"
#include <math.h>
#include <QDebug>
#include <set>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <shaders/Shaders.h>
#include "Context.h"
using namespace gpu;
std::atomic<uint32_t> Shader::_nextShaderID( 1 );
Shader::DomainShaderMaps Shader::_domainShaderMaps;
Shader::ProgramMap Shader::_programMap;
Shader::Shader(Type type, const Source& source) :
_source(source),
_type(type),
_ID(_nextShaderID++)
Shader::Shader(Type type, const Source& source, bool dynamic) :
_type(type)
{
auto& thisSource = const_cast<Source&>(_source);
thisSource = source;
if (!dynamic) {
thisSource.id = source.id;
}
}
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel):
_type(type),
_ID(_nextShaderID++)
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel) :
_type(type)
{
auto& shaders = const_cast<Shaders&>(_shaders);
if (geometry) {
_shaders.resize(3);
_shaders[VERTEX] = vertex;
_shaders[GEOMETRY] = geometry;
_shaders[PIXEL] = pixel;
shaders.resize(3);
shaders[VERTEX] = vertex;
shaders[GEOMETRY] = geometry;
shaders[PIXEL] = pixel;
} else {
_shaders.resize(2);
_shaders[VERTEX] = vertex;
_shaders[PIXEL] = pixel;
shaders.resize(2);
shaders[VERTEX] = vertex;
shaders[PIXEL] = pixel;
}
auto& reflection = const_cast<Reflection&>(getReflection());
for (const auto& subShader : _shaders) {
reflection.merge(subShader->getReflection());
}
if (_shaders[VERTEX]) {
reflection.inputs = _shaders[VERTEX]->getReflection().inputs;
}
if (_shaders[PIXEL]) {
reflection.outputs = _shaders[PIXEL]->getReflection().outputs;
}
}
@ -55,46 +60,27 @@ Shader::~Shader()
{
}
void populateSlotSet(Shader::SlotSet& slotSet, const Shader::LocationMap& map) {
for (const auto& entry : map) {
const auto& name = entry.first;
const auto& location = entry.second;
slotSet.insert({ name, location, Element() });
}
static std::unordered_map<uint32_t, std::weak_ptr<Shader>> _shaderCache;
Shader::ID Shader::getID() const {
if (isProgram()) {
return (_shaders[VERTEX]->getID() << 16) | (_shaders[PIXEL]->getID());
}
return _source.id;
}
Shader::Pointer Shader::createOrReuseDomainShader(Type type, const Source& source) {
auto found = _domainShaderMaps[type].find(source);
if (found != _domainShaderMaps[type].end()) {
Shader::Pointer Shader::createOrReuseDomainShader(Type type, uint32_t sourceId) {
// Don't attempt to cache non-static shaders
auto found = _shaderCache.find(sourceId);
if (found != _shaderCache.end()) {
auto sharedShader = (*found).second.lock();
if (sharedShader) {
return sharedShader;
}
}
auto shader = Pointer(new Shader(type, source));
const auto& reflection = source.getReflection();
if (0 != reflection.count(BindingType::INPUT)) {
populateSlotSet(shader->_inputs, reflection.find(BindingType::INPUT)->second);
}
if (0 != reflection.count(BindingType::OUTPUT)) {
populateSlotSet(shader->_outputs, reflection.find(BindingType::OUTPUT)->second);
}
if (0 != reflection.count(BindingType::UNIFORM_BUFFER)) {
populateSlotSet(shader->_uniformBuffers, reflection.find(BindingType::UNIFORM_BUFFER)->second);
}
if (0 != reflection.count(BindingType::RESOURCE_BUFFER)) {
populateSlotSet(shader->_resourceBuffers, reflection.find(BindingType::RESOURCE_BUFFER)->second);
}
if (0 != reflection.count(BindingType::TEXTURE)) {
populateSlotSet(shader->_textures, reflection.find(BindingType::TEXTURE)->second);
}
if (0 != reflection.count(BindingType::SAMPLER)) {
populateSlotSet(shader->_samplers, reflection.find(BindingType::SAMPLER)->second);
}
if (0 != reflection.count(BindingType::UNIFORM)) {
populateSlotSet(shader->_uniforms, reflection.find(BindingType::UNIFORM)->second);
}
_domainShaderMaps[type].emplace(source, std::weak_ptr<Shader>(shader));
auto shader = Pointer(new Shader(type, getShaderSource(sourceId), false));
_shaderCache.insert({ sourceId, shader });
return shader;
}
@ -137,28 +123,6 @@ ShaderPointer Shader::createOrReuseProgramShader(Type type, const Pointer& verte
// Program is a new one, let's create it
auto program = Pointer(new Shader(type, vertexShader, geometryShader, pixelShader));
// Combine the slots from the sub-shaders
for (const auto& shader : program->_shaders) {
const auto& reflection = shader->_source.getReflection();
if (0 != reflection.count(BindingType::UNIFORM_BUFFER)) {
populateSlotSet(program->_uniformBuffers, reflection.find(BindingType::UNIFORM_BUFFER)->second);
}
if (0 != reflection.count(BindingType::RESOURCE_BUFFER)) {
populateSlotSet(program->_resourceBuffers, reflection.find(BindingType::RESOURCE_BUFFER)->second);
}
if (0 != reflection.count(BindingType::TEXTURE)) {
populateSlotSet(program->_textures, reflection.find(BindingType::TEXTURE)->second);
}
if (0 != reflection.count(BindingType::SAMPLER)) {
populateSlotSet(program->_samplers, reflection.find(BindingType::SAMPLER)->second);
}
if (0 != reflection.count(BindingType::UNIFORM)) {
populateSlotSet(program->_uniforms, reflection.find(BindingType::UNIFORM)->second);
}
}
_programMap.emplace(key, std::weak_ptr<Shader>(program));
return program;
}
@ -175,24 +139,21 @@ void Shader::incrementCompilationAttempt() const {
}
Shader::Pointer Shader::createVertex(const Source& source) {
return createOrReuseDomainShader(VERTEX, source);
return Pointer(new Shader(VERTEX, source, true));
}
Shader::Pointer Shader::createPixel(const Source& source) {
return createOrReuseDomainShader(FRAGMENT, source);
return Pointer(new Shader(FRAGMENT, source, true));
}
Shader::Pointer Shader::createVertex(uint32_t id) {
return createVertex(getShaderSource(id));
return createOrReuseDomainShader(VERTEX, id);
}
Shader::Pointer Shader::createPixel(uint32_t id) {
return createPixel(getShaderSource(id));
return createOrReuseDomainShader(FRAGMENT, id);
}
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, pixelShader);
}
Shader::Pointer Shader::createProgram(uint32_t programId) {
auto vertexShader = createVertex(shader::getVertexId(programId));
@ -200,98 +161,15 @@ Shader::Pointer Shader::createProgram(uint32_t programId) {
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, fragmentShader);
}
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
return Pointer(new Shader(PROGRAM, vertexShader, nullptr, pixelShader));
}
// Dynamic program, bypass caching
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& geometryShader, const Pointer& pixelShader) {
return createOrReuseProgramShader(PROGRAM, vertexShader, geometryShader, pixelShader);
return Pointer(new Shader(PROGRAM, vertexShader, geometryShader, pixelShader));
}
static const std::string IGNORED_BINDING = "transformObjectBuffer";
void updateBindingsFromJsonObject(Shader::LocationMap& inOutSet, const QJsonObject& json) {
for (const auto& key : json.keys()) {
auto keyStr = key.toStdString();
if (IGNORED_BINDING == keyStr) {
continue;
}
inOutSet[keyStr] = json[key].toInt();
}
}
void updateTextureAndResourceBuffersFromJsonObjects(Shader::LocationMap& inOutTextures, Shader::LocationMap& inOutResourceBuffers,
const QJsonObject& json, const QJsonObject& types) {
static const std::string RESOURCE_BUFFER_TEXTURE_TYPE = "samplerBuffer";
for (const auto& key : json.keys()) {
auto keyStr = key.toStdString();
if (keyStr == IGNORED_BINDING) {
continue;
}
auto location = json[key].toInt();
auto type = types[key].toString().toStdString();
if (type == RESOURCE_BUFFER_TEXTURE_TYPE) {
inOutResourceBuffers[keyStr] = location;
} else {
inOutTextures[key.toStdString()] = location;
}
}
}
Shader::ReflectionMap getShaderReflection(const std::string& reflectionJson) {
if (reflectionJson.empty() && reflectionJson != std::string("null")) {
return {};
}
#define REFLECT_KEY_INPUTS "inputs"
#define REFLECT_KEY_OUTPUTS "outputs"
#define REFLECT_KEY_UBOS "uniformBuffers"
#define REFLECT_KEY_SSBOS "storageBuffers"
#define REFLECT_KEY_UNIFORMS "uniforms"
#define REFLECT_KEY_TEXTURES "textures"
#define REFLECT_KEY_TEXTURE_TYPES "textureTypes"
auto doc = QJsonDocument::fromJson(reflectionJson.c_str());
if (doc.isNull()) {
qWarning() << "Invalid shader reflection JSON" << reflectionJson.c_str();
return {};
}
Shader::ReflectionMap result;
auto json = doc.object();
if (json.contains(REFLECT_KEY_INPUTS)) {
updateBindingsFromJsonObject(result[Shader::BindingType::INPUT], json[REFLECT_KEY_INPUTS].toObject());
}
if (json.contains(REFLECT_KEY_OUTPUTS)) {
updateBindingsFromJsonObject(result[Shader::BindingType::OUTPUT], json[REFLECT_KEY_OUTPUTS].toObject());
}
// FIXME eliminate the last of the uniforms
if (json.contains(REFLECT_KEY_UNIFORMS)) {
updateBindingsFromJsonObject(result[Shader::BindingType::UNIFORM], json[REFLECT_KEY_UNIFORMS].toObject());
}
if (json.contains(REFLECT_KEY_UBOS)) {
updateBindingsFromJsonObject(result[Shader::BindingType::UNIFORM_BUFFER], json[REFLECT_KEY_UBOS].toObject());
}
// SSBOs need to come BEFORE the textures. In GL 4.5 the reflection slots aren't really used, but in 4.1 the slots
// are used to explicitly setup bindings after shader linkage, so we want the resource buffer slots to contain the
// texture locations, not the SSBO locations
if (json.contains(REFLECT_KEY_SSBOS)) {
updateBindingsFromJsonObject(result[Shader::BindingType::RESOURCE_BUFFER], json[REFLECT_KEY_SSBOS].toObject());
}
// samplerBuffer textures map to gpu ResourceBuffer, while all other textures map to regular gpu Texture
if (json.contains(REFLECT_KEY_TEXTURES)) {
updateTextureAndResourceBuffersFromJsonObjects(
result[Shader::BindingType::TEXTURE],
result[Shader::BindingType::RESOURCE_BUFFER],
json[REFLECT_KEY_TEXTURES].toObject(),
json[REFLECT_KEY_TEXTURE_TYPES].toObject());
}
return result;
}
Shader::Source Shader::getShaderSource(uint32_t id) {
auto source = shader::loadShaderSource(id);
auto reflectionJson = shader::loadShaderReflection(id);
auto reflection = getShaderReflection(reflectionJson);
return { source, reflection };
const Shader::Source& Shader::getShaderSource(uint32_t id) {
return shader::Source::get(id);
}

View file

@ -19,6 +19,7 @@
#include <unordered_map>
#include <map>
#include <functional>
#include <shaders/Shaders.h>
#include <QUrl>
namespace gpu {
@ -42,58 +43,10 @@ public:
typedef std::shared_ptr<Shader> Pointer;
typedef std::vector<Pointer> Shaders;
// Needs to match values in shaders/Shaders.h
enum class BindingType
{
INVALID = -1,
INPUT = 0,
OUTPUT,
TEXTURE,
SAMPLER,
UNIFORM_BUFFER,
RESOURCE_BUFFER,
UNIFORM,
};
using LocationMap = std::unordered_map<std::string, int32_t>;
using ReflectionMap = std::map<BindingType, LocationMap>;
class Source {
public:
enum Language
{
INVALID = -1,
GLSL = 0,
SPIRV = 1,
MSL = 2,
HLSL = 3,
};
Source() {}
Source(const std::string& code, const ReflectionMap& reflection, Language lang = GLSL) :
_code(code), _reflection(reflection), _lang(lang) {}
Source(const Source& source) : _code(source._code), _reflection(source._reflection), _lang(source._lang) {}
virtual ~Source() {}
virtual const std::string& getCode() const { return _code; }
virtual const ReflectionMap& getReflection() const { return _reflection; }
class Less {
public:
bool operator()(const Source& x, const Source& y) const {
if (x._lang == y._lang) {
return x._code < y._code;
} else {
return (x._lang < y._lang);
}
}
};
protected:
std::string _code;
ReflectionMap _reflection;
Language _lang;
};
using Source = shader::Source;
using Reflection = shader::Reflection;
using Dialect = shader::Dialect;
using Variant = shader::Variant;
struct CompilationLog {
std::string message;
@ -112,85 +65,13 @@ public:
bool operator()(const T& x, const T& y) const { return x._name < y._name; }
};
class Slot {
public:
std::string _name;
int32 _location{ INVALID_LOCATION };
Element _element;
uint16 _resourceType{ Resource::BUFFER };
uint32 _size{ 0 };
Slot(const Slot& s) :
_name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType), _size(s._size) {}
Slot(Slot&& s) :
_name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType), _size(s._size) {}
Slot(const std::string& name,
int32 location,
const Element& element,
uint16 resourceType = Resource::BUFFER,
uint32 size = 0) :
_name(name),
_location(location), _element(element), _resourceType(resourceType), _size(size) {}
Slot(const std::string& name) : _name(name) {}
Slot& operator=(const Slot& s) {
_name = s._name;
_location = s._location;
_element = s._element;
_resourceType = s._resourceType;
_size = s._size;
return (*this);
}
};
class SlotSet : protected std::set<Slot, Less<Slot>> {
using Parent = std::set<Slot, Less<Slot>>;
public:
void insert(const Parent::value_type& value) {
Parent::insert(value);
if (value._location != INVALID_LOCATION) {
_validSlots.insert(value._location);
}
}
using Parent::begin;
using Parent::empty;
using Parent::end;
using Parent::size;
using LocationMap = std::unordered_map<std::string, int32>;
using NameVector = std::vector<std::string>;
NameVector getNames() const {
NameVector result;
for (const auto& entry : *this) {
result.push_back(entry._name);
}
return result;
}
LocationMap getLocationsByName() const {
LocationMap result;
for (const auto& entry : *this) {
result.insert({ entry._name, entry._location });
}
return result;
}
bool isValid(int32 slot) const { return 0 != _validSlots.count(slot); }
protected:
std::unordered_set<int> _validSlots;
};
static Source getShaderSource(uint32_t id);
static Source getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
static Source getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
static const Source& getShaderSource(uint32_t id);
static const Source& getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
static const Source& getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
static Pointer createVertex(const Source& source);
static Pointer createPixel(const Source& source);
static Pointer createGeometry(const Source& source);
static Pointer createVertex(uint32_t shaderId);
static Pointer createPixel(uint32_t shaderId);
static Pointer createGeometry(uint32_t shaderId);
@ -201,8 +82,7 @@ public:
~Shader();
ID getID() const { return _ID; }
ID getID() const;
Type getType() const { return _type; }
bool isProgram() const { return getType() > NUM_DOMAINS; }
bool isDomain() const { return getType() < NUM_DOMAINS; }
@ -211,17 +91,12 @@ public:
const Shaders& getShaders() const { return _shaders; }
// Access the exposed uniform, input and output slot
const SlotSet& getUniforms() const { return _uniforms; }
const SlotSet& getUniformBuffers() const { return _uniformBuffers; }
const SlotSet& getResourceBuffers() const { return _resourceBuffers; }
const SlotSet& getTextures() const { return _textures; }
const SlotSet& getSamplers() const { return _samplers; }
const Reflection& getReflection() const { return _source.reflection; }
// Compilation Handler can be passed while compiling a shader (in the makeProgram call) to be able to give the hand to
// the caller thread if the comilation fails and to prvide a different version of the source for it
// the caller thread if the compilation fails and to provide a different version of the source for it
// @param0 the Shader object that just failed to compile
// @param1 the original source code as submited to the compiler
// @param1 the original source code as submitted to the compiler
// @param2 the compilation log containing the error message
// @param3 a new string ready to be filled with the new version of the source that could be proposed from the handler functor
// @return boolean true if the backend should keep trying to compile the shader with the new source returned or false to stop and fail that shader compilation
@ -240,32 +115,21 @@ public:
const GPUObjectPointer gpuObject{};
protected:
Shader(Type type, const Source& source);
Shader(Type type, const Source& source, bool dynamic);
Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel);
Shader(const Shader& shader); // deep copy of the sysmem shader
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture
// Source contains the actual source code or nothing if the shader is a program
Source _source;
const Source _source;
// if shader is composed of sub shaders, here they are
Shaders _shaders;
// List of exposed uniform, input and output slots
SlotSet _uniforms;
SlotSet _uniformBuffers;
SlotSet _resourceBuffers;
SlotSet _textures;
SlotSet _samplers;
SlotSet _inputs;
SlotSet _outputs;
const Shaders _shaders;
// The type of the shader, the master key
Type _type;
// The unique identifier of a shader in the GPU lib
uint32_t _ID{ 0 };
const Type _type;
// Number of attempts to compile the shader
mutable uint32_t _numCompilationAttempts{ 0 };
@ -277,13 +141,9 @@ protected:
// Global maps of the shaders
// Unique shader ID
static std::atomic<ID> _nextShaderID;
//static std::atomic<ID> _nextShaderID;
using ShaderMap = std::map<Source, std::weak_ptr<Shader>, Source::Less>;
using DomainShaderMaps = std::array<ShaderMap, NUM_DOMAINS>;
static DomainShaderMaps _domainShaderMaps;
static ShaderPointer createOrReuseDomainShader(Type type, const Source& source);
static ShaderPointer createOrReuseDomainShader(Type type, uint32_t sourceId);
using ProgramMapKey = glm::uvec3; // The IDs of the shaders in a program make its key
class ProgramKeyLess {

View file

@ -98,21 +98,6 @@ enum Attribute {
};
} // namespace attr
namespace uniform {
enum Uniform {
Extra0 = GPU_UNIFORM_EXTRA0,
Extra1 = GPU_UNIFORM_EXTRA1,
Extra2 = GPU_UNIFORM_EXTRA2,
Extra3 = GPU_UNIFORM_EXTRA3,
Extra4 = GPU_UNIFORM_EXTRA4,
Extra5 = GPU_UNIFORM_EXTRA5,
Extra6 = GPU_UNIFORM_EXTRA6,
Extra7 = GPU_UNIFORM_EXTRA7,
Extra8 = GPU_UNIFORM_EXTRA8,
Extra9 = GPU_UNIFORM_EXTRA9,
};
} // namespace uniform
} } // namespace gpu::slot
// !>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
set(TARGET_NAME model-networking)
setup_hifi_library()
link_hifi_libraries(shared networking graphics fbx ktx image gl)
link_hifi_libraries(shared shaders networking graphics fbx ktx image gl)
include_hifi_library_headers(gpu)

View file

@ -27,7 +27,7 @@
Q_LOGGING_CATEGORY(proceduralLog, "hifi.gpu.procedural")
// Userdata parsing constants
// User-data parsing constants
static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
static const QString URL_KEY = "shaderUrl";
static const QString VERSION_KEY = "version";
@ -39,11 +39,8 @@ static const std::string PROCEDURAL_BLOCK = "//PROCEDURAL_BLOCK";
static const std::string PROCEDURAL_VERSION = "//PROCEDURAL_VERSION";
bool operator==(const ProceduralData& a, const ProceduralData& b) {
return (
(a.version == b.version) &&
(a.shaderUrl == b.shaderUrl) &&
(a.uniforms == b.uniforms) &&
(a.channels == b.channels));
return ((a.version == b.version) && (a.shaderUrl == b.shaderUrl) && (a.uniforms == b.uniforms) &&
(a.channels == b.channels));
}
QJsonValue ProceduralData::getProceduralData(const QString& proceduralJson) {
@ -109,6 +106,8 @@ Procedural::Procedural() {
_transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
_transparentState->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
_standardInputsBuffer = std::make_shared<gpu::Buffer>(sizeof(StandardInputs), nullptr);
}
void Procedural::setProceduralData(const ProceduralData& proceduralData) {
@ -119,7 +118,7 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
_dirty = true;
_enabled = false;
if (proceduralData.version != _data.version ) {
if (proceduralData.version != _data.version) {
_data.version = proceduralData.version;
_shaderDirty = true;
}
@ -144,7 +143,6 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
_channels[channel] = textureCache->getTexture(QUrl());
}
}
_channelsDirty = true;
}
if (proceduralData.shaderUrl != _data.shaderUrl) {
@ -212,23 +210,6 @@ bool Procedural::isReady() const {
return true;
}
std::string Procedural::replaceProceduralBlock(const std::string& fragmentSource) {
std::string result = fragmentSource;
auto replaceIndex = result.find(PROCEDURAL_VERSION);
if (replaceIndex != std::string::npos) {
if (_data.version == 1) {
result.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1");
} else if (_data.version == 2) {
result.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1");
}
}
replaceIndex = result.find(PROCEDURAL_BLOCK);
if (replaceIndex != std::string::npos) {
result.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data());
}
return result;
}
void Procedural::prepare(gpu::Batch& batch,
const glm::vec3& position,
const glm::vec3& size,
@ -256,19 +237,21 @@ void Procedural::prepare(gpu::Batch& batch,
}
// Build the fragment shader
std::string opaqueShaderSource = replaceProceduralBlock(_opaquefragmentSource.getCode());
auto opaqueReflection = _opaquefragmentSource.getReflection();
auto& opaqueUniforms = opaqueReflection[gpu::Shader::BindingType::UNIFORM];
std::string transparentShaderSource = replaceProceduralBlock(_transparentfragmentSource.getCode());
auto transparentReflection = _transparentfragmentSource.getReflection();
auto& transparentUniforms = transparentReflection[gpu::Shader::BindingType::UNIFORM];
_opaqueFragmentSource.replacements.clear();
if (_data.version == 1) {
_opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V1 1";
} else if (_data.version == 2) {
_opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V2 1";
}
_opaqueFragmentSource.replacements[PROCEDURAL_BLOCK] = _shaderSource.toStdString();
_transparentFragmentSource.replacements = _opaqueFragmentSource.replacements;
// Set any userdata specified uniforms
int customSlot = procedural::slot::uniform::Custom;
for (const auto& key : _data.uniforms.keys()) {
std::string uniformName = key.toLocal8Bit().data();
opaqueUniforms[uniformName] = customSlot;
transparentUniforms[uniformName] = customSlot;
_opaqueFragmentSource.reflection.uniforms[uniformName] = customSlot;
_transparentFragmentSource.reflection.uniforms[uniformName] = customSlot;
++customSlot;
}
@ -276,18 +259,18 @@ void Procedural::prepare(gpu::Batch& batch,
// qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str();
// TODO: THis is a simple fix, we need a cleaner way to provide the "hosting" program for procedural custom shaders to be defined together with the required bindings.
_opaqueFragmentShader = gpu::Shader::createPixel({ opaqueShaderSource, opaqueReflection });
_opaqueFragmentShader = gpu::Shader::createPixel(_opaqueFragmentSource);
_opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader);
if (!transparentShaderSource.empty() && transparentShaderSource != opaqueShaderSource) {
_transparentFragmentShader = gpu::Shader::createPixel({ transparentShaderSource, transparentReflection });
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
if (_transparentFragmentSource.valid()) {
_transparentFragmentShader = gpu::Shader::createPixel(_transparentFragmentSource);
_transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader);
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
} else {
_transparentFragmentShader = _opaqueFragmentShader;
_transparentShader = _opaqueShader;
_transparentPipeline = _opaquePipeline;
}
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
_start = usecTimestampNow();
_frameCount = 0;
}
@ -299,12 +282,8 @@ void Procedural::prepare(gpu::Batch& batch,
setupUniforms(transparent);
}
if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) {
setupChannels(_shaderDirty || _uniformsDirty, transparent);
}
_prevTransparent = transparent;
_shaderDirty = _uniformsDirty = _channelsDirty = false;
_shaderDirty = _uniformsDirty = false;
for (auto lambda : _uniforms) {
lambda(batch);
@ -331,16 +310,10 @@ void Procedural::prepare(gpu::Batch& batch,
void Procedural::setupUniforms(bool transparent) {
_uniforms.clear();
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
const auto& uniformSlots = pipeline->getUniforms();
auto customUniformCount = _data.uniforms.keys().size();
// Set any userdata specified uniforms
for (int i = 0; i < customUniformCount; ++i) {
int slot = procedural::slot::uniform::Custom + i;
if (!uniformSlots.isValid(slot)) {
continue;
}
QString key = _data.uniforms.keys().at(i);
std::string uniformName = key.toLocal8Bit().data();
QJsonValue value = _data.uniforms[key];
@ -390,73 +363,42 @@ void Procedural::setupUniforms(bool transparent) {
}
}
if (uniformSlots.isValid(procedural::slot::uniform::Time)) {
_uniforms.push_back([=](gpu::Batch& batch) {
_uniforms.push_back([=](gpu::Batch& batch) {
// Time and position
{
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
batch._glUniform(procedural::slot::uniform::Time, time);
});
}
_standardInputs.posAndTime = vec4(_entityPosition, time);
}
if (uniformSlots.isValid(procedural::slot::uniform::Date)) {
_uniforms.push_back([=](gpu::Batch& batch) {
// Date
{
QDateTime now = QDateTime::currentDateTimeUtc();
QDate date = now.date();
QTime time = now.time();
vec4 v;
v.x = date.year();
_standardInputs.date.x = date.year();
// Shadertoy month is 0 based
v.y = date.month() - 1;
_standardInputs.date.y = date.month() - 1;
// But not the day... go figure
v.z = date.day();
_standardInputs.date.z = date.day();
float fractSeconds = (time.msec() / 1000.0f);
v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
batch._glUniform(procedural::slot::uniform::Date, v);
});
}
if (uniformSlots.isValid(procedural::slot::uniform::FrameCount)) {
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::FrameCount, ++_frameCount); });
}
if (uniformSlots.isValid(procedural::slot::uniform::Scale)) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Scale, _entityDimensions); });
}
if (uniformSlots.isValid(procedural::slot::uniform::Orientation)) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back(
[=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Orientation, _entityOrientation); });
}
if (uniformSlots.isValid(procedural::slot::uniform::Position)) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back(
[=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Orientation, _entityPosition); });
}
}
void Procedural::setupChannels(bool shouldCreate, bool transparent) {
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
const auto& uniformSlots = pipeline->getUniforms();
if (uniformSlots.isValid(procedural::slot::uniform::ChannelResolution)) {
if (!shouldCreate) {
// Instead of modifying the last element, just remove and recreate it.
_uniforms.pop_back();
_standardInputs.date.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
}
_uniforms.push_back([=](gpu::Batch& batch) {
vec3 channelSizes[MAX_PROCEDURAL_TEXTURE_CHANNELS];
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
if (_channels[i]) {
channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0);
}
_standardInputs.scaleAndCount = vec4(_entityDimensions, ++_frameCount);
_standardInputs.orientation = mat4(_entityOrientation);
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
if (_channels[i]) {
_standardInputs.resolution[i] = vec4(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0f, 1.0f);
} else {
_standardInputs.resolution[i] = vec4(1.0f);
}
batch._glUniform3fv(procedural::slot::uniform::ChannelResolution, MAX_PROCEDURAL_TEXTURE_CHANNELS,
&channelSizes[0].x);
});
}
}
_standardInputsBuffer->setSubData(0, _standardInputs);
batch.setUniformBuffer(0, _standardInputsBuffer, 0, sizeof(StandardInputs));
});
}
glm::vec4 Procedural::getColor(const glm::vec4& entityColor) {

View file

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

View file

@ -14,18 +14,51 @@
<$declareStandardCameraTransform()$>
#define PROCEDURAL 1
#ifdef GL_EXT_shader_non_constant_global_initializers
#extension GL_EXT_shader_non_constant_global_initializers : enable
#endif
//PROCEDURAL_VERSION
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL0) uniform sampler2D iChannel0;
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
#ifdef PROCEDURAL_V1
struct StandardInputs {
vec4 date;
vec4 posAndTime;
vec4 scaleAndCount;
mat4 orientation;
vec4 resolution[4];
};
LAYOUT(binding=0) uniform standardInputsBuffer {
StandardInputs params;
};
// shader playback time (in seconds)
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime;
// the dimensions of the object being rendered
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale;
float iGlobalTime = params.posAndTime.w;
vec4 iDate = params.date;
int iFrameCount = int(params.scaleAndCount.w);
// the position of the object being rendered
vec3 iWorldPosition = params.posAndTime.xyz;
// the dimensions of the object being rendered
vec3 iWorldScale = params.scaleAndCount.xyz;
// the orientation of the object being rendered
mat3 iWorldOrientation = mat3(params.orientation);
vec3 iChannelResolution[4] = vec3[4](
params.resolution[0].xyz,
params.resolution[1].xyz,
params.resolution[2].xyz,
params.resolution[3].xyz
);
#else
// Unimplemented uniforms
// Resolution doesn't make sense in the VR context
@ -37,20 +70,9 @@ const float iSampleRate = 1.0;
// No support for video input
const vec4 iChannelTime = vec4(0.0);
#define PROCEDURAL 1
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime; // shader playback time (in seconds)
layout(location=PROCEDURAL_UNIFORM_DATE) uniform vec4 iDate;
layout(location=PROCEDURAL_UNIFORM_FRAME_COUNT) uniform int iFrameCount;
layout(location=PROCEDURAL_UNIFORM_POSITION) uniform vec3 iWorldPosition; // the position of the object being rendered
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale; // the dimensions of the object being rendered
layout(location=PROCEDURAL_UNIFORM_ORIENTATION) uniform mat3 iWorldOrientation; // the orientation of the object being rendered
layout(location=PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION) uniform vec3 iChannelResolution[4];
layout(binding=PROCEDURAL_TEXTURE_CHANNEL0) uniform sampler2D iChannel0;
layout(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
layout(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
layout(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
#endif
//PROCEDURAL_VERSION
// hack comment for extra whitespace

View file

@ -19,7 +19,7 @@
ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() {
_procedural._vertexSource = gpu::Shader::createVertex(shader::graphics::vertex::skybox)->getSource();
_procedural._opaquefragmentSource = gpu::Shader::createPixel(shader::procedural::fragment::proceduralSkybox)->getSource();
_procedural._opaqueFragmentSource = shader::Source::get(shader::procedural::fragment::proceduralSkybox);
// Adjust the pipeline state for background using the stencil test
_procedural.setDoesFade(false);
// Must match PrepareStencil::STENCIL_BACKGROUND

View file

@ -14,14 +14,6 @@
#ifndef PROCEDURAL_SHADER_CONSTANTS_H
#define PROCEDURAL_SHADER_CONSTANTS_H
#define PROCEDURAL_UNIFORM_TIME 200
#define PROCEDURAL_UNIFORM_DATE 201
#define PROCEDURAL_UNIFORM_FRAME_COUNT 202
#define PROCEDURAL_UNIFORM_POSITION 203
#define PROCEDURAL_UNIFORM_SCALE 204
#define PROCEDURAL_UNIFORM_ORIENTATION 205
// Additional space because orientation will take up 3-4 locations, being a matrix
#define PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION 209
#define PROCEDURAL_UNIFORM_CUSTOM 220
#define PROCEDURAL_TEXTURE_CHANNEL0 0
@ -33,15 +25,9 @@
namespace procedural { namespace slot {
namespace uniform {
enum Uniform {
Time = PROCEDURAL_UNIFORM_TIME,
Date = PROCEDURAL_UNIFORM_DATE,
FrameCount = PROCEDURAL_UNIFORM_FRAME_COUNT,
Position = PROCEDURAL_UNIFORM_POSITION,
Scale = PROCEDURAL_UNIFORM_SCALE,
Orientation = PROCEDURAL_UNIFORM_ORIENTATION,
ChannelResolution = PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION,
Custom = PROCEDURAL_UNIFORM_CUSTOM,
};
}

View file

@ -12,13 +12,13 @@
//
<@include graphics/ShaderConstants.h@>
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
struct Skybox {
vec4 color;
};
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
Skybox skybox;
};
@ -28,9 +28,13 @@ layout(location=0) out vec4 _fragColor;
<@include procedural/ProceduralCommon.slh@>
#line 1001
//PROCEDURAL_BLOCK
//PROCEDURAL_BLOCK_BEGIN
vec3 getSkyboxColor() {
return vec3(abs(sin(iGlobalTime / 5.0)), 1.0, 0.0);
}
//PROCEDURAL_BLOCK_END
#line 2033
#line 2038
void main(void) {
vec3 color = getSkyboxColor();
// Protect from NaNs and negative values

View file

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

View file

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

View file

@ -12,11 +12,11 @@
<@include BloomApply.shared.slh@>
<@include render-utils/ShaderConstants.h@>
layout(binding=0) uniform sampler2D blurMap0;
layout(binding=1) uniform sampler2D blurMap1;
layout(binding=2) uniform sampler2D blurMap2;
LAYOUT(binding=0) uniform sampler2D blurMap0;
LAYOUT(binding=1) uniform sampler2D blurMap1;
LAYOUT(binding=2) uniform sampler2D blurMap2;
layout(std140, binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
Parameters parameters;
};

View file

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

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));
if (customFile.open(QIODevice::ReadOnly)) {
return customFile.readAll().toStdString();
@ -270,7 +270,7 @@ DebugDeferredBuffer::~DebugDeferredBuffer() {
}
}
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string customFile) {
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, const std::string& customFile) {
switch (mode) {
case AlbedoMode:
return DEFAULT_ALBEDO_SHADER;
@ -334,7 +334,7 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
return std::string();
}
bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile) const {
bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, const std::string& customFile) const {
if (mode != CustomMode) {
return !_pipelines[mode];
}
@ -351,19 +351,17 @@ bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile)
return true;
}
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::string customFile) {
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, const std::string& customFile) {
if (pipelineNeedsUpdate(mode, customFile)) {
static const auto FRAGMENT_SHADER_SOURCE =
gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource();
static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER_SOURCE.getCode().find(SOURCE_PLACEHOLDER);
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO, "Could not find source placeholder");
static_assert(shader::render_utils::program::debug_deferred_buffer != 0, "Validate debug deferred program");
auto bakedFragmentShader = FRAGMENT_SHADER_SOURCE.getCode();
bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), getShaderSourceCode(mode, customFile));
static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
shader::Source resolvedFragmentSource;
resolvedFragmentSource = shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
resolvedFragmentSource.replacements[REPLACEMENT_MARKER] = getShaderSourceCode(mode, customFile);
const auto vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
const auto ps = gpu::Shader::createPixel({ bakedFragmentShader, FRAGMENT_SHADER_SOURCE.getReflection() });
const auto ps = gpu::Shader::createPixel(resolvedFragmentSource);
const auto program = gpu::Shader::createProgram(vs, ps);
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>());

View file

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

View file

@ -17,23 +17,23 @@
// See DeferredShader_MapSlot in DeferredLightingEffect.cpp for constants
// the albedo texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_COLOR) uniform sampler2D albedoMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_COLOR) uniform sampler2D albedoMap;
// the normal texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL) uniform sampler2D normalMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL) uniform sampler2D normalMap;
// the specular texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_SPECULAR) uniform sampler2D specularMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_SPECULAR) uniform sampler2D specularMap;
// the depth texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap;
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
// the obscurance texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_OBSCURANCE) uniform sampler2D obscuranceMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_OBSCURANCE) uniform sampler2D obscuranceMap;
// the lighting texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING) uniform sampler2D lightingMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING) uniform sampler2D lightingMap;
struct DeferredFragment {
@ -170,14 +170,14 @@ DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform
<@func declareDeferredCurvature()@>
// the curvature texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE) uniform sampler2D curvatureMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE) uniform sampler2D curvatureMap;
vec4 fetchCurvature(vec2 texcoord) {
return texture(curvatureMap, texcoord);
}
// the curvature texture
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE) uniform sampler2D diffusedCurvatureMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE) uniform sampler2D diffusedCurvatureMap;
vec4 fetchDiffusedCurvature(vec2 texcoord) {
return texture(diffusedCurvatureMap, texcoord);

View file

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

View file

@ -24,7 +24,7 @@ struct CameraCorrection {
mat4 _prevViewInverse;
};
layout(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
LAYOUT(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
CameraCorrection cameraCorrection;
};
@ -42,7 +42,7 @@ struct DeferredFrameTransform {
mat4 _invProjectionUnJittered[2];
};
layout(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer {
LAYOUT(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer {
DeferredFrameTransform frameTransform;
};

View file

@ -19,12 +19,12 @@
<@include FadeObjectParams.shared.slh@>
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h
layout(std140, binding=RENDER_UTILS_BUFFER_FADE_PARAMS) uniform fadeParametersBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_FADE_PARAMS) uniform fadeParametersBuffer {
FadeParameters fadeParameters[CATEGORY_COUNT];
};
// See ShapePipeline::Slot::MAP in ShapePipeline.h
layout(binding=RENDER_UTILS_TEXTURE_FADE_MASK) uniform sampler2D fadeMaskMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_FADE_MASK) uniform sampler2D fadeMaskMap;
vec3 getNoiseInverseSize(int category) {
return fadeParameters[category]._noiseInvSizeAndLevel.xyz;
@ -117,7 +117,7 @@ void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) {
<@func declareFadeFragmentUniform()@>
layout(std140, binding=RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS) uniform fadeObjectParametersBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS) uniform fadeObjectParametersBuffer {
FadeObjectParams fadeObjectParams;
};

View file

@ -21,7 +21,7 @@
<@include Haze.slh@>
layout(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;
vec4 unpackPositionFromZeye(vec2 texcoord) {
float Zeye = -texture(linearDepthMap, texcoord).x;

View file

@ -39,7 +39,7 @@ struct HazeParams {
};
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h
layout(std140, binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
HazeParams hazeParams;
};

View file

@ -15,12 +15,12 @@
<@include Highlight_shared.slh@>
layout(std140, binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuffer {
HighlightParameters params;
};
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap;
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap;
layout(location=0) in vec2 varTexCoord0;
layout(location=0) out vec4 outFragColor;

View file

@ -402,36 +402,31 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
}
void DebugHighlight::initializePipelines() {
static const auto FRAGMENT_SHADER_SOURCE = gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource();
static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER_SOURCE.getCode().find(SOURCE_PLACEHOLDER);
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO,
"Could not find source placeholder");
auto state = std::make_shared<gpu::State>();
state->setDepthTest(gpu::State::DepthTest(false, false));
state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
state->setColorWriteMask(true, true, true, true);
const auto vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
// Depth shader
{
static const std::string DEPTH_SHADER{ R"SHADER(
static const std::string DEPTH_SHADER{ R"SHADER(
vec4 getFragmentColor() {
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
Zdb = 1.0-(1.0-Zdb)*100;
return vec4(Zdb, Zdb, Zdb, 1.0);
}
)SHADER" };
static const auto& vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
auto fragmentShader = FRAGMENT_SHADER_SOURCE.getCode();
fragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), DEPTH_SHADER);
const auto ps = gpu::Shader::createPixel({ fragmentShader, FRAGMENT_SHADER_SOURCE.getReflection() });
const auto program = gpu::Shader::createProgram(vs, ps);
_depthPipeline = gpu::Pipeline::create(program, state);
}
gpu::Shader::Source fragmentSource;
fragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
fragmentSource.replacements[REPLACEMENT_MARKER] = DEPTH_SHADER;
const auto ps = gpu::Shader::createPixel(fragmentSource);
const auto program = gpu::Shader::createProgram(vs, ps);
auto state = std::make_shared<gpu::State>();
state->setDepthTest(gpu::State::DepthTest(false, false));
state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
state->setColorWriteMask(true, true, true, true);
_depthPipeline = gpu::Pipeline::create(program, state);
}
const gpu::PipelinePointer& DebugHighlight::getDepthPipeline() {

View file

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

View file

@ -9,7 +9,7 @@
<@include render-utils/ShaderConstants.h@>
<@func declareSkyboxMap()@>
// declareSkyboxMap
layout(binding=RENDER_UTILS_TEXTURE_SKYBOX) uniform samplerCube skyboxMap;
LAYOUT(binding=RENDER_UTILS_TEXTURE_SKYBOX) uniform samplerCube skyboxMap;
vec4 evalSkyboxLight(vec3 direction, float lod) {
// textureQueryLevels is not available until #430, so we require explicit lod

View file

@ -24,7 +24,7 @@ struct FrustumGrid {
mat4 eyeToWorldMat;
};
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer {
FrustumGrid frustumGrid;
};
@ -60,11 +60,11 @@ float projection_getFar(mat4 projection) {
#define GRID_FETCH_BUFFER(i) i!>
<@endif@>
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer {
GRID_INDEX_TYPE _clusterGridTable[GRID_NUM_ELEMENTS];
};
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer {
GRID_INDEX_TYPE _clusterGridContent[GRID_NUM_ELEMENTS];
};

View file

@ -23,7 +23,7 @@ struct LightingModel {
};
// See DeferredShader_BufferSlot in DeferredLightingEffect.cpp
layout(binding=RENDER_UTILS_BUFFER_LIGHT_MODEL) uniform lightingModelBuffer{
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_MODEL) uniform lightingModelBuffer{
LightingModel lightingModel;
};

View file

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

View file

@ -15,7 +15,7 @@
<@func declareBeckmannSpecular()@>
layout(binding=RENDER_UTILS_TEXTURE_SSSC_SPECULAR_BECKMANN) uniform sampler2D scatteringSpecularBeckmann;
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_SPECULAR_BECKMANN) uniform sampler2D scatteringSpecularBeckmann;
float fetchSpecularBeckmann(float ndoth, float roughness) {
return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);

View file

@ -19,7 +19,7 @@
#define SHADOW_SCREEN_SPACE_DITHER 1
// the shadow texture
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
// Sample the shadowMap with PCF (built-in)
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {

View file

@ -13,7 +13,7 @@
<@include Shadows_shared.slh@>
layout(std140, binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer {
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer {
ShadowParameters shadow;
};

View file

@ -18,7 +18,7 @@
const int MAX_CLUSTERS = 128;
const int INDICES_PER_VERTEX = 4;
layout(std140, binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
LAYOUT_STD140(binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
mat4 clusterMatrices[MAX_CLUSTERS];
};

View file

@ -421,6 +421,10 @@ void DebugSubsurfaceScattering::configure(const Config& config) {
_showSpecularTable = config.showSpecularTable;
_showCursorPixel = config.showCursorPixel;
_debugCursorTexcoord = config.debugCursorTexcoord;
if (!_debugParams) {
_debugParams = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
}
_debugParams->setSubData(0, _debugCursorTexcoord);
}
@ -479,6 +483,10 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
assert(lightStage);
// const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0);
const auto light = lightStage->getLight(0);
if (!_debugParams) {
_debugParams = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
_debugParams->setSubData(0, _debugCursorTexcoord);
}
gpu::doInBatch("DebugSubsurfaceScattering::run", args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
@ -521,9 +529,7 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
batch.setResourceTexture(ru::Texture::DeferredNormal, deferredFramebuffer->getDeferredNormalTexture());
batch.setResourceTexture(ru::Texture::DeferredColor, deferredFramebuffer->getDeferredColorTexture());
batch.setResourceTexture(ru::Texture::DeferredDepth, linearDepthTexture);
batch._glUniform2f(gpu::slot::uniform::Extra0, _debugCursorTexcoord.x, _debugCursorTexcoord.y);
batch.setUniformBuffer(1, _debugParams);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
}

View file

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

View file

@ -56,7 +56,7 @@ vec3 generateProfile(vec2 uv) {
<@func declareSubsurfaceScatteringProfileMap()@>
layout(binding=RENDER_UTILS_TEXTURE_SSSC_PROFILE) uniform sampler2D scatteringProfile;
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_PROFILE) uniform sampler2D scatteringProfile;
vec3 scatter(float r) {
return texture(scatteringProfile, vec2(r * 0.5, 0.5)).rgb;
@ -104,7 +104,7 @@ vec3 integrate(float cosTheta, float skinRadius) {
<@func declareSubsurfaceScatteringResource()@>
layout(binding=RENDER_UTILS_TEXTURE_SSSC_LUT) uniform sampler2D scatteringLUT;
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_LUT) uniform sampler2D scatteringLUT;
vec3 fetchBRDF(float LdotN, float curvature) {
return texture(scatteringLUT, vec2( clamp(LdotN * 0.5 + 0.5, 0.0, 1.0), clamp(2.0 * curvature, 0.0, 1.0))).xyz;
@ -124,7 +124,7 @@ struct ScatteringParameters {
vec4 debugFlags;
};
layout(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
LAYOUT(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
ScatteringParameters parameters;
};

View file

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

View file

@ -16,8 +16,8 @@
<@include gpu/Color.slh@>
<$declareColorWheel()$>
layout(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
LAYOUT(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
<@include ShadowCore.slh@>
@ -36,7 +36,13 @@ float curvatureAO(float k) {
layout(location=0) in vec2 uv;
layout(location=0) out vec4 outFragColor;
//SOURCE_PLACEHOLDER
//SOURCE_PLACEHOLDER_BEGIN
vec4 getFragmentColor() {
DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);
return vec4(pow(frag.albedo, vec3(1.0 / 2.2)), 1.0);
}
//SOURCE_PLACEHOLDER_END
void main(void) {
outFragColor = getFragmentColor();

View file

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

View file

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

View file

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

View file

@ -14,8 +14,10 @@
<@include DefaultMaterials.slh@>
<@include ForwardGlobalLight.slh@>
<$declareEvalSkyboxGlobalColor()$>
<@include gpu/Transform.slh@>
<$declareEvalSkyboxGlobalColor()$>
<$declareStandardCameraTransform()$>
// the interpolated normal
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
@ -35,12 +37,6 @@ layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
layout(location=0) out vec4 _fragColor0;
<@include procedural/ProceduralCommon.slh@>
#line 1001
//PROCEDURAL_BLOCK
#line 2030
void main(void) {
vec3 normal = normalize(_normalWS.xyz);
vec3 diffuse = _color.rgb;
@ -48,45 +44,18 @@ void main(void) {
float shininess = DEFAULT_SHININESS;
float emissiveAmount = 0.0;
#ifdef PROCEDURAL
#ifdef PROCEDURAL_V1
diffuse = getProceduralColor().rgb;
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
//diffuse = pow(diffuse, vec3(2.2));
emissiveAmount = 1.0;
#else
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
#endif
#endif
TransformCamera cam = getTransformCamera();
vec3 fragPosition = _positionES.xyz;
if (emissiveAmount > 0.0) {
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normal,
diffuse,
specular,
DEFAULT_METALLIC,
max(0.0, 1.0 - shininess / 128.0)),
1.0);
} else {
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normal,
diffuse,
DEFAULT_FRESNEL,
length(specular),
max(0.0, 1.0 - shininess / 128.0)),
1.0);
}
_fragColor0 = vec4(evalSkyboxGlobalColor(
cam._viewInverse,
1.0,
DEFAULT_OCCLUSION,
fragPosition,
normal,
diffuse,
DEFAULT_FRESNEL,
length(specular),
max(0.0, 1.0 - shininess / 128.0)),
1.0);
}

View file

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

View file

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

View file

@ -20,7 +20,7 @@
layout(location=0) out vec4 _fragColor0;
// the albedo texture
layout(binding=0) uniform sampler2D originalTexture;
LAYOUT(binding=0) uniform sampler2D originalTexture;
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;

View file

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

Some files were not shown because too many files have changed in this diff Show more