This commit is contained in:
butters dousha 2023-02-23 16:07:11 -05:00 committed by GitHub
commit 371b4ee2ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 22856 additions and 0 deletions

View File

@ -797,6 +797,10 @@ To build the FSR2 sample, please follow the following instructions:
3) Open the solutions in the DX12 or Vulkan directory (depending on your preference), compile and run. 3) Open the solutions in the DX12 or Vulkan directory (depending on your preference), compile and run.
4) There is an off-screen version which currently runs on Vulkan,to use this,you need to provide:
- Color textures (RGBA)
- Motion vectors and depth textures(RG for motion vectors and B for depth,and please remain the A channel)
# Limitations # Limitations
FSR2 requires a GPU with typed UAV load and R16G16B16A16_UNORM support. FSR2 requires a GPU with typed UAV load and R16G16B16A16_UNORM support.

View File

@ -49,6 +49,11 @@ set(sources
AnimatedTexture.h AnimatedTexture.h
dpiawarescaling.manifest) dpiawarescaling.manifest)
set(sources_offscreen
./offscreen/main.cpp
./offscreen/helper.hpp
./offscreen/Vulkan_FSR2.hpp)
set(fsr1_shaders_src set(fsr1_shaders_src
${CMAKE_CURRENT_SOURCE_DIR}/../ffx-fsr2-api/shaders/ffx_core.h ${CMAKE_CURRENT_SOURCE_DIR}/../ffx-fsr2-api/shaders/ffx_core.h
${CMAKE_CURRENT_SOURCE_DIR}/../ffx-fsr2-api/shaders/ffx_common_types.h ${CMAKE_CURRENT_SOURCE_DIR}/../ffx-fsr2-api/shaders/ffx_common_types.h
@ -124,6 +129,7 @@ set(sample_shaders_src
set(APP_ICON_GPUOPEN "${CMAKE_CURRENT_SOURCE_DIR}/../common/GpuOpenIcon.rc") set(APP_ICON_GPUOPEN "${CMAKE_CURRENT_SOURCE_DIR}/../common/GpuOpenIcon.rc")
source_group("sources" FILES ${sources}) source_group("sources" FILES ${sources})
source_group("sources_offscreen" FILES ${sources_offscreen})
source_group("spatial_shaders" FILES ${fsr1_shaders_src}) source_group("spatial_shaders" FILES ${fsr1_shaders_src})
source_group("fsr2_shaders" FILES ${fsr2_shaders_src}) source_group("fsr2_shaders" FILES ${fsr2_shaders_src})
source_group("particle_shaders" FILES ${particle_shaders_src}) source_group("particle_shaders" FILES ${particle_shaders_src})
@ -146,4 +152,13 @@ target_link_directories(FSR2_Sample_VK PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../
add_dependencies(FSR2_Sample_VK copied_vk_shaders_fsr2_src) add_dependencies(FSR2_Sample_VK copied_vk_shaders_fsr2_src)
set_target_properties(FSR2_Sample_VK PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" DEBUG_POSTFIX "d") set_target_properties(FSR2_Sample_VK PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" DEBUG_POSTFIX "d")
add_executable(FSR2_OffScreen_VK ${sources_offscreen} ${fsr2_src} ${fsr1_shaders_src} ${fsr2_shaders_src} ${particle_shaders_src} ${spd_shaders_src} ${common} ${APP_ICON_GPUOPEN})
target_compile_definitions(FSR2_OffScreen_VK PRIVATE $<$<CONFIG:RelWithDebInfo>:FSR2_DEBUG_SHADERS=1>)
target_link_libraries(FSR2_OffScreen_VK LINK_PUBLIC Cauldron_VK Vulkan::Vulkan ffx_fsr2_api_x64 ffx_fsr2_api_vk_x64) # ffx_fsr2_api_x64
target_include_directories(FSR2_OffScreen_VK PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/offscreen/include ${CMAKE_CURRENT_SOURCE_DIR}/../ffx-fsr2-api ${CMAKE_CURRENT_SOURCE_DIR}/../../libs)
target_link_directories(FSR2_OffScreen_VK PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../libs)
set_target_properties(FSR2_OffScreen_VK PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" DEBUG_POSTFIX "d")
set_source_files_properties(${Shaders_src} PROPERTIES VS_TOOL_OVERRIDE "Text") set_source_files_properties(${Shaders_src} PROPERTIES VS_TOOL_OVERRIDE "Text")

File diff suppressed because it is too large Load Diff

123
src/VK/offscreen/helper.hpp Normal file
View File

@ -0,0 +1,123 @@
#pragma once
#define TINYEXR_IMPLEMENTATION
#include <tinyexr.h>
#include <FindFiles.h>
#include <iostream>
struct config
{
std::vector<std::string> file_list;
std::string input_path = "";
std::string motion_depth_path = "";
std::string out_path = "";
float scale_motion_x = 1.0f;
float scale_motion_y = 1.0f;
float scale_depth = 1.0f;
double deltaTime = 33.3f;
int outWidth = 1;
int outHeight = 1;
bool reset = false;
bool enableJitter = false;
};
bool get_files(std::vector<std::string>& fileNames, std::string& input_path)
{
FindFiles finder;
fileNames = finder.findFiles(input_path.c_str());
if (fileNames.empty()) return false;
std::sort(fileNames.begin(), fileNames.end());
return true;
}
std::vector<float> read_image_exr(const std::string& file_path, int& w, int& h,int channel)
{
float* data = nullptr;
const char* err = nullptr;
int ret = LoadEXR(&data, &w, &h, file_path.c_str(), &err);
if (ret != TINYEXR_SUCCESS) {
if (err) {
std::cout << "EXR reading error: " << err << "\n";
FreeEXRErrorMessage(err);
}
}
std::vector<float> data_rgba{ data ,data+(w*h)*channel}; // auto free
return data_rgba;
}
void write_exr(const std::string& _file_path, std::vector<float> &data, int w, int h, int _channels=4,
bool use_half = false)
{
if (data.empty())
return;
std::string file_path = _file_path;
EXRHeader header;
InitEXRHeader(&header);
EXRImage image;
InitEXRImage(&image);
image.num_channels = _channels;
int pixel_n = w * h;
std::vector<float> images[4];
images[0].resize(pixel_n);
images[1].resize(pixel_n);
images[2].resize(pixel_n);
images[3].resize(pixel_n);
for (int i = 0; i < pixel_n; i++) {
images[0][i] = data[4 * i + 0];
images[1][i] = data[4 * i + 1];
images[2][i] = data[4 * i + 2];
images[3][i] = data[4 * i + 3];
}
float* image_ptr[4];
image_ptr[0] = images[3].data(); // A
image_ptr[1] = images[2].data(); // B
image_ptr[2] = images[1].data(); // G
image_ptr[3] = images[0].data(); // R
image.images = (uint8_t**)image_ptr;
image.width = w;
image.height = h;
header.num_channels = 4;
auto channels = std::make_unique<EXRChannelInfo[]>(header.num_channels);
header.channels = channels.get();
// Must be (A)BGR order, since most of EXR viewers expect this channel order
strncpy_s(header.channels[0].name, "A", 255);
header.channels[0].name[strlen("A")] = '\0';
strncpy_s(header.channels[1].name, "B", 255);
header.channels[1].name[strlen("B")] = '\0';
strncpy_s(header.channels[2].name, "G", 255);
header.channels[2].name[strlen("G")] = '\0';
strncpy_s(header.channels[3].name, "R", 255);
header.channels[3].name[strlen("R")] = '\0';
auto pixel_types = std::make_unique<int[]>(header.num_channels);
header.pixel_types = pixel_types.get();
auto requested_pixel_types = std::make_unique<int[]>(header.num_channels);
header.requested_pixel_types = requested_pixel_types.get();
for (int i = 0; i < header.num_channels; i++) {
header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
header.requested_pixel_types[i] =
use_half ? // pixel type of output image to be stored in EXR file
TINYEXR_PIXELTYPE_HALF :
TINYEXR_PIXELTYPE_FLOAT;
}
header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP;
const char* err = nullptr;
int ret = SaveEXRImageToFile(&image, &header, file_path.c_str(), &err);
if (ret != TINYEXR_SUCCESS) {
if (err) {
std::cout << "EXR writing error: " << err << std::endl;
FreeEXRErrorMessage(err);
}
return;
};
}

View File

@ -0,0 +1,143 @@
/*
* Find and generate a file list of the folder.
**/
#ifndef FIND_FILES_H
#define FIND_FILES_H
#include <vector>
#include <string>
class FindFiles
{
public:
FindFiles(){}
~FindFiles(){}
std::vector<std::string> findFiles( const char *lpPath, const char *secName = ".*" );
private:
std::vector<std::string> file_lists;
};
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
#include <Windows.h>
#include <direct.h>
std::vector<std::string> FindFiles::findFiles( const char *lpPath, const char *secName /*= ".*" */ )
{
char szFind[MAX_PATH];
char szFile[MAX_PATH];
WIN32_FIND_DATA FindFileData;
strcpy(szFind,lpPath);
strcat(szFind,"\\*");
strcat(szFind,secName);
HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
if(INVALID_HANDLE_VALUE == hFind)
{
std::cout << "Empty folder!" << std::endl;
return std::vector<std::string>();
}
do
{
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(FindFileData.cFileName[0]!='.')
{
strcpy(szFile,lpPath);
strcat(szFile,"\\");
strcat(szFile,FindFileData.cFileName);
findFiles(szFile);
}
}
else
{
if ( szFile[0] )
{
std::string filePath = lpPath;
filePath += "\\";
filePath = FindFileData.cFileName;
file_lists.push_back(filePath);
}
else
{
std::string filePath = szFile;
filePath = FindFileData.cFileName;
file_lists.push_back(filePath);
}
}
}while(::FindNextFile(hFind,&FindFileData));
::FindClose(hFind);
return file_lists;
}
#else
#include <dirent.h>
#include <string.h>
#include <queue>
std::vector<std::string> FindFiles::findFiles( const char *lpPath, const char *secName /*= ".*" */ )
{
(void)secName;
std::vector<std::string> result;
std::queue<std::string> queue;
std::string dirname;
DIR *dir;
if ( !(dir = opendir ( lpPath )) ) {
return result;
}
queue.push( lpPath );
struct dirent *ent;
while ( !queue.empty() )
{
dirname = queue.front();
dir = opendir( dirname.c_str() );
queue.pop();
if ( !dir ) { continue; }
while( ent = readdir( dir ) )
{
if ( strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0 )
{
continue;
}
if ( ent->d_type == DT_DIR )
{
queue.push( dirname+"/"+ent->d_name );
}
else
{
result.push_back( /*dirname + "/" + */ent->d_name);
}
}
closedir( dir );
}
return result;
}
#endif
#endif // FIND_FILES_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

102
src/VK/offscreen/main.cpp Normal file
View File

@ -0,0 +1,102 @@
#include "Vulkan_FSR2.hpp"
int main(int argc, const char* argv[]) {
if (argc < 2) {
std::cout << "Usage: FSR2 OffScreen [OPTIONS]\n\n";
std::cout << "OPTIONS:\n";
std::cout << " --color_path <input_path> path of input color images\n";
std::cout << " --mv_d_path <motion_depth_path> path of motion vector and depth of input images\n";
std::cout << " --out_path <out_path> the output path of the result images\n";
std::cout << " --s_mv_x <number> the scale of x of motion vector\n";
std::cout << " --s_mv_y <number> the scale of y of motion vector\n";
std::cout << " --s_depth <number> the scale of depth\n";
std::cout << " --fps <number> Frames Per Second\n";
std::cout << " --w <number> output Width\n";
std::cout << " --h <number> output Height\n";
std::cout << " --r reset for every frame\n";
std::cout << " --j enable Jitter\n";
return 0;
}
std::vector<std::string> file_list;
std::string input_path = "";
std::string motion_depth_path = "";
std::string out_path = "";
float scale_motion_x = -0.5f;//default value cause I am working with ue4.
float scale_motion_y = 0.5f;
float scale_depth = 1000.0f;
double deltaTime = 33.3f;//33.3f for 30fps, if running at 60fps, the value passed should be around 16.6f.
float outWidth = 3840;
float outHeight = 2160;
bool reset = false;
bool enableJitter = false;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--color_path") == 0 && i + 1 < argc)
{
input_path = argv[i + 1];
}
else if (strcmp(argv[i], "--mv_d_path") == 0 && i + 1 < argc)
{
motion_depth_path = argv[i + 1];
}
else if (strcmp(argv[i], "--out_path") == 0 && i + 1 < argc)
{
out_path = argv[i + 1];
}
else if (strcmp(argv[i], "--s_mv_x") == 0 && i + 1 < argc)
{
scale_motion_x = atof(argv[i + 1]);
}
else if (strcmp(argv[i], "--s_mv_y") == 0 && i + 1 < argc)
{
scale_motion_y = atof(argv[i + 1]);
}
else if (strcmp(argv[i], "--s_depth") == 0 && i + 1 < argc)
{
scale_depth = atof(argv[i + 1]);
}
else if (strcmp(argv[i], "--fps") == 0 && i + 1 < argc)
{
double fps = atof(argv[i + 1]);
deltaTime = 1.0f / fps;
}
else if (strcmp(argv[i], "--w") == 0 && i + 1 < argc)
{
outWidth = atoi(argv[i + 1]);
}
else if (strcmp(argv[i], "--h") == 0 && i + 1 < argc)
{
outHeight = atoi(argv[i + 1]);
}
else if (strcmp(argv[i], "--r") == 0)
{
reset = true;
}
else if (strcmp(argv[i], "--j") == 0)
{
enableJitter = true;
}
}
get_files(file_list, input_path);
//copy
config config_fsr;
config_fsr.file_list = file_list;
config_fsr.input_path = input_path;
config_fsr.motion_depth_path = motion_depth_path;
config_fsr.out_path = out_path;
config_fsr.scale_motion_x = scale_motion_x;
config_fsr.scale_motion_y = scale_motion_y;
config_fsr.scale_depth = scale_depth;
config_fsr.deltaTime = deltaTime;
config_fsr.outWidth = outWidth;
config_fsr.outHeight = outHeight;
config_fsr.reset = reset;
config_fsr.enableJitter = enableJitter;
Vulkan_FSR2 FSR2;
FSR2.run(config_fsr);
return EXIT_SUCCESS;
}