This commit is contained in:
2025-06-09 10:24:21 +08:00
parent b532ce2f24
commit 398ac7af53
5 changed files with 197 additions and 17 deletions

View File

@@ -1,6 +1,7 @@
#include <thread>
#include <chrono>
#include "test.shader.h"
#include "SDL3/SDL_init.h"
#include "SDL3/SDL_render.h"
#include "SDL3/SDL_video.h"
@@ -16,13 +17,16 @@ int main(int argc, char* argv[]) {
SDL_Log("Could not create window: %s", SDL_GetError());
return 1;
}
SDL_Renderer* renderer = SDL_CreateRenderer(window, "direct3d12,metal,vulkan");
SDL_GPUDevice* gpu_device;
auto renderer = SDL_CreateGPURenderer(window, SDL_GPU_SHADERFORMAT_DXIL, &gpu_device);
if (renderer == nullptr) {
SDL_Log("Could not create renderer: %s", SDL_GetError());
SDL_DestroyWindow(window);
return 1;
}
auto gpu_device = (SDL_GPUDevice*)SDL_GetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_GPU_DEVICE_POINTER, NULL);
SDL3GPU::test_shader_handle_t shader_handle;
auto result = shader_handle.init(gpu_device);
TTF_Init();

View File

@@ -19,3 +19,9 @@ SDL_GPUGraphicsPipeline* pixel_shader_handle_t::create_graphics_pipeline(SDL_GPU
return SDL_CreateGPUGraphicsPipeline(in_gpu_device, &desc);
}
SDL_GPUComputePipeline* compute_shader_handle_t::create_compute_pipeline(SDL_GPUDevice* in_gpu_device) {
SDL_GPUComputePipelineCreateInfo desc = {};
desc.format = SDL_GPU_SHADERFORMAT_DXIL;
return SDL_CreateGPUComputePipeline(in_gpu_device, &desc);
}

View File

