[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

@ -15,6 +15,7 @@ shaders:
glslangValidator -V gradient_color.comp -o gradient_color.comp.spv glslangValidator -V gradient_color.comp -o gradient_color.comp.spv
glslangValidator -V colored_triangle.frag -o colored_triangle.frag.spv glslangValidator -V colored_triangle.frag -o colored_triangle.frag.spv
glslangValidator -V colored_triangle.vert -o colored_triangle.vert.spv glslangValidator -V colored_triangle.vert -o colored_triangle.vert.spv
glslangValidator -V colored_triangle_mesh.vert -o colored_triangle_mesh.vert.spv
%.cpp : %.rl %.cpp : %.rl
ragel -I $(ROOT_DIR) -G1 -o $@ $< ragel -I $(ROOT_DIR) -G1 -o $@ $<

View file

@ -0,0 +1,37 @@
#version 450
#extension GL_EXT_buffer_reference : require
layout (location = 0) out vec3 outColor;
layout (location = 1) out vec2 outUV;
struct Vertex {
vec3 position;
float uv_x;
vec3 normal;
float uv_y;
vec4 color;
};
layout(buffer_reference, std430) readonly buffer VertexBuffer{
Vertex vertices[];
};
//push constants block
layout( push_constant ) uniform constants
{
mat4 render_matrix;
VertexBuffer vertexBuffer;
} PushConstants;
void main()
{
//load vertex data from device adress
Vertex v = PushConstants.vertexBuffer.vertices[gl_VertexIndex];
//output data
gl_Position = PushConstants.render_matrix *vec4(v.position, 1.0f);
outColor = v.color.xyz;
outUV.x = v.uv_x;
outUV.y = v.uv_y;
}

Binary file not shown.

View file

@ -201,6 +201,19 @@ void VulkanEngine::draw_geometry(VkCommandBuffer cmd)
vkCmdDraw(cmd, 3, 1, 0, 0); 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); vkCmdEndRendering(cmd);
} }
@ -465,6 +478,7 @@ void VulkanEngine::init_pipelines()
{ {
init_background_pipelines(); init_background_pipelines();
init_triangle_pipelines(); init_triangle_pipelines();
init_mesh_pipeline();
init_shaders(); init_shaders();
} }
@ -566,6 +580,60 @@ void VulkanEngine::immediate_submit(std::function<void(VkCommandBuffer cmd)>&& f
VK_CHECK(vkWaitForFences(_device, 1, &_immFence, true,9999999999)); 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() void VulkanEngine::init_triangle_pipelines()
{ {
@ -613,3 +681,124 @@ void VulkanEngine::init_triangle_pipelines()
vkDestroyPipeline(_device, _trianglePipeline, nullptr); 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);
});
}

View file

@ -96,6 +96,10 @@ public:
int currentBackgroundEffect{0}; int currentBackgroundEffect{0};
VkPipelineLayout _trianglePipelineLayout; VkPipelineLayout _trianglePipelineLayout;
VkPipeline _trianglePipeline; VkPipeline _trianglePipeline;
VkPipelineLayout _meshPipelineLayout;
VkPipeline _meshPipeline;
GPUMeshBuffers rectangle;
// ZED's REFACTOR // ZED's REFACTOR
VkGUI _gui; VkGUI _gui;
@ -128,11 +132,19 @@ private:
void init_pipelines(); void init_pipelines();
void init_background_pipelines(); void init_background_pipelines();
void init_shaders(); void init_shaders();
void load_shader(const char *file_name, const char *entry_point, ComputeEffect data);
void init_triangle_pipelines(); void init_triangle_pipelines();
void init_mesh_pipeline();
void init_default_data();
void load_shader(const char *file_name, const char *entry_point, ComputeEffect data);
void create_swapchain(uint32_t width, uint32_t height); void create_swapchain(uint32_t width, uint32_t height);
AllocatedBuffer create_buffer(size_t allocSize, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage);
void destroy_swapchain(); void destroy_swapchain();
void destroy_buffer(const AllocatedBuffer& buffer);
void draw_background(VkCommandBuffer cmd); void draw_background(VkCommandBuffer cmd);
void draw_geometry(VkCommandBuffer cmd); void draw_geometry(VkCommandBuffer cmd);
GPUMeshBuffers uploadMesh(std::span<uint32_t> indices, std::span<Vertex> vertices);
}; };

View file

@ -30,6 +30,14 @@
} while (0) } while (0)
constexpr unsigned int FRAME_OVERLAP=2;
struct AllocatedBuffer {
VkBuffer buffer;
VmaAllocation allocation;
VmaAllocationInfo info;
};
struct AllocatedImage { struct AllocatedImage {
VkImage image; VkImage image;
VkImageView imageView; VkImageView imageView;
@ -53,4 +61,22 @@ struct ComputeEffect {
ComputePushConstants data; ComputePushConstants data;
}; };
constexpr unsigned int FRAME_OVERLAP=2; struct Vertex {
glm::vec3 position;
float uv_x;
glm::vec3 normal;
float uv_y;
glm::vec4 color;
};
struct GPUMeshBuffers {
AllocatedBuffer indexBuffer;
AllocatedBuffer vertexBuffer;
VkDeviceAddress vertexBufferAddress;
};
struct GPUDrawPushConstants {
glm::mat4 worldMatrix;
VkDeviceAddress vertexBuffer;
};