Get swapchain texture and clear it red.

This commit is contained in:
Patrick 2024-09-13 00:36:29 +02:00
parent cd4ab6147a
commit 3a42f7cc36
5 changed files with 197 additions and 7 deletions

View File

@ -51,9 +51,9 @@ std::vector<std::uint32_t> compileGLSL(std::string_view source, const CompileGLS
int sourceLength = static_cast<int>(source.size()); int sourceLength = static_cast<int>(source.size());
shader->setStringsWithLengths(&sourcePtr, &sourceLength, 1); shader->setStringsWithLengths(&sourcePtr, &sourceLength, 1);
shader->setDebugInfo(true); shader->setDebugInfo(true);
shader->setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, glslang::EShTargetVulkan_1_3); shader->setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
shader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_3); shader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
shader->setEnvTarget(glslang::EShTargetLanguage::EshTargetSpv, glslang::EShTargetSpv_1_6); shader->setEnvTarget(glslang::EShTargetLanguage::EshTargetSpv, glslang::EShTargetSpv_1_0);
DirStackFileIncluder includer; DirStackFileIncluder includer;
std::string preprocessedCode; std::string preprocessedCode;
@ -110,7 +110,7 @@ std::vector<std::uint32_t> compileGLSL(std::string_view source, const CompileGLS
.optimizeSize = false, .optimizeSize = false,
.disassemble = false, .disassemble = false,
.validate = true, .validate = true,
.emitNonSemanticShaderDebugInfo = true, .emitNonSemanticShaderDebugInfo = false, // requires SPV_KHR_non_semantic_info
.emitNonSemanticShaderDebugSource = false, // maybe? .emitNonSemanticShaderDebugSource = false, // maybe?
.compileOnly = false .compileOnly = false
}; };

View File

@ -4,6 +4,7 @@
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GLSL_COMPILER_HPP_INCLUDED) #if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GLSL_COMPILER_HPP_INCLUDED)
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GLSL_COMPILER_HPP_INCLUDED 1 #define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GLSL_COMPILER_HPP_INCLUDED 1
#include <cstdint>
#include <string_view> #include <string_view>
#include <vector> #include <vector>

View File

@ -56,7 +56,10 @@ int main(int, char**)
}); });
sdlpp::GPUDevice gpuDevice; sdlpp::GPUDevice gpuDevice;
gpuDevice.create({.formatFlags{.spirv = true}}); gpuDevice.create({
.formatFlags{.spirv = true},
.debugMode = true
});
gpuDevice.claimWindow(window); gpuDevice.claimWindow(window);
@ -96,6 +99,21 @@ int main(int, char**)
[](const auto&) {} // default handler [](const auto&) {} // default handler
}, *event); }, *event);
} }
sdlpp::GPUCommandBuffer cmdBuffer = gpuDevice.acquireCommandBuffer();
Uint32 swapchainWidth = 0, swapchainHeight = 0;
sdlpp::GPUTexture swapchainTexture = cmdBuffer.acquireSwapchainTexture(window, 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.end();
cmdBuffer.submit();
} }
return 0; return 0;

View File

@ -4,9 +4,10 @@
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED) #if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED)
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED 1 #define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED 1
#include <optional>
#include <span>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include <span>
#include <vector> #include <vector>
#include <mijin/debug/assert.hpp> #include <mijin/debug/assert.hpp>

View File

