Archived
1
Fork 0

Fix vulkan backend validation errors

This commit is contained in:
redstrate 2020-09-23 09:53:45 -04:00
parent 96758b8b3e
commit 482c7ef748
11 changed files with 66 additions and 29 deletions

View file

@ -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);
}

View file

@ -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<uint32_t>(), 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<uint32_t>(), fragment_shader->size());
@ -1031,7 +1037,7 @@ void GFXVulkan::createInstance(std::vector<const char*> layers, std::vector<cons
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "Prism Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;
appInfo.apiVersion = VK_API_VERSION_1_1;
VkInstanceCreateInfo createInfo = {};
createInfo.pNext = &debugCreateInfo;

View file

@ -11,6 +11,7 @@ class GFXPipeline;
class GFXRenderPass;
class GFXTexture;
class GFXSampler;
class GFXBuffer;
class Scene;
struct CameraFrustum;
@ -26,7 +27,7 @@ public:
GFXSampler* pcf_sampler = nullptr;
private:
void 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 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);
void render_sun(GFXCommandBuffer* command_buffer, Scene& scene, Object light_object, Light& light);
void render_spot(GFXCommandBuffer* command_buffer, Scene& scene, Object light_object, Light& light);
@ -46,6 +47,9 @@ private:
GFXTexture* offscreen_depth = nullptr;
GFXFramebuffer* offscreen_framebuffer = nullptr;
GFXBuffer* point_location_buffer = nullptr;
Vector3* point_location_map = nullptr;
// sun
GFXPipeline* static_sun_pipeline = nullptr;
GFXPipeline* skinned_sun_pipeline = nullptr;

View file

@ -136,7 +136,7 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, const int index) {
if(clip_rect.x < framebuffer_width && clip_rect.y < framebuffer_height && clip_rect.z >= 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);
}
}
}

View file

@ -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);
}
}

View file

@ -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);
};

View file

@ -12,7 +12,6 @@
struct PushConstant {
Matrix4x4 mvp, model;
Vector3 lightPos;
};
const std::array<Matrix4x4, 6> 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<Renderable>()) {
if(!mesh.mesh)
continue;
@ -118,10 +117,11 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c
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<Transform>(obj).model;
pc.model = scene.get<Transform>(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<Transform>(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<Transform>(light_object).model)));
if(light.enable_shadows)
render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get<Transform>(light_object).get_world_position(), Light::Type::Spot, frustum);
render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get<Transform>(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<Transform>(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<Vector3*>(gfx->get_buffer_contents(point_location_buffer));
}

View file

@ -20,7 +20,7 @@ void ShaderCompiler::set_include_path(const std::string_view path) {
}
const std::vector<uint32_t> 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<uint32_t> 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 {};

View file

@ -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]);
}

View file

@ -1,2 +1,5 @@
layout (location = 0) in vec3 inPos;
layout (location = 1) flat in int index;
void main() {
}

View file

@ -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;
}