Set minimum and maximum size for window and use better line terminators

This commit is contained in:
azraptor 2025-04-11 14:48:50 -04:00
parent 270132a58e
commit 8a3385b15c
4 changed files with 263 additions and 257 deletions

2
.gitignore vendored
View File

@ -52,6 +52,6 @@ Mkfile.old
dkms.conf dkms.conf
SDL3/ SDL3/
build/ build*/
.cache/ .cache/
.vscode/ .vscode/

408
main.c
View File

@ -1,201 +1,207 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_gpu.h>
SDL_GPUShader *loadShader(SDL_GPUDevice *device, #include <SDL3/SDL_video.h>
const char *filename,
Uint32 samplerCount, SDL_GPUShader *loadShader(SDL_GPUDevice *device,
Uint32 uniformBufferCount, const char *filename,
Uint32 storageBufferCount, Uint32 samplerCount,
Uint32 storageTextureCount) { Uint32 uniformBufferCount,
SDL_GPUShaderStage stage; Uint32 storageBufferCount,
if(SDL_strstr(filename, ".vert")) Uint32 storageTextureCount) {
stage = SDL_GPU_SHADERSTAGE_VERTEX; SDL_GPUShaderStage stage;
else if(SDL_strstr(filename, ".frag")) if(SDL_strstr(filename, ".vert"))
stage = SDL_GPU_SHADERSTAGE_FRAGMENT; stage = SDL_GPU_SHADERSTAGE_VERTEX;
else { else if(SDL_strstr(filename, ".frag"))
SDL_Log("Invalid shader stage!"); stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
return NULL; else {
} SDL_Log("Invalid shader stage!");
return NULL;
SDL_GPUShaderFormat backendFmt = SDL_GetGPUShaderFormats(device); }
SDL_GPUShaderFormat format = SDL_GPU_SHADERFORMAT_INVALID; SDL_GPUShaderFormat backendFmt = SDL_GetGPUShaderFormats(device);
const char *entryPoint;
SDL_GPUShaderFormat format = SDL_GPU_SHADERFORMAT_INVALID;
if(backendFmt & SDL_GPU_SHADERFORMAT_SPIRV) { const char *entryPoint;
format = SDL_GPU_SHADERFORMAT_SPIRV;
entryPoint = "main"; if(backendFmt & SDL_GPU_SHADERFORMAT_SPIRV) {
} else { format = SDL_GPU_SHADERFORMAT_SPIRV;
SDL_Log("Unsupported shader format!"); entryPoint = "main";
return NULL; } else {
} SDL_Log("Unsupported shader format!");
return NULL;
size_t fSize = 0; }
void *byteCode = SDL_LoadFile(filename, &fSize);
size_t fSize = 0;
if(byteCode == NULL) { void *byteCode = SDL_LoadFile(filename, &fSize);
SDL_Log("Could not load shader bytecode from file: %s", filename);
return NULL; if(byteCode == NULL) {
} SDL_Log("Could not load shader bytecode from file: %s", filename);
return NULL;
SDL_GPUShaderCreateInfo shaderInfo = { }
.code = (Uint8*)byteCode,
.code_size = fSize, SDL_GPUShaderCreateInfo shaderInfo = {
.entrypoint = entryPoint, .code = (Uint8*)byteCode,
.format = format, .code_size = fSize,
.stage = stage, .entrypoint = entryPoint,
.num_samplers = samplerCount, .format = format,
.num_uniform_buffers = uniformBufferCount, .stage = stage,
.num_storage_buffers = storageBufferCount, .num_samplers = samplerCount,
.num_storage_textures = storageTextureCount .num_uniform_buffers = uniformBufferCount,
}; .num_storage_buffers = storageBufferCount,
SDL_GPUShader *shader = SDL_CreateGPUShader(device, &shaderInfo); .num_storage_textures = storageTextureCount
if(shader == NULL) { };
SDL_Log("Could not create shader!"); SDL_GPUShader *shader = SDL_CreateGPUShader(device, &shaderInfo);
SDL_free(byteCode); if(shader == NULL) {
return NULL; SDL_Log("Could not create shader!");
} SDL_free(byteCode);
return NULL;
SDL_free(byteCode); }
return shader;
} SDL_free(byteCode);
return shader;
int main(int argc, char **argv) { }
SDL_Window *window = NULL;
SDL_GPUDevice *GPUDevice = NULL; int main(int argc, char **argv) {
SDL_GPUTexture *swapchainTexture = NULL; SDL_Window *window = NULL;
SDL_GPUCommandBuffer *commandBuf = NULL; SDL_GPUDevice *GPUDevice = NULL;
SDL_GPURenderPass *renderPass = NULL; SDL_GPUTexture *swapchainTexture = NULL;
SDL_GPUCommandBuffer *commandBuf = NULL;
SDL_GPUShader *vertexShader = NULL; SDL_GPURenderPass *renderPass = NULL;
SDL_GPUShader *fragShader = NULL;
SDL_GPUShader *vertexShader = NULL;
SDL_GPUGraphicsPipeline *pipeline = NULL; SDL_GPUShader *fragShader = NULL;
bool done = false; SDL_GPUGraphicsPipeline *pipeline = NULL;
if(!SDL_Init(SDL_INIT_VIDEO)) { bool done = false;
SDL_Log("Unable to initialize SDL3: %s", SDL_GetError());
return 1; if(!SDL_Init(SDL_INIT_VIDEO)) {
} SDL_Log("Unable to initialize SDL3: %s", SDL_GetError());
return 1;
// Create the GPU device }
GPUDevice = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, "vulkan");
// Create the GPU device
const char* device_driver = SDL_GetGPUDeviceDriver(GPUDevice); GPUDevice = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, "vulkan");
SDL_Log("Created GPU device with driver: %s\n", device_driver);
const char* device_driver = SDL_GetGPUDeviceDriver(GPUDevice);
if(GPUDevice == NULL) { SDL_Log("Created GPU device with driver: %s\n", device_driver);
SDL_Log("Create GPU failed");
return 1; if(GPUDevice == NULL) {
} SDL_Log("Create GPU failed");
return 1;
// Create the window }
window = SDL_CreateWindow("SDL3 Window", 640, 480, SDL_WINDOW_RESIZABLE);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); // Create the window
window = SDL_CreateWindow("SDL3 GPU", 640, 480, SDL_WINDOW_RESIZABLE);
if (window == NULL) { SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_Log("Could not create window: %s\n", SDL_GetError()); SDL_SetWindowMinimumSize(window, 640, 480);
return 1; SDL_SetWindowMaximumSize(window, 1280, 720);
}
if (window == NULL) {
// Tie the window to our GPU SDL_Log("Could not create window: %s\n", SDL_GetError());
if(!SDL_ClaimWindowForGPUDevice(GPUDevice, window)) { return 1;
SDL_Log("Claiming SDL3 window failed"); }
return 1;
} // Tie the window to our GPU
if(!SDL_ClaimWindowForGPUDevice(GPUDevice, window)) {
// Shader time SDL_Log("Claiming SDL3 window failed");
vertexShader = loadShader(GPUDevice, "triangle.vert.spv", 0, 0, 0, 0); return 1;
if(vertexShader == NULL) }
{
SDL_Log("Could not create vertex shader!"); // Shader time
return 1; vertexShader = loadShader(GPUDevice, "triangle.vert.spv", 0, 0, 0, 0);
} if(vertexShader == NULL)
{
fragShader = loadShader(GPUDevice, "color.frag.spv", 0, 0, 0, 0); SDL_Log("Could not create vertex shader!");
if(fragShader == NULL) return 1;
{ }
SDL_Log("Could not create fragment shader!");
return 1; fragShader = loadShader(GPUDevice, "color.frag.spv", 0, 0, 0, 0);
} if(fragShader == NULL)
{
// Creating the pipelines SDL_Log("Could not create fragment shader!");
SDL_GPUGraphicsPipelineCreateInfo pipelineCreateInfo = { return 1;
.target_info = { }
.num_color_targets = 1,
.color_target_descriptions = (SDL_GPUColorTargetDescription[]){{ // Creating the pipelines
.format = SDL_GetGPUSwapchainTextureFormat(GPUDevice, window) SDL_GPUGraphicsPipelineCreateInfo pipelineCreateInfo = {
}}, .target_info = {
}, .num_color_targets = 1,
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .color_target_descriptions = (SDL_GPUColorTargetDescription[]){{
.vertex_shader = vertexShader, .format = SDL_GetGPUSwapchainTextureFormat(GPUDevice, window)
.fragment_shader = fragShader, }},
}; },
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
pipelineCreateInfo.rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL; .vertex_shader = vertexShader,
pipeline = SDL_CreateGPUGraphicsPipeline(GPUDevice, &pipelineCreateInfo); .fragment_shader = fragShader,
if(pipeline == NULL) { };
SDL_Log("Could not create pipeline");
return 1; pipelineCreateInfo.rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL;
} pipeline = SDL_CreateGPUGraphicsPipeline(GPUDevice, &pipelineCreateInfo);
if(pipeline == NULL) {
// Free up shaders that are now bound to pipeline SDL_Log("Could not create pipeline");
SDL_ReleaseGPUShader(GPUDevice, vertexShader); return 1;
SDL_ReleaseGPUShader(GPUDevice, fragShader); }
// Now to loop // Free up shaders that are now bound to pipeline
while (!done) { SDL_ReleaseGPUShader(GPUDevice, vertexShader);
SDL_Event event; SDL_ReleaseGPUShader(GPUDevice, fragShader);
//SDL_SetGPUSwapchainParameters(GPUDevice, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC);
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_QUIT) { // Now to loop
done = true; while (!done) {
} SDL_Event event;
}
while (SDL_PollEvent(&event)) {
// Get our command buffer if (event.type == SDL_EVENT_QUIT) {
commandBuf = SDL_AcquireGPUCommandBuffer(GPUDevice); done = true;
if(commandBuf == NULL) { }
SDL_Log("Could not get command buf!"); }
return 1;
} // Get our command buffer
commandBuf = SDL_AcquireGPUCommandBuffer(GPUDevice);
// Get our swapchain if(commandBuf == NULL) {
if(!SDL_WaitAndAcquireGPUSwapchainTexture(commandBuf, window, &swapchainTexture, NULL, NULL)) { SDL_Log("Could not get command buf!");
SDL_Log("Could not create swapchain!"); return 1;
return 1; }
}
// Get our swapchain
// Handle the swapchain if(!SDL_WaitAndAcquireGPUSwapchainTexture(commandBuf, window, &swapchainTexture, NULL, NULL)) {
if(swapchainTexture != NULL) { SDL_Log("Could not create swapchain!");
// Clear (background) color return 1;
SDL_GPUColorTargetInfo colorInfo = { }
.texture = swapchainTexture,
.clear_color = (SDL_FColor){0.25f, 0.5f, 0.1f, 1.0f},
.load_op = SDL_GPU_LOADOP_CLEAR, // Handle the swapchain
.store_op = SDL_GPU_STOREOP_STORE if(swapchainTexture != NULL) {
}; // Clear (background) color
SDL_GPUColorTargetInfo colorInfo = {
// Now for the render pass .texture = swapchainTexture,
renderPass = SDL_BeginGPURenderPass(commandBuf, &colorInfo, 1, NULL); .clear_color = (SDL_FColor){0.25f, 0.5f, 0.1f, 1.0f},
SDL_BindGPUGraphicsPipeline(renderPass, pipeline); .load_op = SDL_GPU_LOADOP_CLEAR,
SDL_DrawGPUPrimitives(renderPass, 3, 1, 0, 0); .store_op = SDL_GPU_STOREOP_STORE
SDL_EndGPURenderPass(renderPass); };
} else {
SDL_Log("Swapchain texture just does not exist! %s", SDL_GetError()); // Now for the render pass
return 1; renderPass = SDL_BeginGPURenderPass(commandBuf, &colorInfo, 1, NULL);
} SDL_BindGPUGraphicsPipeline(renderPass, pipeline);
SDL_DrawGPUPrimitives(renderPass, 3, 1, 0, 0);
SDL_SubmitGPUCommandBuffer(commandBuf); SDL_EndGPURenderPass(renderPass);
} } else {
SDL_Log("Swapchain texture just does not exist! %s", SDL_GetError());
// Cleanup return 1;
SDL_ReleaseGPUGraphicsPipeline(GPUDevice, pipeline); }
SDL_ReleaseWindowFromGPUDevice(GPUDevice, window); SDL_SubmitGPUCommandBuffer(commandBuf);
SDL_DestroyWindow(window); }
SDL_DestroyGPUDevice(GPUDevice);
// Cleanup
SDL_Quit(); SDL_ReleaseGPUGraphicsPipeline(GPUDevice, pipeline);
return 0;
} SDL_ReleaseWindowFromGPUDevice(GPUDevice, window);
SDL_DestroyWindow(window);
SDL_DestroyGPUDevice(GPUDevice);
SDL_Quit();
return 0;
}

