|
8 | 8 | #include "nbl/asset/interchange/IAssetLoader.h"
|
9 | 9 | #include "nbl/ext/FullScreenTriangle/FullScreenTriangle.h"
|
10 | 10 |
|
| 11 | +#include "app_resources/common.hlsl" |
| 12 | + |
11 | 13 | using namespace nbl;
|
12 | 14 | using namespace core;
|
13 | 15 | using namespace hlsl;
|
@@ -186,41 +188,90 @@ class AutoexposureApp final : public examples::SimpleWindowedApplication, public
|
186 | 188 | return logFail("Failed to create Renderpass!");
|
187 | 189 | }
|
188 | 190 |
|
189 |
| - // Load the shaders and create the pipeline |
| 191 | + // Load the shaders and create the pipelines |
190 | 192 | {
|
| 193 | + auto loadCompileAndCreateShader = [&](const std::string& relPath) -> smart_refctd_ptr<IGPUShader> |
| 194 | + { |
| 195 | + IAssetLoader::SAssetLoadParams lp = {}; |
| 196 | + lp.logger = m_logger.get(); |
| 197 | + lp.workingDirectory = ""; // virtual root |
| 198 | + auto assetBundle = m_assetMgr->getAsset(relPath, lp); |
| 199 | + const auto assets = assetBundle.getContents(); |
| 200 | + if (assets.empty()) |
| 201 | + return nullptr; |
| 202 | + |
| 203 | + // lets go straight from ICPUSpecializedShader to IGPUSpecializedShader |
| 204 | + auto source = IAsset::castDown<ICPUShader>(assets[0]); |
| 205 | + if (!source) |
| 206 | + return nullptr; |
| 207 | + const uint32_t workgroupSize = m_physicalDevice->getLimits().maxComputeWorkGroupInvocations; |
| 208 | + const uint32_t subgroupSize = m_physicalDevice->getLimits().maxSubgroupSize; |
| 209 | + auto overriddenSource = CHLSLCompiler::createOverridenCopy( |
| 210 | + source.get(), |
| 211 | + "#define WorkgroupSize %d\n#define DeviceSubgroupSize %d\n", |
| 212 | + workgroupSize, |
| 213 | + subgroupSize |
| 214 | + ); |
| 215 | + |
| 216 | + return m_device->createShader(overriddenSource.get()); |
| 217 | + }; |
| 218 | + |
| 219 | + auto createComputePipeline = [&](smart_refctd_ptr<IGPUShader> shader, smart_refctd_ptr<IGPUComputePipeline> pipeline) -> bool |
| 220 | + { |
| 221 | + const nbl::asset::SPushConstantRange pcRange = { |
| 222 | + .stageFlags = IShader::E_SHADER_STAGE::ESS_COMPUTE, |
| 223 | + .offset = 0, |
| 224 | + .size = sizeof(AutoexposurePushData) |
| 225 | + }; |
| 226 | + |
| 227 | + smart_refctd_ptr<IGPUPipelineLayout> layout; |
| 228 | + { |
| 229 | + layout = m_device->createPipelineLayout({ &pcRange,1 }); |
| 230 | + IGPUComputePipeline::SCreationParams params = {}; |
| 231 | + params.layout = layout.get(); |
| 232 | + params.shader.shader = shader.get(); |
| 233 | + params.shader.entryPoint = "main"; |
| 234 | + params.shader.entries = nullptr; |
| 235 | + params.shader.requireFullSubgroups = true; |
| 236 | + params.shader.requiredSubgroupSize = static_cast<IGPUShader::SSpecInfo::SUBGROUP_SIZE>(5); |
| 237 | + if (!m_device->createComputePipelines(nullptr, { ¶ms,1 }, &pipeline)) |
| 238 | + return logFail("Failed to create compute pipeline!\n"); |
| 239 | + } |
| 240 | + |
| 241 | + return true; |
| 242 | + }; |
| 243 | + |
| 244 | + // Luma Meter |
| 245 | + auto lumaMeterShader = loadCompileAndCreateShader("app_resources/luma_meter.comp.hlsl"); |
| 246 | + if (!lumaMeterShader) |
| 247 | + return logFail("Failed to Load and Compile Compute Shader: lumaMeterShader!"); |
| 248 | + auto lumaPresentLayout = m_device->createPipelineLayout({}, nullptr, nullptr, nullptr, core::smart_refctd_ptr(lumaPresentDSLayout)); |
| 249 | + if (!createComputePipeline(lumaMeterShader, m_lumaMeterPipeline)) |
| 250 | + return logFail("Could not create Luma Meter Pipeline!"); |
| 251 | + |
| 252 | + // Tonemapper |
| 253 | + auto tonemapperShader = loadCompileAndCreateShader("app_resources/tonemapper.comp.hlsl"); |
| 254 | + if (!tonemapperShader) |
| 255 | + return logFail("Failed to Load and Compile Compute Shader: tonemapperShader!"); |
| 256 | + auto tonemapperLayout = m_device->createPipelineLayout({}, nullptr, nullptr, nullptr, core::smart_refctd_ptr(tonemapperDSLayout)); |
| 257 | + if (!createComputePipeline(tonemapperShader, m_tonemapperPipeline)) |
| 258 | + return logFail("Could not create Luma Meter Pipeline!"); |
| 259 | + |
191 | 260 | // Load FSTri Shader
|
192 | 261 | ext::FullScreenTriangle::ProtoPipeline fsTriProtoPPln(m_assetMgr.get(), m_device.get(), m_logger.get());
|
193 | 262 | if (!fsTriProtoPPln)
|
194 | 263 | return logFail("Failed to create Full Screen Triangle protopipeline or load its vertex shader!");
|
195 | 264 |
|
196 |
| - // Load Custom Shader |
197 |
| - auto loadCompileAndCreateShader = [&](const std::string& relPath) -> smart_refctd_ptr<IGPUShader> |
198 |
| - { |
199 |
| - IAssetLoader::SAssetLoadParams lp = {}; |
200 |
| - lp.logger = m_logger.get(); |
201 |
| - lp.workingDirectory = ""; // virtual root |
202 |
| - auto assetBundle = m_assetMgr->getAsset(relPath, lp); |
203 |
| - const auto assets = assetBundle.getContents(); |
204 |
| - if (assets.empty()) |
205 |
| - return nullptr; |
206 |
| - |
207 |
| - // lets go straight from ICPUSpecializedShader to IGPUSpecializedShader |
208 |
| - auto source = IAsset::castDown<ICPUShader>(assets[0]); |
209 |
| - if (!source) |
210 |
| - return nullptr; |
211 |
| - |
212 |
| - return m_device->createShader(source.get()); |
213 |
| - }; |
214 |
| - auto fragmentShader = loadCompileAndCreateShader("app_resources/present.frag.hlsl"); |
| 265 | + // Load Fragment Shader |
| 266 | + auto fragmentShader = loadCompileAndCreateShader("app_resources/present.frag.hlsl");; |
215 | 267 | if (!fragmentShader)
|
216 |
| - return logFail("Failed to Load and Compile Fragment Shader!"); |
| 268 | + return logFail("Failed to Load and Compile Fragment Shader: lumaMeterShader!"); |
217 | 269 |
|
218 |
| - auto layout = m_device->createPipelineLayout({}, nullptr, nullptr, nullptr, core::smart_refctd_ptr(lumaPresentDSLayout)); |
219 | 270 | const IGPUShader::SSpecInfo fragSpec = {
|
220 | 271 | .entryPoint = "main",
|
221 | 272 | .shader = fragmentShader.get()
|
222 | 273 | };
|
223 |
| - m_presentPipeline = fsTriProtoPPln.createPipeline(fragSpec, layout.get(), scResources->getRenderpass()); |
| 274 | + m_presentPipeline = fsTriProtoPPln.createPipeline(fragSpec, lumaPresentLayout.get(), scResources->getRenderpass()); |
224 | 275 | if (!m_presentPipeline)
|
225 | 276 | return logFail("Could not create Graphics Pipeline!");
|
226 | 277 | }
|
|
0 commit comments