summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sdl_gpu_test.c192
1 files changed, 94 insertions, 98 deletions
diff --git a/sdl_gpu_test.c b/sdl_gpu_test.c
index 30e6b83..e769d4c 100644
--- a/sdl_gpu_test.c
+++ b/sdl_gpu_test.c
@@ -13,32 +13,25 @@
SDL_Window *win;
SDL_GPUDevice *gpudev;
SDL_GPUGraphicsPipeline *pipeline_fill;
-SDL_GPUBuffer *buf_vert;
-SDL_GPUTransferBuffer *buf_vert_xfer;
+SDL_GPUBuffer *ptbuf;
+SDL_GPUTransferBuffer *ptbuf_xfer;
-typedef struct {
- float x, y;
- float u, v;
-} Vertex;
-
-Vertex vertices[] = {
- { -1, -1, 0, 0, },
- { 0, -1, 1, 0, },
- { 0, 0, 1, 1, },
-
- { -1, -1, 0, 0, },
- { -1, 0, 0, 1, },
- { 0, 0, 1, 1, },
+typedef enum {
+ PT_CLOUD,
+ PT_FLASH
+} ParticleType;
- { 0, 0, 0, 0, },
- { 1, 0, 1, 0, },
- { 1, 1, 1, 1, },
+typedef struct __attribute__((packed)) {
+ vec2 pos;
+ float radius, life;
+ vec3 color;
+ int type;
+} Particle;
- { 0, 0, 0, 0, },
- { 0, 1, 0, 1, },
- { 1, 1, 1, 1, },
+#define PT_MAX 65536
-};
+Particle pts[PT_MAX];
+size_t npt = 0;
typedef struct {
SDL_GPUShaderStage stage;
@@ -85,56 +78,30 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
SDL_GPUShader *shader_vert = load_shader(gpudev, "shader/tri.vert.spv", &(ShaderDesc) {
.stage = SDL_GPU_SHADERSTAGE_VERTEX,
- .n_uniformbuf = 1
+ .n_uniformbuf = 1,
+ .n_storagebuf = 1,
});
CHECK(shader_vert, "load vertex shader");
SDL_GPUShader *shader_frag = load_shader(gpudev, "shader/tri.frag.spv", &(ShaderDesc) { SDL_GPU_SHADERSTAGE_FRAGMENT });
CHECK(shader_frag, "load fragment shader");
- buf_vert = SDL_CreateGPUBuffer(gpudev, &(SDL_GPUBufferCreateInfo) {
- .usage = SDL_GPU_BUFFERUSAGE_VERTEX,
- .size = sizeof(vertices),
+ ptbuf = SDL_CreateGPUBuffer(gpudev, &(SDL_GPUBufferCreateInfo) {
+ .usage = SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ,
+ .size = sizeof(pts),
.props = 0
});
- CHECK(buf_vert, "vertex buffer");
+ CHECK(ptbuf, "vertex buffer");
- buf_vert_xfer = SDL_CreateGPUTransferBuffer(
+ ptbuf_xfer = SDL_CreateGPUTransferBuffer(
gpudev,
&(SDL_GPUTransferBufferCreateInfo) {
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
- .size = sizeof(vertices),
+ .size = sizeof(pts),
.props = 0
}
);
- CHECK(buf_vert_xfer, "vertex transfer buffer");
-
- void *map = SDL_MapGPUTransferBuffer(gpudev, buf_vert_xfer, false);
- SDL_memcpy(map, vertices, sizeof(vertices));
- SDL_UnmapGPUTransferBuffer(gpudev, buf_vert_xfer);
-
- SDL_GPUCommandBuffer *cmdbuf = SDL_AcquireGPUCommandBuffer(gpudev);
- CHECK(cmdbuf, "gpu command buffer acquisition");
- SDL_GPUCopyPass *copypass = SDL_BeginGPUCopyPass(cmdbuf);
- CHECK(copypass, "gpu copy pass");
-
- SDL_UploadToGPUBuffer(
- copypass,
- &(SDL_GPUTransferBufferLocation) {
- .transfer_buffer = buf_vert_xfer,
- .offset = 0
- },
- &(SDL_GPUBufferRegion) {
- .buffer = buf_vert,
- .offset = 0,
- .size = sizeof(vertices)
- },
- false
- );
-
- SDL_EndGPUCopyPass(copypass);
- SDL_SubmitGPUCommandBuffer(cmdbuf);
- SDL_ReleaseGPUTransferBuffer(gpudev, buf_vert_xfer);
+ CHECK(ptbuf_xfer, "vertex transfer buffer");
pipeline_fill = SDL_CreateGPUGraphicsPipeline(gpudev, &(SDL_GPUGraphicsPipelineCreateInfo) {
.target_info = {
@@ -155,30 +122,6 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
.vertex_shader = shader_vert,
.fragment_shader = shader_frag,
- .vertex_input_state = {
- .num_vertex_buffers = 1,
- .vertex_buffer_descriptions = &(SDL_GPUVertexBufferDescription) {
- .slot = 0,
- .pitch = sizeof(Vertex),
- .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
- .instance_step_rate = 0,
- },
- .num_vertex_attributes = 2,
- .vertex_attributes = (SDL_GPUVertexAttribute[]) {
- {
- .location = 0,
- .buffer_slot = 0,
- .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
- .offset = 0
- },
- {
- .location = 1,
- .buffer_slot = 0,
- .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
- .offset = sizeof(float) * 2
- }
- }
- },
.rasterizer_state = {
.fill_mode = SDL_GPU_FILLMODE_FILL
},
@@ -219,6 +162,28 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
SDL_GPUCommandBuffer *cmdbuf = SDL_AcquireGPUCommandBuffer(gpudev);
CHECK(cmdbuf, "gpu cmd buffer acquisition");
+ void *map = SDL_MapGPUTransferBuffer(gpudev, ptbuf_xfer, true);
+ SDL_memcpy(map, pts, sizeof(Particle) * (npt < PT_MAX ? npt : PT_MAX));
+ SDL_UnmapGPUTransferBuffer(gpudev, ptbuf_xfer);
+
+ SDL_GPUCopyPass *copypass = SDL_BeginGPUCopyPass(cmdbuf);
+ CHECK(copypass, "gpu copy pass");
+
+ SDL_UploadToGPUBuffer(
+ copypass,
+ &(SDL_GPUTransferBufferLocation) {
+ .transfer_buffer = ptbuf_xfer,
+ .offset = 0
+ },
+ &(SDL_GPUBufferRegion) {
+ .buffer = ptbuf,
+ .offset = 0,
+ .size = sizeof(pts)
+ },
+ false
+ );
+ SDL_EndGPUCopyPass(copypass);
+
SDL_GPUTexture *swapchain;
Uint32 swc_width, swc_height;
CHECK(SDL_WaitAndAcquireGPUSwapchainTexture(cmdbuf, win, &swapchain, &swc_width, &swc_height), "swapchain texture acquisition");
@@ -231,25 +196,54 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
last = now;
t += dt;
- float mx, my;
- SDL_GetMouseState(&mx, &my);
- mx -= swc_width * 0.5f;
- my -= swc_height * 0.5f;
- mx *= 1.0f / fminf(swc_width, swc_height);
- my *= 1.0f / fminf(swc_width, swc_height);
-
- float rot = t;
+ float rot = 0;
+ static float rot_vel = 0;
+ static vec2 pos = { 0 }, vel = { 0 };
+ rot += rot_vel * dt;
+ rot_vel *= expf(-1.0f * dt);
+
+ const bool *kbd = SDL_GetKeyboardState(0);
+ float spd = 128 * dt;
+ if (kbd[SDL_SCANCODE_LSHIFT]) spd *= 10;
+ if (kbd[SDL_SCANCODE_LEFT]) vel[0] -= spd;
+ if (kbd[SDL_SCANCODE_RIGHT]) vel[0] += spd;
+ if (kbd[SDL_SCANCODE_UP]) vel[1] += spd;
+ if (kbd[SDL_SCANCODE_DOWN]) vel[1] -= spd;
+ pos[0] += vel[0] * dt;
+ pos[1] += vel[1] * dt;
+ glm_vec2_scale(vel, expf(-dt), vel);
mat4 cam_mat;
- static float x = 0, y = 0;
-
float s = sinf(-rot), c = cosf(-rot);
- float dx = mx * dt * 10;
- float dy = -my * dt * 10;
- x += dx * c - dy * s;
- y += dy * c + dx * s;
- build_cam_mat(cam_mat, swc_width, swc_height, x, y, 0.1, rot);
+ for (int i = 0; i < npt; i++) {
+ pts[i].life -= dt;
+ if (pts[i].life < 0) {
+ if (i + 1 < npt) {
+ pts[i] = pts[--npt];
+ i--;
+ continue;
+ }
+ }
+ }
+
+ float v = hypotf(vel[0], vel[1]);
+ float scale = 0.1 / (1 + 0.05 * v);
+ static size_t npti = 0;
+ for (int i = 0; i < 1 + dt * v; i++) {
+ float sz = 1 + dt * v * 5;
+ vec2 ofs = { (SDL_randf()*2-1) * sz, (SDL_randf()*2-1) * sz };
+ pts[npti++ % PT_MAX] = (Particle) {
+ .pos = { pos[0] + ofs[0], pos[1] + ofs[1] },
+ .radius = SDL_randf() * 2,
+ .life = 10,
+ .color = { SDL_randf(), SDL_randf(), SDL_randf() },
+ .type = PT_CLOUD
+ };
+ npt = npti < PT_MAX ? npti : PT_MAX;
+ }
+ printf("%0.2f FPS : %zu\n", 1.0f / dt, npt);
+ build_cam_mat(cam_mat, swc_width, swc_height, pos[0], pos[1], scale, rot);
SDL_PushGPUVertexUniformData(cmdbuf, 0, &cam_mat, sizeof(cam_mat));
SDL_GPURenderPass *render_pass = SDL_BeginGPURenderPass(
cmdbuf,
@@ -263,8 +257,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
NULL
);
SDL_BindGPUGraphicsPipeline(render_pass, pipeline_fill);
- SDL_BindGPUVertexBuffers(render_pass, 0, &(SDL_GPUBufferBinding) { .buffer = buf_vert, .offset = 0 }, 1);
- SDL_DrawGPUPrimitives(render_pass, sizeof(vertices) / sizeof(Vertex), 1, 0, 0);
+ SDL_BindGPUVertexStorageBuffers(render_pass, 0, &ptbuf, 1);
+ SDL_DrawGPUPrimitives(render_pass, 6 * (npt < PT_MAX ? npt : PT_MAX), 1, 0, 0);
SDL_EndGPURenderPass(render_pass);
SDL_SubmitGPUCommandBuffer(cmdbuf);
@@ -274,6 +268,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
(void)appstate;
(void)result;
+ SDL_ReleaseGPUTransferBuffer(gpudev, ptbuf_xfer);
+ SDL_ReleaseGPUBuffer(gpudev, ptbuf);
SDL_ReleaseGPUGraphicsPipeline(gpudev, pipeline_fill);
SDL_ReleaseWindowFromGPUDevice(gpudev, win);
SDL_DestroyGPUDevice(gpudev);