Skip to content

Commit 5bee07e

Browse files
Port Full Screen Triangle fully, also add our first GLSL.450.STD instrinsics
1 parent 3b138e9 commit 5bee07e

File tree

8 files changed

+136
-120
lines changed

8 files changed

+136
-120
lines changed

3rdparty/dxc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ if(NBL_EMBED_BUILTIN_RESOURCES)
139139
# SPIRV Header in builtin resources, nbl paths as aliases
140140
LIST_BUILTIN_RESOURCE(SPIRV_RESOURCES_TO_EMBED "unified1/spirv.h")
141141
LIST_BUILTIN_RESOURCE(SPIRV_RESOURCES_TO_EMBED "unified1/spirv.hpp")
142+
LIST_BUILTIN_RESOURCE(SPIRV_RESOURCES_TO_EMBED "unified1/GLSL.std.450.h")
142143

143144
ADD_CUSTOM_BUILTIN_RESOURCES(spirvBuiltinResourceData SPIRV_RESOURCES_TO_EMBED "${_SPIRV_BR_BUNDLE_SEARCH_DIRECTORY_}" "spirv" "spirv::builtin" "${_SPIRV_BR_OUTPUT_DIRECTORY_HEADER_}" "${_SPIRV_BR_OUTPUT_DIRECTORY_SOURCE_}" "STATIC" "INTERNAL")
144145
endif()

