summary refs log tree commit diff
path: root/sdl_gpu_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'sdl_gpu_test.c')
-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);