Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rendergraph: use opengl node and add shaders #14021

Merged
merged 21 commits into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4573,7 +4573,9 @@ if(VINYLCONTROL)
endif()

# rendergraph
add_subdirectory(src/rendergraph/opengl)
add_subdirectory(src/rendergraph)
target_link_libraries(mixxx-lib PUBLIC rendergraph_gl)
target_compile_definitions(mixxx-lib PUBLIC rendergraph=rendergraph_gl)

# WavPack audio file support
find_package(wavpack)
Expand Down
5 changes: 4 additions & 1 deletion src/rendergraph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,8 @@ set(
)

add_subdirectory(opengl)
add_subdirectory(scenegraph)
#################################
# TODO: uncomment in follow-up PR
# add_subdirectory(scenegraph)
#################################
Comment on lines -42 to +45
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is the culprit that breaks it for me. WIthout scenegraph, the calls that reference the non-existing rendergraph_sg target fail.

Side note: Splitting the CMake code over multiple small CMakeLists.txt files that reference targets and variables defined elsewhere makes the control flow quite difficult to follow. Have you considered just using a single CMakeLists.txt inside the rendergraph directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, for now the calls that reference the non-existing rendergraph_sg target fail should be commented out. I will do that.

I obsoletely prefer splitting cmake over multiple files, one per target.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please try again, @Holzhaus ? I added conditionals to only add the shaders for the targets that were added.
(It looks like this is a change in Qt, being more strict about this in more recent versions)