include/nbl/builtin/hlsl/ext/FullScreenTriangle/SVertexAttributes.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace ext
1313
namespace FullScreenTriangle
1414
{
1515

16-
struct VertexAttributes
16+
struct SVertexAttributes
1717
{
1818
[[vk::location(0)]] float32_t2 uv : TEXCOORD0;
1919
};

include/nbl/builtin/hlsl/ext/FullScreenTriangle/default.vert.hlsl

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// For conditions of distribution and use, see copyright notice in nabla.h
44
#include <nbl/builtin/hlsl/glsl_compat/core.hlsl>
55
#include <nbl/builtin/hlsl/ext/FullScreenTriangle/SVertexAttributes.hlsl>
6-
//#include <nbl/builtin/glsl/utils/surface_transform.glsl>
6+
#include <nbl/builtin/hlsl/surface_transform.h>
77

88
using namespace ::nbl::hlsl;
99
using namespace ::nbl::hlsl::ext::FullScreenTriangle;
@@ -19,20 +19,18 @@ const static float32_t2 tc[3] = {
1919
float32_t2(2.0,0.0)
2020
};
2121

22-
/*
23-
layout (push_constant) uniform pushConstants
24-
{
25-
layout (offset = 0) uint swapchainTransform;
26-
} u_pushConstants;
27-
*/
22+
[[vk::constant_id(0)]] const uint32_t SwapchainTransform = 0;
23+
2824

29-
VertexAttributes main()
25+
SVertexAttributes main()
3026
{
3127
using namespace ::nbl::hlsl::glsl;
3228

33-
VertexAttributes retval;
34-
// vec2 pos = nbl_glsl_surface_transform_applyToNDC(u_pushConstants.swapchainTransform, pos[gl_VertexIndex]);
35-
spirv::Position = float32_t4(pos[gl_VertexIndex()], 0.f, 1.f);
29+
spirv::Position.xy = SurfaceTransform::applyToNDC((SurfaceTransform::FLAG_BITS)SwapchainTransform,pos[gl_VertexIndex()]);
30+
spirv::Position.z = 0.f;
31+
spirv::Position.w = 1.f;
32+
33+
SVertexAttributes retval;
3634
retval.uv = tc[gl_VertexIndex()];
3735
return retval;
3836
}

include/nbl/builtin/hlsl/glsl_compat/core.hlsl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ namespace glsl
1616
{
1717

1818
#ifdef __HLSL_VERSION
19+
/**
20+
* Generic SPIR-V
21+
*/
1922
template<typename T>
2023
T atomicAdd(NBL_REF_ARG(T) ptr, T value)
2124
{
@@ -57,6 +60,16 @@ T atomicCompSwap(NBL_REF_ARG(T) ptr, T comparator, T value)
5760
return spirv::atomicCompSwap<T>(ptr, spv::ScopeDevice, spv::DecorationRelaxedPrecision, spv::DecorationRelaxedPrecision, value, comparator);
5861
}
5962

63+
/**
64+
* GLSL extended math
65+
*/
66+
template<typename SquareMatrix> // NBL_REQUIRES() extents are square
67+
SquareMatrix inverse(NBL_CONST_REF_ARG(SquareMatrix) mat)
68+
{
69+
return spirv::matrixInverse(mat);
70+
}
71+
72+
6073
/**
6174
* For Vertex Shaders
6275
*/

include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#ifdef __HLSL_VERSION // TODO: AnastZIuk fix public search paths so we don't choke
99
#include "spirv/unified1/spirv.hpp"
10-
//#include "spirv/unified1/spirv.hpp" TODO: also GLSL.450.std for the extended instruction set
10+
#include "spirv/unified1/GLSL.std.450.h"
1111
#endif
1212

1313

@@ -47,6 +47,7 @@ static const uint32_t3 GlobalInvocationId;
4747
[[vk::ext_builtin_input(spv::BuiltInLocalInvocationIndex)]]
4848
static const uint32_t LocalInvocationIndex;
4949

50+
//! General Operations
5051
template<typename T>
5152
T atomicAdd([[vk::ext_reference]] T ptr, uint32_t memoryScope, uint32_t memorySemantics, T value);
5253
template<>
@@ -124,6 +125,10 @@ template<>
124125
uint32_t atomicCompSwap([[vk::ext_reference]] uint32_t ptr, uint32_t memoryScope, uint32_t memSemanticsEqual, uint32_t memSemanticsUnequal, uint32_t value, uint32_t comparator);
125126

126127

128+
//! Std 450 Extended set operations
129+
template<typename SquareMatrix>
130+
[[vk::ext_instruction(GLSLstd450MatrixInverse)]]
131+
SquareMatrix matrixInverse(NBL_CONST_REF_ARG(SquareMatrix) mat);
127132

128133
// Memory Semantics link here: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Memory_Semantics_-id-
129134

include/nbl/builtin/hlsl/surface_transform.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#ifndef _NBL_BUILTIN_HLSL_SURFACE_TRANSFORM_INCLUDED_
55
#define _NBL_BUILTIN_HLSL_SURFACE_TRANSFORM_INCLUDED_
66
#include <nbl/builtin/hlsl/limits.hlsl>
7+
#include <nbl/builtin/hlsl/glsl_compat/core.hlsl>
78

89
namespace nbl
910
{
@@ -82,7 +83,7 @@ inline uint16_t2 transformedExtents(const FLAG_BITS transform, const uint16_t2 s
8283
default:
8384
break;
8485
}
85-
return uint16_t2(0);
86+
return uint16_t2(0,0);
8687
}
8788

8889
inline float transformedAspectRatio(const FLAG_BITS transform, const uint16_t2 screenSize)
@@ -123,7 +124,7 @@ inline uint16_t2 applyInverseToScreenSpaceCoordinate(const FLAG_BITS transform,
123124
default:
124125
break;
125126
}
126-
return uint16_t2(0);
127+
return uint16_t2(0,0);
127128
}
128129

129130
//! Use this function to apply the swapchain tranformation to the screenspace coordinate `coord`
@@ -155,7 +156,7 @@ inline uint16_t2 applyToScreenSpaceCoordinate(const FLAG_BITS transform, const u
155156
default:
156157
break;
157158
}
158-
return uint16_t2(0);
159+
return uint16_t2(0,0);
159160
}
160161

