Files
SDL3Test/src/test_layout.h
2025-06-10 18:24:07 +08:00

137 lines
4.3 KiB
C++

#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: TEXCOORD, offset: 0, size: 8 bytes
float position[2];
// location: 1, semantic: TEXCOORD1, offset: 8, size: 8 bytes
float uv[2];
// location: 2, semantic: TEXCOORD2, offset: 16, size: 16 bytes
float color[4];
// location: 3, semantic: TEXCOORD3, offset: 32, size: 16 bytes
float param_a[4];
// location: 4, semantic: TEXCOORD4, offset: 48, size: 16 bytes
float param_b[4];
// location: 5, semantic: TEXCOORD5, 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
typedef struct ParamBuffer {
float transform[4][4]; // offset: 0, size: 64
} ParamBuffer;
// Binding: 0, Size: 64 bytes (aligned: 64)
// 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;
}
}