|
1 | 1 | #include "nbl/examples/examples.hpp" |
| 2 | +#include "nbl/this_example/builtin/build/spirv/keys.hpp" |
2 | 3 |
|
3 | 4 | using namespace nbl; |
4 | 5 | using namespace nbl::core; |
@@ -32,49 +33,59 @@ class CountingSortApp final : public application_templates::MonoDeviceApplicatio |
32 | 33 | return false; |
33 | 34 |
|
34 | 35 | auto limits = m_physicalDevice->getLimits(); |
| 36 | + constexpr std::array<uint32_t, 3u> AllowedMaxComputeSharedMemorySizes = { |
| 37 | + 16384, 32768, 65536 |
| 38 | + }; |
| 39 | + |
| 40 | + auto upperBoundSharedMemSize = std::upper_bound(AllowedMaxComputeSharedMemorySizes.begin(), AllowedMaxComputeSharedMemorySizes.end(), limits.maxComputeSharedMemorySize); |
| 41 | + // devices which support less than 16KB of max compute shared memory size are not supported |
| 42 | + if (upperBoundSharedMemSize == AllowedMaxComputeSharedMemorySizes.begin()) |
| 43 | + { |
| 44 | + m_logger->log("maxComputeSharedMemorySize is too low (%u)", ILogger::E_LOG_LEVEL::ELL_ERROR, limits.maxComputeSharedMemorySize); |
| 45 | + exit(0); |
| 46 | + } |
| 47 | + |
| 48 | + limits.maxComputeSharedMemorySize = *(upperBoundSharedMemSize - 1); |
| 49 | + |
35 | 50 | const uint32_t WorkgroupSize = limits.maxComputeWorkGroupInvocations; |
36 | 51 | const uint32_t MaxBucketCount = (limits.maxComputeSharedMemorySize / sizeof(uint32_t)) / 2; |
37 | 52 | constexpr uint32_t element_count = 100000; |
38 | 53 | const uint32_t bucket_count = std::min((uint32_t)3000, MaxBucketCount); |
39 | 54 | const uint32_t elements_per_thread = ceil((float)ceil((float)element_count / limits.computeUnits) / WorkgroupSize); |
40 | 55 |
|
41 | | - auto prepShader = [&](const core::string& path) -> smart_refctd_ptr<IShader> |
| 56 | + auto loadPrecompiledShader = [&]<core::StringLiteral ShaderKey>() -> smart_refctd_ptr<IShader> |
42 | 57 | { |
43 | 58 | // this time we load a shader directly from a file |
44 | 59 | IAssetLoader::SAssetLoadParams lp = {}; |
45 | 60 | lp.logger = m_logger.get(); |
46 | | - lp.workingDirectory = ""; // virtual root |
47 | | - auto assetBundle = m_assetMgr->getAsset(path,lp); |
| 61 | + lp.workingDirectory = "app_resources"; // virtual root |
| 62 | + auto key = nbl::this_example::builtin::build::get_spirv_key<ShaderKey>(limits, m_physicalDevice->getFeatures()); |
| 63 | + auto assetBundle = m_assetMgr->getAsset(key.data(), lp); |
48 | 64 | const auto assets = assetBundle.getContents(); |
49 | 65 | if (assets.empty()) |
50 | 66 | { |
51 | 67 | logFail("Could not load shader!"); |
52 | 68 | return nullptr; |
53 | 69 | } |
54 | 70 |
|
55 | | - auto source = IAsset::castDown<IShader>(assets[0]); |
| 71 | + auto shader = IAsset::castDown<IShader>(assets[0]); |
56 | 72 | // The down-cast should not fail! |
57 | | - assert(source); |
| 73 | + assert(shader); |
58 | 74 |
|
59 | 75 | // There's two ways of doing stuff like this: |
60 | 76 | // 1. this - modifying the asset after load |
61 | 77 | // 2. creating a short shader source file that includes the asset you would have wanted to load |
62 | | - auto overrideSource = CHLSLCompiler::createOverridenCopy( |
63 | | - source.get(), "#define WorkgroupSize %d\n#define BucketCount %d\n", |
64 | | - WorkgroupSize, bucket_count |
65 | | - ); |
| 78 | + // |
| 79 | + //auto overrideSource = CHLSLCompiler::createOverridenCopy( |
| 80 | + // source.get(), "#define WorkgroupSize %d\n#define BucketCount %d\n", |
| 81 | + // WorkgroupSize, bucket_count |
| 82 | + //); |
66 | 83 |
|
67 | 84 | // this time we skip the use of the asset converter since the IShader->IGPUShader path is quick and simple |
68 | | - auto shader = m_device->compileShader({ overrideSource.get() }); |
69 | | - if (!shader) |
70 | | - { |
71 | | - logFail("Creation of Prefix Sum Shader from CPU Shader source failed!"); |
72 | | - return nullptr; |
73 | | - } |
74 | 85 | return shader; |
75 | 86 | }; |
76 | | - auto prefixSumShader = prepShader("app_resources/prefix_sum_shader.comp.hlsl"); |
77 | | - auto scatterShader = prepShader("app_resources/scatter_shader.comp.hlsl"); |
| 87 | + auto prefixSumShader = loadPrecompiledShader.operator()<"prefix_sum_shader">(); // "app_resources/prefix_sum_shader.comp.hlsl" |
| 88 | + auto scatterShader = loadPrecompiledShader.operator()<"scatter_shader">(); // "app_resources/scatter_shader.comp.hlsl" |
78 | 89 |
|
79 | 90 | // People love Reflection but I prefer Shader Sources instead! |
80 | 91 | const nbl::asset::SPushConstantRange pcRange = { .stageFlags = IShader::E_SHADER_STAGE::ESS_COMPUTE,.offset = 0,.size = sizeof(CountingPushData) }; |
|
0 commit comments