add_subdirectory(shaders)
7 changes: 5 additions & 2 deletions src/rendergraph/opengl/rendergraph/nodeinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ namespace rendergraph {
template<class T_Node>
class NodeInterface : public T_Node {
public:
void appendChildNode(std::unique_ptr<BaseNode> pNode) {
template<class T_AppendNode>
T_AppendNode* appendChildNode(std::unique_ptr<T_AppendNode> pNode) {
// Transfers ownership to this.
BaseNode* pRawNode = pNode.release();
T_AppendNode* pRawNode = pNode.release();
// Note: Ideally we would use unique_ptrs internally, but
// Qt uses raw pointers for QSGNode hierarchy. For simplicity
// we mimic this.

T_Node::appendChildNode(pRawNode);

return pRawNode;
}

std::unique_ptr<BaseNode> detachChildNode(BaseNode* pNode) {
Expand Down
6 changes: 4 additions & 2 deletions src/rendergraph/scenegraph/rendergraph/nodeinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ namespace rendergraph {
template<class T_Node>
class NodeInterface : public T_Node {
public:
void appendChildNode(std::unique_ptr<BaseNode> pNode) {
BaseNode* pRawNode = pNode.release();
template<class T_AppendNode>
T_AppendNode* appendChildNode(std::unique_ptr<T_AppendNode> pNode) {
T_AppendNode* pRawNode = pNode.release();
pRawNode->setFlag(QSGNode::OwnedByParent, true);
T_Node::appendChildNode(pRawNode);
DEBUG_ASSERT(pRawNode->flags() & QSGNode::OwnedByParent);
return pRawNode;
}
std::unique_ptr<BaseNode> detachChildNode(BaseNode* pNode) {
DEBUG_ASSERT(pNode->flags() & QSGNode::OwnedByParent);
Expand Down
57 changes: 57 additions & 0 deletions src/rendergraph/shaders/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# included from src/rendergraph/CMakeLists.txt

set(
shaders
pattern.frag
pattern.vert
rgb.frag
rgb.vert
rgba.frag
rgba.vert
texture.frag
texture.vert
unicolor.frag
unicolor.vert
)

if(TARGET rendergraph_sg)
qt6_add_shaders(rendergraph_sg "shaders-qsb"
BATCHABLE
PRECOMPILE
OPTIMIZED
PREFIX
/shaders/rendergraph
FILES
${shaders}
)
endif()

if(TARGET rendergraph_gl)
# USE_QSHADER_FOR_GL is set in src/rendergraph/CMakeLists.txt when Qt >= 6.6
if(USE_QSHADER_FOR_GL)
# Add the .qsb shader bundles; rendergraph::MaterialShader will use
# QShader to extract the GLSL shader from the bundle.
message(STATUS "Adding qsb shaders to rendergraph_gl")
qt6_add_shaders(rendergraph_gl "shaders-qsb"
BATCHABLE
PRECOMPILE
OPTIMIZED
PREFIX
/shaders/rendergraph
FILES
${shaders}
)
else()
# Use GLSL shaders extracted from the .qsb shader bundles using
# generate_shaders_gl.pl
message(STATUS "Adding gl shaders to rendergraph_gl")
include(generated_shaders_gl.cmake)

qt_add_resources(rendergraph_gl "shaders-gl"
PREFIX
/shaders/rendergraph
FILES
${generated_shaders_gl}
)
endif()
endif()
34 changes: 34 additions & 0 deletions src/rendergraph/shaders/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# rendergraph shaders

The CMakeLists.txt in this folder generates qsb shader bundles from spirv shaders, to
be used by `rendergraph::MaterialShader`.

## For use with QML / Qt scene graph

The qsb files can be used directly through `QSGShader`. This includes the scenegraph
implementation of rendergraph.

## For use with OpenGL

Depending on the Qt version, the opengl implementation of `rendergraph::MaterialShader`
uses either the .qsb shader bundles directly, or the extracted GLSL shaders:

### Qt >= 6.6

The GLSL shaders are extracted programmatically with `QShader` and then used with
`QOpenGLShader`.

### Qt < 6.6

The GLSL shader have to extracted from the qsb shader bundles to be used by `QOpenGLShader`.
This can be done using the script `rg_generate_shaders_gl.py` in the mixxx/tools directory:

```console
$ ../../../tools/rg_generate_shaders_gl.py --cmake generated_shaders_gl.cmake *.vert *.frag
```

To use this script, make sure that the qsb and spirv commands are in your path. qsb is part
of Qt. spirv is part of the Vulkan SDK and can be downloaded from <https://vulkan.org>

The script also generates the file `generated_shaders_gl.cmake` which sets a cmake
variable containing a list of all GLSL shaders, used by the CMakeLists.txt in this folder.
13 changes: 13 additions & 0 deletions src/rendergraph/shaders/generated_shaders_gl.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(
generated_shaders_gl
pattern.frag.gl
pattern.vert.gl
rgb.frag.gl
rgb.vert.gl
rgba.frag.gl
rgba.vert.gl
texture.frag.gl
texture.vert.gl
unicolor.frag.gl
unicolor.vert.gl
)
m0dB marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 9 additions & 0 deletions src/rendergraph/shaders/pattern.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 440

layout(binding = 1) uniform sampler2D texture1;
layout(location = 0) in vec2 vTexcoord;
layout(location = 0) out vec4 fragColor;

void main() {
fragColor = texture(texture1, fract(vTexcoord));
}
11 changes: 11 additions & 0 deletions src/rendergraph/shaders/pattern.frag.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

uniform sampler2D texture1;

varying vec2 vTexcoord;

void main()
{
gl_FragData[0] = texture2D(texture1, fract(vTexcoord));
}
15 changes: 15 additions & 0 deletions src/rendergraph/shaders/pattern.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 440

layout(std140, binding = 0) uniform buf {
mat4 matrix;
}
ubuf;

layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texcoord;
layout(location = 0) out vec2 vTexcoord;

void main() {
vTexcoord = texcoord;
gl_Position = ubuf.matrix * position;
}
19 changes: 19 additions & 0 deletions src/rendergraph/shaders/pattern.vert.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

struct buf
{
mat4 matrix;
};

uniform buf ubuf;

varying vec2 vTexcoord;
attribute vec2 texcoord;
attribute vec4 position;

void main()
{
vTexcoord = texcoord;
gl_Position = ubuf.matrix * position;
}
8 changes: 8 additions & 0 deletions src/rendergraph/shaders/rgb.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 440

layout(location = 0) in vec3 vColor;
layout(location = 0) out vec4 fragColor;

void main() {
fragColor = vec4(vColor, 1.0);
}
9 changes: 9 additions & 0 deletions src/rendergraph/shaders/rgb.frag.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

varying vec3 vColor;

void main()
{
gl_FragData[0] = vec4(vColor, 1.0);
}
15 changes: 15 additions & 0 deletions src/rendergraph/shaders/rgb.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 440

layout(std140, binding = 0) uniform buf {
mat4 matrix;
}
ubuf;

layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 vColor;

void main() {
vColor = color;
gl_Position = ubuf.matrix * position;
}
19 changes: 19 additions & 0 deletions src/rendergraph/shaders/rgb.vert.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

struct buf
{
mat4 matrix;
};

uniform buf ubuf;

varying vec3 vColor;
attribute vec3 color;
attribute vec4 position;

void main()
{
vColor = color;
gl_Position = ubuf.matrix * position;
}
8 changes: 8 additions & 0 deletions src/rendergraph/shaders/rgba.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 440

layout(location = 0) in vec4 vColor;
layout(location = 0) out vec4 fragColor;

void main() {
fragColor = vec4(vColor.xyz * vColor.w, vColor.w); // premultiple alpha
}
9 changes: 9 additions & 0 deletions src/rendergraph/shaders/rgba.frag.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

varying vec4 vColor;

void main()
{
gl_FragData[0] = vec4(vColor.xyz * vColor.w, vColor.w);
}
15 changes: 15 additions & 0 deletions src/rendergraph/shaders/rgba.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 440

layout(std140, binding = 0) uniform buf {
mat4 matrix;
}
ubuf;

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
layout(location = 0) out vec4 vColor;

void main() {
vColor = color;
gl_Position = ubuf.matrix * position;
}
19 changes: 19 additions & 0 deletions src/rendergraph/shaders/rgba.vert.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

struct buf
{
mat4 matrix;
};

uniform buf ubuf;

varying vec4 vColor;
attribute vec4 color;
attribute vec4 position;

void main()
{
vColor = color;
gl_Position = ubuf.matrix * position;
}
9 changes: 9 additions & 0 deletions src/rendergraph/shaders/texture.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 440

layout(binding = 1) uniform sampler2D texture1;
layout(location = 0) in vec2 vTexcoord;
layout(location = 0) out vec4 fragColor;

void main() {
fragColor = texture(texture1, vTexcoord);
}
11 changes: 11 additions & 0 deletions src/rendergraph/shaders/texture.frag.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

uniform sampler2D texture1;

varying vec2 vTexcoord;

void main()
{
gl_FragData[0] = texture2D(texture1, vTexcoord);
}
15 changes: 15 additions & 0 deletions src/rendergraph/shaders/texture.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 440

layout(std140, binding = 0) uniform buf {
mat4 matrix;
}
ubuf;

layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texcoord;
layout(location = 0) out vec2 vTexcoord;

void main() {
vTexcoord = texcoord;
gl_Position = ubuf.matrix * position;
}
19 changes: 19 additions & 0 deletions src/rendergraph/shaders/texture.vert.gl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#version 120
//// GENERATED - EDITS WILL BE OVERWRITTEN

struct buf
{
mat4 matrix;
};

uniform buf ubuf;

varying vec2 vTexcoord;
attribute vec2 texcoord;
attribute vec4 position;

void main()
{
vTexcoord = texcoord;
gl_Position = ubuf.matrix * position;
}
Loading
Loading