@@ -11,13 +11,14 @@ public:
virtual ~shader_handle_t() = default;
virtual std::expected<bool, std::string> init(SDL_GPUDevice* in_gpu_device) = 0;
virtual void clear(SDL_GPUDevice* in_gpu_device) = 0;
};
class pixel_shader_handle_t : public shader_handle_t {
public:
virtual std::expected<bool, std::string> init(SDL_GPUDevice* in_gpu_device) override {
if (!in_gpu_device) {
return std::unexpected("Invalid GPU device");
}
vertex_shader_ = create_vertex_shader(in_gpu_device);
if (!vertex_shader_) {
return std::unexpected("Failed to create vertex shader");
@@ -36,6 +37,9 @@ public:
}
virtual void clear(SDL_GPUDevice* in_gpu_device) override {
if (!in_gpu_device) {
return;
}
if (graphics_pipeline_) {
SDL_ReleaseGPUGraphicsPipeline(in_gpu_device, graphics_pipeline_);
graphics_pipeline_ = nullptr;
@@ -68,20 +72,27 @@ private:
class compute_shader_handle_t : public shader_handle_t {
public:
virtual std::expected<bool, std::string> init(SDL_GPUDevice* in_gpu_device) override {
compute_shader_ = create_compute_shader(in_gpu_device);
if (!compute_shader_) {
return std::unexpected("Failed to create compute shader");
if (!in_gpu_device) {
return std::unexpected("Invalid GPU device");
}
compute_pipeline_ = SDL_CreateGPUComputePipeline(in_gpu_device, compute_shader_);
compute_pipeline_ = create_compute_pipeline(in_gpu_device);
if (!compute_pipeline_) {
clear(in_gpu_device);
return std::unexpected("Failed to create compute pipeline");
}
return true;
}
virtual void clear(SDL_GPUDevice* in_gpu_device) override {
if (!in_gpu_device) {
return;
}
if (compute_pipeline_) {
SDL_ReleaseGPUComputePipeline(in_gpu_device, compute_pipeline_);
compute_pipeline_ = nullptr;
}
}
protected:
virtual SDL_GPUShader* create_compute_shader(SDL_GPUDevice* in_gpu_device) = 0;
virtual SDL_GPUComputePipeline* create_compute_pipeline(SDL_GPUDevice* in_gpu_device);
private:
SDL_GPUShader* compute_shader_ = nullptr;
SDL_GPUComputePipeline* compute_pipeline_ = nullptr;
};

File diff suppressed because one or more lines are too long

131
src/test_layout.h Normal file
View File

@@ -0,0 +1,131 @@
#pragma once
#include <SDL3/SDL.h>
#include <SDL3/SDL_gpu.h>
#include <cstdint> // For fixed-width integer types
// Auto-generated vertex structure
namespace test_shader {
struct vertex_t {
// location: 0, semantic: POSITION, offset: 0, size: 8 bytes
float position[2];
// location: 1, semantic: TEXCOORD, offset: 8, size: 8 bytes
float uv[2];
// location: 2, semantic: COLOR, offset: 16, size: 16 bytes
float color[4];
// location: 3, semantic: TEXCOORD1, offset: 32, size: 16 bytes
float param_a[4];
// location: 4, semantic: TEXCOORD2, offset: 48, size: 16 bytes
float param_b[4];
// location: 5, semantic: TEXCOORD3, offset: 64, size: 16 bytes
float param_c[4];
};
// Total size: 80 bytes
static_assert(sizeof(vertex_t) == 80, "Vertex struct size mismatch");
// Uniform buffer structures
// Vertex attribute descriptions
static constexpr uint32_t VERTEX_ATTRIBUTE_COUNT = 6;
static const SDL_GPUVertexAttribute vertex_attributes[] = {
{
// position
.location = 0,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 0
},
{
// uv
.location = 1,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 8
},
{
// color
.location = 2,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
.offset = 16
},
{
// param_a
.location = 3,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
.offset = 32
},
{
// param_b
.location = 4,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
.offset = 48
},
{
// param_c
.location = 5,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
.offset = 64
}
};
// Vertex buffer description
static constexpr SDL_GPUVertexBufferDescription vertex_buffer_desc = {
.slot = 0,
.pitch = 80, // sizeof(vertex)
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0
};
// Vertex input state
static constexpr SDL_GPUVertexInputState vertex_input_state = {
.vertex_buffer_descriptions = &vertex_buffer_desc,
.num_vertex_buffers = 1,
.vertex_attributes = vertex_attributes,
.num_vertex_attributes = VERTEX_ATTRIBUTE_COUNT
};
// Helper functions
static SDL_GPUBuffer* create_vertex_buffer(SDL_GPUDevice* device,
const vertex_t* vertices,
Uint32 vertex_count) {
SDL_GPUBufferCreateInfo buffer_info = {
.usage = SDL_GPU_BUFFERUSAGE_VERTEX,
.size = static_cast<Uint32>(sizeof(vertex_t)) * vertex_count
};
SDL_GPUBuffer* buffer = SDL_CreateGPUBuffer(device, &buffer_info);
SDL_GPUTransferBufferCreateInfo transfer_info = {
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
.size = buffer_info.size
};
// Upload vertex data
SDL_GPUTransferBuffer* transfer = SDL_CreateGPUTransferBuffer(device, &transfer_info);
void* mapped = SDL_MapGPUTransferBuffer(device, transfer, false);
SDL_memcpy(mapped, vertices, buffer_info.size);
SDL_UnmapGPUTransferBuffer(device, transfer);
// Copy to GPU
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(device);
SDL_GPUCopyPass* copy = SDL_BeginGPUCopyPass(cmd);
SDL_GPUTransferBufferLocation src = {.transfer_buffer = transfer, .offset = 0};
SDL_GPUBufferRegion dst = {.buffer = buffer, .offset = 0, .size = buffer_info.size};
SDL_UploadToGPUBuffer(copy, &src, &dst, false);
SDL_EndGPUCopyPass(copy);
SDL_SubmitGPUCommandBuffer(cmd);
SDL_ReleaseGPUTransferBuffer(device, transfer);
return buffer;
}
}