another try
This commit is contained in:
@@ -1,121 +1,121 @@
|
||||
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(FIDELITYFX_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/externals/FidelityFX-FSR/ffx-fsr)
|
||||
|
||||
set(GLSL_INCLUDES
|
||||
fidelityfx_fsr.comp
|
||||
${FIDELITYFX_INCLUDE_DIR}/ffx_a.h
|
||||
${FIDELITYFX_INCLUDE_DIR}/ffx_fsr1.h
|
||||
)
|
||||
|
||||
set(SHADER_FILES
|
||||
astc_decoder.comp
|
||||
block_linear_unswizzle_2d.comp
|
||||
block_linear_unswizzle_3d.comp
|
||||
convert_abgr8_to_d24s8.frag
|
||||
convert_d24s8_to_abgr8.frag
|
||||
convert_depth_to_float.frag
|
||||
convert_float_to_depth.frag
|
||||
convert_s8d24_to_abgr8.frag
|
||||
full_screen_triangle.vert
|
||||
fxaa.frag
|
||||
fxaa.vert
|
||||
opengl_convert_s8d24.comp
|
||||
opengl_copy_bc4.comp
|
||||
opengl_present.frag
|
||||
opengl_present.vert
|
||||
opengl_present_scaleforce.frag
|
||||
pitch_unswizzle.comp
|
||||
present_bicubic.frag
|
||||
present_gaussian.frag
|
||||
vulkan_blit_color_float.frag
|
||||
vulkan_blit_depth_stencil.frag
|
||||
vulkan_fidelityfx_fsr_easu_fp16.comp
|
||||
vulkan_fidelityfx_fsr_easu_fp32.comp
|
||||
vulkan_fidelityfx_fsr_rcas_fp16.comp
|
||||
vulkan_fidelityfx_fsr_rcas_fp32.comp
|
||||
vulkan_present.frag
|
||||
vulkan_present.vert
|
||||
vulkan_present_scaleforce_fp16.frag
|
||||
vulkan_present_scaleforce_fp32.frag
|
||||
vulkan_quad_indexed.comp
|
||||
vulkan_uint8.comp
|
||||
)
|
||||
|
||||
find_program(GLSLANGVALIDATOR "glslangValidator")
|
||||
if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND")
|
||||
message(FATAL_ERROR "Required program `glslangValidator` not found.")
|
||||
endif()
|
||||
|
||||
set(GLSL_FLAGS "")
|
||||
set(QUIET_FLAG "--quiet")
|
||||
|
||||
set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders)
|
||||
set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
|
||||
|
||||
set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in)
|
||||
set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake)
|
||||
|
||||
# Check if `--quiet` is available on host's glslangValidator version
|
||||
# glslangValidator prints to STDERR iff an unrecognized flag is passed to it
|
||||
execute_process(
|
||||
COMMAND
|
||||
${GLSLANGVALIDATOR} ${QUIET_FLAG}
|
||||
ERROR_VARIABLE
|
||||
GLSLANG_ERROR
|
||||
# STDOUT variable defined to silence unnecessary output during CMake configuration
|
||||
OUTPUT_VARIABLE
|
||||
GLSLANG_OUTPUT
|
||||
)
|
||||
|
||||
if (NOT GLSLANG_ERROR STREQUAL "")
|
||||
message(WARNING "Refusing to use unavailable flag `${QUIET_FLAG}` on `${GLSLANGVALIDATOR}`")
|
||||
set(QUIET_FLAG "")
|
||||
endif()
|
||||
|
||||
foreach(FILENAME IN ITEMS ${SHADER_FILES})
|
||||
string(REPLACE "." "_" SHADER_NAME ${FILENAME})
|
||||
set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME})
|
||||
# Skip generating source headers on Vulkan exclusive files
|
||||
if (NOT ${FILENAME} MATCHES "vulkan.*")
|
||||
set(SOURCE_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${SOURCE_HEADER_FILE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -P ${HEADER_GENERATOR} ${SOURCE_FILE} ${SOURCE_HEADER_FILE} ${INPUT_FILE}
|
||||
MAIN_DEPENDENCY
|
||||
${SOURCE_FILE}
|
||||
DEPENDS
|
||||
${INPUT_FILE}
|
||||
# HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified
|
||||
)
|
||||
set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE})
|
||||
endif()
|
||||
# Skip compiling to SPIR-V OpenGL exclusive files
|
||||
if (NOT ${FILENAME} MATCHES "opengl.*")
|
||||
string(TOUPPER ${SHADER_NAME}_SPV SPIRV_VARIABLE_NAME)
|
||||
set(SPIRV_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}_spv.h)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${SPIRV_HEADER_FILE}
|
||||
COMMAND
|
||||
${GLSLANGVALIDATOR} -V ${QUIET_FLAG} -I"${FIDELITYFX_INCLUDE_DIR}" ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE}
|
||||
MAIN_DEPENDENCY
|
||||
${SOURCE_FILE}
|
||||
)
|
||||
set(SHADER_HEADERS ${SHADER_HEADERS} ${SPIRV_HEADER_FILE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(SHADER_SOURCES ${SHADER_FILES})
|
||||
list(APPEND SHADER_SOURCES ${GLSL_INCLUDES})
|
||||
|
||||
add_custom_target(host_shaders
|
||||
DEPENDS
|
||||
${SHADER_HEADERS}
|
||||
SOURCES
|
||||
${SHADER_SOURCES}
|
||||
)
|
||||
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(FIDELITYFX_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/externals/FidelityFX-FSR/ffx-fsr)
|
||||
|
||||
set(GLSL_INCLUDES
|
||||
fidelityfx_fsr.comp
|
||||
${FIDELITYFX_INCLUDE_DIR}/ffx_a.h
|
||||
${FIDELITYFX_INCLUDE_DIR}/ffx_fsr1.h
|
||||
)
|
||||
|
||||
set(SHADER_FILES
|
||||
astc_decoder.comp
|
||||
block_linear_unswizzle_2d.comp
|
||||
block_linear_unswizzle_3d.comp
|
||||
convert_abgr8_to_d24s8.frag
|
||||
convert_d24s8_to_abgr8.frag
|
||||
convert_depth_to_float.frag
|
||||
convert_float_to_depth.frag
|
||||
convert_s8d24_to_abgr8.frag
|
||||
full_screen_triangle.vert
|
||||
fxaa.frag
|
||||
fxaa.vert
|
||||
opengl_convert_s8d24.comp
|
||||
opengl_copy_bc4.comp
|
||||
opengl_present.frag
|
||||
opengl_present.vert
|
||||
opengl_present_scaleforce.frag
|
||||
pitch_unswizzle.comp
|
||||
present_bicubic.frag
|
||||
present_gaussian.frag
|
||||
vulkan_blit_color_float.frag
|
||||
vulkan_blit_depth_stencil.frag
|
||||
vulkan_fidelityfx_fsr_easu_fp16.comp
|
||||
vulkan_fidelityfx_fsr_easu_fp32.comp
|
||||
vulkan_fidelityfx_fsr_rcas_fp16.comp
|
||||
vulkan_fidelityfx_fsr_rcas_fp32.comp
|
||||
vulkan_present.frag
|
||||
vulkan_present.vert
|
||||
vulkan_present_scaleforce_fp16.frag
|
||||
vulkan_present_scaleforce_fp32.frag
|
||||
vulkan_quad_indexed.comp
|
||||
vulkan_uint8.comp
|
||||
)
|
||||
|
||||
find_program(GLSLANGVALIDATOR "glslangValidator")
|
||||
if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND")
|
||||
message(FATAL_ERROR "Required program `glslangValidator` not found.")
|
||||
endif()
|
||||
|
||||
set(GLSL_FLAGS "")
|
||||
set(QUIET_FLAG "--quiet")
|
||||
|
||||
set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders)
|
||||
set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
|
||||
|
||||
set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in)
|
||||
set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake)
|
||||
|
||||
# Check if `--quiet` is available on host's glslangValidator version
|
||||
# glslangValidator prints to STDERR iff an unrecognized flag is passed to it
|
||||
execute_process(
|
||||
COMMAND
|
||||
${GLSLANGVALIDATOR} ${QUIET_FLAG}
|
||||
ERROR_VARIABLE
|
||||
GLSLANG_ERROR
|
||||
# STDOUT variable defined to silence unnecessary output during CMake configuration
|
||||
OUTPUT_VARIABLE
|
||||
GLSLANG_OUTPUT
|
||||
)
|
||||
|
||||
if (NOT GLSLANG_ERROR STREQUAL "")
|
||||
message(WARNING "Refusing to use unavailable flag `${QUIET_FLAG}` on `${GLSLANGVALIDATOR}`")
|
||||
set(QUIET_FLAG "")
|
||||
endif()
|
||||
|
||||
foreach(FILENAME IN ITEMS ${SHADER_FILES})
|
||||
string(REPLACE "." "_" SHADER_NAME ${FILENAME})
|
||||
set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME})
|
||||
# Skip generating source headers on Vulkan exclusive files
|
||||
if (NOT ${FILENAME} MATCHES "vulkan.*")
|
||||
set(SOURCE_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${SOURCE_HEADER_FILE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -P ${HEADER_GENERATOR} ${SOURCE_FILE} ${SOURCE_HEADER_FILE} ${INPUT_FILE}
|
||||
MAIN_DEPENDENCY
|
||||
${SOURCE_FILE}
|
||||
DEPENDS
|
||||
${INPUT_FILE}
|
||||
# HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified
|
||||
)
|
||||
set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE})
|
||||
endif()
|
||||
# Skip compiling to SPIR-V OpenGL exclusive files
|
||||
if (NOT ${FILENAME} MATCHES "opengl.*")
|
||||
string(TOUPPER ${SHADER_NAME}_SPV SPIRV_VARIABLE_NAME)
|
||||
set(SPIRV_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}_spv.h)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${SPIRV_HEADER_FILE}
|
||||
COMMAND
|
||||
${GLSLANGVALIDATOR} -V ${QUIET_FLAG} -I"${FIDELITYFX_INCLUDE_DIR}" ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE}
|
||||
MAIN_DEPENDENCY
|
||||
${SOURCE_FILE}
|
||||
)
|
||||
set(SHADER_HEADERS ${SHADER_HEADERS} ${SPIRV_HEADER_FILE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(SHADER_SOURCES ${SHADER_FILES})
|
||||
list(APPEND SHADER_SOURCES ${GLSL_INCLUDES})
|
||||
|
||||
add_custom_target(host_shaders
|
||||
DEPENDS
|
||||
${SHADER_HEADERS}
|
||||
SOURCES
|
||||
${SHADER_SOURCES}
|
||||
)
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
# SPDX-FileCopyrightText: 2020 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(SOURCE_FILE ${CMAKE_ARGV3})
|
||||
set(HEADER_FILE ${CMAKE_ARGV4})
|
||||
set(INPUT_FILE ${CMAKE_ARGV5})
|
||||
|
||||
get_filename_component(CONTENTS_NAME ${SOURCE_FILE} NAME)
|
||||
string(REPLACE "." "_" CONTENTS_NAME ${CONTENTS_NAME})
|
||||
string(TOUPPER ${CONTENTS_NAME} CONTENTS_NAME)
|
||||
|
||||
FILE(READ ${SOURCE_FILE} line_contents)
|
||||
|
||||
# Replace double quotes with single quotes,
|
||||
# as double quotes will be used to wrap the lines
|
||||
STRING(REGEX REPLACE "\"" "'" line_contents "${line_contents}")
|
||||
|
||||
# CMake separates list elements with semicolons, but semicolons
|
||||
# are used extensively in the shader code.
|
||||
# Replace with a temporary marker, to be reverted later.
|
||||
STRING(REGEX REPLACE ";" "{{SEMICOLON}}" line_contents "${line_contents}")
|
||||
|
||||
# Make every line an individual element in the CMake list.
|
||||
STRING(REGEX REPLACE "\n" ";" line_contents "${line_contents}")
|
||||
|
||||
# Build the shader string, wrapping each line in double quotes.
|
||||
foreach(line IN LISTS line_contents)
|
||||
string(CONCAT CONTENTS "${CONTENTS}" \"${line}\\n\"\n)
|
||||
endforeach()
|
||||
|
||||
# Revert the original semicolons in the source.
|
||||
STRING(REGEX REPLACE "{{SEMICOLON}}" ";" CONTENTS "${CONTENTS}")
|
||||
|
||||
get_filename_component(OUTPUT_DIR ${HEADER_FILE} DIRECTORY)
|
||||
make_directory(${OUTPUT_DIR})
|
||||
configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY)
|
||||
# SPDX-FileCopyrightText: 2020 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(SOURCE_FILE ${CMAKE_ARGV3})
|
||||
set(HEADER_FILE ${CMAKE_ARGV4})
|
||||
set(INPUT_FILE ${CMAKE_ARGV5})
|
||||
|
||||
get_filename_component(CONTENTS_NAME ${SOURCE_FILE} NAME)
|
||||
string(REPLACE "." "_" CONTENTS_NAME ${CONTENTS_NAME})
|
||||
string(TOUPPER ${CONTENTS_NAME} CONTENTS_NAME)
|
||||
|
||||
FILE(READ ${SOURCE_FILE} line_contents)
|
||||
|
||||
# Replace double quotes with single quotes,
|
||||
# as double quotes will be used to wrap the lines
|
||||
STRING(REGEX REPLACE "\"" "'" line_contents "${line_contents}")
|
||||
|
||||
# CMake separates list elements with semicolons, but semicolons
|
||||
# are used extensively in the shader code.
|
||||
# Replace with a temporary marker, to be reverted later.
|
||||
STRING(REGEX REPLACE ";" "{{SEMICOLON}}" line_contents "${line_contents}")
|
||||
|
||||
# Make every line an individual element in the CMake list.
|
||||
STRING(REGEX REPLACE "\n" ";" line_contents "${line_contents}")
|
||||
|
||||
# Build the shader string, wrapping each line in double quotes.
|
||||
foreach(line IN LISTS line_contents)
|
||||
string(CONCAT CONTENTS "${CONTENTS}" \"${line}\\n\"\n)
|
||||
endforeach()
|
||||
|
||||
# Revert the original semicolons in the source.
|
||||
STRING(REGEX REPLACE "{{SEMICOLON}}" ";" CONTENTS "${CONTENTS}")
|
||||
|
||||
get_filename_component(OUTPUT_DIR ${HEADER_FILE} DIRECTORY)
|
||||
make_directory(${OUTPUT_DIR})
|
||||
configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,121 +1,121 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 2
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#else
|
||||
#define HAS_EXTENDED_TYPES 0
|
||||
#endif
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 0
|
||||
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) uvec3 origin;
|
||||
UNIFORM(1) ivec3 destination;
|
||||
UNIFORM(2) uint bytes_per_block_log2;
|
||||
UNIFORM(3) uint layer_stride;
|
||||
UNIFORM(4) uint block_size;
|
||||
UNIFORM(5) uint x_shift;
|
||||
UNIFORM(6) uint block_height;
|
||||
UNIFORM(7) uint block_height_mask;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
||||
uint swizzle_table[];
|
||||
};
|
||||
|
||||
#if HAS_EXTENDED_TYPES
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||
#endif
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; };
|
||||
|
||||
layout(binding = BINDING_OUTPUT_IMAGE) uniform writeonly uimage2DArray output_image;
|
||||
|
||||
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
|
||||
|
||||
const uint GOB_SIZE_X = 64;
|
||||
const uint GOB_SIZE_Y = 8;
|
||||
const uint GOB_SIZE_Z = 1;
|
||||
const uint GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
|
||||
|
||||
const uint GOB_SIZE_X_SHIFT = 6;
|
||||
const uint GOB_SIZE_Y_SHIFT = 3;
|
||||
const uint GOB_SIZE_Z_SHIFT = 0;
|
||||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
|
||||
|
||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
||||
|
||||
uint SwizzleOffset(uvec2 pos) {
|
||||
pos = pos & SWIZZLE_MASK;
|
||||
return swizzle_table[pos.y * 64 + pos.x];
|
||||
}
|
||||
|
||||
uvec4 ReadTexel(uint offset) {
|
||||
switch (bytes_per_block_log2) {
|
||||
#if HAS_EXTENDED_TYPES
|
||||
case 0:
|
||||
return uvec4(u8data[offset], 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(u16data[offset / 2], 0, 0, 0);
|
||||
#else
|
||||
case 0:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
|
||||
#endif
|
||||
case 2:
|
||||
return uvec4(u32data[offset / 4], 0, 0, 0);
|
||||
case 3:
|
||||
return uvec4(u64data[offset / 8], 0, 0);
|
||||
case 4:
|
||||
return u128data[offset / 16];
|
||||
}
|
||||
return uvec4(0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec3 pos = gl_GlobalInvocationID + origin;
|
||||
pos.x <<= bytes_per_block_log2;
|
||||
|
||||
// Read as soon as possible due to its latency
|
||||
const uint swizzle = SwizzleOffset(pos.xy);
|
||||
|
||||
const uint block_y = pos.y >> GOB_SIZE_Y_SHIFT;
|
||||
|
||||
uint offset = 0;
|
||||
offset += pos.z * layer_stride;
|
||||
offset += (block_y >> block_height) * block_size;
|
||||
offset += (block_y & block_height_mask) << GOB_SIZE_SHIFT;
|
||||
offset += (pos.x >> GOB_SIZE_X_SHIFT) << x_shift;
|
||||
offset += swizzle;
|
||||
|
||||
const uvec4 texel = ReadTexel(offset);
|
||||
const ivec3 coord = ivec3(gl_GlobalInvocationID) + destination;
|
||||
imageStore(output_image, coord, texel);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 2
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#else
|
||||
#define HAS_EXTENDED_TYPES 0
|
||||
#endif
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 0
|
||||
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) uvec3 origin;
|
||||
UNIFORM(1) ivec3 destination;
|
||||
UNIFORM(2) uint bytes_per_block_log2;
|
||||
UNIFORM(3) uint layer_stride;
|
||||
UNIFORM(4) uint block_size;
|
||||
UNIFORM(5) uint x_shift;
|
||||
UNIFORM(6) uint block_height;
|
||||
UNIFORM(7) uint block_height_mask;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
||||
uint swizzle_table[];
|
||||
};
|
||||
|
||||
#if HAS_EXTENDED_TYPES
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||
#endif
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; };
|
||||
|
||||
layout(binding = BINDING_OUTPUT_IMAGE) uniform writeonly uimage2DArray output_image;
|
||||
|
||||
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
|
||||
|
||||
const uint GOB_SIZE_X = 64;
|
||||
const uint GOB_SIZE_Y = 8;
|
||||
const uint GOB_SIZE_Z = 1;
|
||||
const uint GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
|
||||
|
||||
const uint GOB_SIZE_X_SHIFT = 6;
|
||||
const uint GOB_SIZE_Y_SHIFT = 3;
|
||||
const uint GOB_SIZE_Z_SHIFT = 0;
|
||||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
|
||||
|
||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
||||
|
||||
uint SwizzleOffset(uvec2 pos) {
|
||||
pos = pos & SWIZZLE_MASK;
|
||||
return swizzle_table[pos.y * 64 + pos.x];
|
||||
}
|
||||
|
||||
uvec4 ReadTexel(uint offset) {
|
||||
switch (bytes_per_block_log2) {
|
||||
#if HAS_EXTENDED_TYPES
|
||||
case 0:
|
||||
return uvec4(u8data[offset], 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(u16data[offset / 2], 0, 0, 0);
|
||||
#else
|
||||
case 0:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
|
||||
#endif
|
||||
case 2:
|
||||
return uvec4(u32data[offset / 4], 0, 0, 0);
|
||||
case 3:
|
||||
return uvec4(u64data[offset / 8], 0, 0);
|
||||
case 4:
|
||||
return u128data[offset / 16];
|
||||
}
|
||||
return uvec4(0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec3 pos = gl_GlobalInvocationID + origin;
|
||||
pos.x <<= bytes_per_block_log2;
|
||||
|
||||
// Read as soon as possible due to its latency
|
||||
const uint swizzle = SwizzleOffset(pos.xy);
|
||||
|
||||
const uint block_y = pos.y >> GOB_SIZE_Y_SHIFT;
|
||||
|
||||
uint offset = 0;
|
||||
offset += pos.z * layer_stride;
|
||||
offset += (block_y >> block_height) * block_size;
|
||||
offset += (block_y & block_height_mask) << GOB_SIZE_SHIFT;
|
||||
offset += (pos.x >> GOB_SIZE_X_SHIFT) << x_shift;
|
||||
offset += swizzle;
|
||||
|
||||
const uvec4 texel = ReadTexel(offset);
|
||||
const ivec3 coord = ivec3(gl_GlobalInvocationID) + destination;
|
||||
imageStore(output_image, coord, texel);
|
||||
}
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 2
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#else
|
||||
#define HAS_EXTENDED_TYPES 0
|
||||
#endif
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 0
|
||||
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) uvec3 origin;
|
||||
UNIFORM(1) ivec3 destination;
|
||||
UNIFORM(2) uint bytes_per_block_log2;
|
||||
UNIFORM(3) uint slice_size;
|
||||
UNIFORM(4) uint block_size;
|
||||
UNIFORM(5) uint x_shift;
|
||||
UNIFORM(6) uint block_height;
|
||||
UNIFORM(7) uint block_height_mask;
|
||||
UNIFORM(8) uint block_depth;
|
||||
UNIFORM(9) uint block_depth_mask;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
||||
uint swizzle_table[];
|
||||
};
|
||||
|
||||
#if HAS_EXTENDED_TYPES
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||
#endif
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; };
|
||||
|
||||
layout(binding = BINDING_OUTPUT_IMAGE) uniform writeonly uimage3D output_image;
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
const uint GOB_SIZE_X = 64;
|
||||
const uint GOB_SIZE_Y = 8;
|
||||
const uint GOB_SIZE_Z = 1;
|
||||
const uint GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
|
||||
|
||||
const uint GOB_SIZE_X_SHIFT = 6;
|
||||
const uint GOB_SIZE_Y_SHIFT = 3;
|
||||
const uint GOB_SIZE_Z_SHIFT = 0;
|
||||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
|
||||
|
||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
||||
|
||||
uint SwizzleOffset(uvec2 pos) {
|
||||
pos = pos & SWIZZLE_MASK;
|
||||
return swizzle_table[pos.y * 64 + pos.x];
|
||||
}
|
||||
|
||||
uvec4 ReadTexel(uint offset) {
|
||||
switch (bytes_per_block_log2) {
|
||||
#if HAS_EXTENDED_TYPES
|
||||
case 0:
|
||||
return uvec4(u8data[offset], 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(u16data[offset / 2], 0, 0, 0);
|
||||
#else
|
||||
case 0:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
|
||||
#endif
|
||||
case 2:
|
||||
return uvec4(u32data[offset / 4], 0, 0, 0);
|
||||
case 3:
|
||||
return uvec4(u64data[offset / 8], 0, 0);
|
||||
case 4:
|
||||
return u128data[offset / 16];
|
||||
}
|
||||
return uvec4(0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec3 pos = gl_GlobalInvocationID + origin;
|
||||
pos.x <<= bytes_per_block_log2;
|
||||
|
||||
// Read as soon as possible due to its latency
|
||||
const uint swizzle = SwizzleOffset(pos.xy);
|
||||
|
||||
const uint block_y = pos.y >> GOB_SIZE_Y_SHIFT;
|
||||
|
||||
uint offset = 0;
|
||||
offset += (pos.z >> block_depth) * slice_size;
|
||||
offset += (pos.z & block_depth_mask) << (GOB_SIZE_SHIFT + block_height);
|
||||
offset += (block_y >> block_height) * block_size;
|
||||
offset += (block_y & block_height_mask) << GOB_SIZE_SHIFT;
|
||||
offset += (pos.x >> GOB_SIZE_X_SHIFT) << x_shift;
|
||||
offset += swizzle;
|
||||
|
||||
const uvec4 texel = ReadTexel(offset);
|
||||
const ivec3 coord = ivec3(gl_GlobalInvocationID) + destination;
|
||||
imageStore(output_image, coord, texel);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 2
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#else
|
||||
#define HAS_EXTENDED_TYPES 0
|
||||
#endif
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#define BINDING_SWIZZLE_BUFFER 0
|
||||
#define BINDING_INPUT_BUFFER 1
|
||||
#define BINDING_OUTPUT_IMAGE 0
|
||||
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) uvec3 origin;
|
||||
UNIFORM(1) ivec3 destination;
|
||||
UNIFORM(2) uint bytes_per_block_log2;
|
||||
UNIFORM(3) uint slice_size;
|
||||
UNIFORM(4) uint block_size;
|
||||
UNIFORM(5) uint x_shift;
|
||||
UNIFORM(6) uint block_height;
|
||||
UNIFORM(7) uint block_height_mask;
|
||||
UNIFORM(8) uint block_depth;
|
||||
UNIFORM(9) uint block_depth_mask;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable {
|
||||
uint swizzle_table[];
|
||||
};
|
||||
|
||||
#if HAS_EXTENDED_TYPES
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; };
|
||||
#endif
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU128 { uvec4 u128data[]; };
|
||||
|
||||
layout(binding = BINDING_OUTPUT_IMAGE) uniform writeonly uimage3D output_image;
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
const uint GOB_SIZE_X = 64;
|
||||
const uint GOB_SIZE_Y = 8;
|
||||
const uint GOB_SIZE_Z = 1;
|
||||
const uint GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
|
||||
|
||||
const uint GOB_SIZE_X_SHIFT = 6;
|
||||
const uint GOB_SIZE_Y_SHIFT = 3;
|
||||
const uint GOB_SIZE_Z_SHIFT = 0;
|
||||
const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
|
||||
|
||||
const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1);
|
||||
|
||||
uint SwizzleOffset(uvec2 pos) {
|
||||
pos = pos & SWIZZLE_MASK;
|
||||
return swizzle_table[pos.y * 64 + pos.x];
|
||||
}
|
||||
|
||||
uvec4 ReadTexel(uint offset) {
|
||||
switch (bytes_per_block_log2) {
|
||||
#if HAS_EXTENDED_TYPES
|
||||
case 0:
|
||||
return uvec4(u8data[offset], 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(u16data[offset / 2], 0, 0, 0);
|
||||
#else
|
||||
case 0:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
|
||||
case 1:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
|
||||
#endif
|
||||
case 2:
|
||||
return uvec4(u32data[offset / 4], 0, 0, 0);
|
||||
case 3:
|
||||
return uvec4(u64data[offset / 8], 0, 0);
|
||||
case 4:
|
||||
return u128data[offset / 16];
|
||||
}
|
||||
return uvec4(0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec3 pos = gl_GlobalInvocationID + origin;
|
||||
pos.x <<= bytes_per_block_log2;
|
||||
|
||||
// Read as soon as possible due to its latency
|
||||
const uint swizzle = SwizzleOffset(pos.xy);
|
||||
|
||||
const uint block_y = pos.y >> GOB_SIZE_Y_SHIFT;
|
||||
|
||||
uint offset = 0;
|
||||
offset += (pos.z >> block_depth) * slice_size;
|
||||
offset += (pos.z & block_depth_mask) << (GOB_SIZE_SHIFT + block_height);
|
||||
offset += (block_y >> block_height) * block_size;
|
||||
offset += (block_y & block_height_mask) << GOB_SIZE_SHIFT;
|
||||
offset += (pos.x >> GOB_SIZE_X_SHIFT) << x_shift;
|
||||
offset += swizzle;
|
||||
|
||||
const uvec4 texel = ReadTexel(offset);
|
||||
const ivec3 coord = ivec3(gl_GlobalInvocationID) + destination;
|
||||
imageStore(output_image, coord, texel);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_shader_stencil_export : require
|
||||
|
||||
layout(binding = 0) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
uvec4 color = uvec4(texelFetch(color_texture, coord, 0).abgr * (exp2(8) - 1.0f));
|
||||
uvec4 bytes = color << uvec4(24, 16, 8, 0);
|
||||
uint depth_stencil_unorm = bytes.x | bytes.y | bytes.z | bytes.w;
|
||||
|
||||
gl_FragDepth = float(depth_stencil_unorm & 0x00FFFFFFu) / (exp2(24.0) - 1.0f);
|
||||
gl_FragStencilRefARB = int(depth_stencil_unorm >> 24);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_shader_stencil_export : require
|
||||
|
||||
layout(binding = 0) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
uvec4 color = uvec4(texelFetch(color_texture, coord, 0).abgr * (exp2(8) - 1.0f));
|
||||
uvec4 bytes = color << uvec4(24, 16, 8, 0);
|
||||
uint depth_stencil_unorm = bytes.x | bytes.y | bytes.z | bytes.w;
|
||||
|
||||
gl_FragDepth = float(depth_stencil_unorm & 0x00FFFFFFu) / (exp2(24.0) - 1.0f);
|
||||
gl_FragStencilRefARB = int(depth_stencil_unorm >> 24);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
|
||||
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
|
||||
|
||||
highp uint depth_val =
|
||||
uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0));
|
||||
lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r;
|
||||
highp uvec4 components =
|
||||
uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu);
|
||||
color.abgr = vec4(components) / (exp2(8.0) - 1.0);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
|
||||
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
|
||||
|
||||
highp uint depth_val =
|
||||
uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0));
|
||||
lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r;
|
||||
highp uvec4 components =
|
||||
uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu);
|
||||
color.abgr = vec4(components) / (exp2(8.0) - 1.0);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_texture;
|
||||
layout(location = 0) out float output_color;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
output_color = texelFetch(depth_texture, coord, 0).r;
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_texture;
|
||||
layout(location = 0) out float output_color;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
output_color = texelFetch(depth_texture, coord, 0).r;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
float color = texelFetch(color_texture, coord, 0).r;
|
||||
gl_FragDepth = color;
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
float color = texelFetch(color_texture, coord, 0).r;
|
||||
gl_FragDepth = color;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
|
||||
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
|
||||
|
||||
highp uint depth_val =
|
||||
uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0));
|
||||
lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r;
|
||||
highp uvec4 components =
|
||||
uvec4((uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu, stencil_val);
|
||||
color.rgba = vec4(components) / (exp2(8.0) - 1.0);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
|
||||
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
|
||||
|
||||
highp uint depth_val =
|
||||
uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0));
|
||||
lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r;
|
||||
highp uvec4 components =
|
||||
uvec4((uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu, stencil_val);
|
||||
color.rgba = vec4(components) / (exp2(8.0) - 1.0);
|
||||
}
|
||||
|
||||
@@ -1,115 +1,115 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
//!#version 460 core
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types : require
|
||||
|
||||
// FidelityFX Super Resolution Sample
|
||||
//
|
||||
// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
layout( push_constant ) uniform constants {
|
||||
uvec4 Const0;
|
||||
uvec4 Const1;
|
||||
uvec4 Const2;
|
||||
uvec4 Const3;
|
||||
};
|
||||
|
||||
layout(set=0,binding=0) uniform sampler2D InputTexture;
|
||||
layout(set=0,binding=1,rgba16f) uniform image2D OutputTexture;
|
||||
|
||||
#define A_GPU 1
|
||||
#define A_GLSL 1
|
||||
|
||||
#ifndef YUZU_USE_FP16
|
||||
#include "ffx_a.h"
|
||||
|
||||
#if USE_EASU
|
||||
#define FSR_EASU_F 1
|
||||
AF4 FsrEasuRF(AF2 p) { AF4 res = textureGather(InputTexture, p, 0); return res; }
|
||||
AF4 FsrEasuGF(AF2 p) { AF4 res = textureGather(InputTexture, p, 1); return res; }
|
||||
AF4 FsrEasuBF(AF2 p) { AF4 res = textureGather(InputTexture, p, 2); return res; }
|
||||
#endif
|
||||
#if USE_RCAS
|
||||
#define FSR_RCAS_F 1
|
||||
AF4 FsrRcasLoadF(ASU2 p) { return texelFetch(InputTexture, ASU2(p), 0); }
|
||||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
|
||||
#endif
|
||||
#else
|
||||
#define A_HALF
|
||||
#include "ffx_a.h"
|
||||
|
||||
#if USE_EASU
|
||||
#define FSR_EASU_H 1
|
||||
AH4 FsrEasuRH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 0)); return res; }
|
||||
AH4 FsrEasuGH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 1)); return res; }
|
||||
AH4 FsrEasuBH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 2)); return res; }
|
||||
#endif
|
||||
#if USE_RCAS
|
||||
#define FSR_RCAS_H 1
|
||||
AH4 FsrRcasLoadH(ASW2 p) { return AH4(texelFetch(InputTexture, ASU2(p), 0)); }
|
||||
void FsrRcasInputH(inout AH1 r,inout AH1 g,inout AH1 b){}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ffx_fsr1.h"
|
||||
|
||||
void CurrFilter(AU2 pos) {
|
||||
#if USE_BILINEAR
|
||||
AF2 pp = (AF2(pos) * AF2_AU2(Const0.xy) + AF2_AU2(Const0.zw)) * AF2_AU2(Const1.xy) + AF2(0.5, -0.5) * AF2_AU2(Const1.zw);
|
||||
imageStore(OutputTexture, ASU2(pos), textureLod(InputTexture, pp, 0.0));
|
||||
#endif
|
||||
#if USE_EASU
|
||||
#ifndef YUZU_USE_FP16
|
||||
AF3 c;
|
||||
FsrEasuF(c, pos, Const0, Const1, Const2, Const3);
|
||||
imageStore(OutputTexture, ASU2(pos), AF4(c, 1));
|
||||
#else
|
||||
AH3 c;
|
||||
FsrEasuH(c, pos, Const0, Const1, Const2, Const3);
|
||||
imageStore(OutputTexture, ASU2(pos), AH4(c, 1));
|
||||
#endif
|
||||
#endif
|
||||
#if USE_RCAS
|
||||
#ifndef YUZU_USE_FP16
|
||||
AF3 c;
|
||||
FsrRcasF(c.r, c.g, c.b, pos, Const0);
|
||||
imageStore(OutputTexture, ASU2(pos), AF4(c, 1));
|
||||
#else
|
||||
AH3 c;
|
||||
FsrRcasH(c.r, c.g, c.b, pos, Const0);
|
||||
imageStore(OutputTexture, ASU2(pos), AH4(c, 1));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
layout(local_size_x=64) in;
|
||||
void main() {
|
||||
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
|
||||
AU2 gxy = ARmp8x8(gl_LocalInvocationID.x) + AU2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u);
|
||||
CurrFilter(gxy);
|
||||
gxy.x += 8u;
|
||||
CurrFilter(gxy);
|
||||
gxy.y += 8u;
|
||||
CurrFilter(gxy);
|
||||
gxy.x -= 8u;
|
||||
CurrFilter(gxy);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
//!#version 460 core
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types : require
|
||||
|
||||
// FidelityFX Super Resolution Sample
|
||||
//
|
||||
// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
layout( push_constant ) uniform constants {
|
||||
uvec4 Const0;
|
||||
uvec4 Const1;
|
||||
uvec4 Const2;
|
||||
uvec4 Const3;
|
||||
};
|
||||
|
||||
layout(set=0,binding=0) uniform sampler2D InputTexture;
|
||||
layout(set=0,binding=1,rgba16f) uniform image2D OutputTexture;
|
||||
|
||||
#define A_GPU 1
|
||||
#define A_GLSL 1
|
||||
|
||||
#ifndef YUZU_USE_FP16
|
||||
#include "ffx_a.h"
|
||||
|
||||
#if USE_EASU
|
||||
#define FSR_EASU_F 1
|
||||
AF4 FsrEasuRF(AF2 p) { AF4 res = textureGather(InputTexture, p, 0); return res; }
|
||||
AF4 FsrEasuGF(AF2 p) { AF4 res = textureGather(InputTexture, p, 1); return res; }
|
||||
AF4 FsrEasuBF(AF2 p) { AF4 res = textureGather(InputTexture, p, 2); return res; }
|
||||
#endif
|
||||
#if USE_RCAS
|
||||
#define FSR_RCAS_F 1
|
||||
AF4 FsrRcasLoadF(ASU2 p) { return texelFetch(InputTexture, ASU2(p), 0); }
|
||||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
|
||||
#endif
|
||||
#else
|
||||
#define A_HALF
|
||||
#include "ffx_a.h"
|
||||
|
||||
#if USE_EASU
|
||||
#define FSR_EASU_H 1
|
||||
AH4 FsrEasuRH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 0)); return res; }
|
||||
AH4 FsrEasuGH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 1)); return res; }
|
||||
AH4 FsrEasuBH(AF2 p) { AH4 res = AH4(textureGather(InputTexture, p, 2)); return res; }
|
||||
#endif
|
||||
#if USE_RCAS
|
||||
#define FSR_RCAS_H 1
|
||||
AH4 FsrRcasLoadH(ASW2 p) { return AH4(texelFetch(InputTexture, ASU2(p), 0)); }
|
||||
void FsrRcasInputH(inout AH1 r,inout AH1 g,inout AH1 b){}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ffx_fsr1.h"
|
||||
|
||||
void CurrFilter(AU2 pos) {
|
||||
#if USE_BILINEAR
|
||||
AF2 pp = (AF2(pos) * AF2_AU2(Const0.xy) + AF2_AU2(Const0.zw)) * AF2_AU2(Const1.xy) + AF2(0.5, -0.5) * AF2_AU2(Const1.zw);
|
||||
imageStore(OutputTexture, ASU2(pos), textureLod(InputTexture, pp, 0.0));
|
||||
#endif
|
||||
#if USE_EASU
|
||||
#ifndef YUZU_USE_FP16
|
||||
AF3 c;
|
||||
FsrEasuF(c, pos, Const0, Const1, Const2, Const3);
|
||||
imageStore(OutputTexture, ASU2(pos), AF4(c, 1));
|
||||
#else
|
||||
AH3 c;
|
||||
FsrEasuH(c, pos, Const0, Const1, Const2, Const3);
|
||||
imageStore(OutputTexture, ASU2(pos), AH4(c, 1));
|
||||
#endif
|
||||
#endif
|
||||
#if USE_RCAS
|
||||
#ifndef YUZU_USE_FP16
|
||||
AF3 c;
|
||||
FsrRcasF(c.r, c.g, c.b, pos, Const0);
|
||||
imageStore(OutputTexture, ASU2(pos), AF4(c, 1));
|
||||
#else
|
||||
AH3 c;
|
||||
FsrRcasH(c.r, c.g, c.b, pos, Const0);
|
||||
imageStore(OutputTexture, ASU2(pos), AH4(c, 1));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
layout(local_size_x=64) in;
|
||||
void main() {
|
||||
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
|
||||
AU2 gxy = ARmp8x8(gl_LocalInvocationID.x) + AU2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u);
|
||||
CurrFilter(gxy);
|
||||
gxy.x += 8u;
|
||||
CurrFilter(gxy);
|
||||
gxy.y += 8u;
|
||||
CurrFilter(gxy);
|
||||
gxy.x -= 8u;
|
||||
CurrFilter(gxy);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
#ifdef VULKAN
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) vec2 tex_scale;
|
||||
UNIFORM(1) vec2 tex_offset;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
layout(location = 0) out vec2 texcoord;
|
||||
|
||||
void main() {
|
||||
float x = float((gl_VertexIndex & 1) << 2);
|
||||
float y = float((gl_VertexIndex & 2) << 1);
|
||||
gl_Position = vec4(x - 1.0, y - 1.0, 0.0, 1.0);
|
||||
texcoord = fma(vec2(x, y) / 2.0, tex_scale, tex_offset);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
#ifdef VULKAN
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) vec2 tex_scale;
|
||||
UNIFORM(1) vec2 tex_offset;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
layout(location = 0) out vec2 texcoord;
|
||||
|
||||
void main() {
|
||||
float x = float((gl_VertexIndex & 1) << 2);
|
||||
float y = float((gl_VertexIndex & 2) << 1);
|
||||
gl_Position = vec4(x - 1.0, y - 1.0, 0.0, 1.0);
|
||||
texcoord = fma(vec2(x, y) / 2.0, tex_scale, tex_offset);
|
||||
}
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Source code is adapted from
|
||||
// https://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/
|
||||
|
||||
#version 460
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
layout (location = 0) in vec4 posPos;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
|
||||
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
|
||||
#define FxaaTexLod0(t, p) textureLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o) textureLodOffset(t, p, 0.0, o)
|
||||
|
||||
vec3 FxaaPixelShader(vec4 posPos, sampler2D tex) {
|
||||
|
||||
vec3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;
|
||||
vec3 rgbNE = FxaaTexOff(tex, posPos.zw, ivec2(1,0)).xyz;
|
||||
vec3 rgbSW = FxaaTexOff(tex, posPos.zw, ivec2(0,1)).xyz;
|
||||
vec3 rgbSE = FxaaTexOff(tex, posPos.zw, ivec2(1,1)).xyz;
|
||||
vec3 rgbM = FxaaTexLod0(tex, posPos.xy).xyz;
|
||||
/*---------------------------------------------------------*/
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
/*---------------------------------------------------------*/
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
/*---------------------------------------------------------*/
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
/*---------------------------------------------------------*/
|
||||
float dirReduce = max(
|
||||
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
|
||||
FXAA_REDUCE_MIN);
|
||||
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) / textureSize(tex, 0);
|
||||
/*--------------------------------------------------------*/
|
||||
vec3 rgbA = (1.0 / 2.0) * (
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (1.0 / 3.0 - 0.5)).xyz +
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (2.0 / 3.0 - 0.5)).xyz);
|
||||
vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * (
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (0.0 / 3.0 - 0.5)).xyz +
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (3.0 / 3.0 - 0.5)).xyz);
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
|
||||
return rgbB;
|
||||
}
|
||||
|
||||
void main() {
|
||||
frag_color = vec4(FxaaPixelShader(posPos, input_texture), 1.0);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Source code is adapted from
|
||||
// https://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/
|
||||
|
||||
#version 460
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
layout (location = 0) in vec4 posPos;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
|
||||
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
|
||||
#define FxaaTexLod0(t, p) textureLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o) textureLodOffset(t, p, 0.0, o)
|
||||
|
||||
vec3 FxaaPixelShader(vec4 posPos, sampler2D tex) {
|
||||
|
||||
vec3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;
|
||||
vec3 rgbNE = FxaaTexOff(tex, posPos.zw, ivec2(1,0)).xyz;
|
||||
vec3 rgbSW = FxaaTexOff(tex, posPos.zw, ivec2(0,1)).xyz;
|
||||
vec3 rgbSE = FxaaTexOff(tex, posPos.zw, ivec2(1,1)).xyz;
|
||||
vec3 rgbM = FxaaTexLod0(tex, posPos.xy).xyz;
|
||||
/*---------------------------------------------------------*/
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
/*---------------------------------------------------------*/
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
/*---------------------------------------------------------*/
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
/*---------------------------------------------------------*/
|
||||
float dirReduce = max(
|
||||
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
|
||||
FXAA_REDUCE_MIN);
|
||||
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) / textureSize(tex, 0);
|
||||
/*--------------------------------------------------------*/
|
||||
vec3 rgbA = (1.0 / 2.0) * (
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (1.0 / 3.0 - 0.5)).xyz +
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (2.0 / 3.0 - 0.5)).xyz);
|
||||
vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * (
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (0.0 / 3.0 - 0.5)).xyz +
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (3.0 / 3.0 - 0.5)).xyz);
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
|
||||
return rgbB;
|
||||
}
|
||||
|
||||
void main() {
|
||||
frag_color = vec4(FxaaPixelShader(posPos, input_texture), 1.0);
|
||||
}
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
const vec2 vertices[4] =
|
||||
vec2[4](vec2(-1.0, 1.0), vec2(1.0, 1.0), vec2(-1.0, -1.0), vec2(1.0, -1.0));
|
||||
|
||||
layout (location = 0) out vec4 posPos;
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
#define VERTEX_ID gl_VertexIndex
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
#define VERTEX_ID gl_VertexID
|
||||
|
||||
#endif
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
|
||||
|
||||
const float FXAA_SUBPIX_SHIFT = 0;
|
||||
|
||||
void main() {
|
||||
vec2 vertex = vertices[VERTEX_ID];
|
||||
gl_Position = vec4(vertex, 0.0, 1.0);
|
||||
vec2 vert_tex_coord = (vertex + 1.0) / 2.0;
|
||||
posPos.xy = vert_tex_coord;
|
||||
posPos.zw = vert_tex_coord - (0.5 + FXAA_SUBPIX_SHIFT) / textureSize(input_texture, 0);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
const vec2 vertices[4] =
|
||||
vec2[4](vec2(-1.0, 1.0), vec2(1.0, 1.0), vec2(-1.0, -1.0), vec2(1.0, -1.0));
|
||||
|
||||
layout (location = 0) out vec4 posPos;
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
#define VERTEX_ID gl_VertexIndex
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
#define VERTEX_ID gl_VertexID
|
||||
|
||||
#endif
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
|
||||
|
||||
const float FXAA_SUBPIX_SHIFT = 0;
|
||||
|
||||
void main() {
|
||||
vec2 vertex = vertices[VERTEX_ID];
|
||||
gl_Position = vec4(vertex, 0.0, 1.0);
|
||||
vec2 vert_tex_coord = (vertex + 1.0) / 2.0;
|
||||
posPos.xy = vert_tex_coord;
|
||||
posPos.zw = vert_tex_coord - (0.5 + FXAA_SUBPIX_SHIFT) / textureSize(input_texture, 0);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 8) in;
|
||||
|
||||
layout(binding = 0, rgba8ui) restrict uniform uimage2D destination;
|
||||
layout(location = 0) uniform uvec3 size;
|
||||
|
||||
void main() {
|
||||
if (any(greaterThanEqual(gl_GlobalInvocationID, size))) {
|
||||
return;
|
||||
}
|
||||
uvec4 components = imageLoad(destination, ivec2(gl_GlobalInvocationID.xy));
|
||||
imageStore(destination, ivec2(gl_GlobalInvocationID.xy), components.wxyz);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 8) in;
|
||||
|
||||
layout(binding = 0, rgba8ui) restrict uniform uimage2D destination;
|
||||
layout(location = 0) uniform uvec3 size;
|
||||
|
||||
void main() {
|
||||
if (any(greaterThanEqual(gl_GlobalInvocationID, size))) {
|
||||
return;
|
||||
}
|
||||
uvec4 components = imageLoad(destination, ivec2(gl_GlobalInvocationID.xy));
|
||||
imageStore(destination, ivec2(gl_GlobalInvocationID.xy), components.wxyz);
|
||||
}
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
|
||||
layout (local_size_x = 4, local_size_y = 4) in;
|
||||
|
||||
layout(binding = 0, rg32ui) readonly uniform uimage3D bc4_input;
|
||||
layout(binding = 1, rgba8ui) writeonly uniform uimage3D bc4_output;
|
||||
|
||||
layout(location = 0) uniform uvec3 src_offset;
|
||||
layout(location = 1) uniform uvec3 dst_offset;
|
||||
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_rgtc.txt
|
||||
uint DecompressBlock(uint64_t bits, uvec2 coord) {
|
||||
const uint code_offset = 16 + 3 * (4 * coord.y + coord.x);
|
||||
const uint code = uint(bits >> code_offset) & 7;
|
||||
const uint red0 = uint(bits >> 0) & 0xff;
|
||||
const uint red1 = uint(bits >> 8) & 0xff;
|
||||
if (red0 > red1) {
|
||||
switch (code) {
|
||||
case 0:
|
||||
return red0;
|
||||
case 1:
|
||||
return red1;
|
||||
case 2:
|
||||
return (6 * red0 + 1 * red1) / 7;
|
||||
case 3:
|
||||
return (5 * red0 + 2 * red1) / 7;
|
||||
case 4:
|
||||
return (4 * red0 + 3 * red1) / 7;
|
||||
case 5:
|
||||
return (3 * red0 + 4 * red1) / 7;
|
||||
case 6:
|
||||
return (2 * red0 + 5 * red1) / 7;
|
||||
case 7:
|
||||
return (1 * red0 + 6 * red1) / 7;
|
||||
}
|
||||
} else {
|
||||
switch (code) {
|
||||
case 0:
|
||||
return red0;
|
||||
case 1:
|
||||
return red1;
|
||||
case 2:
|
||||
return (4 * red0 + 1 * red1) / 5;
|
||||
case 3:
|
||||
return (3 * red0 + 2 * red1) / 5;
|
||||
case 4:
|
||||
return (2 * red0 + 3 * red1) / 5;
|
||||
case 5:
|
||||
return (1 * red0 + 4 * red1) / 5;
|
||||
case 6:
|
||||
return 0;
|
||||
case 7:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec2 packed_bits = imageLoad(bc4_input, ivec3(gl_WorkGroupID + src_offset)).rg;
|
||||
uint64_t bits = packUint2x32(packed_bits);
|
||||
uint red = DecompressBlock(bits, gl_LocalInvocationID.xy);
|
||||
uvec4 color = uvec4(red & 0xff, 0, 0, 0xff);
|
||||
imageStore(bc4_output, ivec3(gl_GlobalInvocationID + dst_offset), color);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
|
||||
layout (local_size_x = 4, local_size_y = 4) in;
|
||||
|
||||
layout(binding = 0, rg32ui) readonly uniform uimage3D bc4_input;
|
||||
layout(binding = 1, rgba8ui) writeonly uniform uimage3D bc4_output;
|
||||
|
||||
layout(location = 0) uniform uvec3 src_offset;
|
||||
layout(location = 1) uniform uvec3 dst_offset;
|
||||
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_rgtc.txt
|
||||
uint DecompressBlock(uint64_t bits, uvec2 coord) {
|
||||
const uint code_offset = 16 + 3 * (4 * coord.y + coord.x);
|
||||
const uint code = uint(bits >> code_offset) & 7;
|
||||
const uint red0 = uint(bits >> 0) & 0xff;
|
||||
const uint red1 = uint(bits >> 8) & 0xff;
|
||||
if (red0 > red1) {
|
||||
switch (code) {
|
||||
case 0:
|
||||
return red0;
|
||||
case 1:
|
||||
return red1;
|
||||
case 2:
|
||||
return (6 * red0 + 1 * red1) / 7;
|
||||
case 3:
|
||||
return (5 * red0 + 2 * red1) / 7;
|
||||
case 4:
|
||||
return (4 * red0 + 3 * red1) / 7;
|
||||
case 5:
|
||||
return (3 * red0 + 4 * red1) / 7;
|
||||
case 6:
|
||||
return (2 * red0 + 5 * red1) / 7;
|
||||
case 7:
|
||||
return (1 * red0 + 6 * red1) / 7;
|
||||
}
|
||||
} else {
|
||||
switch (code) {
|
||||
case 0:
|
||||
return red0;
|
||||
case 1:
|
||||
return red1;
|
||||
case 2:
|
||||
return (4 * red0 + 1 * red1) / 5;
|
||||
case 3:
|
||||
return (3 * red0 + 2 * red1) / 5;
|
||||
case 4:
|
||||
return (2 * red0 + 3 * red1) / 5;
|
||||
case 5:
|
||||
return (1 * red0 + 4 * red1) / 5;
|
||||
case 6:
|
||||
return 0;
|
||||
case 7:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec2 packed_bits = imageLoad(bc4_input, ivec3(gl_WorkGroupID + src_offset)).rg;
|
||||
uint64_t bits = packUint2x32(packed_bits);
|
||||
uint red = DecompressBlock(bits, gl_LocalInvocationID.xy);
|
||||
uvec4 color = uvec4(red & 0xff, 0, 0, 0xff);
|
||||
imageStore(bc4_output, ivec3(gl_GlobalInvocationID + dst_offset), color);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
|
||||
layout (location = 0) in vec2 frag_tex_coord;
|
||||
layout (location = 0) out vec4 color;
|
||||
|
||||
layout (binding = 0) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
color = vec4(texture(color_texture, frag_tex_coord).rgb, 1.0f);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
|
||||
layout (location = 0) in vec2 frag_tex_coord;
|
||||
layout (location = 0) out vec4 color;
|
||||
|
||||
layout (binding = 0) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
color = vec4(texture(color_texture, frag_tex_coord).rgb, 1.0f);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 vert_position;
|
||||
layout (location = 1) in vec2 vert_tex_coord;
|
||||
layout (location = 0) out vec2 frag_tex_coord;
|
||||
|
||||
// This is a truncated 3x3 matrix for 2D transformations:
|
||||
// The upper-left 2x2 submatrix performs scaling/rotation/mirroring.
|
||||
// The third column performs translation.
|
||||
// The third row could be used for projection, which we don't need in 2D. It hence is assumed to
|
||||
// implicitly be [0, 0, 1]
|
||||
layout (location = 0) uniform mat3x2 modelview_matrix;
|
||||
|
||||
void main() {
|
||||
// Multiply input position by the rotscale part of the matrix and then manually translate by
|
||||
// the last column. This is equivalent to using a full 3x3 matrix and expanding the vector
|
||||
// to `vec3(vert_position.xy, 1.0)`
|
||||
gl_Position = vec4(mat2(modelview_matrix) * vert_position + modelview_matrix[2], 0.0, 1.0);
|
||||
frag_tex_coord = vert_tex_coord;
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430 core
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 vert_position;
|
||||
layout (location = 1) in vec2 vert_tex_coord;
|
||||
layout (location = 0) out vec2 frag_tex_coord;
|
||||
|
||||
// This is a truncated 3x3 matrix for 2D transformations:
|
||||
// The upper-left 2x2 submatrix performs scaling/rotation/mirroring.
|
||||
// The third column performs translation.
|
||||
// The third row could be used for projection, which we don't need in 2D. It hence is assumed to
|
||||
// implicitly be [0, 0, 1]
|
||||
layout (location = 0) uniform mat3x2 modelview_matrix;
|
||||
|
||||
void main() {
|
||||
// Multiply input position by the rotscale part of the matrix and then manually translate by
|
||||
// the last column. This is equivalent to using a full 3x3 matrix and expanding the vector
|
||||
// to `vec3(vert_position.xy, 1.0)`
|
||||
gl_Position = vec4(mat2(modelview_matrix) * vert_position + modelview_matrix[2], 0.0, 1.0);
|
||||
frag_tex_coord = vert_tex_coord;
|
||||
}
|
||||
|
||||
@@ -1,111 +1,111 @@
|
||||
// SPDX-FileCopyrightText: 2020 BreadFish64
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Adapted from https://github.com/BreadFish64/ScaleFish/tree/master/scaleforce
|
||||
|
||||
//! #version 460
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
#ifdef YUZU_USE_FP16
|
||||
|
||||
#extension GL_AMD_gpu_shader_half_float : enable
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
|
||||
#define lfloat float16_t
|
||||
#define lvec2 f16vec2
|
||||
#define lvec3 f16vec3
|
||||
#define lvec4 f16vec4
|
||||
|
||||
#else
|
||||
|
||||
#define lfloat float
|
||||
#define lvec2 vec2
|
||||
#define lvec3 vec3
|
||||
#define lvec4 vec4
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
layout (location = 0) in vec2 tex_coord;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
|
||||
|
||||
const bool ignore_alpha = true;
|
||||
|
||||
lfloat ColorDist1(lvec4 a, lvec4 b) {
|
||||
// https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion
|
||||
const lvec3 K = lvec3(0.2627, 0.6780, 0.0593);
|
||||
const lfloat scaleB = lfloat(0.5) / (lfloat(1.0) - K.b);
|
||||
const lfloat scaleR = lfloat(0.5) / (lfloat(1.0) - K.r);
|
||||
lvec4 diff = a - b;
|
||||
lfloat Y = dot(diff.rgb, K);
|
||||
lfloat Cb = scaleB * (diff.b - Y);
|
||||
lfloat Cr = scaleR * (diff.r - Y);
|
||||
lvec3 YCbCr = lvec3(Y, Cb, Cr);
|
||||
lfloat d = length(YCbCr);
|
||||
if (ignore_alpha) {
|
||||
return d;
|
||||
}
|
||||
return sqrt(a.a * b.a * d * d + diff.a * diff.a);
|
||||
}
|
||||
|
||||
lvec4 ColorDist(lvec4 ref, lvec4 A, lvec4 B, lvec4 C, lvec4 D) {
|
||||
return lvec4(
|
||||
ColorDist1(ref, A),
|
||||
ColorDist1(ref, B),
|
||||
ColorDist1(ref, C),
|
||||
ColorDist1(ref, D)
|
||||
);
|
||||
}
|
||||
|
||||
vec4 Scaleforce(sampler2D tex, vec2 tex_coord) {
|
||||
lvec4 bl = lvec4(textureOffset(tex, tex_coord, ivec2(-1, -1)));
|
||||
lvec4 bc = lvec4(textureOffset(tex, tex_coord, ivec2(0, -1)));
|
||||
lvec4 br = lvec4(textureOffset(tex, tex_coord, ivec2(1, -1)));
|
||||
lvec4 cl = lvec4(textureOffset(tex, tex_coord, ivec2(-1, 0)));
|
||||
lvec4 cc = lvec4(texture(tex, tex_coord));
|
||||
lvec4 cr = lvec4(textureOffset(tex, tex_coord, ivec2(1, 0)));
|
||||
lvec4 tl = lvec4(textureOffset(tex, tex_coord, ivec2(-1, 1)));
|
||||
lvec4 tc = lvec4(textureOffset(tex, tex_coord, ivec2(0, 1)));
|
||||
lvec4 tr = lvec4(textureOffset(tex, tex_coord, ivec2(1, 1)));
|
||||
|
||||
lvec4 offset_tl = ColorDist(cc, tl, tc, tr, cr);
|
||||
lvec4 offset_br = ColorDist(cc, br, bc, bl, cl);
|
||||
|
||||
// Calculate how different cc is from the texels around it
|
||||
const lfloat plus_weight = lfloat(1.5);
|
||||
const lfloat cross_weight = lfloat(1.5);
|
||||
lfloat total_dist = dot(offset_tl + offset_br, lvec4(cross_weight, plus_weight, cross_weight, plus_weight));
|
||||
|
||||
if (total_dist == lfloat(0.0)) {
|
||||
return cc;
|
||||
} else {
|
||||
// Add together all the distances with direction taken into account
|
||||
lvec4 tmp = offset_tl - offset_br;
|
||||
lvec2 total_offset = tmp.wy * plus_weight + (tmp.zz + lvec2(-tmp.x, tmp.x)) * cross_weight;
|
||||
|
||||
// When the image has thin points, they tend to split apart.
|
||||
// This is because the texels all around are different and total_offset reaches into clear areas.
|
||||
// This works pretty well to keep the offset in bounds for these cases.
|
||||
lfloat clamp_val = length(total_offset) / total_dist;
|
||||
vec2 final_offset = vec2(clamp(total_offset, -clamp_val, clamp_val)) / textureSize(tex, 0);
|
||||
|
||||
return texture(tex, tex_coord - final_offset);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
frag_color = Scaleforce(input_texture, tex_coord);
|
||||
}
|
||||
// SPDX-FileCopyrightText: 2020 BreadFish64
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Adapted from https://github.com/BreadFish64/ScaleFish/tree/master/scaleforce
|
||||
|
||||
//! #version 460
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
#ifdef YUZU_USE_FP16
|
||||
|
||||
#extension GL_AMD_gpu_shader_half_float : enable
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
|
||||
#define lfloat float16_t
|
||||
#define lvec2 f16vec2
|
||||
#define lvec3 f16vec3
|
||||
#define lvec4 f16vec4
|
||||
|
||||
#else
|
||||
|
||||
#define lfloat float
|
||||
#define lvec2 vec2
|
||||
#define lvec3 vec3
|
||||
#define lvec4 vec4
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
layout (location = 0) in vec2 tex_coord;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D input_texture;
|
||||
|
||||
const bool ignore_alpha = true;
|
||||
|
||||
lfloat ColorDist1(lvec4 a, lvec4 b) {
|
||||
// https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion
|
||||
const lvec3 K = lvec3(0.2627, 0.6780, 0.0593);
|
||||
const lfloat scaleB = lfloat(0.5) / (lfloat(1.0) - K.b);
|
||||
const lfloat scaleR = lfloat(0.5) / (lfloat(1.0) - K.r);
|
||||
lvec4 diff = a - b;
|
||||
lfloat Y = dot(diff.rgb, K);
|
||||
lfloat Cb = scaleB * (diff.b - Y);
|
||||
lfloat Cr = scaleR * (diff.r - Y);
|
||||
lvec3 YCbCr = lvec3(Y, Cb, Cr);
|
||||
lfloat d = length(YCbCr);
|
||||
if (ignore_alpha) {
|
||||
return d;
|
||||
}
|
||||
return sqrt(a.a * b.a * d * d + diff.a * diff.a);
|
||||
}
|
||||
|
||||
lvec4 ColorDist(lvec4 ref, lvec4 A, lvec4 B, lvec4 C, lvec4 D) {
|
||||
return lvec4(
|
||||
ColorDist1(ref, A),
|
||||
ColorDist1(ref, B),
|
||||
ColorDist1(ref, C),
|
||||
ColorDist1(ref, D)
|
||||
);
|
||||
}
|
||||
|
||||
vec4 Scaleforce(sampler2D tex, vec2 tex_coord) {
|
||||
lvec4 bl = lvec4(textureOffset(tex, tex_coord, ivec2(-1, -1)));
|
||||
lvec4 bc = lvec4(textureOffset(tex, tex_coord, ivec2(0, -1)));
|
||||
lvec4 br = lvec4(textureOffset(tex, tex_coord, ivec2(1, -1)));
|
||||
lvec4 cl = lvec4(textureOffset(tex, tex_coord, ivec2(-1, 0)));
|
||||
lvec4 cc = lvec4(texture(tex, tex_coord));
|
||||
lvec4 cr = lvec4(textureOffset(tex, tex_coord, ivec2(1, 0)));
|
||||
lvec4 tl = lvec4(textureOffset(tex, tex_coord, ivec2(-1, 1)));
|
||||
lvec4 tc = lvec4(textureOffset(tex, tex_coord, ivec2(0, 1)));
|
||||
lvec4 tr = lvec4(textureOffset(tex, tex_coord, ivec2(1, 1)));
|
||||
|
||||
lvec4 offset_tl = ColorDist(cc, tl, tc, tr, cr);
|
||||
lvec4 offset_br = ColorDist(cc, br, bc, bl, cl);
|
||||
|
||||
// Calculate how different cc is from the texels around it
|
||||
const lfloat plus_weight = lfloat(1.5);
|
||||
const lfloat cross_weight = lfloat(1.5);
|
||||
lfloat total_dist = dot(offset_tl + offset_br, lvec4(cross_weight, plus_weight, cross_weight, plus_weight));
|
||||
|
||||
if (total_dist == lfloat(0.0)) {
|
||||
return cc;
|
||||
} else {
|
||||
// Add together all the distances with direction taken into account
|
||||
lvec4 tmp = offset_tl - offset_br;
|
||||
lvec2 total_offset = tmp.wy * plus_weight + (tmp.zz + lvec2(-tmp.x, tmp.x)) * cross_weight;
|
||||
|
||||
// When the image has thin points, they tend to split apart.
|
||||
// This is because the texels all around are different and total_offset reaches into clear areas.
|
||||
// This works pretty well to keep the offset in bounds for these cases.
|
||||
lfloat clamp_val = length(total_offset) / total_dist;
|
||||
vec2 final_offset = vec2(clamp(total_offset, -clamp_val, clamp_val)) / textureSize(tex, 0);
|
||||
|
||||
return texture(tex, tex_coord - final_offset);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
frag_color = Scaleforce(input_texture, tex_coord);
|
||||
}
|
||||
|
||||
@@ -1,85 +1,85 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#define BINDING_INPUT_BUFFER 0
|
||||
#define BINDING_OUTPUT_IMAGE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#else
|
||||
#define HAS_EXTENDED_TYPES 0
|
||||
#endif
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#define BINDING_INPUT_BUFFER 0
|
||||
#define BINDING_OUTPUT_IMAGE 0
|
||||
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) uvec2 origin;
|
||||
UNIFORM(1) ivec2 destination;
|
||||
UNIFORM(2) uint bytes_per_block;
|
||||
UNIFORM(3) uint pitch;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
#if HAS_EXTENDED_TYPES
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU8 { uint8_t u8data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU16 { uint16_t u16data[]; };
|
||||
#endif
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU32 { uint u32data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU64 { uvec2 u64data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU128 { uvec4 u128data[]; };
|
||||
|
||||
layout(binding = BINDING_OUTPUT_IMAGE) writeonly uniform uimage2D output_image;
|
||||
|
||||
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
|
||||
|
||||
uvec4 ReadTexel(uint offset) {
|
||||
switch (bytes_per_block) {
|
||||
#if HAS_EXTENDED_TYPES
|
||||
case 1:
|
||||
return uvec4(u8data[offset], 0, 0, 0);
|
||||
case 2:
|
||||
return uvec4(u16data[offset / 2], 0, 0, 0);
|
||||
#else
|
||||
case 1:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
|
||||
case 2:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
|
||||
#endif
|
||||
case 4:
|
||||
return uvec4(u32data[offset / 4], 0, 0, 0);
|
||||
case 8:
|
||||
return uvec4(u64data[offset / 8], 0, 0);
|
||||
case 16:
|
||||
return u128data[offset / 16];
|
||||
}
|
||||
return uvec4(0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec2 pos = gl_GlobalInvocationID.xy + origin;
|
||||
|
||||
uint offset = 0;
|
||||
offset += pos.x * bytes_per_block;
|
||||
offset += pos.y * pitch;
|
||||
|
||||
const uvec4 texel = ReadTexel(offset);
|
||||
const ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + destination;
|
||||
imageStore(output_image, coord, texel);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 430
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
|
||||
#define END_PUSH_CONSTANTS };
|
||||
#define UNIFORM(n)
|
||||
#define BINDING_INPUT_BUFFER 0
|
||||
#define BINDING_OUTPUT_IMAGE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#extension GL_NV_gpu_shader5 : enable
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define HAS_EXTENDED_TYPES 1
|
||||
#else
|
||||
#define HAS_EXTENDED_TYPES 0
|
||||
#endif
|
||||
#define BEGIN_PUSH_CONSTANTS
|
||||
#define END_PUSH_CONSTANTS
|
||||
#define UNIFORM(n) layout (location = n) uniform
|
||||
#define BINDING_INPUT_BUFFER 0
|
||||
#define BINDING_OUTPUT_IMAGE 0
|
||||
|
||||
#endif
|
||||
|
||||
BEGIN_PUSH_CONSTANTS
|
||||
UNIFORM(0) uvec2 origin;
|
||||
UNIFORM(1) ivec2 destination;
|
||||
UNIFORM(2) uint bytes_per_block;
|
||||
UNIFORM(3) uint pitch;
|
||||
END_PUSH_CONSTANTS
|
||||
|
||||
#if HAS_EXTENDED_TYPES
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU8 { uint8_t u8data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU16 { uint16_t u16data[]; };
|
||||
#endif
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU32 { uint u32data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU64 { uvec2 u64data[]; };
|
||||
layout(binding = BINDING_INPUT_BUFFER, std430) readonly buffer InputBufferU128 { uvec4 u128data[]; };
|
||||
|
||||
layout(binding = BINDING_OUTPUT_IMAGE) writeonly uniform uimage2D output_image;
|
||||
|
||||
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
|
||||
|
||||
uvec4 ReadTexel(uint offset) {
|
||||
switch (bytes_per_block) {
|
||||
#if HAS_EXTENDED_TYPES
|
||||
case 1:
|
||||
return uvec4(u8data[offset], 0, 0, 0);
|
||||
case 2:
|
||||
return uvec4(u16data[offset / 2], 0, 0, 0);
|
||||
#else
|
||||
case 1:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 24), 8), 0, 0, 0);
|
||||
case 2:
|
||||
return uvec4(bitfieldExtract(u32data[offset / 4], int((offset * 8) & 16), 16), 0, 0, 0);
|
||||
#endif
|
||||
case 4:
|
||||
return uvec4(u32data[offset / 4], 0, 0, 0);
|
||||
case 8:
|
||||
return uvec4(u64data[offset / 8], 0, 0);
|
||||
case 16:
|
||||
return u128data[offset / 16];
|
||||
}
|
||||
return uvec4(0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec2 pos = gl_GlobalInvocationID.xy + origin;
|
||||
|
||||
uint offset = 0;
|
||||
offset += pos.x * bytes_per_block;
|
||||
offset += pos.y * pitch;
|
||||
|
||||
const uvec4 texel = ReadTexel(offset);
|
||||
const ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + destination;
|
||||
imageStore(output_image, coord, texel);
|
||||
}
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
layout (location = 0) in vec2 frag_tex_coord;
|
||||
|
||||
layout (location = 0) out vec4 color;
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture;
|
||||
|
||||
vec4 cubic(float v) {
|
||||
vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
|
||||
vec4 s = n * n * n;
|
||||
float x = s.x;
|
||||
float y = s.y - 4.0 * s.x;
|
||||
float z = s.z - 4.0 * s.y + 6.0 * s.x;
|
||||
float w = 6.0 - x - y - z;
|
||||
return vec4(x, y, z, w) * (1.0 / 6.0);
|
||||
}
|
||||
|
||||
vec4 textureBicubic( sampler2D textureSampler, vec2 texCoords ) {
|
||||
|
||||
vec2 texSize = textureSize(textureSampler, 0);
|
||||
vec2 invTexSize = 1.0 / texSize;
|
||||
|
||||
texCoords = texCoords * texSize - 0.5;
|
||||
|
||||
vec2 fxy = fract(texCoords);
|
||||
texCoords -= fxy;
|
||||
|
||||
vec4 xcubic = cubic(fxy.x);
|
||||
vec4 ycubic = cubic(fxy.y);
|
||||
|
||||
vec4 c = texCoords.xxyy + vec2(-0.5, +1.5).xyxy;
|
||||
|
||||
vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw);
|
||||
vec4 offset = c + vec4(xcubic.yw, ycubic.yw) / s;
|
||||
|
||||
offset *= invTexSize.xxyy;
|
||||
|
||||
vec4 sample0 = texture(textureSampler, offset.xz);
|
||||
vec4 sample1 = texture(textureSampler, offset.yz);
|
||||
vec4 sample2 = texture(textureSampler, offset.xw);
|
||||
vec4 sample3 = texture(textureSampler, offset.yw);
|
||||
|
||||
float sx = s.x / (s.x + s.y);
|
||||
float sy = s.z / (s.z + s.w);
|
||||
|
||||
return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy);
|
||||
}
|
||||
|
||||
void main() {
|
||||
color = vec4(textureBicubic(color_texture, frag_tex_coord).rgb, 1.0f);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
layout (location = 0) in vec2 frag_tex_coord;
|
||||
|
||||
layout (location = 0) out vec4 color;
|
||||
|
||||
layout (binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture;
|
||||
|
||||
vec4 cubic(float v) {
|
||||
vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
|
||||
vec4 s = n * n * n;
|
||||
float x = s.x;
|
||||
float y = s.y - 4.0 * s.x;
|
||||
float z = s.z - 4.0 * s.y + 6.0 * s.x;
|
||||
float w = 6.0 - x - y - z;
|
||||
return vec4(x, y, z, w) * (1.0 / 6.0);
|
||||
}
|
||||
|
||||
vec4 textureBicubic( sampler2D textureSampler, vec2 texCoords ) {
|
||||
|
||||
vec2 texSize = textureSize(textureSampler, 0);
|
||||
vec2 invTexSize = 1.0 / texSize;
|
||||
|
||||
texCoords = texCoords * texSize - 0.5;
|
||||
|
||||
vec2 fxy = fract(texCoords);
|
||||
texCoords -= fxy;
|
||||
|
||||
vec4 xcubic = cubic(fxy.x);
|
||||
vec4 ycubic = cubic(fxy.y);
|
||||
|
||||
vec4 c = texCoords.xxyy + vec2(-0.5, +1.5).xyxy;
|
||||
|
||||
vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw);
|
||||
vec4 offset = c + vec4(xcubic.yw, ycubic.yw) / s;
|
||||
|
||||
offset *= invTexSize.xxyy;
|
||||
|
||||
vec4 sample0 = texture(textureSampler, offset.xz);
|
||||
vec4 sample1 = texture(textureSampler, offset.yz);
|
||||
vec4 sample2 = texture(textureSampler, offset.xw);
|
||||
vec4 sample3 = texture(textureSampler, offset.yw);
|
||||
|
||||
float sx = s.x / (s.x + s.y);
|
||||
float sy = s.z / (s.z + s.w);
|
||||
|
||||
return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy);
|
||||
}
|
||||
|
||||
void main() {
|
||||
color = vec4(textureBicubic(color_texture, frag_tex_coord).rgb, 1.0f);
|
||||
}
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Code adapted from the following sources:
|
||||
// - https://learnopengl.com/Advanced-Lighting/Bloom
|
||||
// - https://www.rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
|
||||
#version 460 core
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
layout(location = 0) in vec2 frag_tex_coord;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
layout(binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture;
|
||||
|
||||
const float offset[3] = float[](0.0, 1.3846153846, 3.2307692308);
|
||||
const float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703);
|
||||
|
||||
vec4 blurVertical(sampler2D textureSampler, vec2 coord, vec2 norm) {
|
||||
vec4 result = vec4(0.0f);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
result += texture(textureSampler, vec2(coord) + (vec2(0.0, offset[i]) * norm)) * weight[i];
|
||||
result += texture(textureSampler, vec2(coord) - (vec2(0.0, offset[i]) * norm)) * weight[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blurHorizontal(sampler2D textureSampler, vec2 coord, vec2 norm) {
|
||||
vec4 result = vec4(0.0f);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
result += texture(textureSampler, vec2(coord) + (vec2(offset[i], 0.0) * norm)) * weight[i];
|
||||
result += texture(textureSampler, vec2(coord) - (vec2(offset[i], 0.0) * norm)) * weight[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blurDiagonal(sampler2D textureSampler, vec2 coord, vec2 norm) {
|
||||
vec4 result = vec4(0.0f);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
result +=
|
||||
texture(textureSampler, vec2(coord) + (vec2(offset[i], offset[i]) * norm)) * weight[i];
|
||||
result +=
|
||||
texture(textureSampler, vec2(coord) - (vec2(offset[i], offset[i]) * norm)) * weight[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 base = texture(color_texture, vec2(frag_tex_coord)).rgb * weight[0];
|
||||
vec2 tex_offset = 1.0f / textureSize(color_texture, 0);
|
||||
|
||||
// TODO(Blinkhawk): This code can be optimized through shader group instructions.
|
||||
vec3 horizontal = blurHorizontal(color_texture, frag_tex_coord, tex_offset).rgb;
|
||||
vec3 vertical = blurVertical(color_texture, frag_tex_coord, tex_offset).rgb;
|
||||
vec3 diagonalA = blurDiagonal(color_texture, frag_tex_coord, tex_offset).rgb;
|
||||
vec3 diagonalB = blurDiagonal(color_texture, frag_tex_coord, tex_offset * vec2(1.0, -1.0)).rgb;
|
||||
vec3 combination = mix(mix(horizontal, vertical, 0.5f), mix(diagonalA, diagonalB, 0.5f), 0.5f);
|
||||
color = vec4(combination + base, 1.0f);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Code adapted from the following sources:
|
||||
// - https://learnopengl.com/Advanced-Lighting/Bloom
|
||||
// - https://www.rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
|
||||
#version 460 core
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 1
|
||||
|
||||
#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
|
||||
|
||||
#define BINDING_COLOR_TEXTURE 0
|
||||
|
||||
#endif
|
||||
|
||||
layout(location = 0) in vec2 frag_tex_coord;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
layout(binding = BINDING_COLOR_TEXTURE) uniform sampler2D color_texture;
|
||||
|
||||
const float offset[3] = float[](0.0, 1.3846153846, 3.2307692308);
|
||||
const float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703);
|
||||
|
||||
vec4 blurVertical(sampler2D textureSampler, vec2 coord, vec2 norm) {
|
||||
vec4 result = vec4(0.0f);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
result += texture(textureSampler, vec2(coord) + (vec2(0.0, offset[i]) * norm)) * weight[i];
|
||||
result += texture(textureSampler, vec2(coord) - (vec2(0.0, offset[i]) * norm)) * weight[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blurHorizontal(sampler2D textureSampler, vec2 coord, vec2 norm) {
|
||||
vec4 result = vec4(0.0f);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
result += texture(textureSampler, vec2(coord) + (vec2(offset[i], 0.0) * norm)) * weight[i];
|
||||
result += texture(textureSampler, vec2(coord) - (vec2(offset[i], 0.0) * norm)) * weight[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blurDiagonal(sampler2D textureSampler, vec2 coord, vec2 norm) {
|
||||
vec4 result = vec4(0.0f);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
result +=
|
||||
texture(textureSampler, vec2(coord) + (vec2(offset[i], offset[i]) * norm)) * weight[i];
|
||||
result +=
|
||||
texture(textureSampler, vec2(coord) - (vec2(offset[i], offset[i]) * norm)) * weight[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 base = texture(color_texture, vec2(frag_tex_coord)).rgb * weight[0];
|
||||
vec2 tex_offset = 1.0f / textureSize(color_texture, 0);
|
||||
|
||||
// TODO(Blinkhawk): This code can be optimized through shader group instructions.
|
||||
vec3 horizontal = blurHorizontal(color_texture, frag_tex_coord, tex_offset).rgb;
|
||||
vec3 vertical = blurVertical(color_texture, frag_tex_coord, tex_offset).rgb;
|
||||
vec3 diagonalA = blurDiagonal(color_texture, frag_tex_coord, tex_offset).rgb;
|
||||
vec3 diagonalB = blurDiagonal(color_texture, frag_tex_coord, tex_offset * vec2(1.0, -1.0)).rgb;
|
||||
vec3 combination = mix(mix(horizontal, vertical, 0.5f), mix(diagonalA, diagonalB, 0.5f), 0.5f);
|
||||
color = vec4(combination + base, 1.0f);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace HostShaders {
|
||||
|
||||
constexpr std::string_view @CONTENTS_NAME@ = {
|
||||
@CONTENTS@
|
||||
};
|
||||
|
||||
} // namespace HostShaders
|
||||
// SPDX-FileCopyrightText: 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace HostShaders {
|
||||
|
||||
constexpr std::string_view @CONTENTS_NAME@ = {
|
||||
@CONTENTS@
|
||||
};
|
||||
|
||||
} // namespace HostShaders
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D tex;
|
||||
|
||||
layout(location = 0) in vec2 texcoord;
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main() {
|
||||
color = textureLod(tex, texcoord, 0);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2D tex;
|
||||
|
||||
layout(location = 0) in vec2 texcoord;
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
void main() {
|
||||
color = textureLod(tex, texcoord, 0);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_shader_stencil_export : require
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) in vec2 texcoord;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = textureLod(depth_tex, texcoord, 0).r;
|
||||
gl_FragStencilRefARB = textureLod(stencil_tex, texcoord, 0).r;
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_shader_stencil_export : require
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) in vec2 texcoord;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = textureLod(depth_tex, texcoord, 0).r;
|
||||
gl_FragStencilRefARB = textureLod(stencil_tex, texcoord, 0).r;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define YUZU_USE_FP16
|
||||
#define USE_EASU 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define YUZU_USE_FP16
|
||||
#define USE_EASU 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define USE_EASU 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define USE_EASU 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define YUZU_USE_FP16
|
||||
#define USE_RCAS 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define YUZU_USE_FP16
|
||||
#define USE_RCAS 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define USE_RCAS 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define USE_RCAS 1
|
||||
|
||||
#include "fidelityfx_fsr.comp"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec2 frag_tex_coord;
|
||||
|
||||
layout (location = 0) out vec4 color;
|
||||
|
||||
layout (binding = 1) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
color = texture(color_texture, frag_tex_coord);
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec2 frag_tex_coord;
|
||||
|
||||
layout (location = 0) out vec4 color;
|
||||
|
||||
layout (binding = 1) uniform sampler2D color_texture;
|
||||
|
||||
void main() {
|
||||
color = texture(color_texture, frag_tex_coord);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec2 vert_position;
|
||||
layout (location = 1) in vec2 vert_tex_coord;
|
||||
|
||||
layout (location = 0) out vec2 frag_tex_coord;
|
||||
|
||||
layout (set = 0, binding = 0) uniform MatrixBlock {
|
||||
mat4 modelview_matrix;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = modelview_matrix * vec4(vert_position, 0.0, 1.0);
|
||||
frag_tex_coord = vert_tex_coord;
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec2 vert_position;
|
||||
layout (location = 1) in vec2 vert_tex_coord;
|
||||
|
||||
layout (location = 0) out vec2 frag_tex_coord;
|
||||
|
||||
layout (set = 0, binding = 0) uniform MatrixBlock {
|
||||
mat4 modelview_matrix;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = modelview_matrix * vec4(vert_position, 0.0, 1.0);
|
||||
frag_tex_coord = vert_tex_coord;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define YUZU_USE_FP16
|
||||
|
||||
#include "opengl_present_scaleforce.frag"
|
||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define YUZU_USE_FP16
|
||||
|
||||
#include "opengl_present_scaleforce.frag"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "opengl_present_scaleforce.frag"
|
||||
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "opengl_present_scaleforce.frag"
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
layout (local_size_x = 1024) in;
|
||||
|
||||
layout (std430, set = 0, binding = 0) readonly buffer InputBuffer {
|
||||
uint input_indexes[];
|
||||
};
|
||||
|
||||
layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer {
|
||||
uint output_indexes[];
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
uint base_vertex;
|
||||
int index_shift; // 0: uint8, 1: uint16, 2: uint32
|
||||
};
|
||||
|
||||
void main() {
|
||||
int primitive = int(gl_GlobalInvocationID.x);
|
||||
if (primitive * 6 >= output_indexes.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index_size = 8 << index_shift;
|
||||
int flipped_shift = 2 - index_shift;
|
||||
int mask = (1 << flipped_shift) - 1;
|
||||
|
||||
const int quad_swizzle[6] = int[](0, 1, 2, 0, 2, 3);
|
||||
for (uint vertex = 0; vertex < 6; ++vertex) {
|
||||
int offset = primitive * 4 + quad_swizzle[vertex];
|
||||
int int_offset = offset >> flipped_shift;
|
||||
int bit_offset = (offset & mask) * index_size;
|
||||
uint packed_input = input_indexes[int_offset];
|
||||
uint index = bitfieldExtract(packed_input, bit_offset, index_size);
|
||||
output_indexes[primitive * 6 + vertex] = index + base_vertex;
|
||||
}
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
|
||||
layout (local_size_x = 1024) in;
|
||||
|
||||
layout (std430, set = 0, binding = 0) readonly buffer InputBuffer {
|
||||
uint input_indexes[];
|
||||
};
|
||||
|
||||
layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer {
|
||||
uint output_indexes[];
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
uint base_vertex;
|
||||
int index_shift; // 0: uint8, 1: uint16, 2: uint32
|
||||
};
|
||||
|
||||
void main() {
|
||||
int primitive = int(gl_GlobalInvocationID.x);
|
||||
if (primitive * 6 >= output_indexes.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index_size = 8 << index_shift;
|
||||
int flipped_shift = 2 - index_shift;
|
||||
int mask = (1 << flipped_shift) - 1;
|
||||
|
||||
const int quad_swizzle[6] = int[](0, 1, 2, 0, 2, 3);
|
||||
for (uint vertex = 0; vertex < 6; ++vertex) {
|
||||
int offset = primitive * 4 + quad_swizzle[vertex];
|
||||
int int_offset = offset >> flipped_shift;
|
||||
int bit_offset = (offset & mask) * index_size;
|
||||
uint packed_input = input_indexes[int_offset];
|
||||
uint index = bitfieldExtract(packed_input, bit_offset, index_size);
|
||||
output_indexes[primitive * 6 + vertex] = index + base_vertex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
|
||||
layout (local_size_x = 1024) in;
|
||||
|
||||
layout (std430, set = 0, binding = 0) readonly buffer InputBuffer {
|
||||
uint8_t input_indexes[];
|
||||
};
|
||||
|
||||
layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer {
|
||||
uint16_t output_indexes[];
|
||||
};
|
||||
|
||||
uint AssembleIndex(uint id) {
|
||||
// Most primitive restart indices are 0xFF
|
||||
// Hardcode this to 0xFF for now
|
||||
uint index = uint(input_indexes[id]);
|
||||
return index == 0xFF ? 0xFFFF : index;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uint id = gl_GlobalInvocationID.x;
|
||||
if (id < input_indexes.length()) {
|
||||
output_indexes[id] = uint16_t(AssembleIndex(id));
|
||||
}
|
||||
}
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#version 460 core
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
|
||||
layout (local_size_x = 1024) in;
|
||||
|
||||
layout (std430, set = 0, binding = 0) readonly buffer InputBuffer {
|
||||
uint8_t input_indexes[];
|
||||
};
|
||||
|
||||
layout (std430, set = 0, binding = 1) writeonly buffer OutputBuffer {
|
||||
uint16_t output_indexes[];
|
||||
};
|
||||
|
||||
uint AssembleIndex(uint id) {
|
||||
// Most primitive restart indices are 0xFF
|
||||
// Hardcode this to 0xFF for now
|
||||
uint index = uint(input_indexes[id]);
|
||||
return index == 0xFF ? 0xFFFF : index;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uint id = gl_GlobalInvocationID.x;
|
||||
if (id < input_indexes.length()) {
|
||||
output_indexes[id] = uint16_t(AssembleIndex(id));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user