diff --git a/NOTES.md b/NOTES.md index 63c1bcc..4047325 100644 --- a/NOTES.md +++ b/NOTES.md @@ -11,3 +11,9 @@ Descriptor sets - 0 are read-only resources (samplers, storage images, storage buffers) - 1 are write-only resources (storage images and storage buffers) - 2 are uniform buffers + +Cycling +=== + - due to the nature of in-flight frames, resources might still be in use in a previous frames + - to make up for this, many SDL_gpu APIs have a `cycle` parameter + - if set to true, SDL will provide an unused resource if the previous one is still in use \ No newline at end of file diff --git a/assets/shaders/glsl/color_from_texcoord.frag b/assets/shaders/glsl/color_from_texcoord.frag new file mode 100644 index 0000000..f42ad66 --- /dev/null +++ b/assets/shaders/glsl/color_from_texcoord.frag @@ -0,0 +1,18 @@ +#version 460 + +layout(set = 3, binding = 0) +uniform Parameters +{ + vec4 u_color; +}; + +layout(location = 0) +in vec2 i_texCoord; + +layout(location = 0) +out vec4 o_color; + +void main() +{ + o_color = vec4(i_texCoord, 1, 1) * u_color; +} diff --git a/assets/shaders/glsl/textured_triangles_from_buffer.vert b/assets/shaders/glsl/textured_triangles_from_buffer.vert new file mode 100644 index 0000000..6ab5caa --- /dev/null +++ b/assets/shaders/glsl/textured_triangles_from_buffer.vert @@ -0,0 +1,16 @@ +#version 460 + +layout(location = 0) +in vec2 i_position; + +layout(location = 1) +in vec2 i_texCoord; + +layout(location = 0) +out vec2 o_texCoord; + +void main() +{ + gl_Position = vec4(i_position, 0.0, 1.0); + o_texCoord = i_texCoord; +} diff --git a/private/sdl_gpu_test/SModule b/private/sdl_gpu_test/SModule index 754937c..8cf9933 100644 --- a/private/sdl_gpu_test/SModule +++ b/private/sdl_gpu_test/SModule @@ -7,9 +7,11 @@ src_files = Split(""" shader_files = Split(""" #assets/shaders/glsl/color_from_uniform.frag + #assets/shaders/glsl/color_from_texcoord.frag #assets/shaders/glsl/green.frag #assets/shaders/glsl/triangle.vert #assets/shaders/glsl/triangles_from_buffer.vert + #assets/shaders/glsl/textured_triangles_from_buffer.vert """) env.Append(CPPDEFINES = ['GLM_FORCE_DEPTH_ZERO_TO_ONE', 'GLM_FORCE_RADIANS']) diff --git a/private/sdl_gpu_test/main.cpp b/private/sdl_gpu_test/main.cpp index c3ba801..238c99d 100644 --- a/private/sdl_gpu_test/main.cpp +++ b/private/sdl_gpu_test/main.cpp @@ -15,6 +15,12 @@ namespace { +struct Vertex +{ + glm::vec2 pos; + glm::vec2 texCoord; +}; + mijin::StackedFileSystemAdapter gFileSystem; void initFileSystem(const fs::path& executablePath) noexcept @@ -43,6 +49,33 @@ mijin::TypelessBuffer getFileContentsBinary(const fs::path& path) mijin::throwOnError(stream->readRest(content), "Error reading file contents."); return content; } + +template +void uploadVertexData(const sdlpp::GPUDevice& gpuDevice, const sdlpp::GPUBuffer& vertexBuffer, std::span vertices) +{ + sdlpp::GPUTransferBuffer transferBuffer; + transferBuffer.create(gpuDevice, { + .usage = sdlpp::GPUTransferBufferUsage::UPLOAD, + .size = static_cast(vertices.size_bytes()) + }); + void* ptr = transferBuffer.map(); + std::memcpy(ptr, vertices.data(), vertices.size_bytes()); + transferBuffer.unmap(); + + sdlpp::GPUCommandBuffer cmdBuffer = gpuDevice.acquireCommandBuffer(); + sdlpp::GPUCopyPass copyPass = cmdBuffer.beginCopyPass(); + copyPass.uploadToGPUBuffer( + /* source = */ { + .transferBuffer = transferBuffer + }, + /* destination = */ { + .buffer = vertexBuffer, + .size = static_cast(vertices.size_bytes()) + } + ); + copyPass.end(); + cmdBuffer.submit(); +} } int main(int argc, char* argv[]) @@ -67,7 +100,7 @@ int main(int argc, char* argv[]) sdlpp::Window window; window.create({ .title = "SDL_gpu Test", - .flags = {.vulkan = true} + .flags = {.resizable = true} }); sdlpp::GPUDevice gpuDevice; @@ -79,7 +112,7 @@ int main(int argc, char* argv[]) gpuDevice.claimWindow(window); // create vertex shader - mijin::TypelessBuffer vertexSpv = getFileContentsBinary("shaders/glsl/triangles_from_buffer.vert.spv"); + mijin::TypelessBuffer vertexSpv = getFileContentsBinary("shaders/glsl/textured_triangles_from_buffer.vert.spv"); sdlpp::GPUShader vertexShader; vertexShader.create(gpuDevice, { .code = {static_cast(vertexSpv.data()), vertexSpv.byteSize()}, @@ -88,7 +121,7 @@ int main(int argc, char* argv[]) }); // create fragment shader - mijin::TypelessBuffer fragmentSpv = getFileContentsBinary("shaders/glsl/color_from_uniform.frag.spv"); + mijin::TypelessBuffer fragmentSpv = getFileContentsBinary("shaders/glsl/color_from_texcoord.frag.spv"); sdlpp::GPUShader fragmentShader; fragmentShader.create(gpuDevice, { .code = {static_cast(fragmentSpv.data()), fragmentSpv.byteSize()}, @@ -107,7 +140,7 @@ int main(int argc, char* argv[]) std::array vertexBindings = { sdlpp::GPUVertexBinding{ .index = 0, - .pitch = sizeof(glm::vec2) + .pitch = sizeof(Vertex) } }; std::array vertexAttributes = { @@ -115,7 +148,13 @@ int main(int argc, char* argv[]) .location = 0, .bindingIndex = 0, .format = sdlpp::GPUVertexElementFormat::FLOAT2, - .offset = 0 + .offset = offsetof(Vertex, pos) + }, + sdlpp::GPUVertexAttribute{ + .location = 1, + .bindingIndex = 0, + .format = sdlpp::GPUVertexElementFormat::FLOAT2, + .offset = offsetof(Vertex, texCoord) } }; pipeline.create(gpuDevice, { @@ -132,9 +171,9 @@ int main(int argc, char* argv[]) std::array vertices = { - glm::vec2{-1.f, -1.f}, - glm::vec2{ 1.f, -1.f}, - glm::vec2{ 0.f, 1.f} + Vertex{.pos = {-1.f, -1.f}, .texCoord = {0.f, 0.f}}, + Vertex{.pos = { 1.f, -1.f}, .texCoord = {1.f, 0.f}}, + Vertex{.pos = { 0.f, 1.f}, .texCoord = {0.5f, 1.f}} }; // create vertex buffer @@ -143,31 +182,7 @@ int main(int argc, char* argv[]) .usage = {.vertex = true}, .size = sizeof(vertices) }); - { - sdlpp::GPUTransferBuffer transferBuffer; - transferBuffer.create(gpuDevice, { - .usage = sdlpp::GPUTransferBufferUsage::UPLOAD, - .size = sizeof(vertices) - }); - void* ptr = transferBuffer.map(); - std::memcpy(ptr, vertices.data(), sizeof(vertices)); - transferBuffer.unmap(); - - sdlpp::GPUCommandBuffer cmdBuffer = gpuDevice.acquireCommandBuffer(); - sdlpp::GPUCopyPass copyPass = cmdBuffer.beginCopyPass(); - copyPass.uploadToGPUBuffer( - /* source = */ { - .transferBuffer = transferBuffer - }, - /* destination = */ { - .buffer = vertexBuffer, - .size = sizeof(vertices) - } - ); - copyPass.end(); - cmdBuffer.submit(); - } - + uploadVertexData(gpuDevice, vertexBuffer, std::span(vertices.begin(), vertices.end())); bool running = true; while(running) @@ -192,8 +207,8 @@ int main(int argc, char* argv[]) sdlpp::GPURenderPass renderPass = cmdBuffer.beginRenderPass({ .colorTargetInfos = colorTargets }); - static const glm::vec4 BLUE(0.f, 0.f, 1.f, 1.f); - cmdBuffer.pushFragmentUniformData(0, std::span(&BLUE, 1)); + static const glm::vec4 WHITE(1.f, 1.f, 1.f, 1.f); + cmdBuffer.pushFragmentUniformData(0, std::span(&WHITE, 1)); renderPass.bindGraphicsPipeline(pipeline); renderPass.bindVertexBuffer({.buffer = vertexBuffer}); renderPass.drawPrimitives({.numVertices = 3});