From 482c7ef748a6309b6c9f528740b85624f7734f4a Mon Sep 17 00:00:00 2001 From: redstrate <54911369+redstrate@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:53:45 -0400 Subject: [PATCH] Fix vulkan backend validation errors --- engine/gfx/public/gfx_commandbuffer.hpp | 4 ++- engine/gfx/vulkan/src/gfx_vulkan.cpp | 12 ++++++-- engine/renderer/include/shadowpass.hpp | 6 +++- engine/renderer/src/imguipass.cpp | 2 +- engine/renderer/src/renderer.cpp | 2 +- engine/renderer/src/scenecapture.cpp | 6 ++-- engine/renderer/src/shadowpass.cpp | 31 ++++++++++++++------ engine/shadercompiler/src/shadercompiler.cpp | 8 ++--- shaders/omnishadow.frag.glsl | 12 ++++---- shaders/shadow.frag.glsl | 3 ++ shaders/shadow.vert.nocompile.glsl | 9 +++++- 11 files changed, 66 insertions(+), 29 deletions(-) diff --git a/engine/gfx/public/gfx_commandbuffer.hpp b/engine/gfx/public/gfx_commandbuffer.hpp index 93870ec..912d19d 100755 --- a/engine/gfx/public/gfx_commandbuffer.hpp +++ b/engine/gfx/public/gfx_commandbuffer.hpp @@ -121,6 +121,7 @@ struct GFXDrawCommand { int index_count = 0; int first_index = 0; int vertex_offset = 0; + int base_instance = 0; } draw_indexed; struct CopyTextureData { @@ -261,12 +262,13 @@ public: commands.push_back(command); } - void draw_indexed(int indexCount, int firstIndex, int vertexOffset) { + void draw_indexed(int indexCount, int firstIndex, int vertexOffset, int base_instance) { GFXDrawCommand command; command.type = GFXCommandType::DrawIndexed; command.data.draw_indexed.vertex_offset = vertexOffset; command.data.draw_indexed.first_index = firstIndex; command.data.draw_indexed.index_count = indexCount; + command.data.draw_indexed.base_instance = base_instance; commands.push_back(command); } diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index dfcff89..e448770 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -21,6 +21,9 @@ VkFormat toVkFormat(GFXPixelFormat format) { case GFXPixelFormat::R_32F: return VK_FORMAT_R32_SFLOAT; + case GFXPixelFormat::R_16F: + return VK_FORMAT_R16_SFLOAT; + case GFXPixelFormat::RGBA_32F: return VK_FORMAT_R32G32B32A32_SFLOAT; @@ -33,6 +36,9 @@ VkFormat toVkFormat(GFXPixelFormat format) { case GFXPixelFormat::R8G8_UNORM: return VK_FORMAT_R8G8_UNORM; + case GFXPixelFormat::R8G8_SFLOAT: + return VK_FORMAT_R8G8_SSCALED; + case GFXPixelFormat::R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; @@ -552,7 +558,7 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate vertex_module = createShaderModule(vertex_shader_vector.data(), vertex_shader_vector.size() * sizeof(uint32_t)); } else { - auto vertex_shader = file::open(file::internal_domain / (std::string(info.shaders.vertex_path) + ".spv")); + auto vertex_shader = file::open(file::internal_domain / (std::string(info.shaders.vertex_path) + ".spv"), true); vertex_shader->read_all(); vertex_module = createShaderModule(vertex_shader->cast_data(), vertex_shader->size()); @@ -564,7 +570,7 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate fragment_module = createShaderModule(fragment_shader_vector.data(), fragment_shader_vector.size() * sizeof(uint32_t)); } else { - auto fragment_shader = file::open(file::internal_domain / (std::string(info.shaders.fragment_path) + ".spv")); + auto fragment_shader = file::open(file::internal_domain / (std::string(info.shaders.fragment_path) + ".spv"), true); fragment_shader->read_all(); fragment_module = createShaderModule(fragment_shader->cast_data(), fragment_shader->size()); @@ -1031,7 +1037,7 @@ void GFXVulkan::createInstance(std::vector layers, std::vector= 0.0f && clip_rect.w >= 0.0f) { command_buffer->draw_indexed(pcmd->ElemCount, (index_offset + pcmd->IdxOffset), - (vertex_offset + pcmd->VtxOffset)); + (vertex_offset + pcmd->VtxOffset), 0); } } } diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index 1995cdb..cbfdefb 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -519,7 +519,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj command_buffer->bind_texture(texture_to_bind, index); } - command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset); + command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, 0); } } diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index b83efc7..cafc2a4 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -265,7 +265,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { command_buffer->bind_texture(texture_to_bind, index); } - command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset); + command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, 0); } } } @@ -326,7 +326,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { command_buffer->bind_texture(environmentCube, 2); command_buffer->set_push_constant(&mvp, sizeof(Matrix4x4)); - command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0); + command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); command_buffer->copy_texture(irradianceOffscreenTexture, irradiance_cubemap_resolution, irradiance_cubemap_resolution, scene->irradianceCubeArray, face, last_probe, 0); }; @@ -366,7 +366,7 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { command_buffer->bind_texture(environmentCube, 2); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0); + command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); command_buffer->copy_texture(prefilteredOffscreenTexture, info.render_area.extent.width, info.render_area.extent.height, scene->prefilteredCubeArray, face, last_probe, mip); }; diff --git a/engine/renderer/src/shadowpass.cpp b/engine/renderer/src/shadowpass.cpp index 6bafcd2..68403c6 100755 --- a/engine/renderer/src/shadowpass.cpp +++ b/engine/renderer/src/shadowpass.cpp @@ -12,7 +12,6 @@ struct PushConstant { Matrix4x4 mvp, model; - Vector3 lightPos; }; const std::array shadowTransforms = { @@ -109,7 +108,7 @@ void ShadowPass::render(GFXCommandBuffer* command_buffer, Scene& scene) { } } -void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, const Matrix4x4 light_matrix, const Matrix4x4 model, const Vector3 light_position, const Light::Type type, const CameraFrustum& frustum) { +void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, const Matrix4x4 light_matrix, const Matrix4x4 model, const Vector3 light_position, const Light::Type type, const CameraFrustum& frustum, const int base_instance) { for(auto [obj, mesh] : scene.get_all()) { if(!mesh.mesh) continue; @@ -117,11 +116,12 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c command_buffer->set_vertex_buffer(mesh.mesh->position_buffer, 0, position_buffer_index); command_buffer->set_index_buffer(mesh.mesh->index_buffer, IndexType::UINT32); + + command_buffer->bind_shader_buffer(point_location_buffer, 0, 2, sizeof(Vector3) * max_point_shadows); PushConstant pc; pc.mvp = light_matrix * model * scene.get(obj).model; pc.model = scene.get(obj).model; - pc.lightPos = light_position; if(mesh.mesh->bones.empty()) { switch(type) { @@ -143,7 +143,7 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) continue; - command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset); + command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, base_instance); } } else { switch(type) { @@ -168,7 +168,7 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c continue; command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 1, sizeof(Matrix4x4) * 128); - command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset); + command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, base_instance); } } } @@ -203,7 +203,7 @@ void ShadowPass::render_sun(GFXCommandBuffer* command_buffer, Scene& scene, Obje const auto frustum = normalize_frustum(extract_frustum(projection * view)); if(light.enable_shadows) - render_meshes(command_buffer, scene, realMVP, Matrix4x4(), lightPos, Light::Type::Sun, frustum); + render_meshes(command_buffer, scene, realMVP, Matrix4x4(), lightPos, Light::Type::Sun, frustum, 0); scene.sun_light_dirty = false; } @@ -238,7 +238,7 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, Obj const auto frustum = normalize_frustum(extract_frustum(perspective * inverse(scene.get(light_object).model))); if(light.enable_shadows) - render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get(light_object).get_world_position(), Light::Type::Spot, frustum); + render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get(light_object).get_world_position(), Light::Type::Spot, frustum, 0); command_buffer->copy_texture(offscreen_depth, render_options.shadow_resolution, render_options.shadow_resolution, scene.spotLightArray, 0, last_spot_light, 0); @@ -256,6 +256,8 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, Ob return; if(scene.point_light_dirty[last_point_light] || light.use_dynamic_shadows) { + *(point_location_map + last_point_light) = scene.get(light_object).get_world_position(); + for(int face = 0; face < 6; face++) { GFXRenderPassBeginInfo info = {}; info.framebuffer = offscreen_framebuffer; @@ -277,7 +279,7 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, Ob const auto frustum = normalize_frustum(extract_frustum(projection * shadowTransforms[face] * model)); - render_meshes(command_buffer, scene, projection * shadowTransforms[face], model, lightPos, Light::Type::Point, frustum); + render_meshes(command_buffer, scene, projection * shadowTransforms[face], model, lightPos, Light::Type::Point, frustum, last_point_light); command_buffer->copy_texture(offscreen_color_texture, render_options.shadow_resolution, render_options.shadow_resolution, scene.pointLightArray, face, last_point_light, 0); } @@ -305,12 +307,20 @@ void ShadowPass::create_render_passes() { } void ShadowPass::create_pipelines() { + GFXShaderConstant point_light_max_constant = {}; + point_light_max_constant.value = max_point_shadows; + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.shaders.vertex_constants = {point_light_max_constant}; pipelineInfo.shaders.vertex_path = "shadow.vert"; + + pipelineInfo.shaders.fragment_constants = { point_light_max_constant }; pipelineInfo.shaders.fragment_path = "shadow.frag"; pipelineInfo.shader_input.bindings = { - {0, GFXBindingType::PushConstant} + {0, GFXBindingType::PushConstant}, + {1, GFXBindingType::StorageBuffer}, + {2, GFXBindingType::StorageBuffer} }; pipelineInfo.shader_input.push_constants = { @@ -382,4 +392,7 @@ void ShadowPass::create_offscreen_resources() { info.render_pass = render_pass; offscreen_framebuffer = gfx->create_framebuffer(info); + + point_location_buffer = gfx->create_buffer(nullptr, sizeof(Vector3) * max_point_shadows, false, GFXBufferUsage::Storage); + point_location_map = reinterpret_cast(gfx->get_buffer_contents(point_location_buffer)); } diff --git a/engine/shadercompiler/src/shadercompiler.cpp b/engine/shadercompiler/src/shadercompiler.cpp index 9ab94cb..ec37f9a 100755 --- a/engine/shadercompiler/src/shadercompiler.cpp +++ b/engine/shadercompiler/src/shadercompiler.cpp @@ -20,7 +20,7 @@ void ShaderCompiler::set_include_path(const std::string_view path) { } const std::vector compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { - std::string newString = "#version 430 core\n"; + std::string newString = "#version 460 core\n"; newString += "#extension GL_GOOGLE_include_directive : enable\n"; newString += "#extension GL_GOOGLE_cpp_style_line_directive : enable\n"; @@ -47,12 +47,12 @@ const std::vector compile_glsl_to_spv(const std::string_view source_st Shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion); TBuiltInResource Resources = DefaultTBuiltInResource; - EShMessages messages = (EShMessages) (EShMsgSpvRules); + EShMessages messages = (EShMessages) (EShMsgDefault); DirStackFileIncluder includer; includer.pushExternalLocalDirectory(include_path); - if (!Shader.parse(&Resources, 100, false, (EShMessages)0, includer)) { + if (!Shader.parse(&Resources, 100, false, messages, includer)) { console::error(System::Renderer, "{}", Shader.getInfoLog()); return {}; @@ -66,7 +66,7 @@ const std::vector compile_glsl_to_spv(const std::string_view source_st return {}; } - + std::vector SpirV; spv::SpvBuildLogger logger; glslang::SpvOptions spvOptions; diff --git a/shaders/omnishadow.frag.glsl b/shaders/omnishadow.frag.glsl index 3f23b4e..61e4d2c 100755 --- a/shaders/omnishadow.frag.glsl +++ b/shaders/omnishadow.frag.glsl @@ -1,12 +1,14 @@ -layout(location = 0) in vec3 inPos; +layout (constant_id = 0) const int max_lights = 25; + +layout (location = 0) in vec3 inPos; +layout (location = 1) flat in int index; layout (location = 0) out float outFragColor; -layout(push_constant, binding = 0) uniform PushConstant { - mat4 mvp, model; - vec3 lightPos; +layout(std430, binding = 2) buffer readonly LightInformation { + vec3 light_locations[max_lights]; }; void main() { - outFragColor = length(inPos - lightPos); + outFragColor = length(inPos - light_locations[index]); } diff --git a/shaders/shadow.frag.glsl b/shaders/shadow.frag.glsl index 34f46e2..2cb1536 100755 --- a/shaders/shadow.frag.glsl +++ b/shaders/shadow.frag.glsl @@ -1,2 +1,5 @@ +layout (location = 0) in vec3 inPos; +layout (location = 1) flat in int index; + void main() { } diff --git a/shaders/shadow.vert.nocompile.glsl b/shaders/shadow.vert.nocompile.glsl index 3a5c64b..bc29e3d 100755 --- a/shaders/shadow.vert.nocompile.glsl +++ b/shaders/shadow.vert.nocompile.glsl @@ -1,3 +1,5 @@ +layout (constant_id = 0) const int max_lights = 25; + layout (location = 0) in vec3 inPosition; #ifdef BONE @@ -6,10 +8,10 @@ layout (location = 5) in vec4 inBoneWeight; #endif layout (location = 0) out vec3 outPos; +layout (location = 1) flat out int index; layout(push_constant, binding = 0) uniform PushConstant { mat4 mvp, model; - vec3 lightPos; }; #ifdef BONE @@ -18,6 +20,10 @@ layout(std430, binding = 1) buffer readonly BoneInformation { }; #endif +layout(std430, binding = 2) buffer readonly LightInformation { + vec3 light_locations[max_lights]; +}; + void main() { #ifdef BONE mat4 BoneTransform; @@ -33,4 +39,5 @@ void main() { gl_Position = mvp * vec4(inPosition, 1.0); outPos = vec3(model * vec4(inPosition, 1.0)); #endif + index = gl_BaseInstance; }