diff --git a/include/Orange/Core/Span.h b/include/Orange/Core/Span.h index 88ceaec..adf04dd 100644 --- a/include/Orange/Core/Span.h +++ b/include/Orange/Core/Span.h @@ -17,9 +17,6 @@ namespace orange Span(J& x) : data(x.begin()) , size(x.end() - x.begin()) {} - - explicit Span(T* data) : data(data), size(1) {} - explicit Span(T& data) : data(&data), size(1) {} T& operator [] (size_t idx) { return data[idx]; } const T& operator [] (size_t idx) const { return data[idx]; } diff --git a/include/Orange/Graphics/Vertex.h b/include/Orange/Graphics/Vertex.h index d292402..a84e2ef 100644 --- a/include/Orange/Graphics/Vertex.h +++ b/include/Orange/Graphics/Vertex.h @@ -17,7 +17,7 @@ namespace orange Skinned, }; - struct StaticVertex + struct alignas(8) StaticVertex { vec3 pos; vec2 uv; @@ -41,7 +41,7 @@ namespace orange } }; - struct SkinnedVertex : public StaticVertex + struct alignas(8) SkinnedVertex : public StaticVertex { static constexpr uint32_t MaxVertexWeights = 4; diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index c62c8ea..b717047 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -18,9 +18,159 @@ #include #include #include +#include +#include using namespace orange; +struct MiniPipelineInfo +{ + VkShaderModule vs; + VkShaderModule fs; + + VkPipelineLayout pipelineLayout; + + VkFormat colorFormat; + VkFormat depthFormat; + + bool enableDepthTest; + bool enableDepthWrites; + + Span vertexAttributes; +}; + +static VulkanResult CreateGraphicsPipeline(VkDevice device, const MiniPipelineInfo& info) +{ + VkPipelineShaderStageCreateInfo stages[] = + { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = info.vs, + .pName = "main", + }, + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = info.fs, + .pName = "main", + }, + }; + + Array dynamicStates = + { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + + VkPipelineDynamicStateCreateInfo dynamicStateInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = uint32_t(dynamicStates.Size()), + .pDynamicStates = dynamicStates.Data(), + }; + + VkVertexInputBindingDescription inputBindingDescription = + { + .binding = 0, + .stride = sizeof(StaticVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }; + + VkPipelineVertexInputStateCreateInfo vertexInputInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = info.vertexAttributes.size ? 1u : 0u, + .pVertexBindingDescriptions = &inputBindingDescription, + .vertexAttributeDescriptionCount = uint32_t(info.vertexAttributes.size), + .pVertexAttributeDescriptions = info.vertexAttributes.data, + }; + + VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, + }; + + VkPipelineViewportStateCreateInfo viewportStateInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1, + .scissorCount = 1, + }; + + VkPipelineRasterizationStateCreateInfo rasterizationInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .lineWidth = 1.0f, + }; + + VkPipelineMultisampleStateCreateInfo multisampleInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + }; + + VkPipelineDepthStencilStateCreateInfo depthStencilInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = info.enableDepthTest, + .depthWriteEnable = info.enableDepthWrites, + .depthCompareOp = VK_COMPARE_OP_LESS, + .minDepthBounds = 0.0f, + .maxDepthBounds = 1.0f, + }; + + VkPipelineColorBlendAttachmentState attachmentBlendState = + { + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + }; + + VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &attachmentBlendState, + }; + + VkPipelineRenderingCreateInfo renderingInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + .viewMask = 0u, + .colorAttachmentCount = 1u, + .pColorAttachmentFormats = &info.colorFormat, + .depthAttachmentFormat = info.depthFormat, + }; + + VkGraphicsPipelineCreateInfo pipelineInfo = + { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = &renderingInfo, + .stageCount = Size(stages), + .pStages = stages, + .pVertexInputState = &vertexInputInfo, + .pInputAssemblyState = &inputAssemblyInfo, + .pViewportState = &viewportStateInfo, + .pRasterizationState = &rasterizationInfo, + .pMultisampleState = &multisampleInfo, + .pDepthStencilState = &depthStencilInfo, + .pColorBlendState = &colorBlendStateInfo, + .pDynamicState = &dynamicStateInfo, + .layout = info.pipelineLayout, + }; + + VkPipeline pipeline = VK_NULL_HANDLE; + VkResult res = VK_SUCCESS; + if ((res = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline)) != VK_SUCCESS) + return VulkanResult::Error(res); + + return VulkanResult::Success(pipeline); +} + int main(int argc, char** argv) { (void)argc; (void)argv; @@ -48,10 +198,16 @@ int main(int argc, char** argv) auto r_mesh = ParseOBJ(*r_objData); - auto r_vs = r_renderContext->CreateShader(vs_Mesh); - if (!r_vs) return 1; - auto r_fs = r_renderContext->CreateShader(fs_DebugVertColor); - if (!r_fs) return 1; + auto r_vsMesh = r_renderContext->CreateShader(vs_Mesh); + if (!r_vsMesh) return 1; + auto r_vsFullscreen = r_renderContext->CreateShader(vs_Fullscreen); + if (!r_vsFullscreen) return 1; + auto r_fsMesh = r_renderContext->CreateShader(fs_DebugVertColor); + if (!r_fsMesh) return 1; + auto r_fsRed = r_renderContext->CreateShader(fs_Red); + if (!r_fsRed) return 1; + auto r_fsSky = r_renderContext->CreateShader(fs_SkyGradient); + if (!r_fsSky) return 1; // @@ -76,14 +232,16 @@ int main(int argc, char** argv) constexpr uint32_t MaxBindlessResources = 32768; VkDescriptorPoolSize bindlessPoolSizes[] = { - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources } + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u}, + { VK_DESCRIPTOR_TYPE_SAMPLER, 1u}, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources }, }; VkDescriptorPoolCreateInfo poolInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, - .maxSets = MaxBindlessResources * Size(bindlessPoolSizes), + .maxSets = 1u, .poolSizeCount = uint32_t(Size(bindlessPoolSizes)), .pPoolSizes = bindlessPoolSizes, }; @@ -96,7 +254,7 @@ int main(int argc, char** argv) { .binding = 0, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = MaxBindlessResources, + .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL, }, { @@ -161,104 +319,6 @@ int main(int argc, char** argv) VkDescriptorSet descriptorSet = VK_NULL_HANDLE; vkAllocateDescriptorSets(r_renderContext->Device(), &descriptorSetAllocInfo, &descriptorSet); - // - - VkPipelineShaderStageCreateInfo stages[] = - { - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = *r_vs, - .pName = "main", - }, - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = *r_fs, - .pName = "main", - }, - }; - - Array dynamicStates = - { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }; - - VkPipelineDynamicStateCreateInfo dynamicStateInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = uint32_t(dynamicStates.Size()), - .pDynamicStates = dynamicStates.Data(), - }; - - VkVertexInputBindingDescription inputBindingDescription = - { - .binding = 0, - .stride = sizeof(StaticVertex), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }; - - VkPipelineVertexInputStateCreateInfo vertexInputInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1u, - .pVertexBindingDescriptions = &inputBindingDescription, - .vertexAttributeDescriptionCount = Size(StaticVertex::Attributes), - .pVertexAttributeDescriptions = StaticVertex::Attributes, - }; - - VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - .primitiveRestartEnable = VK_FALSE, - }; - - VkPipelineViewportStateCreateInfo viewportStateInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, - .scissorCount = 1, - }; - - VkPipelineRasterizationStateCreateInfo rasterizationInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT, - .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, - .lineWidth = 1.0f, - }; - - VkPipelineMultisampleStateCreateInfo multisampleInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, - }; - - VkPipelineDepthStencilStateCreateInfo depthStencilInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_TRUE, - .depthWriteEnable = VK_TRUE, - .depthCompareOp = VK_COMPARE_OP_LESS, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f, - }; - - VkPipelineColorBlendAttachmentState attachmentBlendState = - { - .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - }; - - VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &attachmentBlendState, - }; - VkPipelineLayoutCreateInfo pipelineLayoutInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, @@ -268,56 +328,36 @@ int main(int argc, char** argv) VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; vkCreatePipelineLayout(r_renderContext->Device(), &pipelineLayoutInfo, nullptr, &pipelineLayout); - VkFormat colorFormat = FormatToSrgbFormat(r_swapchain->Format()); + // VkFormat depthFormat = *FindDepthFormat(r_renderContext->PhysicalDevice()); - VkPipelineRenderingCreateInfo renderingInfo = + auto pipeline = *CreateGraphicsPipeline(r_renderContext->Device(), MiniPipelineInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - .viewMask = 0u, - .colorAttachmentCount = 1u, - .pColorAttachmentFormats = &colorFormat, - .depthAttachmentFormat = depthFormat - }; + .vs = *r_vsMesh, + .fs = *r_fsMesh, + .pipelineLayout = pipelineLayout, + .colorFormat = FormatToSrgbFormat(r_swapchain->Format()), + .depthFormat = depthFormat, + .enableDepthTest = true, + .enableDepthWrites = true, + .vertexAttributes = Span(StaticVertex::Attributes), + }); - VkGraphicsPipelineCreateInfo pipelineInfo = + auto skyPipeline = *CreateGraphicsPipeline(r_renderContext->Device(), MiniPipelineInfo { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &renderingInfo, - .stageCount = Size(stages), - .pStages = stages, - .pVertexInputState = &vertexInputInfo, - .pInputAssemblyState = &inputAssemblyInfo, - .pViewportState = &viewportStateInfo, - .pRasterizationState = &rasterizationInfo, - .pMultisampleState = &multisampleInfo, - .pDepthStencilState = &depthStencilInfo, - .pColorBlendState = &colorBlendStateInfo, - .pDynamicState = &dynamicStateInfo, - .layout = pipelineLayout, - }; - - VkPipeline pipeline = VK_NULL_HANDLE; - if (vkCreateGraphicsPipelines(r_renderContext->Device(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline) != VK_SUCCESS) - { - log::err("Blah"); - return 1; - } + .vs = *r_vsFullscreen, + .fs = *r_fsSky, + .pipelineLayout = pipelineLayout, + .colorFormat = FormatToSrgbFormat(r_swapchain->Format()), + .depthFormat = depthFormat, + .enableDepthTest = false, + .enableDepthWrites = false, + .vertexAttributes = Span(nullptr, 0), + }); auto r_buffer = r_renderContext->CreateBuffer(256 * 1024 * 1024); if (!r_buffer) return 1; - VkBufferViewCreateInfo bufferViewInfo = - { - .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, - .buffer = r_buffer->buffer, - .format = VK_FORMAT_R8G8B8A8_UNORM, - .offset = 0, - .range = r_buffer->size, - }; - VkBufferView bufferView = VK_NULL_HANDLE; - vkCreateBufferView(r_renderContext->Device(), &bufferViewInfo, nullptr, &bufferView); - struct UniformData { mat4 projection; @@ -456,9 +496,7 @@ int main(int argc, char** argv) vkCmdSetViewport(cmdBuf, 0, 1, &viewport); vkCmdSetScissor(cmdBuf, 0, 1, &scissor); - vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); - vkCmdBindVertexBuffers2(cmdBuf, 0, 1, &vertexSlice.buffer, &vertexSlice.offset, &vertexSlice.size, nullptr); vkCmdBindIndexBuffer(cmdBuf, r_buffer->buffer, indexSlice.offset, VK_INDEX_TYPE_UINT16); @@ -488,7 +526,7 @@ int main(int argc, char** argv) .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, .newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, .image = *r_depthImage, - .subresourceRange = FirstColorMipSubresourceRange, + .subresourceRange = FirstDepthMipSubresourceRange, }; vkCmdPipelineBarrier( @@ -532,7 +570,13 @@ int main(int argc, char** argv) .pDepthAttachment = &depthAttachmentInfo, }; vkCmdBeginRendering(cmdBuf, &renderInfo); - vkCmdDrawIndexed(cmdBuf, r_mesh->indices.Size(), 1, 0, 0, 0); + { + vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, skyPipeline); + vkCmdDraw(cmdBuf, 3, 1, 0, 0); + + vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdDrawIndexed(cmdBuf, r_mesh->indices.Size(), 1, 0, 0, 0); + } vkCmdEndRendering(cmdBuf); const VkImageMemoryBarrier colorToPresentBarrier = diff --git a/src/Orange/Render/Shaders/fs_Red.frag b/src/Orange/Render/Shaders/fs_Red.frag new file mode 100644 index 0000000..663202b --- /dev/null +++ b/src/Orange/Render/Shaders/fs_Red.frag @@ -0,0 +1,8 @@ +#version 450 + +layout(location = 0) out vec4 outColor; + +void main() +{ + outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); +} \ No newline at end of file diff --git a/src/Orange/Render/Shaders/fs_SkyGradient.frag b/src/Orange/Render/Shaders/fs_SkyGradient.frag new file mode 100644 index 0000000..23c30f0 --- /dev/null +++ b/src/Orange/Render/Shaders/fs_SkyGradient.frag @@ -0,0 +1,21 @@ +#version 450 + +layout(location = 0) in vec2 coords; + +layout(location = 0) out vec4 outColor; + +vec3 srgbToLinear(vec3 color) +{ + bvec3 isLo = lessThanEqual(color, vec3(0.04045f)); + + vec3 loPart = color / 12.92f; + vec3 hiPart = pow((color + 0.055f) / 1.055f, vec3(12.0f / 5.0f)); + return mix(hiPart, loPart, isLo); +} + +void main() +{ + const vec3 start = srgbToLinear(vec3(1.0f, 0.51f, 0.56f)); + const vec3 end = srgbToLinear(vec3(0.48f, 0.76f, 0.84f)); + outColor = vec4(mix(start, end, coords.y), 1.0f); +} \ No newline at end of file diff --git a/src/Orange/Render/Shaders/vs_Fullscreen.vert b/src/Orange/Render/Shaders/vs_Fullscreen.vert index 5502ee3..c644322 100644 --- a/src/Orange/Render/Shaders/vs_Fullscreen.vert +++ b/src/Orange/Render/Shaders/vs_Fullscreen.vert @@ -1,6 +1,6 @@ #version 450 -layout(location = 1) out vec2 o_texcoord; +layout(location = 0) out vec2 o_texcoord; void main() { diff --git a/src/Orange/meson.build b/src/Orange/meson.build index 84b164c..0af84dd 100644 --- a/src/Orange/meson.build +++ b/src/Orange/meson.build @@ -1,5 +1,7 @@ orange_shaders = glsl_generator.process([ 'Render/Shaders/fs_DebugVertColor.frag', + 'Render/Shaders/fs_Red.frag', + 'Render/Shaders/fs_SkyGradient.frag', 'Render/Shaders/vs_Fullscreen.vert', 'Render/Shaders/vs_Mesh.vert', ])