@ -214,6 +214,19 @@ enum class GPUShaderStage
FRAGMENT = SDL_GPU_SHADERSTAGE_FRAGMENT FRAGMENT = SDL_GPU_SHADERSTAGE_FRAGMENT
}; };
enum class GPULoadOp
{
LOAD = SDL_GPU_LOADOP_LOAD,
CLEAR = SDL_GPU_LOADOP_CLEAR,
DONT_CARE = SDL_GPU_LOADOP_DONT_CARE
};
enum class GPUStoreOp
{
STORE = SDL_GPU_STOREOP_STORE,
DONT_CARE = SDL_GPU_STOREOP_DONT_CARE
};
// //
// bitflags // bitflags
// //
@ -354,9 +367,158 @@ struct GPUGraphicsPipelineTargetInfo
} }
}; };
using FColor = SDL_FColor;
struct GPUColorTargetInfo
{
SDL_GPUTexture* texture = nullptr;
Uint32 mipLevel = 0;
Uint32 layerOrDepthPlane = 0;
FColor clearColor = {.r = 0, .g = 0, .b = 0, .a = 1};
GPULoadOp loadOp = GPULoadOp::LOAD;
GPUStoreOp storeOp = GPUStoreOp::STORE;
bool cycle = false;
};
static_assert(sizeof(GPUColorTargetInfo) == sizeof(SDL_GPUColorTargetInfo)
&& alignof(GPUColorTargetInfo) == alignof(SDL_GPUColorTargetInfo));
struct GPUDepthStencilTargetInfo
{
SDL_GPUTexture* texture = nullptr;
float clearDepth = 0.f;
GPULoadOp loadOp = GPULoadOp::LOAD;
GPUStoreOp storeOp = GPUStoreOp::STORE;
GPULoadOp stencilLoadOp = GPULoadOp::LOAD;
GPUStoreOp stencilStoreOp = GPUStoreOp::STORE;
bool cycle = false;
Uint8 clearStencil;
};
static_assert(sizeof(GPUDepthStencilTargetInfo) == sizeof(SDL_GPUDepthStencilTargetInfo)
&& alignof(GPUDepthStencilTargetInfo) == alignof(SDL_GPUDepthStencilTargetInfo));
// //
// classes // classes
// //
class GPURenderPass : public Base<SDL_GPURenderPass, GPURenderPass>
{
public:
GPURenderPass() noexcept = default;
GPURenderPass(const GPURenderPass&) = delete;
GPURenderPass(GPURenderPass&& other) noexcept : Base(std::move(other)) {}
GPURenderPass& operator=(const GPURenderPass&) = delete;
GPURenderPass& operator=(GPURenderPass&& other) noexcept
{
Base::operator=(std::move(other));
return *this;
}
auto operator<=>(const GPURenderPass& other) const noexcept = default;
void end() noexcept
{
SDL_EndGPURenderPass(mHandle);
mHandle = nullptr;
}
void destroy() noexcept
{
MIJIN_ASSERT(mHandle == nullptr, "Renderpass has not been ended.");
}
friend class GPUCommandBuffer;
};
class GPUTexture : public Base<SDL_GPUTexture, GPUTexture>
{
private:
SDL_GPUDevice* mDevice = nullptr;
public:
GPUTexture() noexcept = default;
GPUTexture(const GPUTexture&) = delete;
GPUTexture(GPUTexture&& other) noexcept : Base(std::move(other)) {}
GPUTexture& operator=(const GPUTexture&) = delete;
GPUTexture& operator=(GPUTexture&& other) noexcept
{
Base::operator=(std::move(other));
return *this;
}
auto operator<=>(const GPUTexture& other) const noexcept = default;
void destroy() noexcept
{
if (mHandle != nullptr)
{
// if this is not manually created (e.g. a swapchain image), device will be nullptr
if (mDevice != nullptr)
{
SDL_ReleaseGPUTexture(mDevice, mHandle);
}
mHandle = nullptr;
mDevice = nullptr;
}
}
friend class GPUCommandBuffer;
};
struct GPUBeginRenderPassArgs
{
std::span<const GPUColorTargetInfo> colorTargetInfos;
std::optional<GPUDepthStencilTargetInfo> depthStencilTargetInfo;
};
class GPUCommandBuffer : public Base<SDL_GPUCommandBuffer, GPUCommandBuffer>
{
public:
GPUCommandBuffer() noexcept = default;
GPUCommandBuffer(const GPUCommandBuffer&) = delete;
GPUCommandBuffer(GPUCommandBuffer&& other) noexcept : Base(std::move(other)) {}
GPUCommandBuffer& operator=(const GPUCommandBuffer&) = delete;
GPUCommandBuffer& operator=(GPUCommandBuffer&& other) noexcept
{
Base::operator=(std::move(other));
return *this;
}
auto operator<=>(const GPUCommandBuffer& other) const noexcept = default;
void submit() noexcept
{
SDL_SubmitGPUCommandBuffer(mHandle);
mHandle = nullptr;
}
void destroy() noexcept
{
MIJIN_ASSERT(mHandle == nullptr, "Command buffer has not been submitted.");
}
[[nodiscard]]
GPURenderPass beginRenderPass(const GPUBeginRenderPassArgs& args) const noexcept
{
GPURenderPass renderPass;
renderPass.mHandle = SDL_BeginGPURenderPass(
/* command_buffer = */ mHandle,
/* color_target_infos = */ std::bit_cast<const SDL_GPUColorTargetInfo*>(args.colorTargetInfos.data()),
/* num_color_targets = */ static_cast<Uint32>(args.colorTargetInfos.size()),
/* depth_stencil_target_info = */ args.depthStencilTargetInfo.has_value() ? std::bit_cast<const SDL_GPUDepthStencilTargetInfo*>(&*args.depthStencilTargetInfo) : nullptr
);
return renderPass;
}
[[nodiscard]]
GPUTexture acquireSwapchainTexture(SDL_Window* window, Uint32& outWidth, Uint32& outHeight) noexcept
{
GPUTexture texture;
texture.mHandle = SDL_AcquireGPUSwapchainTexture(mHandle, window, &outWidth, &outHeight);
return texture;
}
friend class GPUDevice;
};
struct GPUDeviceCreateArgs struct GPUDeviceCreateArgs
{ {
GPUShaderFormatFlags formatFlags = {}; GPUShaderFormatFlags formatFlags = {};
@ -400,11 +562,19 @@ public:
void claimWindow(SDL_Window* window) const void claimWindow(SDL_Window* window) const
{ {
if (!SDL_ClaimWindowForGPUDevice(*this, window)) if (!SDL_ClaimWindowForGPUDevice(mHandle, window))
{ {
throw SDLError(); throw SDLError();
} }
} }
[[nodiscard]]
GPUCommandBuffer acquireCommandBuffer() const noexcept
{
GPUCommandBuffer cmdBuffer;
cmdBuffer.mHandle = SDL_AcquireGPUCommandBuffer(mHandle);
return cmdBuffer;
}
}; };
struct GPUGraphicsPipelineCreateArgs struct GPUGraphicsPipelineCreateArgs