Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
7a313bf524 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -81,3 +81,4 @@ __pycache__/
|
|||||||
|
|
||||||
# Compiled shaders
|
# Compiled shaders
|
||||||
*.spv
|
*.spv
|
||||||
|
*.dxil
|
||||||
|
48
README.md
48
README.md
@ -1,48 +0,0 @@
|
|||||||
# sdl_gpu_test
|
|
||||||
Just a little sandbox for me to try out [SDL3](https://github.com/libsdl-org/SDL/)'s SDL_gpu.h. Feel free to do with it whatever you want. Note however that the included assets have their own licenses.
|
|
||||||
|
|
||||||
## Compiling
|
|
||||||
This project uses [SCons](https://scons.org/) and my personal extension "[SCons++](https://git.mewin.de/mewin/scons-plus-plus)" for compilation. After installing SCons it should work out of the box on Linux and Windows 10, anything else hasn't been tested.
|
|
||||||
|
|
||||||
On Linux you should be able to get SCons from your repository on any major distribution. On Windows you can either download it from their website (https://scons.org/) or (my recommendation) install it via [Scoop](https://scoop.sh/).
|
|
||||||
|
|
||||||
Just make sure to initialise the git submodule for SCons++. Either by cloning recursively:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone --recurse-submodules https://git.mewin.de/mewin/sdl_gpu_test.git
|
|
||||||
```
|
|
||||||
|
|
||||||
or by updating it after cloning:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
```
|
|
||||||
|
|
||||||
After that you can compile the project using SCons:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
scons -j<jobs>
|
|
||||||
```
|
|
||||||
|
|
||||||
This will automatically fetch and build dependencies (stored in `~/.cache/spp_cache` on Linux and `%LocalAppData%\spp_cache` on Windows).
|
|
||||||
|
|
||||||
Note that as of now the SDL repository needs to be patched in order for the build to work. You first have to run SCons once to update the repo and let the build fail, then apply the patch from `external/scons-plus-plus/recipes/SDL/fix_sdl3_from_worktree.patch`:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cd <spp_cache_dir>/cloned/git/SDL/b70daef4eb57
|
|
||||||
git apply <path to fix_sdl3_from_worktree.patch>
|
|
||||||
```
|
|
||||||
|
|
||||||
After that run the build again and everything should work just fine.
|
|
||||||
|
|
||||||
## Running
|
|
||||||
After compiling you can find the executable in `bin/sdl_gpu_test[.exe]`. You can either run it without any arguments to execute the latest iteration of my test application or pass the `--app` parameter to choose another one. You can find the names of the apps in [main.cpp](https://git.mewin.de/mewin/sdl_gpu_test/src/branch/master/private/sdl_gpu_test/main.cpp) or by using `--app` with an invalid value :).
|
|
||||||
|
|
||||||
## Further Reading
|
|
||||||
If you want to learn more about SDL_gpu.h, try the following:
|
|
||||||
|
|
||||||
* read the long comment at the beginning of SDL_gpu.h itself: https://github.com/libsdl-org/SDL/blob/main/include/SDL3/SDL_gpu.h
|
|
||||||
* look at the examples provided here: https://github.com/TheSpydog/SDL_gpu_examples
|
|
||||||
* read this blog entry about why there is no unified way for distributing shaders: https://moonside.games/posts/layers-all-the-way-down/
|
|
||||||
* look at this little helper for compiling your shaders for SDL_gpu.h: https://github.com/libsdl-org/SDL_gpu_shadercross (I haven't tested it myself yet)
|
|
@ -1,6 +1,6 @@
|
|||||||
config = {
|
config = {
|
||||||
'PROJECT_NAME': 'sdl_gpu_test',
|
'PROJECT_NAME': 'sdl_gpu_test',
|
||||||
'TOOLS': ['glslang']
|
'TOOLS': ['glslang', 'dxc']
|
||||||
}
|
}
|
||||||
env = SConscript('external/scons-plus-plus/SConscript', exports = ['config'])
|
env = SConscript('external/scons-plus-plus/SConscript', exports = ['config'])
|
||||||
env.Append(CPPPATH = [Dir('private'), Dir('public')])
|
env.Append(CPPPATH = [Dir('private'), Dir('public')])
|
||||||
|
2
external/scons-plus-plus
vendored
2
external/scons-plus-plus
vendored
@ -1 +1 @@
|
|||||||
Subproject commit e3b3fd8f7cb0ff0d1973e8f719a024b81322f7d7
|
Subproject commit 0a29b416391359a84cb847f57fc391da71a8e3cb
|
64
private/sdl_gpu_test/1_green_triangle_dxil/app.cpp
Normal file
64
private/sdl_gpu_test/1_green_triangle_dxil/app.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
#include "./app.hpp"
|
||||||
|
|
||||||
|
namespace sdl_gpu_test
|
||||||
|
{
|
||||||
|
void GreenTriangleDXILApp::init(const AppInitArgs& args)
|
||||||
|
{
|
||||||
|
mOptions.shaderFormats = {.dxil = true};
|
||||||
|
Application::init(args);
|
||||||
|
|
||||||
|
// create vertex shader
|
||||||
|
mijin::TypelessBuffer vertexSpv = getFileContentsBinary("shaders/hlsl/triangle.vs.dxil");
|
||||||
|
sdlpp::GPUShader vertexShader;
|
||||||
|
vertexShader.create(mDevice, {
|
||||||
|
.code = {static_cast<const Uint8*>(vertexSpv.data()), vertexSpv.byteSize()},
|
||||||
|
.format = sdlpp::GPUShaderFormat::DXIL,
|
||||||
|
.stage = sdlpp::GPUShaderStage::VERTEX
|
||||||
|
});
|
||||||
|
|
||||||
|
// create fragment shader
|
||||||
|
mijin::TypelessBuffer fragmentSpv = getFileContentsBinary("shaders/hlsl/green.ps.dxil");
|
||||||
|
sdlpp::GPUShader fragmentShader;
|
||||||
|
fragmentShader.create(mDevice, {
|
||||||
|
.code = {static_cast<const Uint8*>(fragmentSpv.data()), fragmentSpv.byteSize()},
|
||||||
|
.format = sdlpp::GPUShaderFormat::DXIL,
|
||||||
|
.stage = sdlpp::GPUShaderStage::FRAGMENT
|
||||||
|
});
|
||||||
|
|
||||||
|
// create graphics pipeline
|
||||||
|
std::array colorTargetsDescs = {
|
||||||
|
sdlpp::GPUColorTargetDescription{
|
||||||
|
.format = mDevice.getSwapchainTextureFormat(mWindow)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mPipeline.create(mDevice, {
|
||||||
|
.vertexShader = vertexShader,
|
||||||
|
.fragmentShader = fragmentShader,
|
||||||
|
.targetInfo = {
|
||||||
|
.colorTargetDescriptions = colorTargetsDescs
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void GreenTriangleDXILApp::update(const AppUpdateArgs& args)
|
||||||
|
{
|
||||||
|
Application::update(args);
|
||||||
|
|
||||||
|
sdlpp::GPUCommandBuffer cmdBuffer = mDevice.acquireCommandBuffer();
|
||||||
|
Uint32 swapchainWidth = 0, swapchainHeight = 0;
|
||||||
|
sdlpp::GPUTexture swapchainTexture = cmdBuffer.acquireSwapchainTexture(mWindow, swapchainWidth, swapchainHeight);
|
||||||
|
std::array colorTargets = {sdlpp::GPUColorTargetInfo{
|
||||||
|
.texture = swapchainTexture,
|
||||||
|
.clearColor = {.r = 1.f, .g = 0.f, .b = 0.f, .a = 1.f},
|
||||||
|
.loadOp = sdlpp::GPULoadOp::CLEAR,
|
||||||
|
}};
|
||||||
|
sdlpp::GPURenderPass renderPass = cmdBuffer.beginRenderPass({
|
||||||
|
.colorTargetInfos = colorTargets
|
||||||
|
});
|
||||||
|
renderPass.bindGraphicsPipeline(mPipeline);
|
||||||
|
renderPass.drawPrimitives({.numVertices = 3});
|
||||||
|
renderPass.end();
|
||||||
|
cmdBuffer.submit();
|
||||||
|
}
|
||||||
|
}
|
21
private/sdl_gpu_test/1_green_triangle_dxil/app.hpp
Normal file
21
private/sdl_gpu_test/1_green_triangle_dxil/app.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_1_GREEN_TRIANGLE_DXIL_APP_HPP_INCLUDED)
|
||||||
|
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_1_GREEN_TRIANGLE_DXIL_APP_HPP_INCLUDED 1
|
||||||
|
|
||||||
|
#include "../application.hpp"
|
||||||
|
|
||||||
|
namespace sdl_gpu_test
|
||||||
|
{
|
||||||
|
class GreenTriangleDXILApp : public Application
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
sdlpp::GPUGraphicsPipeline mPipeline;
|
||||||
|
public:
|
||||||
|
void init(const AppInitArgs& args) override;
|
||||||
|
void update(const AppUpdateArgs& args) override;
|
||||||
|
};
|
||||||
|
} // namespace sdl_gpu_test
|
||||||
|
|
||||||
|
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_1_GREEN_TRIANGLE_DXIL_APP_HPP_INCLUDED)
|
@ -20,7 +20,9 @@ src_files = Split("""
|
|||||||
util/texture_atlas.cpp
|
util/texture_atlas.cpp
|
||||||
|
|
||||||
0_clear_swapchain/app.cpp
|
0_clear_swapchain/app.cpp
|
||||||
|
0_clear_swapchain_dxil/app.cpp
|
||||||
1_green_triangle/app.cpp
|
1_green_triangle/app.cpp
|
||||||
|
1_green_triangle_dxil/app.cpp
|
||||||
2_triangle_with_texcoords/app.cpp
|
2_triangle_with_texcoords/app.cpp
|
||||||
3_textured_quad/app.cpp
|
3_textured_quad/app.cpp
|
||||||
4_textured_cube/app.cpp
|
4_textured_cube/app.cpp
|
||||||
@ -30,13 +32,15 @@ src_files = Split("""
|
|||||||
8_post_process/app.cpp
|
8_post_process/app.cpp
|
||||||
""")
|
""")
|
||||||
|
|
||||||
shader_files = env.Glob("#assets/shaders/glsl/*.frag") \
|
glsl_files = env.Glob("#assets/shaders/glsl/*.frag") \
|
||||||
+ env.Glob("#assets/shaders/glsl/*.vert") \
|
+ env.Glob("#assets/shaders/glsl/*.vert") \
|
||||||
+ env.Glob("#assets/shaders/glsl/*.comp")
|
+ env.Glob("#assets/shaders/glsl/*.comp")
|
||||||
|
|
||||||
|
hlsl_files = env.Glob('#assets/shaders/hlsl/*.ps') \
|
||||||
|
+ env.Glob('#assets/shaders/hlsl/*.vs')
|
||||||
|
|
||||||
env.Append(CPPDEFINES = ['GLM_FORCE_DEPTH_ZERO_TO_ONE', 'GLM_FORCE_RADIANS', 'GLM_ENABLE_EXPERIMENTAL'])
|
env.Append(CPPDEFINES = ['GLM_FORCE_DEPTH_ZERO_TO_ONE', 'GLM_FORCE_RADIANS', 'GLM_ENABLE_EXPERIMENTAL'])
|
||||||
prog_app = env.UnityProgram(
|
prog_app = env.UnityProgram(
|
||||||
name = 'SDL GPU Test',
|
|
||||||
target = env['BIN_DIR'] + '/sdl_gpu_test',
|
target = env['BIN_DIR'] + '/sdl_gpu_test',
|
||||||
source = src_files,
|
source = src_files,
|
||||||
dependencies = {
|
dependencies = {
|
||||||
@ -56,10 +60,15 @@ prog_app = env.UnityProgram(
|
|||||||
)
|
)
|
||||||
env.Default(prog_app)
|
env.Default(prog_app)
|
||||||
|
|
||||||
for shader_file in shader_files:
|
for glsl_file in glsl_files:
|
||||||
spv = env.SpirV(source = shader_file, target=f'{shader_file}.spv')
|
spv = env.SpirV(source=glsl_file, target=f'{glsl_file}.spv')
|
||||||
env.Default(spv)
|
env.Default(spv)
|
||||||
|
|
||||||
|
if 'DXC' in env['BUILDERS']:
|
||||||
|
for hlsl_file in hlsl_files:
|
||||||
|
dxc = env.DXC(source=hlsl_file, target=f'{hlsl_file}.dxil')
|
||||||
|
env.Default(dxc)
|
||||||
|
|
||||||
pack = env.PackTextures(
|
pack = env.PackTextures(
|
||||||
target = '#assets/bitmaps/ui.png',
|
target = '#assets/bitmaps/ui.png',
|
||||||
source = ['#assets/bitmaps/ui_elements.txt']
|
source = ['#assets/bitmaps/ui_elements.txt']
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
#include <mijin/debug/stacktrace.hpp>
|
#include <mijin/debug/stacktrace.hpp>
|
||||||
|
|
||||||
#include "./0_clear_swapchain/app.hpp"
|
#include "./0_clear_swapchain/app.hpp"
|
||||||
|
#include "./0_clear_swapchain_dxil/app.hpp"
|
||||||
#include "./1_green_triangle/app.hpp"
|
#include "./1_green_triangle/app.hpp"
|
||||||
|
#include "./1_green_triangle_dxil/app.hpp"
|
||||||
#include "./2_triangle_with_texcoords/app.hpp"
|
#include "./2_triangle_with_texcoords/app.hpp"
|
||||||
#include "./3_textured_quad/app.hpp"
|
#include "./3_textured_quad/app.hpp"
|
||||||
#include "./4_textured_cube/app.hpp"
|
#include "./4_textured_cube/app.hpp"
|
||||||
@ -36,7 +38,9 @@ AppListEntry makeAppHelper(std::string name) noexcept
|
|||||||
|
|
||||||
const std::array APPS = {
|
const std::array APPS = {
|
||||||
makeAppHelper<sdl_gpu_test::ClearSwapchainApp>("clear_swapchain"),
|
makeAppHelper<sdl_gpu_test::ClearSwapchainApp>("clear_swapchain"),
|
||||||
|
makeAppHelper<sdl_gpu_test::ClearSwapchainDXILApp>("clear_swapchain_dxil"),
|
||||||
makeAppHelper<sdl_gpu_test::GreenTriangleApp>("green_triangle"),
|
makeAppHelper<sdl_gpu_test::GreenTriangleApp>("green_triangle"),
|
||||||
|
makeAppHelper<sdl_gpu_test::GreenTriangleDXILApp>("green_triangle_dxil"),
|
||||||
makeAppHelper<sdl_gpu_test::TriangleWithTexcoordsApp>("triangle_with_texcoords"),
|
makeAppHelper<sdl_gpu_test::TriangleWithTexcoordsApp>("triangle_with_texcoords"),
|
||||||
makeAppHelper<sdl_gpu_test::TexturedQuadApp>("textured_quad"),
|
makeAppHelper<sdl_gpu_test::TexturedQuadApp>("textured_quad"),
|
||||||
makeAppHelper<sdl_gpu_test::TexturedCubeApp>("textured_cube"),
|
makeAppHelper<sdl_gpu_test::TexturedCubeApp>("textured_cube"),
|
||||||
|
@ -15,7 +15,6 @@ src_files = Split("""
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
prog_packer = env.UnityProgram(
|
prog_packer = env.UnityProgram(
|
||||||
name = 'Texture Packer',
|
|
||||||
target = env['BIN_DIR'] + '/texture_packer',
|
target = env['BIN_DIR'] + '/texture_packer',
|
||||||
source = src_files,
|
source = src_files,
|
||||||
dependencies = {
|
dependencies = {
|
||||||
|
29
site_scons/site_tools/dxc.py
Normal file
29
site_scons/site_tools/dxc.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
import shutil
|
||||||
|
from SCons.Script import *
|
||||||
|
|
||||||
|
def exists(env: Environment) -> bool:
|
||||||
|
return shutil.which('dxc.exe') is not None
|
||||||
|
|
||||||
|
def generate(env : Environment):
|
||||||
|
if not exists(env):
|
||||||
|
return
|
||||||
|
def _build(target, source, env):
|
||||||
|
if len(target) != 1:
|
||||||
|
env.Error('Invalid number of targets for DXC builder, must be 1.')
|
||||||
|
if len(source) != 1:
|
||||||
|
env.Error('Invalid number of sources for DXC builder, must be 1.')
|
||||||
|
ext = source[0].name.split('.')[-1]
|
||||||
|
profile = {
|
||||||
|
'vs': 'vs_6_0',
|
||||||
|
'ps': 'ps_6_0'
|
||||||
|
}.get(ext.lower())
|
||||||
|
if not profile:
|
||||||
|
env.Error(f'Could not detect DXC shader profile from extension: {ext}')
|
||||||
|
env.Execute(f'"$DXC" -O0 -Zi -E main -T {profile} -Fo "{target[0]}" -Fd "{target[0]}.pdb" "{source[0]}')
|
||||||
|
dxc_builder = Builder(
|
||||||
|
action=_build
|
||||||
|
)
|
||||||
|
env.AddMethod(_build, 'DXC')
|
||||||
|
env['DXC'] = shutil.which('dxc.exe')
|
||||||
|
env.Append(BUILDERS={'DXC': dxc_builder})
|
Loading…
x
Reference in New Issue
Block a user