161162
//! Same as `applyToScreenSpaceCoordinate` but const NDC space
@@ -173,6 +174,7 @@ inline float32_t2 applyToNDC(const FLAG_BITS transform, const float32_t2 ndc)
173174
template<typename TwoColumns>
174175
TwoColumns applyToDerivatives(const FLAG_BITS transform, TwoColumns dDx_dDy)
175176
{
177+
using namespace glsl; // IN HLSL mode, C++ doens't need this to access `inverse`
176178
return mul(inverse(transformMatrix(transform)),dDx_dDy);
177179
}
178180

include/nbl/ext/FullScreenTriangle/FullScreenTriangle.h

Lines changed: 100 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,110 +8,107 @@
88

99
namespace nbl::ext::FullScreenTriangle
1010
{
11-
12-
#if 0
13-
inline NBL_PROTO_PIPELINE createProtoPipeline(, uint32_t pushConstantOffset)
14-
{
15-
if (!cpu2gpuParams.assetManager)
16-
assert(false);
17-
18-
nbl::video::IGPUObjectFromAssetConverter cpu2gpu;
19-
auto* assetManager = cpu2gpuParams.assetManager;
20-
21-
NBL_PROTO_PIPELINE protoPipeline;
22-
23-
asset::IAsset::E_TYPE types[] = { asset::IAsset::ET_SPECIALIZED_SHADER,static_cast<asset::IAsset::E_TYPE>(0u) };
24-
auto found = assetManager->findAssets("nbl/builtin/specialized_shader/fullscreentriangle.vert", types);
25-
assert(found->size());
26-
auto contents = found->begin()->getContents();
27-
assert(!contents.empty());
28-
auto pShader = static_cast<asset::ICPUSpecializedShader*>((contents.begin()->get()));
29-
30-
auto& gpuSpecializedShader = std::get<core::smart_refctd_ptr<video::IGPUSpecializedShader>>(protoPipeline);
31-
{
32-
auto gpu_array = cpu2gpu.getGPUObjectsFromAssets(&pShader, &pShader + 1, cpu2gpuParams);
33-
if (!gpu_array || gpu_array->size() < 1u || !(*gpu_array)[0])
34-
assert(false);
35-
36-
gpuSpecializedShader = (*gpu_array)[0];
37-
}
38-
39-
auto& inputParams = std::get<asset::SVertexInputParams>(protoPipeline);
40-
{
41-
inputParams.enabledBindingFlags = inputParams.enabledAttribFlags = 0u;
42-
for (size_t i=0ull; i<asset::SVertexInputParams::MAX_VERTEX_ATTRIB_COUNT; i++)
43-
inputParams.attributes[i] = {0u,asset::EF_UNKNOWN,0u};
44-
for (size_t i=0ull; i<asset::SVertexInputParams::MAX_ATTR_BUF_BINDING_COUNT; i++)
45-
inputParams.bindings[i] = {0u,asset::EVIR_PER_VERTEX};
46-
}
47-
48-
auto& assemblyParams = std::get<asset::SPrimitiveAssemblyParams>(protoPipeline);
49-
assemblyParams.primitiveRestartEnable = false;
50-
assemblyParams.primitiveType = asset::EPT_TRIANGLE_LIST;
51-
assemblyParams.tessPatchVertCount = 3u;
52-
53-
auto& blendParams = std::get<asset::SBlendParams>(protoPipeline);
54-
blendParams.logicOpEnable = false;
55-
blendParams.logicOp = nbl::asset::ELO_NO_OP;
56-
57-
auto& rasterParams = std::get<asset::SRasterizationParams>(protoPipeline);
58-
rasterParams.faceCullingMode = nbl::asset::EFCM_NONE;
59-
rasterParams.depthCompareOp = nbl::asset::ECO_ALWAYS;
60-
rasterParams.minSampleShading = 1.f;
61-
rasterParams.depthWriteEnable = false;
62-
rasterParams.depthTestEnable = false;
63-
64-
// Push constant for surface transform and screen size, used in VS
65-
auto& swapchainOrientationConstants = std::get<asset::SPushConstantRange>(protoPipeline);
66-
swapchainOrientationConstants.stageFlags = asset::IShader::ESS_VERTEX;
67-
swapchainOrientationConstants.offset = pushConstantOffset;
68-
swapchainOrientationConstants.size = 1 * sizeof(uint32_t);
69-
70-
return protoPipeline;
71-
}
72-
73-
inline core::smart_refctd_ptr<video::IGPURenderpassIndependentPipeline> createRenderpassIndependentPipeline(video::ILogicalDevice* logicalDevice, NBL_PROTO_PIPELINE& protoPipeline, core::smart_refctd_ptr<video::IGPUSpecializedShader>&& gpuFragmentShader, core::smart_refctd_ptr<video::IGPUPipelineLayout>&& pipelineLayout)
11+
struct ProtoPipeline final
12+
{
13+
inline core::smart_refctd_ptr<video::IGPUShader> createDefaultVertexShader(asset::IAssetManager* assMan, video::ILogicalDevice* device, system::ILogger* logger=nullptr)
14+
{
15+
if (!assMan || !device)
16+
return nullptr;
17+
18+
using namespace ::nbl::asset;
19+
IAssetLoader::SAssetLoadParams lp = {};
20+
lp.logger = logger;
21+
lp.workingDirectory = ""; // virtual root
22+
auto assetBundle = assMan->getAsset("nbl/builtin/hlsl/ext/FullScreenTriangle/default.vert.hlsl",lp);
23+
const auto assets = assetBundle.getContents();
24+
if (assets.empty())
25+
return nullptr;
26+
27+
auto source = IAsset::castDown<ICPUShader>(assets[0]);
28+
if (!source)
29+
return nullptr;
30+
31+
return device->createShader(source.get());
32+
}
33+
34+
public:
35+
inline ProtoPipeline(asset::IAssetManager* assMan, video::ILogicalDevice* device, system::ILogger* logger=nullptr)
36+
{
37+
m_vxShader = createDefaultVertexShader(assMan,device,logger);
38+
}
39+
40+
inline operator bool() const {return m_vxShader.get();}
41+
42+
inline core::smart_refctd_ptr<video::IGPUGraphicsPipeline> createPipeline(
43+
const video::IGPUShader::SSpecInfo& fragShader,
44+
video::IGPUPipelineLayout* layout,
45+
video::IGPURenderpass* renderpass,
46+
const uint32_t subpassIx=0,
47+
const hlsl::SurfaceTransform::FLAG_BITS swapchainTransform=hlsl::SurfaceTransform::FLAG_BITS::IDENTITY_BIT
48+
)
49+
{
50+
if (!renderpass || !bool(*this) || hlsl::bitCount(swapchainTransform)!=1)
51+
return nullptr;
52+
53+
using namespace ::nbl::video;
54+
auto device = const_cast<ILogicalDevice*>(renderpass->getOriginDevice());
55+
56+
core::smart_refctd_ptr<IGPUGraphicsPipeline> m_retval;
7457
{
75-
if (!logicalDevice)
76-
assert(false);
77-
78-
video::IGPUSpecializedShader* gpuShaders[] = { std::get<core::smart_refctd_ptr<video::IGPUSpecializedShader>>(protoPipeline).get(), gpuFragmentShader.get() };
79-
auto gpuRenderpassIndependentPipeline = logicalDevice->createRenderpassIndependentPipeline
80-
(
81-
nullptr,
82-
std::move(pipelineLayout),
83-
gpuShaders,
84-
gpuShaders + 2,
85-
std::get<asset::SVertexInputParams>(protoPipeline),
86-
std::get<asset::SBlendParams>(protoPipeline),
87-
std::get<asset::SPrimitiveAssemblyParams>(protoPipeline),
88-
std::get<asset::SRasterizationParams>(protoPipeline)
89-
);
90-
91-
return gpuRenderpassIndependentPipeline;
58+
const auto orientationAsUint32 = static_cast<uint32_t>(swapchainTransform);
59+
60+
IGPUShader::SSpecInfo::spec_constant_map_t specConstants;
61+
specConstants[0] = {.data=&orientationAsUint32,.size=sizeof(orientationAsUint32)};
62+
63+
const IGPUShader::SSpecInfo shaders[2] = {
64+
{.shader=m_vxShader.get(),.entries=&specConstants},
65+
fragShader
66+
};
67+
68+
IGPUGraphicsPipeline::SCreationParams params[1];
69+
params[0].layout = layout;
70+
params[0].shaders = shaders;
71+
params[0].cached = {
72+
.vertexInput = inputParams,
73+
.primitiveAssembly = assemblyParams,
74+
.rasterization = rasterParams,
75+
.blend = blendParams,
76+
.subpassIx = subpassIx
77+
};
78+
params[0].renderpass = renderpass;
79+
80+
if (!device->createGraphicsPipelines(nullptr,params,&m_retval))
81+
return nullptr;
9282
}
93-
94-
/*
95-
Helper function for drawing full screen triangle.
96-
It should be called between command buffer render pass
97-
records.
98-
*/
99-
100-
inline bool recordDrawCalls(
101-
core::smart_refctd_ptr<nbl::video::IGPUGraphicsPipeline> gpuGraphicsPipeline,
102-
uint32_t pushConstantOffset,
103-
video::ISurface::E_SURFACE_TRANSFORM_FLAGS swapchainTransform,
104-
video::IGPUCommandBuffer* commandBuffer
105-
) {
106-
_NBL_STATIC_INLINE_CONSTEXPR auto VERTEX_COUNT = 3;
107-
_NBL_STATIC_INLINE_CONSTEXPR auto INSTANCE_COUNT = 1;
108-
109-
auto layout = gpuGraphicsPipeline->getRenderpassIndependentPipeline()->getLayout();
110-
uint32_t surfaceTransform = uint32_t(swapchainTransform);
111-
commandBuffer->pushConstants(layout, asset::IShader::ESS_VERTEX, pushConstantOffset, 1 * sizeof(uint32_t), &surfaceTransform);
112-
113-
return commandBuffer->draw(VERTEX_COUNT, INSTANCE_COUNT, 0, 0);
114-
}
115-
#endif
83+
return m_retval;
84+
}
85+
86+
87+
core::smart_refctd_ptr<video::IGPUShader> m_vxShader;
88+
// The Full Screen Triangle doesn't use any HW vertex input state
89+
constexpr static inline asset::SVertexInputParams inputParams = {};
90+
// The default is correct for us
91+
constexpr static inline asset::SPrimitiveAssemblyParams assemblyParams = {};
92+
// Default is no blending, also ok.
93+
constexpr static inline asset::SBlendParams blendParams = {};
94+
constexpr static inline asset::SRasterizationParams rasterParams = {
95+
.faceCullingMode = asset::EFCM_NONE,
96+
.depthWriteEnable = false,
97+
.depthCompareOp = asset::ECO_ALWAYS
98+
};
99+
};
100+
101+
102+
/*
103+
Helper function for drawing full screen triangle.
104+
It should be called between command buffer render pass
105+
records.
106+
*/
107+
static inline bool recordDrawCall(video::IGPUCommandBuffer* commandBuffer)
108+
{
109+
constexpr auto VERTEX_COUNT = 3;
110+
constexpr auto INSTANCE_COUNT = 1;
111+
return commandBuffer->draw(VERTEX_COUNT,INSTANCE_COUNT,0,0);
112+
}
116113
}
117114
#endif

0 commit comments

Comments
 (0)