diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index 2c88c8c..571257a 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -256,6 +256,20 @@ int main(int argc, char** argv) { .transform = mat4{}, .meshIdx = meshIdx, + .color = 16_vec3, + }); + + g_renderables.EmplaceBack(Renderable + { + .transform = Math::translate(32_vec3), + .meshIdx = meshIdx, + .color = 1_vec3, + }); + + g_renderables.EmplaceBack(Renderable + { + .transform = Math::translate(-32_vec3), + .meshIdx = meshIdx, .color = 1_vec3, }); @@ -283,7 +297,7 @@ int main(int argc, char** argv) constexpr uint32_t MaxBindlessResources = 32768; VkDescriptorPoolSize bindlessPoolSizes[] = { - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u}, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u}, { VK_DESCRIPTOR_TYPE_SAMPLER, 1u}, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources }, }; @@ -317,6 +331,12 @@ int main(int argc, char** argv) }, { .binding = 2, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 3, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .descriptorCount = MaxBindlessResources, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, @@ -325,6 +345,7 @@ int main(int argc, char** argv) constexpr VkDescriptorBindingFlags bindingFlags[] = { + 0, 0, 0, VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT, @@ -456,7 +477,7 @@ int main(int argc, char** argv) { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .dstSet = descriptorSet, - .dstBinding = 2, + .dstBinding = 3, .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, @@ -472,12 +493,6 @@ int main(int argc, char** argv) .extent = VkExtent3D{ ihdr.width, ihdr.height, 1u }, }); - struct UniformData - { - mat4 projection; - mat4 view; - }; - Camera camera; camera.transform.position = vec3{0.0f, 0.0f, 80.0f}; camera.viewportAspectRatio = 16.0f / 9.0f; @@ -489,14 +504,20 @@ int main(int argc, char** argv) auto r_depthImage = r_renderContext->CreateImage(pooler, 1280, 720, depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); auto depthImageView = *r_renderContext->CreateImageView(*r_depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); - auto uniformSlice = *pooler.AllocSlice(MaxFramesInFlight * sizeof(UniformData), 16); - UniformData* uniformData = reinterpret_cast(uniformSlice.ptr); + struct FrameData + { + mat4 projection; + mat4 view; + }; + + auto frameDataSlice = *pooler.AllocSlice(MaxFramesInFlight * sizeof(FrameData), 16); + FrameData* frameData = reinterpret_cast(frameDataSlice.ptr); VkDescriptorBufferInfo bufferInfo = { .buffer = r_buffer->buffer, - .offset = uniformSlice.offset, - .range = uniformSlice.size, + .offset = frameDataSlice.offset, + .range = frameDataSlice.size, }; VkWriteDescriptorSet writeDescriptorSet[] = @@ -512,24 +533,57 @@ int main(int argc, char** argv) }; vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeDescriptorSet), writeDescriptorSet, 0, nullptr); + struct Renderables + { + Renderable renderables[1024]; + }; + + auto renderablesSlice = *pooler.AllocSlice(MaxFramesInFlight * sizeof(Renderables), 16); + Renderables* gpuRenderables = reinterpret_cast(renderablesSlice.ptr); + + VkDescriptorBufferInfo renderblesBufferInfo = + { + .buffer = r_buffer->buffer, + .offset = renderablesSlice.offset, + .range = renderablesSlice.size, + }; + + VkWriteDescriptorSet renderablesWriteDescriptorSet[] = + { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 2, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &renderblesBufferInfo, + }, + }; + vkUpdateDescriptorSets(r_renderContext->Device(), Size(renderablesWriteDescriptorSet), renderablesWriteDescriptorSet, 0, nullptr); + Input::InputHandler handler; r_window->EnableRelativeMouse(true); - auto indirectBuffer = *pooler.AllocSlice(sizeof(VkDrawIndexedIndirectCommand), 16); + auto indirectBuffer = *pooler.AllocSlice(1024 * sizeof(VkDrawIndexedIndirectCommand), 256); auto indirectPtr = reinterpret_cast(indirectBuffer.ptr); - *indirectPtr = VkDrawIndexedIndirectCommand - { - .indexCount = g_meshes[0].indexCount, - .instanceCount = 1u, - .firstIndex = g_meshes[0].indexOffset, - .vertexOffset = int32_t(g_meshes[0].vertexOffset), - .firstInstance = 1u, - }; + for (size_t i = 0; i < g_renderables.Size(); i++) { + const auto& renderable = g_renderables[i]; + const uint32_t meshIdx = 0;//renderable.meshIdx; + + indirectPtr[i] = VkDrawIndexedIndirectCommand + { + .indexCount = g_meshes[meshIdx].indexCount, + .instanceCount = 1u, + .firstIndex = g_meshes[meshIdx].indexOffset, + .vertexOffset = int32_t(g_meshes[meshIdx].vertexOffset), + .firstInstance = 0u, + }; + } auto countBuffer = *pooler.AllocSlice(sizeof(uint32_t), 16); auto countPtr = reinterpret_cast(countBuffer.ptr); - *countPtr = 1; + *countPtr = uint32_t(g_renderables.Size()); auto t1 = Time::now(); while (r_window->Update(handler)) @@ -557,12 +611,14 @@ int main(int argc, char** argv) -sensitivity * dt * Radian( mouseDelta.x ), sensitivity * dt * Radian( mouseDelta.y )); - uniformData[r_swapchain->CurrentFrame()] = UniformData + frameData[r_swapchain->CurrentFrame()] = FrameData { .projection = camera.projection(), .view = camera.view(), }; + g_renderables.Copy(gpuRenderables[r_swapchain->CurrentFrame()].renderables); + const float movementSpeed = handler.get(Input::ButtonCodes::Key_LShift) ? 64.0f : 16.0f; if (scrollDelta.y) @@ -711,7 +767,7 @@ int main(int argc, char** argv) vkCmdDraw(cmdBuf, 3, 1, 0, 0); vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - vkCmdDrawIndexedIndirectCount(cmdBuf, indirectBuffer.buffer, indirectBuffer.offset, countBuffer.buffer, countBuffer.offset, 1024u, sizeof(StaticVertex)); + vkCmdDrawIndexedIndirectCount(cmdBuf, indirectBuffer.buffer, indirectBuffer.offset, countBuffer.buffer, countBuffer.offset, 1024u, sizeof(VkDrawIndexedIndirectCommand)); } vkCmdEndRendering(cmdBuf); diff --git a/src/Orange/Render/RenderContext_Init.cpp b/src/Orange/Render/RenderContext_Init.cpp index d50be32..fc439e4 100644 --- a/src/Orange/Render/RenderContext_Init.cpp +++ b/src/Orange/Render/RenderContext_Init.cpp @@ -122,19 +122,6 @@ namespace orange { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .drawIndirectCount = VK_TRUE, - }; - - VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = - { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, - .pNext = &vulkan12features, - .dynamicRendering = VK_TRUE, - }; - - VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures = - { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, - .pNext = &dynamicRenderingFeatures, .shaderInputAttachmentArrayDynamicIndexing = VK_FALSE, .shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE, .shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE, @@ -157,6 +144,13 @@ namespace orange .runtimeDescriptorArray = VK_TRUE, }; + VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + .pNext = &vulkan12features, + .dynamicRendering = VK_TRUE, + }; + VkPhysicalDeviceFeatures features { .samplerAnisotropy = VK_TRUE, @@ -165,7 +159,7 @@ namespace orange VkDeviceCreateInfo deviceInfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = &descriptorIndexingFeatures, + .pNext = &dynamicRenderingFeatures, .queueCreateInfoCount = 1, .pQueueCreateInfos = &queueInfo, .enabledExtensionCount = Size(deviceExtensions), diff --git a/src/Orange/Render/Shaders/fs_Mesh.frag b/src/Orange/Render/Shaders/fs_Mesh.frag index a40caa7..efa3461 100644 --- a/src/Orange/Render/Shaders/fs_Mesh.frag +++ b/src/Orange/Render/Shaders/fs_Mesh.frag @@ -1,15 +1,15 @@ #version 450 -#extension GL_EXT_nonuniform_qualifier : enable +#extension GL_EXT_nonuniform_qualifier : require layout(set = 0, binding = 1) uniform sampler s_sampler; -layout(set = 0, binding = 2) uniform texture2D s_images[]; +layout(set = 0, binding = 3) uniform texture2D s_images[]; -layout(location = 0) in flat int id; +layout(location = 0) in flat uint meshIdx; layout(location = 1) in vec2 uv; layout(location = 0) out vec4 outColor; void main() { - outColor = texture(sampler2D(s_images[nonuniformEXT(id)], s_sampler), uv); + outColor = texture(sampler2D(s_images[nonuniformEXT(meshIdx)], s_sampler), uv); } \ No newline at end of file diff --git a/src/Orange/Render/Shaders/vs_Mesh.vert b/src/Orange/Render/Shaders/vs_Mesh.vert index ff6215f..6cff7b6 100644 --- a/src/Orange/Render/Shaders/vs_Mesh.vert +++ b/src/Orange/Render/Shaders/vs_Mesh.vert @@ -1,5 +1,6 @@ #version 450 -#extension GL_ARB_shader_draw_parameters : enable +#extension GL_EXT_scalar_block_layout : require +#extension GL_ARB_shader_draw_parameters : require struct UniformData { @@ -7,30 +8,48 @@ struct UniformData mat4 view; }; +struct Renderable +{ + mat4 world; + uint meshIdx; + vec3 color; +}; + +struct Renderables +{ + Renderable renderables[1024]; +}; + layout(push_constant) uniform p_constants_t { uint frame; } p_constants; -layout(binding = 0) uniform u_data_t +layout(binding = 0) uniform u_frame_data_t { UniformData frame[4]; -} u_data; +} u_frame_data; + +layout(scalar, binding = 2) uniform u_renderable_t +{ + Renderables frame[4]; +} u_renderable; layout(location = 0) in vec3 i_pos; layout(location = 1) in vec2 i_uv; layout(location = 2) in vec3 i_normal; -layout(location = 0) out flat int o_id; +layout(location = 0) out flat uint o_meshIdx; layout(location = 1) out vec2 o_uv; void main() { gl_Position = - u_data.frame[p_constants.frame].projection * - u_data.frame[p_constants.frame].view * + u_frame_data.frame[p_constants.frame].projection * + u_frame_data.frame[p_constants.frame].view * + u_renderable.frame[p_constants.frame].renderables[gl_DrawIDARB].world * vec4(i_pos, 1.0); - o_id = gl_DrawIDARB; + o_meshIdx = u_renderable.frame[p_constants.frame].renderables[gl_DrawIDARB].meshIdx; o_uv = i_uv; } \ No newline at end of file