View File

@ -1,13 +1,13 @@
#version 450 #version 450
// layout(location = 0) in vec4 in_var_TEXCOORD0; // layout(location = 0) in vec4 in_var_TEXCOORD0;
// layout(location = 0) out vec4 out_var_SV_Target0; // layout(location = 0) out vec4 out_var_SV_Target0;
layout(location = 0) in vec4 inColor; layout(location = 0) in vec4 inColor;
layout(location = 0) out vec4 outColor; layout(location = 0) out vec4 outColor;
void main() void main()
{ {
outColor = inColor; outColor = inColor;
} }

View File

@ -1,42 +1,42 @@
#version 450 #version 450
vec2 temp_pos; vec2 temp_pos;
vec4 temp_color; vec4 temp_color;
// layout(location = 0) out vec4 out_var_TEXCOORD0; // layout(location = 0) out vec4 out_var_TEXCOORD0;
layout(location = 0) out vec4 outColor; layout(location = 0) out vec4 outColor;
void main() void main()
{ {
vec4 color; vec4 color;
vec2 pos; vec2 pos;
if (uint(gl_VertexIndex) == 0u) if (uint(gl_VertexIndex) == 0u)
{ {
color = vec4(1.0, 0.0, 0.0, 1.0); color = vec4(1.0, 0.0, 0.0, 1.0);
pos = vec2(-0.5); pos = vec2(-0.5);
} }
else else
{ {
vec4 vert_color; vec4 vert_color;
vec2 vert_pos; vec2 vert_pos;
if (uint(gl_VertexIndex) == 1u) if (uint(gl_VertexIndex) == 1u)
{ {
vert_color = vec4(0.0, 1.0, 0.0, 1.0); vert_color = vec4(0.0, 1.0, 0.0, 1.0);
vert_pos = vec2(0.5, -0.5); vert_pos = vec2(0.5, -0.5);
} }
else else
{ {
bool index_exists = uint(gl_VertexIndex) == 2u; bool index_exists = uint(gl_VertexIndex) == 2u;
vert_color = mix(temp_color, vec4(0.0, 0.0, 1.0, 1.0), bvec4(index_exists)); vert_color = mix(temp_color, vec4(0.0, 0.0, 1.0, 1.0), bvec4(index_exists));
vert_pos = mix(temp_pos, vec2(0.0, 0.5), bvec2(index_exists)); vert_pos = mix(temp_pos, vec2(0.0, 0.5), bvec2(index_exists));
} }
color = vert_color; color = vert_color;
pos = vert_pos; pos = vert_pos;
} }
// out_var_TEXCOORD0 = color; // out_var_TEXCOORD0 = color;
outColor = color; outColor = color;
gl_Position = vec4(pos, 0.0, 1.0); gl_Position = vec4(pos, 0.0, 1.0);
} }