Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autoexposure example restoration #137

Open
wants to merge 50 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
345ac7b
Add 26_Autoexposure
nipunG314 Jul 19, 2024
87d4794
Change 26_Autoexposure to SimpleWindowedApplication
nipunG314 Jul 19, 2024
7a5ea7c
Build a staging buffer and upload exr image
nipunG314 Jul 24, 2024
5026a64
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Jul 24, 2024
5d63d04
Init surface and create the swapchain
nipunG314 Jul 25, 2024
640e6a3
Load shaders and create the pipeline for full screen triagnle
nipunG314 Jul 25, 2024
0148f60
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Jul 25, 2024
d69a111
Set window size according to loaded image
nipunG314 Jul 25, 2024
54bf38f
Stop running if window is closed
nipunG314 Jul 25, 2024
461efd3
Acquire swapchain image and present uploaded image to it
nipunG314 Jul 26, 2024
734fea9
Set window size directly and use that for swapchain rendering
nipunG314 Jul 26, 2024
fc9b0bb
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Jul 26, 2024
4a11724
m_computeSubgroupSize
nipunG314 Aug 5, 2024
734b887
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Aug 5, 2024
7d4895a
Allocate buffer for gathered luma values
nipunG314 Aug 8, 2024
0e3e125
Create gpu resources for all passes
nipunG314 Aug 9, 2024
cef80b3
Create shaders and pipelines
nipunG314 Aug 9, 2024
15e489f
Allocate and create texture for tonemapping
nipunG314 Aug 12, 2024
c646c7d
Create separate ds for luma and present
nipunG314 Aug 12, 2024
36d7097
Record luma meter commands
nipunG314 Aug 13, 2024
3a70977
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Aug 13, 2024
6addbf1
fix layout issues with compute pipeline in 26_Autoexposure example + …
AnastaZIuk Aug 13, 2024
8434f20
Create two sets from common lumaPresentLayout correctly
nipunG314 Aug 13, 2024
bf08caa
Create compute and graphics resources separately and finish luma meter
nipunG314 Aug 13, 2024
b342c6c
Fix descriptor binding for luma_meter
nipunG314 Aug 13, 2024
817c4a7
Create separate pipeline layouts for luma and present
nipunG314 Aug 13, 2024
7f89542
Setup luma_meter.comp.hlsl
nipunG314 Aug 13, 2024
defd45e
Pass push constants
nipunG314 Aug 13, 2024
f6f8154
Record draw pass correctly
nipunG314 Aug 14, 2024
64eb610
Add a pipeline barrier to transition image layout
nipunG314 Aug 14, 2024
3d3d646
Record tonemapping pass
nipunG314 Aug 14, 2024
b4102dc
Revert "Record tonemapping pass"
nipunG314 Aug 15, 2024
8307e92
Remove separate tonemapping pass
nipunG314 Aug 15, 2024
7b5ca05
Compute final EV value on CPU
nipunG314 Aug 16, 2024
edbf8d1
Compute EV correctly and tonemap in fragment shader
nipunG314 Aug 16, 2024
dca49d2
Separate LumaMeteringWindow into a common header
nipunG314 Aug 20, 2024
9e28395
Simplify luma_meter naming
nipunG314 Aug 20, 2024
8b6675b
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Aug 20, 2024
18fae9f
Update luma examples to shared accessor api
nipunG314 Aug 20, 2024
9b31c2c
Refactor tonemapping operators
nipunG314 Aug 20, 2024
e987452
Simplify push constants and remove explicit sample counts
nipunG314 Aug 21, 2024
e135e43
Infer sample count from viewportSize and simplify userspace HLSL
nipunG314 Aug 21, 2024
57e49ae
Templatize float type and add toXYZ method to TexAccessor
nipunG314 Aug 22, 2024
f8d50e8
Refactor the example into using a 2-compute, 1-fragment architecture
nipunG314 Aug 27, 2024
d3b5765
Handle image layouts correctly
nipunG314 Aug 28, 2024
612f0f6
Simplify type
nipunG314 Sep 27, 2024
cb46d82
Wait for correct semaphore value
nipunG314 Sep 27, 2024
1996cf3
Remove unnecessary data members
nipunG314 Sep 29, 2024
36633f5
Merge branch 'master' of github.com:Devsh-Graphics-Programming/Nabla-…
nipunG314 Dec 11, 2024
bc11b4a
Use asset converter for images and descriptors
nipunG314 Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions 23_Autoexposure/CMakeLists.txt

This file was deleted.

177 changes: 0 additions & 177 deletions 23_Autoexposure/main.cpp

