Skip to content

Commit b661519

Browse files
committed
Merge branch 'swapchain_utilities'
2 parents 8cde0d0 + 36dc451 commit b661519

20 files changed

+390
-50
lines changed

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,59 @@ If you want to use git (without a submodule) then you can use `ExternalProject_A
414414

415415
I recommend you use `ExternalProject_Add` instead of `add_subdirectory` for **Nabla** as we haven't tested its use by *3rdparty* applications that use *CMake* to build themselves yet.
416416

417+
# Caveats and Particular Behaviour
418+
419+
## Hardcoded Caps
420+
421+
### Max Descriptor Sets is always 4
422+
423+
## Debugging with RenderDoc
424+
425+
### Non-programmatic OpenGL catpures will be delimited inconsistently
426+
427+
Due to our no-pollution opengl state isolation policy, we have 1 queue or swapchain = 1 thread = 1 gl context + 1 master context and thread for device calls.
428+
429+
Renderdoc therefore serializes all calls, and presents them inside the capture in interleaved order (records them on a single timeline "as they happened").
430+
431+
Furthermore it has no idea what constitutes a frame, because swap-buffers call happens on a separate thread than all the other API calls. **So use the `IGPUQueue` start/end capture methods!**
432+
433+
### RenderDoc flips images for display in the ImageViewer tab on OpenGL captures
434+
435+
Ctrl+F `localRenderer in https://github.com/baldurk/renderdoc/blob/4103f6a5455b9734e9bf74e254577f5c03188136/renderdoc/core/image_viewer.cpp
436+
437+
### OpenGL/Vulkan Inconsistencies
438+
439+
In certain cases same calls to Vulkan and OpenGL might result in y-flipped image relevant to the other API.
440+
441+
Both APIs write (-1,-1) in NDC space to (0,0) in image space (two wrongs make right), and memory-wise (0,0) always represents the lowest byte in memory.
442+
443+
This inconsistency comes from swapchain presentation. When presenting the swapchain, the image location (0,0) corresponds to **bottom-left** in OpenGL and **top-left** in Vulkan.
444+
445+
#### Solution by Surface Transforms
446+
447+
We solve this inconsistency by using [surface transforms](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSurfaceTransformFlagBitsKHR.html); This transforms are relative to `presentation engine’s natural orientation`. and we report `HORIZONTAL_MIRROR_180` support in our OpenGL backend and defer handling these rotations (relative to natural orientaion) to the user.
448+
449+
We provide helper functions in both GLSL and C++ Nabla codebase to consider surface transforms, See [surface_transform.glsl](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/builtin/glsl/utils/surface_transform.glsl)
450+
451+
Note that it is common to apply surface transformation to projection matrices to account for this fact. See [getSurfaceTransformationMatrix](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/video/surface/ISurface.h) and [Android Developers Guide to Pre-rotation](https://developer.android.com/games/optimize/vulkan-prerotation)
452+
453+
Use [`ISwapchain getSurfaceTransform()`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/video/ISwapchain.h) to get the transformation from swapchain.
454+
455+
- When generating projection matricies, take into account the aspect ratio (which is changed when rotating 90 or 270 degrees). For this, we have helper functions in both GLSL and the ISurface class:
456+
- [`float getTransformedAspectRatio(const E_SURFACE_TRANSFORM_FLAGS transform, uint32_t w, uint32_t h)`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/video/surface/ISurface.h)
457+
- [`nbl_glsl_surface_transform_transformedExtents`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/builtin/glsl/utils/surface_transform.glsl)
458+
459+
- On the swapchain rendering pass, perform **one** of the following transforms:
460+
- If rendering **directly to the swapchain**, you can apply the (post) transform matrix to your projection or combined view-projection matrix **for rendering** (don't pre-multiply with projection matrix for use outside rendering):
461+
- [`matrix4SIMD ISurface::getSurfaceTransformationMatrix(const E_SURFACE_TRANSFORM_FLAGS transform)`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/video/surface/ISurface.h)
462+
- [`nbl_glsl_surface_transform_applyToNDC`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/builtin/glsl/utils/surface_transform.glsl) (This takes in an NDC coordinate and multiplies it with the transform matrix in one function)
463+
464+
- If using `imageStore` to write **directly to the swapchain**, you can either:
465+
- Apply a transform to the screen-space coordinates being written to the swapchain:
466+
- [`nbl_glsl_surface_transform_applyToScreenSpaceCoordinate`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/builtin/glsl/utils/surface_transform.glsl)
467+
- Apply an **inverse** transform to the screen-space coordinates (taken from `gl_GlobalInvocationID.xy`) before turning them into UV/world-space coordinates for rendering:
468+
- [`nbl_glsl_surface_transform_applyInverseToScreenSpaceCoordinate`](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/builtin/glsl/utils/surface_transform.glsl)
469+
417470
## Automated Builds (TODO)
418471

419472
## License
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#ifndef _NBL_BUILTIN_GLSL_SURFACE_TRANSFORM_INCLUDED_
2+
#define _NBL_BUILTIN_GLSL_SURFACE_TRANSFORM_INCLUDED_
3+
4+
#include "nbl/builtin/glsl/utils/surface_transform_e.h"
5+
6+
//! Use this function to apply the INVERSE of swapchain tranformation to the screenspace coordinate `coord`
7+
//! For example when the device orientation is 90°CW then this transforms the point 90°CCW.
8+
//! Usecase = [Gather]:
9+
//! Applications such as raytracing in shaders where you would want to generate rays from screen space coordinates.
10+
//! Warnings:
11+
//! - You don't need to consider this using in your raytracing shaders if you apply the forward transformation to your projection matrix.
12+
//! - Be aware that almost always you'd want to do a single transform in your rendering pipeline.
13+
ivec2 nbl_glsl_surface_transform_applyInverseToScreenSpaceCoordinate(in uint swapchainTransform, in ivec2 coord, in ivec2 screenSize) {
14+
ivec2 lastTexel = screenSize - ivec2(1);
15+
switch (swapchainTransform)
16+
{
17+
case NBL_GLSL_SURFACE_TRANSFORM_E_IDENTITY:
18+
return coord;
19+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_90:
20+
return ivec2(lastTexel.y - coord.y, coord.x);
21+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_180:
22+
return ivec2(lastTexel) - coord;
23+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_270:
24+
return ivec2(coord.y, lastTexel.x - coord.x);
25+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR:
26+
return ivec2(lastTexel.x - coord.x, coord.y);
27+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_90:
28+
return lastTexel - coord.yx;
29+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_180:
30+
return ivec2(coord.x, lastTexel.y - coord.y);
31+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_270:
32+
return coord.yx;
33+
default:
34+
return ivec2(0);
35+
}
36+
}
37+
38+
//! Use this function to apply the swapchain tranformation to the screenspace coordinate `coord`
39+
//! Usecase = [Scatter]:
40+
//! When directly writing to your swapchain using `imageStore` in order to match the orientation of the device relative to it's natural orientation.
41+
//! Warning: Be aware that almost always you'd want to do a single transform in your rendering pipeline.
42+
ivec2 nbl_glsl_surface_transform_applyToScreenSpaceCoordinate(in uint swapchainTransform, in ivec2 coord, in ivec2 screenSize) {
43+
ivec2 lastTexel = screenSize - ivec2(1);
44+
switch (swapchainTransform)
45+
{
46+
case NBL_GLSL_SURFACE_TRANSFORM_E_IDENTITY:
47+
return coord;
48+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_90:
49+
return ivec2(coord.y, lastTexel.x - coord.x);
50+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_180:
51+
return ivec2(lastTexel) - coord;
52+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_270:
53+
return ivec2(lastTexel.y - coord.y, coord.x);
54+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR:
55+
return ivec2(lastTexel.x - coord.x, coord.y);
56+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_90:
57+
return coord.yx;
58+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_180:
59+
return ivec2(coord.x, lastTexel.y - coord.y);
60+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_270:
61+
return lastTexel - coord.yx;
62+
default:
63+
return ivec2(0);
64+
}
65+
}
66+
67+
//! [width,height] might switch to [height, width] in orientations such as 90°CW
68+
//! Usecase: Currently none in the shaders
69+
ivec2 nbl_glsl_surface_transform_transformedExtents(in uint swapchainTransform, in ivec2 screenSize) {
70+
switch (swapchainTransform)
71+
{
72+
case NBL_GLSL_SURFACE_TRANSFORM_E_IDENTITY:
73+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR:
74+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_180:
75+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_180:
76+
return screenSize;
77+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_90:
78+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_270:
79+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_90:
80+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_270:
81+
return screenSize.yx;
82+
default:
83+
return ivec2(0);
84+
}
85+
}
86+
87+
// TODO: nbl_glsl_surface_transform_transformedDerivatives implementations are untested
88+
89+
// If rendering directly to the swapchain, dFdx/dFdy operations may be incorrect due to the swapchain
90+
// transform. Use these helper functions to transform the dFdx or dFdy accordingly.
91+
92+
vec2 nbl_glsl_surface_transform_transformedDerivatives(in uint swapchainTransform, in vec2 ddxDdy) {
93+
#define OUTPUT_TYPE vec2
94+
#include "nbl/builtin/glsl/utils/surface_transform_transformedDerivatives.glsl"
95+
#undef OUTPUT_TYPE
96+
}
97+
mat2 nbl_glsl_surface_transform_transformedDerivatives(in uint swapchainTransform, in mat2 ddxDdy) {
98+
#define OUTPUT_TYPE mat2
99+
#include "nbl/builtin/glsl/utils/surface_transform_transformedDerivatives.glsl"
100+
#undef OUTPUT_TYPE
101+
}
102+
mat2x3 nbl_glsl_surface_transform_transformedDerivatives(in uint swapchainTransform, in mat2x3 ddxDdy) {
103+
#define OUTPUT_TYPE mat2x3
104+
#include "nbl/builtin/glsl/utils/surface_transform_transformedDerivatives.glsl"
105+
#undef OUTPUT_TYPE
106+
}
107+
mat2x4 nbl_glsl_surface_transform_transformedDerivatives(in uint swapchainTransform, in mat2x4 ddxDdy) {
108+
#define OUTPUT_TYPE mat2x4
109+
#include "nbl/builtin/glsl/utils/surface_transform_transformedDerivatives.glsl"
110+
#undef OUTPUT_TYPE
111+
}
112+
113+
//! Same as `nbl_glsl_surface_transform_applyToScreenSpaceCoordinate` but in NDC space
114+
//! If rendering to the swapchain, you may use this function to transform the NDC coordinates directly
115+
//! to be fed into gl_Position in vertex shading
116+
//! Warning: Be aware that almost always you'd want to do a single transform in your rendering pipeline.
117+
vec2 nbl_glsl_surface_transform_applyToNDC(in uint swapchainTransform, in vec2 ndc) {
118+
const float sin90 = 1.0, cos90 = 0.0,
119+
sin180 = 0.0, cos180 = -1.0,
120+
sin270 = -1.0, cos270 = 0.0;
121+
switch (swapchainTransform)
122+
{
123+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_90:
124+
return ndc * mat2(vec2(cos90, -sin90),
125+
vec2(sin90, cos90));
126+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_180:
127+
return ndc * mat2(vec2(cos180, -sin180),
128+
vec2(sin180, cos180));
129+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_270:
130+
return ndc * mat2(vec2(cos270, -sin270),
131+
vec2(sin270, cos270));
132+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR:
133+
return ndc * mat2(vec2(-1, 0),
134+
vec2(0, 1));
135+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_90:
136+
return ndc * mat2(vec2(-cos90, sin90),
137+
vec2(sin90, cos90));
138+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_180:
139+
return ndc * mat2(vec2(-cos180, sin180),
140+
vec2(sin180, cos180));
141+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_270:
142+
return ndc * mat2(vec2(-cos270, sin270),
143+
vec2(sin270, cos270));
144+
default:
145+
return ndc;
146+
}
147+
}
148+
149+
#endif
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef _NBL_BUILTIN_GLSL_SURFACE_TRANSFORM_E_INCLUDED_
2+
#define _NBL_BUILTIN_GLSL_SURFACE_TRANSFORM_E_INCLUDED_
3+
4+
#define NBL_GLSL_SURFACE_TRANSFORM_E_IDENTITY 0x00000001
5+
#define NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_90 0x00000002
6+
#define NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_180 0x00000004
7+
#define NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_270 0x00000008
8+
#define NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR 0x00000010
9+
#define NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_90 0x00000020
10+
#define NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_180 0x00000040
11+
#define NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_270 0x00000080
12+
13+
#endif
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
switch (swapchainTransform)
2+
{
3+
case NBL_GLSL_SURFACE_TRANSFORM_E_IDENTITY:
4+
return ddxDdy;
5+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR:
6+
return OUTPUT_TYPE(-ddxDdy[0], ddxDdy[1]);
7+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_180:
8+
return OUTPUT_TYPE(ddxDdy[0], -ddxDdy[1]);
9+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_180:
10+
return OUTPUT_TYPE(-ddxDdy[0], -ddxDdy[1]);
11+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_90:
12+
return OUTPUT_TYPE(ddxDdy[1], -ddxDdy[0]);
13+
case NBL_GLSL_SURFACE_TRANSFORM_E_ROTATE_270:
14+
return OUTPUT_TYPE(-ddxDdy[1], ddxDdy[0]);
15+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_90:
16+
return OUTPUT_TYPE(ddxDdy[1], ddxDdy[0]);
17+
case NBL_GLSL_SURFACE_TRANSFORM_E_HORIZONTAL_MIRROR_ROTATE_270:
18+
return OUTPUT_TYPE(-ddxDdy[1], -ddxDdy[0]);
19+
default:
20+
return OUTPUT_TYPE(0);
21+
}

include/nbl/builtin/specialized_shader/fullscreentriangle.vert

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@
44

55
#version 430 core
66

7-
const vec2 pos[3] = vec2[3](vec2(-1.0, 1.0),vec2(-1.0,-3.0),vec2( 3.0, 1.0));
7+
#include <nbl/builtin/glsl/utils/surface_transform.glsl>
8+
9+
const vec2 pos[3] = vec2[3](vec2(-1.0, -1.0),vec2(-1.0, 3.0),vec2( 3.0, -1.0));
810
const vec2 tc[3] = vec2[3](vec2( 0.0, 0.0),vec2( 0.0, 2.0),vec2( 2.0, 0.0));
911

1012
layout(location = 0) out vec2 TexCoord;
1113

14+
layout (push_constant) uniform pushConstants
15+
{
16+
layout (offset = 0) uint swapchainTransform;
17+
} u_pushConstants;
18+
1219
void main()
1320
{
14-
gl_Position = vec4(pos[gl_VertexIndex],0.0,1.0);
21+
vec2 pos = nbl_glsl_surface_transform_applyToNDC(u_pushConstants.swapchainTransform, pos[gl_VertexIndex]);
22+
gl_Position = vec4(pos, 0.0, 1.0);
1523
TexCoord = tc[gl_VertexIndex];
1624
}

include/nbl/ext/FullScreenTriangle/FullScreenTriangle.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ namespace nbl
1313
{
1414
namespace FullScreenTriangle
1515
{
16-
using NBL_PROTO_PIPELINE = std::tuple<core::smart_refctd_ptr<video::IGPUSpecializedShader>, asset::SVertexInputParams, asset::SPrimitiveAssemblyParams, asset::SBlendParams, nbl::asset::SRasterizationParams>;
16+
using NBL_PROTO_PIPELINE = std::tuple<core::smart_refctd_ptr<video::IGPUSpecializedShader>, asset::SVertexInputParams, asset::SPrimitiveAssemblyParams, asset::SBlendParams, nbl::asset::SRasterizationParams, asset::SPushConstantRange>;
1717

18-
inline NBL_PROTO_PIPELINE createProtoPipeline(video::IGPUObjectFromAssetConverter::SParams& cpu2gpuParams)
18+
inline NBL_PROTO_PIPELINE createProtoPipeline(video::IGPUObjectFromAssetConverter::SParams& cpu2gpuParams, uint32_t pushConstantOffset)
1919
{
2020
if (!cpu2gpuParams.assetManager)
2121
assert(false);
@@ -66,6 +66,12 @@ namespace nbl
6666
rasterParams.depthWriteEnable = false;
6767
rasterParams.depthTestEnable = false;
6868

69+
// Push constant for surface transform and screen size, used in VS
70+
auto& swapchainOrientationConstants = std::get<asset::SPushConstantRange>(protoPipeline);
71+
swapchainOrientationConstants.stageFlags = asset::IShader::ESS_VERTEX;
72+
swapchainOrientationConstants.offset = pushConstantOffset;
73+
swapchainOrientationConstants.size = 1 * sizeof(uint32_t);
74+
6975
return protoPipeline;
7076
}
7177

@@ -96,11 +102,19 @@ namespace nbl
96102
records.
97103
*/
98104

99-
inline bool recordDrawCalls(video::IGPUCommandBuffer* commandBuffer)
100-
{
105+
inline bool recordDrawCalls(
106+
core::smart_refctd_ptr<nbl::video::IGPUGraphicsPipeline> gpuGraphicsPipeline,
107+
uint32_t pushConstantOffset,
108+
video::ISurface::E_SURFACE_TRANSFORM_FLAGS swapchainTransform,
109+
video::IGPUCommandBuffer* commandBuffer
110+
) {
101111
_NBL_STATIC_INLINE_CONSTEXPR auto VERTEX_COUNT = 3;
102112
_NBL_STATIC_INLINE_CONSTEXPR auto INSTANCE_COUNT = 1;
103113

114+
auto layout = gpuGraphicsPipeline->getRenderpassIndependentPipeline()->getLayout();
115+
uint32_t surfaceTransform = uint32_t(swapchainTransform);
116+
commandBuffer->pushConstants(layout, asset::IShader::ESS_VERTEX, pushConstantOffset, 1 * sizeof(uint32_t), &surfaceTransform);
117+
104118
return commandBuffer->draw(VERTEX_COUNT, INSTANCE_COUNT, 0, 0);
105119
}
106120
}

include/nbl/ext/OIT/OIT.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class NBL_API COIT
3939
asset::SPrimitiveAssemblyParams primAsm;
4040
asset::SBlendParams blend;
4141
asset::SRasterizationParams raster;
42+
asset::SPushConstantRange pushConstants;
4243
};
4344

4445
bool initialize(video::ILogicalDevice* dev, uint32_t w, uint32_t h,
@@ -126,8 +127,9 @@ class NBL_API COIT
126127
m_proto_pipeline.vtx,
127128
m_proto_pipeline.primAsm,
128129
m_proto_pipeline.blend,
129-
m_proto_pipeline.raster
130-
) = ext::FullScreenTriangle::createProtoPipeline(c2gparams);
130+
m_proto_pipeline.raster,
131+
m_proto_pipeline.pushConstants
132+
) = ext::FullScreenTriangle::createProtoPipeline(c2gparams, 0u);
131133

132134
m_proto_pipeline.blend.blendParams[0].blendEnable = 1;
133135
m_proto_pipeline.blend.blendParams[0].srcColorFactor = asset::EBF_ONE;

include/nbl/video/ISwapchain.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ class NBL_API ISwapchain : public core::IReferenceCounted, public IBackendObject
5757
return { m_images->begin(), m_images->end() };
5858
}
5959

60+
// The value passed to `preTransform` when creating the swapchain. "pre" refers to the transform happening
61+
// as an operation before the presentation engine presents the image.
62+
inline ISurface::E_SURFACE_TRANSFORM_FLAGS getPreTransform() const { return m_params.preTransform; }
63+
6064
virtual E_ACQUIRE_IMAGE_RESULT acquireNextImage(uint64_t timeout, IGPUSemaphore* semaphore, IGPUFence* fence, uint32_t* out_imgIx) = 0;
6165
// 100% blocking version, guaranteed to **not** return TIMEOUT or NOT_READY
6266
virtual E_ACQUIRE_IMAGE_RESULT acquireNextImage(IGPUSemaphore* semaphore, IGPUFence* fence, uint32_t* out_imgIx)

include/nbl/video/surface/CSurfaceGL.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ class CSurfaceGLImpl : public Base<Window,ISurface>
7373
capabilities.minImageExtent = { 1u, 1u };
7474
capabilities.maxImageExtent = { static_cast<uint32_t>(physicalDevice->getLimits().maxImageDimension2D), static_cast<uint32_t>(physicalDevice->getLimits().maxImageDimension2D) };
7575
capabilities.maxImageArrayLayers = physicalDevice->getLimits().maxImageArrayLayers;
76-
capabilities.supportedTransforms = ISurface::EST_IDENTITY_BIT;
77-
capabilities.currentTransform = ISurface::EST_IDENTITY_BIT;
76+
// Only supported transform exposed for OpenGL is mirror rotate 180 (effectively flip Y) to match Vulkan
77+
capabilities.supportedTransforms = ISurface::EST_HORIZONTAL_MIRROR_ROTATE_180_BIT;
78+
capabilities.currentTransform = ISurface::EST_HORIZONTAL_MIRROR_ROTATE_180_BIT;
7879
capabilities.supportedCompositeAlpha = static_cast<ISurface::E_COMPOSITE_ALPHA>(ISurface::ECA_OPAQUE_BIT | ISurface::ECA_PRE_MULTIPLIED_BIT | ISurface::ECA_POST_MULTIPLIED_BIT);
7980
capabilities.supportedUsageFlags = static_cast<asset::IImage::E_USAGE_FLAGS>(
8081
asset::IImage::EUF_TRANSFER_SRC_BIT | asset::IImage::EUF_TRANSFER_DST_BIT |

0 commit comments

Comments
 (0)