add msaa toggle

This commit is contained in:
Sven Balzer 2025-03-16 16:06:52 +01:00
parent 45ca42df99
commit 31823101a5

View File

@ -39,6 +39,10 @@ static SDL_GPUBuffer *tile_infos_buffer;
static Sint32 window_width;
static Sint32 window_height;
static Sint32 msaa_texture_width;
static Sint32 msaa_texture_height;
static SDL_GPUTexture *msaa_texture;
static bool Running = true;
static M4x4 view_matrix = view (V3_(0.0f, 0.0f, 0.0f), radians(45.0f), 10.0f);
@ -661,105 +665,10 @@ static void setup_memory_functions() {
static void setup_memory_functions() {}
#endif
int main(int argc, char **argv) {
setup_memory_functions();
load_map();
#ifdef SDL_PLATFORM_LINUX
if (!getenv("ENABLE_VULKAN_RENDERDOC_CAPTURE"))
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "wayland,x11");
#endif
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
log_error("Failed to initialize SDL (%s). Exiting.", SDL_GetError());
return 1;
}
device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, NULL);
if (!device) {
log_error("Failed to create gpu device (%s). Exiting.", SDL_GetError());
return 1;
}
SDL_SetGPUAllowedFramesInFlight(device, 1);
window = SDL_CreateWindow("Mikemon", 1280, 720, SDL_WINDOW_RESIZABLE);
if (!window) {
log_error("Failed to create window (%s). Exiting.", SDL_GetError());
return 1;
}
if (!SDL_ClaimWindowForGPUDevice(device, window)) {
log_error("Failed to claim window for gpu device (%s). Exiting.", SDL_GetError());
return 1;
}
SDL_SetGPUSwapchainParameters(device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR, SDL_GPU_PRESENTMODE_VSYNC);
SDL_GPUShaderCreateInfo basic_vertex_shader_info = {
.code_size = SDL_arraysize(SPIRV_basic),
.code = SPIRV_basic,
.entrypoint = "main_vertex",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_VERTEX,
.num_uniform_buffers = 1,
};
SDL_GPUShader *basic_vertex_shader = SDL_CreateGPUShader(device, &basic_vertex_shader_info);
if (!basic_vertex_shader) {
log_error("Failed to create basic vertex shader. Exiting.");
return 1;
}
SDL_GPUShaderCreateInfo basic_pixel_shader_info = {
.code_size = SDL_arraysize(SPIRV_basic),
.code = SPIRV_basic,
.entrypoint = "main_fragment",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_FRAGMENT,
.num_samplers = 1,
};
SDL_GPUShader *basic_pixel_shader = SDL_CreateGPUShader(device, &basic_pixel_shader_info);
if (!basic_pixel_shader) {
log_error("Failed to create basic pixel shader. Exiting.");
return 1;
}
SDL_GPUShaderCreateInfo world_vertex_shader_info = {
.code_size = SDL_arraysize(SPIRV_world),
.code = SPIRV_world,
.entrypoint = "main_vertex",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_VERTEX,
.num_storage_buffers = 1,
.num_uniform_buffers = 1,
};
SDL_GPUShader *world_vertex_shader = SDL_CreateGPUShader(device, &world_vertex_shader_info);
if (!world_vertex_shader) {
log_error("Failed to create world vertex shader. Exiting.");
return 1;
}
SDL_GPUShaderCreateInfo world_pixel_shader_info = {
.code_size = SDL_arraysize(SPIRV_world),
.code = SPIRV_world,
.entrypoint = "main_fragment",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_FRAGMENT,
.num_samplers = 1,
};
SDL_GPUShader *world_pixel_shader = SDL_CreateGPUShader(device, &world_pixel_shader_info);
if (!world_pixel_shader) {
log_error("Failed to create world pixel shader. Exiting.");
return 1;
}
bool enable_msaa = false;
SDL_GPUSampleCount highest_supported_sample_count = SDL_GPU_SAMPLECOUNT_1;
static bool recreate_graphics_pipelines() {
SDL_GPUColorTargetDescription color_target_descriptions[] = {
{
.format = SDL_GetGPUSwapchainTextureFormat(device, window),
@ -772,12 +681,44 @@ int main(int argc, char **argv) {
.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.alpha_blend_op = SDL_GPU_BLENDOP_ADD,
.enable_blend = true,
.enable_blend = true,
},
},
};
{
{ // basic_graphics_pipeline
SDL_GPUShaderCreateInfo basic_vertex_shader_info = {
.code_size = SDL_arraysize(SPIRV_basic),
.code = SPIRV_basic,
.entrypoint = "main_vertex",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_VERTEX,
.num_uniform_buffers = 1,
};
SDL_GPUShader *basic_vertex_shader = SDL_CreateGPUShader(device, &basic_vertex_shader_info);
if (!basic_vertex_shader) {
log_error("Failed to create basic vertex shader. Exiting.");
return false;
}
SDL_GPUShaderCreateInfo basic_pixel_shader_info = {
.code_size = SDL_arraysize(SPIRV_basic),
.code = SPIRV_basic,
.entrypoint = "main_fragment",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_FRAGMENT,
.num_samplers = 1,
};
SDL_GPUShader *basic_pixel_shader = SDL_CreateGPUShader(device, &basic_pixel_shader_info);
if (!basic_pixel_shader) {
log_error("Failed to create basic pixel shader. Exiting.");
return false;
}
SDL_GPUVertexBufferDescription vertex_buffer_descriptions[] = {
{
.slot = 0,
@ -835,12 +776,20 @@ int main(int argc, char **argv) {
.front_face = SDL_GPU_FRONTFACE_CLOCKWISE,
.enable_depth_clip = true,
},
.multisample_state = {
.sample_count = enable_msaa ? highest_supported_sample_count : SDL_GPU_SAMPLECOUNT_1,
},
.target_info = {
.color_target_descriptions = color_target_descriptions,
.num_color_targets = SDL_arraysize(color_target_descriptions),
},
};
if (basic_graphics_pipeline) {
SDL_ReleaseGPUGraphicsPipeline(device, basic_graphics_pipeline);
basic_graphics_pipeline = NULL;
}
basic_graphics_pipeline = SDL_CreateGPUGraphicsPipeline(device, &basic_graphics_pipeline_info);
if (!basic_graphics_pipeline) {
log_error("Failed to create basic graphics pipeline. Exiting.");
@ -851,7 +800,40 @@ int main(int argc, char **argv) {
SDL_ReleaseGPUShader(device, basic_pixel_shader);
}
{
{ // world_graphics_pipeline
SDL_GPUShaderCreateInfo world_vertex_shader_info = {
.code_size = SDL_arraysize(SPIRV_world),
.code = SPIRV_world,
.entrypoint = "main_vertex",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_VERTEX,
.num_storage_buffers = 1,
.num_uniform_buffers = 1,
};
SDL_GPUShader *world_vertex_shader = SDL_CreateGPUShader(device, &world_vertex_shader_info);
if (!world_vertex_shader) {
log_error("Failed to create world vertex shader. Exiting.");
return false;
}
SDL_GPUShaderCreateInfo world_pixel_shader_info = {
.code_size = SDL_arraysize(SPIRV_world),
.code = SPIRV_world,
.entrypoint = "main_fragment",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_FRAGMENT,
.num_samplers = 1,
};
SDL_GPUShader *world_pixel_shader = SDL_CreateGPUShader(device, &world_pixel_shader_info);
if (!world_pixel_shader) {
log_error("Failed to create world pixel shader. Exiting.");
return false;
}
SDL_GPUVertexBufferDescription vertex_buffer_descriptions[] = {
{
.slot = 0,
@ -897,12 +879,20 @@ int main(int argc, char **argv) {
.front_face = SDL_GPU_FRONTFACE_CLOCKWISE,
.enable_depth_clip = true,
},
.multisample_state = {
.sample_count = enable_msaa ? highest_supported_sample_count : SDL_GPU_SAMPLECOUNT_1,
},
.target_info = {
.color_target_descriptions = color_target_descriptions,
.num_color_targets = SDL_arraysize(color_target_descriptions),
},
};
if (world_graphics_pipeline) {
SDL_ReleaseGPUGraphicsPipeline(device, world_graphics_pipeline);
world_graphics_pipeline = NULL;
}
world_graphics_pipeline = SDL_CreateGPUGraphicsPipeline(device, &world_graphics_pipeline_info);
if (!world_graphics_pipeline) {
log_error("Failed to create world graphics pipeline. Exiting.");
@ -913,6 +903,50 @@ int main(int argc, char **argv) {
SDL_ReleaseGPUShader(device, world_pixel_shader);
}
return true;
}
int main(int argc, char **argv) {
setup_memory_functions();
load_map();
#ifdef SDL_PLATFORM_LINUX
if (!getenv("ENABLE_VULKAN_RENDERDOC_CAPTURE"))
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "wayland,x11");
#endif
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
log_error("Failed to initialize SDL (%s). Exiting.", SDL_GetError());
return 1;
}
device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, NULL);
if (!device) {
log_error("Failed to create gpu device (%s). Exiting.", SDL_GetError());
return 1;
}
SDL_SetGPUAllowedFramesInFlight(device, 1);
window = SDL_CreateWindow("Mikemon", 1280, 720, SDL_WINDOW_RESIZABLE);
if (!window) {
log_error("Failed to create window (%s). Exiting.", SDL_GetError());
return 1;
}
if (!SDL_ClaimWindowForGPUDevice(device, window)) {
log_error("Failed to claim window for gpu device (%s). Exiting.", SDL_GetError());
return 1;
}
SDL_SetGPUSwapchainParameters(device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR, SDL_GPU_PRESENTMODE_VSYNC);
SDL_GPUTextureFormat swapchain_format = SDL_GetGPUSwapchainTextureFormat(device, window);
highest_supported_sample_count = SDL_GPUTextureSupportsSampleCount(device, swapchain_format, SDL_GPU_SAMPLECOUNT_2) ? SDL_GPU_SAMPLECOUNT_2 : highest_supported_sample_count;
highest_supported_sample_count = SDL_GPUTextureSupportsSampleCount(device, swapchain_format, SDL_GPU_SAMPLECOUNT_4) ? SDL_GPU_SAMPLECOUNT_4 : highest_supported_sample_count;
highest_supported_sample_count = SDL_GPUTextureSupportsSampleCount(device, swapchain_format, SDL_GPU_SAMPLECOUNT_8) ? SDL_GPU_SAMPLECOUNT_8 : highest_supported_sample_count;
recreate_graphics_pipelines();
SDL_GPUTexture *player_texture = create_shader_texture("../assets/decorations/strawberry.png");
if (!player_texture) {
log_error("Failed to create shader texture. Exiting.");
@ -1115,6 +1149,14 @@ int main(int argc, char **argv) {
ImGui::DragFloat("fovy", &per_frame.fovy_degrees);
ImGui::DragFloat("camera_distance", &per_frame.camera_distance, 0.25f, 1.0f, INFINITY);
ImGui::DragFloat("camera_tilt", &per_frame.camera_tilt, 0.25f, 0.0f, 89.0f);
if (ImGui::Checkbox("MSAA", &enable_msaa)) {
recreate_graphics_pipelines();
if (msaa_texture) {
SDL_ReleaseGPUTexture(device, msaa_texture);
msaa_texture = NULL;
}
}
}
ImGui::End();
@ -1276,6 +1318,33 @@ int main(int argc, char **argv) {
ImDrawData *draw_data = ImGui::GetDrawData();
continue;
}
if (enable_msaa && (!msaa_texture || msaa_texture_width != width || msaa_texture_height != height)) {
if (msaa_texture) {
SDL_ReleaseGPUTexture(device, msaa_texture);
msaa_texture = NULL;
}
SDL_GPUTextureCreateInfo texture_info = {
.type = SDL_GPU_TEXTURETYPE_2D,
.format = swapchain_format,
.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET,
.width = (Uint32)width,
.height = (Uint32)height,
.layer_count_or_depth = 1,
.num_levels = 1,
.sample_count = highest_supported_sample_count,
};
msaa_texture = SDL_CreateGPUTexture(device, &texture_info);
if (!msaa_texture) {
log_error("Failed to create gpu texture (%s).", SDL_GetError());
return 1;
}
msaa_texture_width = width;
msaa_texture_height = height;
}
{
ZoneScopedN("Update");
@ -1308,10 +1377,12 @@ int main(int argc, char **argv) {
}
SDL_GPUColorTargetInfo color_target_info = {
.texture = swapchain_texture,
.clear_color = { .r = 1.0f, .g = 0.0f, .b = 1.0f, .a = 1.0f },
.load_op = SDL_GPU_LOADOP_CLEAR,
.store_op = SDL_GPU_STOREOP_STORE,
.texture = enable_msaa ? msaa_texture : swapchain_texture,
.clear_color = { .r = 1.0f, .g = 0.0f, .b = 1.0f, .a = 1.0f },
.load_op = SDL_GPU_LOADOP_CLEAR,
.store_op = enable_msaa ? SDL_GPU_STOREOP_RESOLVE : SDL_GPU_STOREOP_STORE,
.resolve_texture = swapchain_texture,
.cycle = true,
};
SDL_GPURenderPass *render_pass = SDL_BeginGPURenderPass(command_buffer, &color_target_info, 1, NULL);