This file was deleted.

25 changes: 25 additions & 0 deletions 26_Autoexposure/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

include(common RESULT_VARIABLE RES)
if(NOT RES)
message(FATAL_ERROR "common.cmake not found. Should be in {repo_root}/cmake directory")
endif()

nbl_create_executable_project("" "" "" "" "${NBL_EXECUTABLE_PROJECT_CREATION_PCH_TARGET}")

if(NBL_EMBED_BUILTIN_RESOURCES)
set(_BR_TARGET_ ${EXECUTABLE_NAME}_builtinResourceData)
set(RESOURCE_DIR "app_resources")

get_filename_component(_SEARCH_DIRECTORIES_ "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
get_filename_component(_OUTPUT_DIRECTORY_SOURCE_ "${CMAKE_CURRENT_BINARY_DIR}/src" ABSOLUTE)
get_filename_component(_OUTPUT_DIRECTORY_HEADER_ "${CMAKE_CURRENT_BINARY_DIR}/include" ABSOLUTE)

file(GLOB_RECURSE BUILTIN_RESOURCE_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_DIR}" CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_DIR}/*")
foreach(RES_FILE ${BUILTIN_RESOURCE_FILES})
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "${RES_FILE}")
endforeach()

ADD_CUSTOM_BUILTIN_RESOURCES(${_BR_TARGET_} RESOURCES_TO_EMBED "${_SEARCH_DIRECTORIES_}" "${RESOURCE_DIR}" "nbl::this_example::builtin" "${_OUTPUT_DIRECTORY_HEADER_}" "${_OUTPUT_DIRECTORY_SOURCE_}")

LINK_BUILTIN_RESOURCES_TO_TARGET(${EXECUTABLE_NAME} ${_BR_TARGET_})
endif()
21 changes: 21 additions & 0 deletions 26_Autoexposure/app_resources/common.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2018-2024 - DevSH Graphics Programming Sp. z O.O.
// This file is part of the "Nabla Engine".
// For conditions of distribution and use, see copyright notice in nabla.h

#ifndef _AUTOEXPOSURE_COMMON_INCLUDED_
#define _AUTOEXPOSURE_COMMON_INCLUDED_

#include "nbl/builtin/hlsl/cpp_compat.hlsl"

struct AutoexposurePushData
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't a struct for push constants shared between your Luma Meter and Tonemapper supposed to be in the extension headers?

{
float meteringWindowScaleX, meteringWindowScaleY;
float meteringWindowOffsetX, meteringWindowOffsetY;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use float32_t2 instead of splitting for X and Y

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize earlier that *_t2 types are available C++ side. I'll update these.

float lumaMin, lumaMax;
float EV;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EV bias! not just EV

uint32_t sampleCountX, sampleCountY;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need an X and Y sample count you just need an overall one

uint32_t viewportSizeX, viewportSizeY;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you need viewport sizes for ?

uint64_t lumaMeterBDA;
};

#endif
69 changes: 69 additions & 0 deletions 26_Autoexposure/app_resources/luma_meter.comp.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (C) 2024-2024 - DevSH Graphics Programming Sp. z O.O.
// This file is part of the "Nabla Engine".
// For conditions of distribution and use, see copyright notice in nabla.h

#include "nbl/builtin/hlsl/luma_meter/luma_meter.hlsl"
#include "nbl/builtin/hlsl/bda/bda_accessor.hlsl"
#include "app_resources/common.hlsl"

[[vk::combinedImageSampler]] [[vk::binding(0, 0)]] Texture2D texture;
[[vk::combinedImageSampler]] [[vk::binding(0, 0)]] SamplerState samplerState;

[[vk::push_constant]] AutoexposurePushData pushData;

