From 709215526309e06a3adc1f08de6cd7b5a039b6f5 Mon Sep 17 00:00:00 2001 From: Jake Ryan Date: Fri, 19 May 2023 16:27:39 -0700 Subject: [PATCH] Added FSR2 to gltf viewer (bugged) --- example/03_gltf_viewer.cpp | 146 +++++++++++++++++++++++++++----- example/CMakeLists.txt | 4 +- example/external/CMakeLists.txt | 17 ++++ src/Rendering.cpp | 2 +- src/Texture.cpp | 50 ++++++----- 5 files changed, 176 insertions(+), 43 deletions(-) diff --git a/example/03_gltf_viewer.cpp b/example/03_gltf_viewer.cpp index 3449eb9..c88a4dc 100644 --- a/example/03_gltf_viewer.cpp +++ b/example/03_gltf_viewer.cpp @@ -11,7 +11,9 @@ #include #include -#include FWOG_OPENGL_HEADER +#include "src/ffx-fsr2-api/ffx_fsr2.h" +#include "src/ffx-fsr2-api/gl/ffx_fsr2_gl.h" + #include #include @@ -29,6 +31,7 @@ #include #include #include +#include #include #include @@ -206,6 +209,9 @@ class GltfViewerApplication final : public Application std::optional gDepth; std::optional gNormalPrev; std::optional gDepthPrev; + std::optional gMotion; + std::optional colorLdrRenderRes; + std::optional colorLdrWindowRes; std::optional rsm; // For debug drawing with ImGui @@ -243,6 +249,15 @@ class GltfViewerApplication final : public Application Utility::Scene scene; std::optional> lightBuffer; std::optional> meshUniformBuffer; + + uint32_t renderWidth; + uint32_t renderHeight; + + bool fsr2FirstInit = true; + FfxFsr2QualityMode fsr2QualityMode = FFX_FSR2_QUALITY_MODE_BALANCED; + FfxFsr2Context fsr2Context; + std::unique_ptr fsr2ScratchMemory; + uint32_t frameIndex = 0; }; GltfViewerApplication::GltfViewerApplication(const Application::CreateInfo& createInfo, @@ -323,14 +338,35 @@ GltfViewerApplication::GltfViewerApplication(const Application::CreateInfo& crea void GltfViewerApplication::OnWindowResize(uint32_t newWidth, uint32_t newHeight) { + // create FSR 2 context + if (!fsr2FirstInit) + { + ffxFsr2ContextDestroy(&fsr2Context); + } + frameIndex = 0; + fsr2FirstInit = false; + ffxFsr2GetRenderResolutionFromQualityMode(&renderWidth, &renderHeight, newWidth, newHeight, fsr2QualityMode); + FfxFsr2ContextDescription contextDesc{ + .flags = FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE | FFX_FSR2_ENABLE_AUTO_EXPOSURE, + .maxRenderSize = {renderWidth, renderHeight}, + .displaySize = {newWidth, newHeight}, + .device = (void*)0x1, + }; + fsr2ScratchMemory = std::make_unique(ffxFsr2GetScratchMemorySizeGL()); + ffxFsr2GetInterfaceGL(&contextDesc.callbacks, fsr2ScratchMemory.get(), ffxFsr2GetScratchMemorySizeGL(), glfwGetProcAddress); + ffxFsr2ContextCreate(&fsr2Context, &contextDesc); + // create gbuffer textures and render info - frame.gAlbedo = Fwog::CreateTexture2D({newWidth, newHeight}, Fwog::Format::R8G8B8A8_SRGB); - frame.gNormal = Fwog::CreateTexture2D({newWidth, newHeight}, Fwog::Format::R16G16B16_SNORM); - frame.gDepth = Fwog::CreateTexture2D({newWidth, newHeight}, Fwog::Format::D32_UNORM); - frame.gNormalPrev = Fwog::CreateTexture2D({newWidth, newHeight}, Fwog::Format::R16G16B16_SNORM); - frame.gDepthPrev = Fwog::CreateTexture2D({newWidth, newHeight}, Fwog::Format::D32_UNORM); + frame.gAlbedo = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::R8G8B8A8_SRGB); + frame.gNormal = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::R16G16B16_SNORM); + frame.gDepth = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::D32_FLOAT); + frame.gNormalPrev = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::R16G16B16_SNORM); + frame.gDepthPrev = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::D32_FLOAT); + frame.gMotion = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::R16G16_FLOAT); + frame.colorLdrRenderRes = Fwog::CreateTexture2D({renderWidth, renderHeight}, Fwog::Format::R8G8B8A8_SRGB); + frame.colorLdrWindowRes = Fwog::CreateTexture2D({newWidth, newHeight}, Fwog::Format::R8G8B8A8_SRGB); - frame.rsm = RSM::RsmTechnique(newWidth, newHeight); + frame.rsm = RSM::RsmTechnique(renderWidth, renderHeight); // create debug views frame.gAlbedoSwizzled = frame.gAlbedo->CreateSwizzleView({.a = Fwog::ComponentSwizzle::ONE}); @@ -339,7 +375,10 @@ void GltfViewerApplication::OnWindowResize(uint32_t newWidth, uint32_t newHeight frame.gRsmIlluminanceSwizzled = frame.rsm->GetIndirectLighting().CreateSwizzleView({.a = Fwog::ComponentSwizzle::ONE}); } -void GltfViewerApplication::OnUpdate([[maybe_unused]] double dt) {} +void GltfViewerApplication::OnUpdate([[maybe_unused]] double dt) +{ + frameIndex++; +} void GltfViewerApplication::OnRender([[maybe_unused]] double dt) { @@ -364,7 +403,17 @@ void GltfViewerApplication::OnRender([[maybe_unused]] double dt) ss.compareOp = Fwog::CompareOp::LESS; auto shadowSampler = Fwog::Sampler(ss); - auto proj = glm::perspective(glm::radians(70.f), windowWidth / (float)windowHeight, 0.1f, 100.f); + constexpr float cameraNear = 0.1f; + constexpr float cameraFar = 100.0f; + constexpr float cameraFovY = glm::radians(70.f); + auto proj = glm::perspective(cameraFovY, renderWidth / (float)renderHeight, cameraNear, cameraFar); + float jitterX{}; + float jitterY{}; + ffxFsr2GetJitterOffset(&jitterX, &jitterY, frameIndex, ffxFsr2GetJitterPhaseCount(renderWidth, windowWidth)); + const float jitterOffsetX = 2.0f * jitterX / (float)renderWidth; + const float jitterOffsetY = -2.0f * jitterY / (float)renderHeight; + const auto jitterMatrix = glm::translate(glm::mat4(1), glm::vec3(jitterOffsetX, jitterOffsetY, 0)); + proj = jitterMatrix * proj; GlobalUniforms mainCameraUniforms{}; mainCameraUniforms.viewProj = proj * mainCamera.GetViewMatrix(); @@ -517,18 +566,14 @@ void GltfViewerApplication::OnRender([[maybe_unused]] double dt) // shading pass (full screen tri) - Fwog::BeginSwapchainRendering({ + Fwog::RenderColorAttachment shadingColorAttachment{ + .texture = &frame.colorLdrRenderRes.value(), + .loadOp = Fwog::AttachmentLoadOp::CLEAR, + .clearValue = {.1f, .3f, .5f, 0.0f}, + }; + Fwog::BeginRendering({ .name = "Shading", - .viewport = - Fwog::Viewport{ - .drawRect{.offset = {0, 0}, .extent = {windowWidth, windowHeight}}, - .minDepth = 0.0f, - .maxDepth = 1.0f, - }, - .colorLoadOp = Fwog::AttachmentLoadOp::CLEAR, - .clearColorValue = {.1f, .3f, .5f, 0.0f}, - .depthLoadOp = Fwog::AttachmentLoadOp::DONT_CARE, - .stencilLoadOp = Fwog::AttachmentLoadOp::DONT_CARE, + .colorAttachments = {&shadingColorAttachment, 1}, }); { Fwog::Cmd::BindGraphicsPipeline(shadingPipeline); @@ -561,6 +606,65 @@ void GltfViewerApplication::OnRender([[maybe_unused]] double dt) } } Fwog::EndRendering(); + + constexpr float clearValue[2] = {0, 0}; + frame.gMotion->ClearImage({.data = clearValue}); + + auto colorResource = ffxGetTextureResourceGL(&fsr2Context, frame.colorLdrRenderRes->Handle(), renderWidth, renderHeight, GL_SRGB8_ALPHA8); + auto depthResource = ffxGetTextureResourceGL(&fsr2Context, frame.gDepth->Handle(), renderWidth, renderHeight, GL_DEPTH_COMPONENT32F); + auto motionResource = ffxGetTextureResourceGL(&fsr2Context, frame.gMotion->Handle(), renderWidth, renderHeight, GL_RG16F); + auto outputResource = ffxGetTextureResourceGL(&fsr2Context, frame.colorLdrWindowRes->Handle(), windowWidth, windowHeight, GL_SRGB8_ALPHA8); + FfxFsr2DispatchDescription dispatchDesc + { + .commandList = (void*)0x1, + .color = colorResource, + .depth = depthResource, + .motionVectors = motionResource, + .exposure = {}, + .reactive = {}, + .transparencyAndComposition = {}, + .output = outputResource, + .jitterOffset = {jitterX, jitterY}, + .motionVectorScale = {1, 1}, + .renderSize = {renderWidth, renderHeight}, + .enableSharpening = false, + .sharpness = 0, + .frameTimeDelta = static_cast(dt), + .preExposure = 1, + .reset = false, + .cameraNear = cameraNear, + .cameraFar = cameraFar, + .cameraFovAngleVertical = cameraFovY, + .viewSpaceToMetersFactor = 1, + }; + + if (auto err = ffxFsr2ContextDispatch(&fsr2Context, &dispatchDesc); err != FFX_OK) + { + printf("Error: %d\n", err); + } + + glMemoryBarrier(GL_ALL_BARRIER_BITS); + + Fwog::BlitTextureToSwapchain(frame.colorLdrWindowRes.value(), + {}, + {}, + frame.colorLdrWindowRes->Extent(), + frame.colorLdrWindowRes->Extent(), + Fwog::Filter::LINEAR); + + //Fwog::BeginSwapchainRendering({ + // .name = "Shading", + // .viewport = + // Fwog::Viewport{ + // .drawRect{.offset = {0, 0}, .extent = {windowWidth, windowHeight}}, + // .minDepth = 0.0f, + // .maxDepth = 1.0f, + // }, + // .colorLoadOp = Fwog::AttachmentLoadOp::DONT_CARE, + // .depthLoadOp = Fwog::AttachmentLoadOp::DONT_CARE, + // .stencilLoadOp = Fwog::AttachmentLoadOp::DONT_CARE, + //}); + //Fwog::EndRendering(); } void GltfViewerApplication::OnGui([[maybe_unused]] double dt) @@ -616,7 +720,7 @@ void GltfViewerApplication::OnGui([[maybe_unused]] double dt) ImGui::BeginTabBar("tabbed"); if (ImGui::BeginTabItem("G-Buffers")) { - float aspect = float(windowWidth) / windowHeight; + float aspect = float(renderWidth) / renderHeight; ImGui::Image(reinterpret_cast(static_cast(frame.gAlbedoSwizzled.value().Handle())), {100 * aspect, 100}, {0, 1}, diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 0eda4e1..7db85ce 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -13,8 +13,8 @@ target_link_libraries(02_deferred PRIVATE glfw lib_glad fwog glm lib_imgui) add_dependencies(02_deferred copy_shaders copy_textures) add_executable(03_gltf_viewer "03_gltf_viewer.cpp" common/Application.cpp common/Application.h common/SceneLoader.cpp common/SceneLoader.h "common/RsmTechnique.h" "common/RsmTechnique.cpp") -target_include_directories(03_gltf_viewer PUBLIC ${tinygltf_SOURCE_DIR} vendor) -target_link_libraries(03_gltf_viewer PRIVATE glfw lib_glad fwog glm lib_imgui) +target_include_directories(03_gltf_viewer PUBLIC ${tinygltf_SOURCE_DIR} ${FSR2_SOURCE} vendor) +target_link_libraries(03_gltf_viewer PRIVATE glfw lib_glad fwog glm lib_imgui ffx_fsr2_api_x64 ffx_fsr2_api_gl_x64) add_dependencies(03_gltf_viewer copy_shaders copy_models copy_textures) add_executable(04_volumetric "04_volumetric.cpp" common/Application.cpp common/Application.h common/SceneLoader.cpp common/SceneLoader.h) diff --git a/example/external/CMakeLists.txt b/example/external/CMakeLists.txt index b343a05..ddd87c9 100644 --- a/example/external/CMakeLists.txt +++ b/example/external/CMakeLists.txt @@ -30,8 +30,25 @@ FetchContent_Declare( GIT_TAG v1.88 ) + +option(GFX_API_DX12 "" OFF) +option(GFX_API_VK "" OFF) +option(GFX_API_GL "" ON) +option(FFX_FSR2_API_DX12 "" OFF) +option(FFX_FSR2_API_VK "" OFF) +option(FFX_FSR2_API_GL "" ON) +FetchContent_Declare( + fsr2 + GIT_REPOSITORY https://github.com/JuanDiegoMontoya/FidelityFX-FSR2.git + GIT_TAG 3312ca8c3ee25377d515512e54e72697dc62f251 + GIT_SUBMODULES "" +) + FetchContent_MakeAvailable(glm) FetchContent_MakeAvailable(tinygltf) +FetchContent_MakeAvailable(fsr2) + +set(FSR2_SOURCE ${fsr2_SOURCE_DIR} PARENT_SCOPE) FetchContent_GetProperties(imgui) if(NOT imgui_POPULATED) diff --git a/src/Rendering.cpp b/src/Rendering.cpp index 948293f..bfe25c8 100644 --- a/src/Rendering.cpp +++ b/src/Rendering.cpp @@ -1142,7 +1142,7 @@ namespace Fwog FWOG_ASSERT(context->isRendering || context->isComputeActive); FWOG_ASSERT(level < texture.GetCreateInfo().mipLevels); FWOG_ASSERT(IsValidImageFormat(texture.GetCreateInfo().format)); - + glBindImageTexture(index, const_cast(texture).Handle(), level, diff --git a/src/Texture.cpp b/src/Texture.cpp index 8d7a977..43b4b92 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -12,24 +12,6 @@ namespace Fwog { - namespace - { - void clearImage(uint32_t texture, const TextureClearInfo& info) - { - glClearTexSubImage(texture, - info.level, - info.offset.x, - info.offset.y, - info.offset.z, - info.extent.width, - info.extent.height, - info.extent.depth, - detail::UploadFormatToGL(info.format), - detail::UploadTypeToGL(info.type), - info.data); - } - } // namespace - namespace detail { uint32_t GetHandle(const Texture& texture) @@ -283,7 +265,37 @@ namespace Fwog void Texture::ClearImage(const TextureClearInfo& info) { - clearImage(id_, info); + GLenum format{}; + if (info.format == UploadFormat::INFER_FORMAT) + { + format = detail::UploadFormatToGL(detail::FormatToUploadFormat(createInfo_.format)); + } + else + { + format = detail::UploadFormatToGL(info.format); + } + + GLenum type{}; + if (info.type == UploadType::INFER_TYPE) + { + type = detail::FormatToTypeGL(createInfo_.format); + } + else + { + type = detail::UploadTypeToGL(info.type); + } + + glClearTexSubImage(id_, + info.level, + info.offset.x, + info.offset.y, + info.offset.z, + info.extent.width, + info.extent.height, + info.extent.depth, + format, + type, + info.data); } void Texture::GenMipmaps()