From ddff2fa5d0cbae17cb819c91bad0a79105ba0ea7 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Tue, 31 Jan 2023 21:16:16 +0100 Subject: Graphics pipeline rendering --- api-test/command-buffer.cpp | 76 ++++++++++++++++++++++++++++++++++-- api-test/main.cpp | 30 +++++++++++++- api-test/vk-device.cpp | 41 ++++++++++++++++--- include/api-test/command-buffer.hpp | 28 ++++++++++++- include/api-test/vk-device-types.hpp | 3 ++ include/vulkan-loader.hpp | 2 + shaders/api-test-ui.frag | 17 ++++---- shaders/api-test-ui.vert | 21 +++++----- 8 files changed, 189 insertions(+), 29 deletions(-) diff --git a/api-test/command-buffer.cpp b/api-test/command-buffer.cpp index 799968c..b130d3d 100644 --- a/api-test/command-buffer.cpp +++ b/api-test/command-buffer.cpp @@ -18,7 +18,7 @@ void command_buffer::start() const { VKCHECK(vkBeginCommandBuffer(vk_command_buffer, &begin_info)); - const auto& bindless = vkdevice::get_render_device()->get_bindingmodel(); + const auto& bindless = vkdevice::get_render_device()->get_bindingmodel(); const auto* global_set = &bindless.sets[BindlessSetType::GLOBAL]; if (queue_type == QueueType::GRAPHICS) { vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.layout, 0, 1U, global_set, 0U, nullptr); @@ -80,7 +80,7 @@ void command_buffer::barrier(handle texture_handle, VkPipelineSt } void command_buffer::copy(handle buffer_handle, ::handle texture_handle, VkDeviceSize offset) const { - auto* device = vkdevice::get_render_device(); + auto* device = vkdevice::get_render_device(); const auto& buffer = device->get_buffer(buffer_handle); const auto& texture = device->get_texture(texture_handle); VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U) @@ -109,7 +109,7 @@ void command_buffer::copy(handle buffer_handle, ::handleget_pipeline(params.pipeline); const auto& bindless = vkdevice::get_render_device()->get_bindingmodel(); vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast(BindlessSetType::UNIFORMS), 1U, &bindless.sets[BindlessSetType::UNIFORMS], 1U, ¶ms.uniforms_offset); @@ -118,3 +118,73 @@ void graphics_command_buffer::dispatch(const dispatch_params& params) { vkCmdDispatch(vk_command_buffer, params.group_size.x / params.local_group_size.x, params.group_size.y / params.local_group_size.y, params.group_size.z / params.local_group_size.z); } + +void graphics_command_buffer::begin_renderpass(const renderpass_params& params) const { + std::vector attachments_info(params.color_attachments.size()); + + for (auto index{ 0U }; index < params.color_attachments.size(); index++) { + auto& attachment_info = attachments_info[index]; + auto& attachment = vkdevice::get_render_device()->get_texture(params.color_attachments[index]); + + attachment_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + attachment_info.pNext = nullptr; + attachment_info.imageView = attachment.whole_view; + attachment_info.imageLayout = attachment.layout; + attachment_info.resolveMode = VK_RESOLVE_MODE_NONE; + attachment_info.resolveImageView = nullptr; + attachment_info.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment_info.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment_info.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment_info.clearValue = VkClearValue{ + .color = { + .float32 = { 0.f, 0.f, 0.f, 0.f }, + }, + }; + } + + VkRect2D scissor{ + .offset{ + .x = params.render_area.x, + .y = params.render_area.x, + }, + .extent{ + .width = params.render_area.width, + .height = params.render_area.height, + }, + }; + VkViewport viewport{ + .x = static_cast(params.render_area.x), + .y = static_cast(params.render_area.y), + .width = static_cast(params.render_area.width), + .height = static_cast(params.render_area.height), + .minDepth = 0.f, + .maxDepth = 1.f, + }; + VkRenderingInfo rendering_info{ + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .pNext = nullptr, + .flags = 0U, + .renderArea = scissor, + .layerCount = 1U, + .viewMask = 0U, + .colorAttachmentCount = static_cast(attachments_info.size()), + .pColorAttachments = attachments_info.data(), + .pDepthAttachment = nullptr, + .pStencilAttachment = nullptr, + }; + vkCmdBeginRendering(vk_command_buffer, &rendering_info); + + vkCmdSetScissor(vk_command_buffer, 0U, 1U, &scissor); + vkCmdSetViewport(vk_command_buffer, 0U, 1U, &viewport); +} + +void graphics_command_buffer::render(const draw_params& params) const { + const auto& pipeline = vkdevice::get_render_device()->get_pipeline(params.pipeline); + + vkCmdBindPipeline(vk_command_buffer, pipeline.bind_point, pipeline.vk_pipeline); + vkCmdDraw(vk_command_buffer, params.vertex_count, params.instance_count, 0U, 0U); +} + +void graphics_command_buffer::end_renderpass() const { + vkCmdEndRendering(vk_command_buffer); +} diff --git a/api-test/main.cpp b/api-test/main.cpp index 35b8639..d6a4b3b 100644 --- a/api-test/main.cpp +++ b/api-test/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #define STB_IMAGE_IMPLEMENTATION @@ -10,6 +11,8 @@ #include "vk-device.hpp" #include "utils.hpp" +struct device_texture; + #define ENABLE_RENDERDOC #ifdef ENABLE_RENDERDOC @@ -30,7 +33,9 @@ int main() { } #endif - window wnd { 640U, 360U }; + constexpr size_t window_width = 640U; + constexpr size_t window_height = 360U; + window wnd { window_width, window_height }; #ifdef ENABLE_RENDERDOC if(rdoc_api != nullptr) rdoc_api->StartFrameCapture(nullptr, nullptr); @@ -58,7 +63,7 @@ int main() { auto gpu_texture_handle = device->create_texture({ .width = static_cast(width), .height = static_cast(height), - .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT, + .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, .format = VK_FORMAT_R8G8B8A8_UNORM, .type = VK_IMAGE_TYPE_2D, }); @@ -97,11 +102,13 @@ int main() { .cs_code = std::span(code), }); + std::array formats { VK_FORMAT_R8G8B8A8_UNORM }; auto vertex_code = read_file("shaders/api-test-ui.vert.spv"); auto fragment_code = read_file("shaders/api-test-ui.frag.spv"); auto graphics = device->create_pipeline({ .vs_code = std::span(vertex_code), .fs_code = std::span(fragment_code), + .color_attachments_format = formats }); @@ -138,6 +145,25 @@ int main() { .uniforms_offset = 0U, }); + std::array, 1U> color_attachment {gpu_texture_handle}; + + command_buffer.barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + command_buffer.begin_renderpass({ + .render_area = { + .x = 0, + .y = 0, + .width = window_width, + .height = window_height, + }, + .color_attachments = color_attachment, + }); + command_buffer.render({ + .pipeline = graphics, + .vertex_count = 3U, + .instance_count = 1U, + }); + command_buffer.end_renderpass(); + command_buffer.stop(); device->submit(&command_buffer, 1); diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp index 0815592..6967e41 100644 --- a/api-test/vk-device.cpp +++ b/api-test/vk-device.cpp @@ -330,9 +330,9 @@ handle vkdevice::create_pipeline(const pipeline_desc& desc) { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0U, - .viewportCount = 0U, + .viewportCount = 1U, .pViewports = nullptr, - .scissorCount = 0U, + .scissorCount = 1U, .pScissors = nullptr, }; @@ -349,6 +349,35 @@ handle vkdevice::create_pipeline(const pipeline_desc& desc) { .lineWidth = 1.f, }; + VkPipelineMultisampleStateCreateInfo multisample_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + .sampleShadingEnable = VK_FALSE, + .minSampleShading = 1.f, + }; + + VkPipelineColorBlendAttachmentState color_attachment_state { + .blendEnable = VK_TRUE, + .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, + .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaBlendOp = VK_BLEND_OP_ADD, + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + }; + + VkPipelineColorBlendStateCreateInfo color_blend_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .logicOpEnable = VK_FALSE, + .attachmentCount = 1, + .pAttachments = &color_attachment_state, + }; + VkDynamicState dynamic_states[] { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, @@ -366,8 +395,8 @@ handle vkdevice::create_pipeline(const pipeline_desc& desc) { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, .pNext = nullptr, .viewMask = 0U, - .colorAttachmentCount = 0U, - .pColorAttachmentFormats = nullptr, + .colorAttachmentCount = static_cast(desc.color_attachments_format.size()), + .pColorAttachmentFormats = desc.color_attachments_format.data(), .depthAttachmentFormat = VK_FORMAT_UNDEFINED, .stencilAttachmentFormat = VK_FORMAT_UNDEFINED, }; @@ -383,9 +412,9 @@ handle vkdevice::create_pipeline(const pipeline_desc& desc) { .pTessellationState = nullptr, .pViewportState = &viewport_state_create_info, .pRasterizationState = &rasterization_state_create_info, - .pMultisampleState = nullptr, + .pMultisampleState = &multisample_state_create_info, .pDepthStencilState = nullptr, - .pColorBlendState = nullptr, + .pColorBlendState = &color_blend_state_create_info, .pDynamicState = &dynamic_state_create_info, .layout = bindless.layout, .renderPass = nullptr, diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp index ffeafc4..2cd1d75 100644 --- a/include/api-test/command-buffer.hpp +++ b/include/api-test/command-buffer.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -27,6 +28,27 @@ struct dispatch_params { uint32_t uniforms_offset; }; +struct renderpass_params { +private: + struct rect { + int32_t x; + int32_t y; + uint32_t width; + uint32_t height; + }; + +public: + rect render_area; + std::span> color_attachments; + // optional viewport + // optional scissor +}; +struct draw_params { + handle pipeline; + uint32_t vertex_count; + uint32_t instance_count; +}; + struct command_buffer { void start() const; void stop() const; @@ -41,7 +63,11 @@ struct command_buffer { // General purpose queue struct graphics_command_buffer: public command_buffer { - void dispatch(const dispatch_params& params); + void dispatch(const dispatch_params& params) const; + + void begin_renderpass(const renderpass_params& params) const; + void render(const draw_params& params) const; + void end_renderpass() const; }; struct compute_command_buffer: public command_buffer { diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp index 33a7738..bca57af 100644 --- a/include/api-test/vk-device-types.hpp +++ b/include/api-test/vk-device-types.hpp @@ -59,6 +59,9 @@ struct pipeline_desc { std::span vs_code; std::span fs_code; std::span cs_code; + std::span color_attachments_format; + VkFormat depth_attachment_format; + VkFormat stencil_attachment_format; }; struct device_pipeline { diff --git a/include/vulkan-loader.hpp b/include/vulkan-loader.hpp index d0ad3a5..cd93415 100644 --- a/include/vulkan-loader.hpp +++ b/include/vulkan-loader.hpp @@ -88,6 +88,7 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES; X(vkCmdPushConstants) \ X(vkCmdClearColorImage) \ X(vkCmdBeginRenderPass) \ + X(vkCmdBeginRendering) \ X(vkCmdBindPipeline) \ X(vkCmdBindVertexBuffers) \ X(vkCmdBindIndexBuffer) \ @@ -101,6 +102,7 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES; X(vkCmdDraw) \ X(vkCmdDrawIndexed) \ X(vkCmdDispatch) \ + X(vkCmdEndRendering) \ X(vkCmdEndRenderPass) \ X(vkEndCommandBuffer) \ X(vkResetCommandBuffer) \ diff --git a/shaders/api-test-ui.frag b/shaders/api-test-ui.frag index 5c6a61f..0272ba2 100644 --- a/shaders/api-test-ui.frag +++ b/shaders/api-test-ui.frag @@ -7,14 +7,15 @@ layout(location = 0) in struct { vec4 color; } In; -layout(set = 0, binding = 0) uniform sampler samplers[]; -layout(set = 0, binding = 1) uniform texture2D textures[]; -layout(set = 0, binding = 2, rgba32f) uniform image2D images[]; -layout(set = 1, binding = 0) uniform parameters { - uint texture_index; - uint sampler_index; -} params; +// layout(set = 0, binding = 0) uniform sampler samplers[]; +// layout(set = 0, binding = 1) uniform texture2D textures[]; +// layout(set = 0, binding = 2, rgba32f) uniform image2D images[]; +// layout(set = 1, binding = 0) uniform parameters { +// uint texture_index; +// uint sampler_index; +// } params; void main() { - o_Color = In.color * texture(sampler2D(textures[params.texture_index], samplers[params.sampler_index]), In.uv.xy); + // o_Color = In.color * texture(sampler2D(textures[params.texture_index], samplers[params.sampler_index]), In.uv.xy); + o_Color = vec4(1, 0, 0, 1); } diff --git a/shaders/api-test-ui.vert b/shaders/api-test-ui.vert index 6a37abc..3b6d0b5 100644 --- a/shaders/api-test-ui.vert +++ b/shaders/api-test-ui.vert @@ -11,11 +11,11 @@ layout(buffer_reference) readonly buffer vertices { vertex vertices[]; }; -layout(set = 1, binding = 0) uniform parameters { - vertices vertex_buffer; - vec2 scale; - vec2 translate; -} params; +// layout(set = 1, binding = 0) uniform parameters { +// vertices vertex_buffer; +// vec2 scale; +// vec2 translate; +// } params; out gl_PerVertex { vec4 gl_Position; @@ -28,10 +28,13 @@ layout(location = 0) out struct { void main() { - vertex v = params.vertex_buffer.vertices[gl_VertexIndex]; + // vertex v = params.vertex_buffer.vertices[gl_VertexIndex]; - Out.color = unpackUnorm4x8(v.color); - Out.uv = v.uv; + // Out.color = unpackUnorm4x8(v.color); + // Out.uv = v.uv; - gl_Position = vec4(v.pos * params.scale + params.translate, 0.0, 1.0); + // gl_Position = vec4(v.pos * params.scale + params.translate, 0.0, 1.0); + + vec2 pos[3] = vec2[3]( vec2(-0.7, 0.7), vec2(0.7, 0.7), vec2(0.0, -0.7) ); + gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0); } -- cgit v1.3