Switch to using push constants for scene data

main
noah metz 2024-01-12 21:12:31 -07:00
parent ed034b39ab
commit 8dea83ca37
4 changed files with 61 additions and 31 deletions

@ -57,7 +57,7 @@ debug: spacegame
%.vert.spv: %.vert
glslc $< -o $@
glslangValidator -V -o $@ $<
%.frag.spv: %.frag
glslc $< -o $@
glslangValidator -V -o $@ $<

@ -1,10 +1,14 @@
#version 450
layout(set = 0, binding = 0) uniform SceneUniform {
layout( push_constant ) uniform constants {
mat4 view;
mat4 proj;
} scene;
layout(set = 0, binding = 0) uniform SceneUniform {
mat4 test;
} scene_ubo;
layout(set = 2, binding = 0) uniform ModelUniform {
mat4 model;
} model_ubo;

@ -1,8 +1,12 @@
#version 450
layout(set = 0, binding = 0) uniform SceneUniformBuffer {
layout( push_constant ) uniform constants {
mat4 view;
mat4 proj;
} scene_pc;
layout(set = 0, binding = 0) uniform SceneUniformBuffer {
mat4 test;
} scene_ubo;
layout(set = 2, binding = 1) uniform ObjectUniformBuffer {
@ -17,7 +21,7 @@ layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTex;
void main() {
gl_Position = scene_ubo.proj * scene_ubo.view * object_ubo.model * vec4(inPosition, 1.0);
gl_Position = scene_pc.proj * scene_pc.view * object_ubo.model * vec4(inPosition, 1.0);
fragColor = inColor;
fragTex = inTex;
}

@ -190,6 +190,7 @@ typedef struct SceneContextStruct {
VkDescriptorSet* descriptors;
GPUBuffer* ubos;
void** ubo_ptrs;
VkPushConstantRange pcr;
} SceneContext;
struct TextureVertex {
@ -208,6 +209,10 @@ struct ModelUBO {
};
struct SceneUBO {
mat4 test;
};
struct ScenePC {
mat4 view;
mat4 proj;
};
@ -895,13 +900,25 @@ VkShaderModule create_shader_module(VkDevice device, const char * code, uint32_t
return shader;
}
VkShaderModule load_shader_file(uint32_t buffer_size, const char* path, VkDevice device) {
VkShaderModule load_shader_file(const char* path, VkDevice device) {
FILE* file;
file = fopen(path, "r");
file = fopen(path, "rb");
if(file == 0) {
return VK_NULL_HANDLE;
}
int result = fseek(file, 0, SEEK_END);
if(result != 0) {
return VK_NULL_HANDLE;
}
long buffer_size = ftell(file);
result = fseek(file, 0, SEEK_SET);
if(result != 0) {
return VK_NULL_HANDLE;
}
char * buffer = malloc(buffer_size);
if(buffer == 0) {
return VK_NULL_HANDLE;
@ -1554,8 +1571,9 @@ void command_draw_object(Material material, Object object, uint32_t frame_num, V
vkCmdDrawIndexed(command_buffer, mesh->index_count, 1, 0, 0, 0);
}
void command_draw_material(Material material, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer) {
void command_draw_material(Material material, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer) {
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline);
vkCmdPushConstants(command_buffer, material.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(struct ScenePC), scene_constants);
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_descriptors[frame_num], 0, 0);
if(material.material_descriptors != 0) {
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 1, 1, &material.material_descriptors[frame_num], 0, 0);
@ -1565,7 +1583,7 @@ void command_draw_material(Material material, uint32_t object_count, Object* obj
}
}
VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) {
VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) {
VkCommandBufferBeginInfo begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = 0,
@ -1625,7 +1643,7 @@ VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint3
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
for(uint i = 0; i < materials_count; i++) {
command_draw_material(materials[i], object_counts[i], objects[i], frame_num, scene_descriptors, command_buffer);
command_draw_material(materials[i], object_counts[i], objects[i], frame_num, scene_descriptors, scene_constants, command_buffer);
}
vkCmdEndRenderPass(command_buffer);
@ -1762,6 +1780,7 @@ Material create_material(
uint32_t shader_stage_count,
VkPipelineShaderStageCreateInfo* shader_stages,
VkDescriptorSetLayout scene_ubo_layout,
VkPushConstantRange scene_pcr,
PipelineLayout pipeline_layout,
MeshType mesh_type,
uint32_t max_frames_in_flight,
@ -1862,8 +1881,8 @@ Material create_material(
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 3,
.pSetLayouts = all_layouts,
.pushConstantRangeCount = 0,
.pPushConstantRanges = 0,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &scene_pcr,
};
result = vkCreatePipelineLayout(device, &layout_info, 0, &layout);
@ -1892,9 +1911,9 @@ Material create_material(
return material;
}
Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t max_frames_in_flight) {
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/basic.vert.spv", device);
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/basic.frag.spv", device);
Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, VkPushConstantRange scene_pcr, uint32_t max_frames_in_flight) {
VkShaderModule vert_shader = load_shader_file("shader_src/basic.vert.spv", device);
VkShaderModule frag_shader = load_shader_file("shader_src/basic.frag.spv", device);
VkPipelineShaderStageCreateInfo shader_stages[2] = {
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
@ -1979,16 +1998,16 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
return tmp;
}
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, simple_layout, simple_mesh_type, max_frames_in_flight, object_descriptor_mappings);
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, scene_pcr, simple_layout, simple_mesh_type, max_frames_in_flight, object_descriptor_mappings);
}
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t max_frames_in_flight) {
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/texture.vert.spv", device);
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, VkPushConstantRange scene_pcr, uint32_t max_frames_in_flight) {
VkShaderModule vert_shader = load_shader_file("shader_src/texture.vert.spv", device);
if(vert_shader == VK_NULL_HANDLE) {
Material tmp = {};
return tmp;
}
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/texture.frag.spv", device);
VkShaderModule frag_shader = load_shader_file("shader_src/texture.frag.spv", device);
if(frag_shader == VK_NULL_HANDLE) {
Material tmp = {};
return tmp;
@ -2090,7 +2109,7 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend
return tmp;
}
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, texture_layout, textured_mesh_type, max_frames_in_flight, object_descriptor_mappings);
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, scene_pcr, texture_layout, textured_mesh_type, max_frames_in_flight, object_descriptor_mappings);
}
VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, VkQueue queue) {
@ -2502,6 +2521,11 @@ SceneContext create_scene_context(VkDevice device, VkPhysicalDeviceMemoryPropert
.descriptors = sets,
.ubos = ubos,
.ubo_ptrs = ubo_ptrs,
.pcr = {
.offset = 0,
.size = sizeof(struct ScenePC),
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
},
};
return scene;
@ -2641,7 +2665,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
vec3 world_position = {0.0f, 0.0f, 0.0f};
versor world_rotation = {-1.0f, 0.0f, 0.0f, 0.0f};
VkResult update_scene_descriptor(void** buffers, uint32_t frame_index, vec3 world_position, versor world_rotation, float aspect_ratio, float time_delta) {
struct ScenePC get_scene_constants(vec3 world_position, versor world_rotation, float aspect_ratio, float time_delta) {
vec3 movement_sum = {0.0f, 0.0f, 0.0f};
if(key_flags.forward) {
@ -2718,18 +2742,16 @@ VkResult update_scene_descriptor(void** buffers, uint32_t frame_index, vec3 worl
glm_quat_rotatev(world_rotation, movement_sum, movement_rot);
glm_vec3_add(movement_rot, world_position, world_position);
struct SceneUBO ubo = {};
glm_perspective(1.5708f, aspect_ratio, 0.01, 1000, ubo.proj);
glm_quat_look(world_position, world_rotation, ubo.view);
struct ScenePC constants = {};
memcpy(buffers[frame_index], (void*)&ubo, sizeof(ubo));
glm_perspective(1.5708f, aspect_ratio, 0.01, 1000, constants.proj);
glm_quat_look(world_position, world_rotation, constants.view);
return VK_SUCCESS;
return constants;
}
VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, Material* materials, uint32_t* objects_counts, Object** objects) {
update_scene_descriptor(scene->ubo_ptrs, context->current_frame, world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01);
struct ScenePC scene_constants = get_scene_constants(world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01);
VkResult result;
result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
@ -2753,7 +2775,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi
return result;
}
result = command_draw_scene(materials_count, materials, objects_counts, objects, context->current_frame, scene->descriptors, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
result = command_draw_scene(materials_count, materials, objects_counts, objects, context->current_frame, scene->descriptors, &scene_constants, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
if(result != VK_SUCCESS) {
return result;
}
@ -3080,7 +3102,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) {
return;
}
Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight);
Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr, context->max_frames_in_flight);
if(simple_mesh_material.pipeline == VK_NULL_HANDLE) {
fprintf(stderr, "failed to create simple mesh material\n");
return;
@ -3113,7 +3135,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) {
return;
}
Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight);
Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr, context->max_frames_in_flight);
if(texture_mesh_material.pipeline == VK_NULL_HANDLE) {
fprintf(stderr, "failed to create texture mesh material\n");
return;