using Ptr = nbl::hlsl::bda::__ptr < uint32_t >;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pro tip, you can actually put `using namespace nbl::hlsl; in your "main" hlsl files (the ones with entry points)

using PtrAccessor = nbl::hlsl::BdaAccessor < uint32_t >;

groupshared float32_t sdata[WorkgroupSize];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you tying histogram size to WorkgroupSize ?


struct SharedAccessor
{
uint32_t get(const uint32_t index)
{
return sdata[index];
}

void set(const uint32_t index, const uint32_t value)
{
sdata[index] = value;
}

void workgroupExecutionAndMemoryBarrier()
{
nbl::hlsl::glsl::barrier();
}
};

struct TexAccessor
{
float32_t3 get(float32_t2 uv) {
return texture.Sample(samplerState, uv).rgb;
}
Comment on lines +45 to +47
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the TexAcessor is supposed to "know" the colorspace of the input image, I'd rather have it return float32_t luma with the CIE XYZ luminance component extraction finished here already

};

uint32_t3 nbl::hlsl::glsl::gl_WorkGroupSize()
{
return uint32_t3(WorkgroupSize, 1, 1);
}

[numthreads(DeviceSubgroupSize, DeviceSubgroupSize, 1)]
void main(uint32_t3 ID : SV_GroupThreadID, uint32_t3 GroupID : SV_GroupID)
{
nbl::hlsl::luma_meter::LumaMeteringWindow luma_meter_window;
luma_meter_window.meteringWindowScale = float32_t2(pushData.meteringWindowScaleX, pushData.meteringWindowScaleY);
luma_meter_window.meteringWindowOffset = float32_t2(pushData.meteringWindowOffsetX, pushData.meteringWindowOffsetY);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be using nbl::hlsl::luma_meter::LumaMeteringWindow directly in your pushData, instead of having to reconstitute it from individual scalars


const Ptr val_ptr = Ptr::create(pushData.lumaMeterBDA);
PtrAccessor val_accessor = PtrAccessor::create(val_ptr);

SharedAccessor sdata;
TexAccessor tex;

using LumaMeter = nbl::hlsl::luma_meter::geom_luma_meter< WorkgroupSize, PtrAccessor, SharedAccessor, TexAccessor>;
LumaMeter meter = LumaMeter::create(luma_meter_window, pushData.lumaMin, pushData.lumaMax);

uint32_t2 sampleCount = uint32_t2(pushData.sampleCountX, pushData.sampleCountY);
uint32_t2 viewportSize = uint32_t2(pushData.viewportSizeX, pushData.viewportSizeY);

meter.gatherLuma(val_accessor, tex, sdata, sampleCount, viewportSize);
}
34 changes: 34 additions & 0 deletions 26_Autoexposure/app_resources/present.frag.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2024-2024 - DevSH Graphics Programming Sp. z O.O.
// This file is part of the "Nabla Engine".
// For conditions of distribution and use, see copyright notice in nabla.h

#pragma wave shader_stage(fragment)

#include "nbl/builtin/hlsl/colorspace/EOTF.hlsl"
#include "nbl/builtin/hlsl/colorspace/encodeCIEXYZ.hlsl"
#include "nbl/builtin/hlsl/colorspace/decodeCIEXYZ.hlsl"
#include "nbl/builtin/hlsl/colorspace/OETF.hlsl"
#include "nbl/builtin/hlsl/tonemapper/operators.hlsl"
#include "app_resources/common.hlsl"

// vertex shader is provided by the fullScreenTriangle extension
#include <nbl/builtin/hlsl/ext/FullScreenTriangle/SVertexAttributes.hlsl>
using namespace nbl::hlsl::ext::FullScreenTriangle;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slap more using namespace here so this is easier to read


// binding 0 set 1
[[vk::combinedImageSampler]] [[vk::binding(0, 1)]] Texture2D texture;
[[vk::combinedImageSampler]] [[vk::binding(0, 1)]] SamplerState samplerState;

[[vk::push_constant]] AutoexposurePushData pushData;

[[vk::location(0)]] float32_t4 main(SVertexAttributes vxAttr) : SV_Target0
{
float32_t3 color = nbl::hlsl::colorspace::oetf::sRGB(texture.Sample(samplerState, vxAttr.uv).rgb);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the texture view you bound to texture is already an SRGB format image, no eotf needs to be applied! (the sampler returns linear colours)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. also it would have been eotf not oetf IIRC

float32_t3 CIEColor = mul(nbl::hlsl::colorspace::sRGBtoXYZ, color);

nbl::hlsl::tonemapper::ReinhardParams params = nbl::hlsl::tonemapper::ReinhardParams::create(pushData.EV);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're not supposed to get the EV value from a push constant, this is why the OLD GLSL code used compute to do the tonemapping, because workgroups were cooperatively used to get the mid-gray value


float32_t3 tonemappedColor = mul(nbl::hlsl::colorspace::decode::XYZtoscRGB, nbl::hlsl::tonemapper::reinhard(params, CIEColor));

return float32_t4(nbl::hlsl::colorspace::eotf::sRGB(tonemappedColor), 1.0);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, if you're rendering to a framebuffer that has an sRGB format attachment, you don't need an oetf.

You'd only need it if doign an imageStore in a compute tonemapper to an RGBA8_UNORM image view of an RGBA8_SRGB image

}
Loading