Skip to content

Commit 974d23f

Browse files
committed
Enabled build time shader compilation in example 10
1 parent 22f2a17 commit 974d23f

File tree

3 files changed

+102
-17
lines changed

3 files changed

+102
-17
lines changed

10_CountingSort/CMakeLists.txt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,71 @@ if(NBL_EMBED_BUILTIN_RESOURCES)
2222

2323
LINK_BUILTIN_RESOURCES_TO_TARGET(${EXECUTABLE_NAME} ${_BR_TARGET_})
2424
endif()
25+
26+
set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/auto-gen")
27+
set(DEPENDS
28+
app_resources/common.hlsl
29+
app_resources/prefix_sum_shader.comp.hlsl
30+
app_resources/scatter_shader.comp.hlsl
31+
)
32+
target_sources(${EXECUTABLE_NAME} PRIVATE ${DEPENDS})
33+
set_source_files_properties(${DEPENDS} PROPERTIES HEADER_FILE_ONLY ON)
34+
35+
set(SM 6_8)
36+
set(REQUIRED_CAPS [=[
37+
{
38+
"kind": "limits",
39+
"name": "maxComputeWorkGroupInvocations",
40+
"type": "uint32_t",
41+
"values": [256,512,1024]
42+
},
43+
{
44+
"kind": "limits",
45+
"name": "maxComputeSharedMemorySize",
46+
"type": "uint32_t",
47+
"values": [16384, 32768, 65536]
48+
}
49+
]=])
50+
51+
set(JSON [=[
52+
[
53+
{
54+
"INPUT": "app_resources/prefix_sum_shader.comp.hlsl",
55+
"KEY": "prefix_sum_shader",
56+
"CAPS": [${REQUIRED_CAPS}]
57+
},
58+
{
59+
"INPUT": "app_resources/scatter_shader.comp.hlsl",
60+
"KEY": "scatter_shader",
61+
"CAPS": [${REQUIRED_CAPS}]
62+
}
63+
]
64+
]=])
65+
string(CONFIGURE "${JSON}" JSON)
66+
67+
set(COMPILE_OPTIONS
68+
-I "${CMAKE_CURRENT_SOURCE_DIR}"
69+
-O3
70+
-T lib_${SM}
71+
)
72+
73+
NBL_CREATE_NSC_COMPILE_RULES(
74+
TARGET ${EXECUTABLE_NAME}SPIRV
75+
LINK_TO ${EXECUTABLE_NAME}
76+
DEPENDS ${DEPENDS}
77+
BINARY_DIR ${OUTPUT_DIRECTORY}
78+
MOUNT_POINT_DEFINE NBL_THIS_EXAMPLE_BUILD_MOUNT_POINT
79+
COMMON_OPTIONS ${COMPILE_OPTIONS}
80+
OUTPUT_VAR KEYS
81+
INCLUDE nbl/this_example/builtin/build/spirv/keys.hpp
82+
NAMESPACE nbl::this_example::builtin::build
83+
INPUTS ${JSON}
84+
)
85+
86+
NBL_CREATE_RESOURCE_ARCHIVE(
87+
NAMESPACE nbl::this_example::builtin::build
88+
TARGET ${EXECUTABLE_NAME}_builtinsBuild
89+
LINK_TO ${EXECUTABLE_NAME}
90+
BIND ${OUTPUT_DIRECTORY}
91+
BUILTINS ${KEYS}
92+
)

10_CountingSort/app_resources/common.hlsl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ using namespace nbl::hlsl;
2222
#ifdef __HLSL_VERSION
2323
#include "nbl/builtin/hlsl/bda/bda_accessor.hlsl"
2424

25+
static const uint32_t WorkgroupSize = DeviceConfigCaps::maxComputeWorkGroupInvocations;
26+
static const uint32_t MaxBucketCount = (DeviceConfigCaps::maxComputeSharedMemorySize / sizeof(uint32_t)) / 2;
27+
static const uint32_t BucketCount = (MaxBucketCount > 3000) ? 3000 : MaxBucketCount;
28+
2529
using Ptr = bda::__ptr<uint32_t>;
2630
using PtrAccessor = BdaAccessor<uint32_t>;
2731

@@ -54,6 +58,8 @@ uint32_t3 glsl::gl_WorkGroupSize()
5458
{
5559
return uint32_t3(WorkgroupSize, 1, 1);
5660
}
61+
62+
5763
#endif
5864

5965
#endif

10_CountingSort/main.cpp

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "nbl/examples/examples.hpp"
2+
#include "nbl/this_example/builtin/build/spirv/keys.hpp"
23

34
using namespace nbl;
45
using namespace nbl::core;
@@ -32,49 +33,59 @@ class CountingSortApp final : public application_templates::MonoDeviceApplicatio
3233
return false;
3334

3435
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+
3550
const uint32_t WorkgroupSize = limits.maxComputeWorkGroupInvocations;
3651
const uint32_t MaxBucketCount = (limits.maxComputeSharedMemorySize / sizeof(uint32_t)) / 2;
3752
constexpr uint32_t element_count = 100000;
3853
const uint32_t bucket_count = std::min((uint32_t)3000, MaxBucketCount);
3954
const uint32_t elements_per_thread = ceil((float)ceil((float)element_count / limits.computeUnits) / WorkgroupSize);
4055

41-
auto prepShader = [&](const core::string& path) -> smart_refctd_ptr<IShader>
56+
auto loadPrecompiledShader = [&]<core::StringLiteral ShaderKey>() -> smart_refctd_ptr<IShader>
4257
{
4358
// this time we load a shader directly from a file
4459
IAssetLoader::SAssetLoadParams lp = {};
4560
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);
4864
const auto assets = assetBundle.getContents();
4965
if (assets.empty())
5066
{
5167
logFail("Could not load shader!");
5268
return nullptr;
5369
}
5470

55-
auto source = IAsset::castDown<IShader>(assets[0]);
71+
auto shader = IAsset::castDown<IShader>(assets[0]);
5672
// The down-cast should not fail!
57-
assert(source);
73+
assert(shader);
5874

5975
// There's two ways of doing stuff like this:
6076
// 1. this - modifying the asset after load
6177
// 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+
//);
6683

6784
// 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-
}
7485
return shader;
7586
};
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"
7889

7990
// People love Reflection but I prefer Shader Sources instead!
8091
const nbl::asset::SPushConstantRange pcRange = { .stageFlags = IShader::E_SHADER_STAGE::ESS_COMPUTE,.offset = 0,.size = sizeof(CountingPushData) };

0 commit comments

Comments
 (0)