[BREAKING] This crashes on Linux, and looks like it's crashing wayland? Testing on Windows.

This commit is contained in:
Zed A. Shaw 2025-12-14 13:28:49 -05:00
parent 5435880d34
commit c905ef9ca7
6 changed files with 267 additions and 2 deletions

View file

@ -201,6 +201,19 @@ void VulkanEngine::draw_geometry(VkCommandBuffer cmd)
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _meshPipeline);
GPUDrawPushConstants push_constants{
.worldMatrix = glm::mat4{ 1.0f },
.vertexBuffer = rectangle.vertexBufferAddress,
};
vkCmdPushConstants(cmd, _meshPipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(GPUDrawPushConstants),
&push_constants);
vkCmdBindIndexBuffer(cmd, rectangle.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0);
vkCmdEndRendering(cmd);
}
@ -465,6 +478,7 @@ void VulkanEngine::init_pipelines()
{
init_background_pipelines();
init_triangle_pipelines();
init_mesh_pipeline();
init_shaders();
}
@ -566,6 +580,60 @@ void VulkanEngine::immediate_submit(std::function<void(VkCommandBuffer cmd)>&& f
VK_CHECK(vkWaitForFences(_device, 1, &_immFence, true,9999999999));
}
void VulkanEngine::init_mesh_pipeline()
{
VkShaderModule triangleFragShader;
if (!vkutil::load_shader_module("colored_triangle.frag.spv", _device, &triangleFragShader)) {
std::print("Error when building the triangle fragment shader module");
}
else {
std::print("Triangle fragment shader succesfully loaded");
}
VkShaderModule triangleVertexShader;
if (!vkutil::load_shader_module("colored_triangle_mesh.vert.spv", _device, &triangleVertexShader)) {
std::print("Error when building the triangle vertex shader module");
}
else {
std::print("Triangle vertex shader succesfully loaded");
}
VkPushConstantRange bufferRange{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0,
.size = sizeof(GPUDrawPushConstants),
};
VkPipelineLayoutCreateInfo pipeline_layout_info = vkinit::pipeline_layout_create_info();
pipeline_layout_info.pPushConstantRanges = &bufferRange;
pipeline_layout_info.pushConstantRangeCount = 1;
VK_CHECK(vkCreatePipelineLayout(_device, &pipeline_layout_info, nullptr, &_meshPipelineLayout));
PipelineBuilder pipelineBuilder;
pipelineBuilder._pipelineLayout = _meshPipelineLayout;
pipelineBuilder.set_shaders(triangleVertexShader, triangleFragShader);
pipelineBuilder.set_input_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
pipelineBuilder.set_polygon_mode(VK_POLYGON_MODE_FILL);
pipelineBuilder.set_cull_mode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE);
pipelineBuilder.set_multisampling_none();
pipelineBuilder.disable_blending();
pipelineBuilder.disable_depthtest();
pipelineBuilder.set_color_attachment_format(_drawImage.imageFormat);
pipelineBuilder.set_depth_format(VK_FORMAT_UNDEFINED);
_meshPipeline = pipelineBuilder.build_pipeline(_device);
vkDestroyShaderModule(_device, triangleFragShader, nullptr);
vkDestroyShaderModule(_device, triangleVertexShader, nullptr);
_mainDeletionQueue.push_function([&]() {
vkDestroyPipelineLayout(_device, _meshPipelineLayout, nullptr);
vkDestroyPipeline(_device, _meshPipeline, nullptr);
});
}
void VulkanEngine::init_triangle_pipelines()
{
@ -613,3 +681,124 @@ void VulkanEngine::init_triangle_pipelines()
vkDestroyPipeline(_device, _trianglePipeline, nullptr);
});
}
AllocatedBuffer VulkanEngine::create_buffer(size_t allocSize, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage)
{
VkBufferCreateInfo bufferInfo{
.sType=VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = allocSize,
.usage = usage,
};
VmaAllocationCreateInfo vmaallocInfo{
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = memoryUsage,
};
AllocatedBuffer newBuffer;
VK_CHECK(vmaCreateBuffer(_allocator, &bufferInfo,
&vmaallocInfo, &newBuffer.buffer,
&newBuffer.allocation, &newBuffer.info));
return newBuffer;
}
void VulkanEngine::destroy_buffer(const AllocatedBuffer& buffer)
{
vmaDestroyBuffer(_allocator, buffer.buffer, buffer.allocation);
}
GPUMeshBuffers VulkanEngine::uploadMesh(std::span<uint32_t> indices, std::span<Vertex> vertices)
{
const size_t vertexBufferSize = vertices.size() * sizeof(Vertex);
const size_t indexBufferSize = indices.size() * sizeof(uint32_t);
GPUMeshBuffers newSurface;
newSurface.vertexBuffer = create_buffer(
vertexBufferSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
VkBufferDeviceAddressInfo deviceAddressInfo{
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = newSurface.vertexBuffer.buffer
};
newSurface.vertexBufferAddress = vkGetBufferDeviceAddress(_device, &deviceAddressInfo);
newSurface.indexBuffer = create_buffer(indexBufferSize,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
AllocatedBuffer staging = create_buffer(vertexBufferSize + indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
void* data = staging.allocation->GetMappedData();
memcpy(data, vertices.data(), vertexBufferSize);
memcpy((char *)data + vertexBufferSize, indices.data(), indexBufferSize);
immediate_submit([&](VkCommandBuffer cmd) {
VkBufferCopy vertexCopy{
.srcOffset = 0,
.dstOffset = 0,
.size = vertexBufferSize,
};
vkCmdCopyBuffer(cmd, staging.buffer,
newSurface.vertexBuffer.buffer, 1,
&vertexCopy);
VkBufferCopy indexCopy{
.srcOffset = vertexBufferSize,
.dstOffset = 0,
.size = indexBufferSize,
};
vkCmdCopyBuffer(cmd, staging.buffer,
newSurface.indexBuffer.buffer, 1,
&indexCopy);
});
destroy_buffer(staging);
return newSurface;
}
void VulkanEngine::init_default_data() {
std::array<Vertex,4> rect_vertices;
rect_vertices[0].position = {0.5,-0.5, 0};
rect_vertices[1].position = {0.5,0.5, 0};
rect_vertices[2].position = {-0.5,-0.5, 0};
rect_vertices[3].position = {-0.5,0.5, 0};
rect_vertices[0].color = {0,0, 0,1};
rect_vertices[1].color = { 0.5,0.5,0.5 ,1};
rect_vertices[2].color = { 1,0, 0,1 };
rect_vertices[3].color = { 0,1, 0,1 };
std::array<uint32_t,6> rect_indices;
rect_indices[0] = 0;
rect_indices[1] = 1;
rect_indices[2] = 2;
rect_indices[3] = 2;
rect_indices[4] = 1;
rect_indices[5] = 3;
rectangle = uploadMesh(rect_indices, rect_vertices);
_mainDeletionQueue.push_function([&](){
destroy_buffer(rectangle.indexBuffer);
destroy_buffer(rectangle.vertexBuffer);
});
}