From b00a39c474824d16733126b5049dc0c44736dc80 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 15 Aug 2022 11:07:28 -0400 Subject: [PATCH] Okay, reformat the rest of the engine code! --- engine/CMakeLists.txt | 4 +- engine/gfx/CMakeLists.txt | 34 +- engine/gfx/dx12/include/gfx_dx12.hpp | 19 +- engine/gfx/dx12/src/gfx_dx12.cpp | 6 +- engine/gfx/metal/CMakeLists.txt | 34 +- engine/gfx/metal/include/gfx_metal.hpp | 42 +- engine/gfx/metal/src/gfx_metal.cpp | 652 +++--- engine/gfx/metal/src/gfx_metal_pipeline.hpp | 10 +- engine/gfx/metal/src/gfx_metal_texture.hpp | 2 +- engine/gfx/public/gfx.hpp | 169 +- engine/gfx/public/gfx_buffer.hpp | 1 - engine/gfx/public/gfx_commandbuffer.hpp | 149 +- engine/gfx/public/gfx_framebuffer.hpp | 1 - engine/gfx/public/gfx_renderpass.hpp | 1 - engine/gfx/public/gfx_sampler.hpp | 1 - engine/gfx/vulkan/CMakeLists.txt | 34 +- engine/gfx/vulkan/include/gfx_vulkan.hpp | 123 +- engine/gfx/vulkan/src/gfx_vulkan.cpp | 1874 ++++++++--------- engine/gfx/vulkan/src/gfx_vulkan_buffer.hpp | 4 +- .../gfx/vulkan/src/gfx_vulkan_framebuffer.hpp | 4 +- engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp | 10 +- .../gfx/vulkan/src/gfx_vulkan_renderpass.hpp | 8 +- engine/gfx/vulkan/src/gfx_vulkan_sampler.hpp | 4 +- engine/gfx/vulkan/src/gfx_vulkan_texture.hpp | 18 +- engine/log/CMakeLists.txt | 4 +- engine/log/include/log.hpp | 5 +- engine/math/CMakeLists.txt | 18 +- engine/math/include/aabb.hpp | 18 +- engine/math/include/math.hpp | 15 +- engine/math/include/matrix.hpp | 56 +- engine/math/include/plane.hpp | 13 +- engine/math/include/quaternion.hpp | 33 +- engine/math/include/ray.hpp | 2 +- engine/math/include/transform.hpp | 6 +- engine/math/include/vector.hpp | 108 +- engine/math/src/math.cpp | 70 +- engine/math/src/transform.cpp | 20 +- engine/platform/CMakeLists.txt | 8 +- engine/platform/include/file.hpp | 50 +- engine/platform/include/platform.hpp | 32 +- engine/renderer/CMakeLists.txt | 60 +- engine/renderer/include/dofpass.hpp | 10 +- engine/renderer/include/frustum.hpp | 8 +- engine/renderer/include/imguipass.hpp | 6 +- engine/renderer/include/materialcompiler.hpp | 8 +- engine/renderer/include/pass.hpp | 21 +- engine/renderer/include/render_options.hpp | 10 +- engine/renderer/include/renderer.hpp | 33 +- engine/renderer/include/rendertarget.hpp | 19 +- engine/renderer/include/scenecapture.hpp | 21 +- engine/renderer/include/shadowpass.hpp | 32 +- engine/renderer/include/smaapass.hpp | 8 +- engine/renderer/src/dofpass.cpp | 87 +- engine/renderer/src/frustum.cpp | 40 +- engine/renderer/src/imguipass.cpp | 131 +- engine/renderer/src/materialcompiler.cpp | 158 +- engine/renderer/src/renderer.cpp | 428 ++-- engine/renderer/src/scenecapture.cpp | 358 ++-- engine/renderer/src/shadowpass.cpp | 284 +-- engine/renderer/src/smaapass.cpp | 71 +- engine/shadercompiler/CMakeLists.txt | 30 +- .../shadercompiler/include/shadercompiler.hpp | 36 +- .../shadercompiler/src/defaultresources.hpp | 210 +- engine/shadercompiler/src/includer.hpp | 40 +- engine/shadercompiler/src/shadercompiler.cpp | 70 +- engine/tests/CMakeLists.txt | 8 +- engine/tests/string_tests.cpp | 14 +- engine/tests/utility_tests.cpp | 2 +- engine/utility/CMakeLists.txt | 18 +- engine/utility/include/common.hpp | 9 +- engine/utility/include/json_conversions.hpp | 8 +- engine/utility/include/path.hpp | 5 +- engine/utility/include/timer.hpp | 6 +- engine/utility/include/utility.hpp | 85 +- engine/utility/src/string_utils.cpp | 38 +- 75 files changed, 3059 insertions(+), 2975 deletions(-) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 5a52768..6785d1b 100755 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -11,7 +11,7 @@ add_subdirectory(shadercompiler) add_subdirectory(platform) add_subdirectory(base) -if(NOT ENABLE_IOS AND NOT ENABLE_TVOS) +if (NOT ENABLE_IOS AND NOT ENABLE_TVOS) add_subdirectory(audio) add_subdirectory(tests) -endif() \ No newline at end of file +endif () \ No newline at end of file diff --git a/engine/gfx/CMakeLists.txt b/engine/gfx/CMakeLists.txt index 37ad782..f2911a5 100755 --- a/engine/gfx/CMakeLists.txt +++ b/engine/gfx/CMakeLists.txt @@ -5,28 +5,28 @@ target_include_directories(GFX INTERFACE public) target_link_libraries(GFX INTERFACE Utility ShaderCompiler) add_custom_target(GFXInterface SOURCES - public/gfx.hpp - public/gfx_buffer.hpp - public/gfx_pipeline.hpp - public/gfx_commandbuffer.hpp - public/gfx_texture.hpp - public/gfx_framebuffer.hpp - public/gfx_renderpass.hpp - public/gfx_object.hpp - public/gfx_sampler.hpp - public/gfx_context.hpp) + public/gfx.hpp + public/gfx_buffer.hpp + public/gfx_pipeline.hpp + public/gfx_commandbuffer.hpp + public/gfx_texture.hpp + public/gfx_framebuffer.hpp + public/gfx_renderpass.hpp + public/gfx_object.hpp + public/gfx_sampler.hpp + public/gfx_context.hpp) set_target_properties(GFXInterface PROPERTIES CMAKE_FOLDER "GFX") add_subdirectory(dummy) -if(ENABLE_DX12) +if (ENABLE_DX12) add_subdirectory(dx12) -endif() +endif () -if(ENABLE_METAL) +if (ENABLE_METAL) add_subdirectory(metal) -endif() +endif () -if(ENABLE_VULKAN) - add_subdirectory(vulkan) -endif() \ No newline at end of file +if (ENABLE_VULKAN) + add_subdirectory(vulkan) +endif () \ No newline at end of file diff --git a/engine/gfx/dx12/include/gfx_dx12.hpp b/engine/gfx/dx12/include/gfx_dx12.hpp index 26b7ff2..6fce9ec 100755 --- a/engine/gfx/dx12/include/gfx_dx12.hpp +++ b/engine/gfx/dx12/include/gfx_dx12.hpp @@ -1,8 +1,8 @@ #pragma once #include -#include #include +#include #include #include "gfx.hpp" @@ -11,11 +11,20 @@ using namespace Microsoft::WRL; class gfx_dx12 : public GFX { public: - bool is_supported() override { return true; } - ShaderLanguage accepted_shader_language() override { return ShaderLanguage::HLSL; } - GFXContext required_context() override { return GFXContext::DirectX; } + bool is_supported() override { + return true; + } + + ShaderLanguage accepted_shader_language() override { + return ShaderLanguage::HLSL; + } + + GFXContext required_context() override { + return GFXContext::DirectX; + } + bool initialize(const GFXCreateInfo& info) override; - + const char* get_name() override; private: diff --git a/engine/gfx/dx12/src/gfx_dx12.cpp b/engine/gfx/dx12/src/gfx_dx12.cpp index e2f02d0..b43b02a 100755 --- a/engine/gfx/dx12/src/gfx_dx12.cpp +++ b/engine/gfx/dx12/src/gfx_dx12.cpp @@ -1,11 +1,11 @@ #include "gfx_dx12.hpp" #include -#include #include +#include -#include #include +#include // from https://stackoverflow.com/a/18374698 std::string ws2s(const std::wstring& wstr) { @@ -18,7 +18,7 @@ std::string ws2s(const std::wstring& wstr) { bool gfx_dx12::initialize(const GFXCreateInfo& info) { get_device(); - return true; + return true; } void gfx_dx12::get_device() { diff --git a/engine/gfx/metal/CMakeLists.txt b/engine/gfx/metal/CMakeLists.txt index 155d84f..8f63c77 100755 --- a/engine/gfx/metal/CMakeLists.txt +++ b/engine/gfx/metal/CMakeLists.txt @@ -1,24 +1,24 @@ set(SRC - include/gfx_metal.hpp - - src/gfx_metal.cpp - src/gfx_metal_buffer.hpp - src/gfx_metal_pipeline.hpp - src/gfx_metal_texture.hpp - src/gfx_metal_framebuffer.hpp - src/gfx_metal_renderpass.hpp - src/gfx_metal_sampler.hpp) + include/gfx_metal.hpp + + src/gfx_metal.cpp + src/gfx_metal_buffer.hpp + src/gfx_metal_pipeline.hpp + src/gfx_metal_texture.hpp + src/gfx_metal_framebuffer.hpp + src/gfx_metal_renderpass.hpp + src/gfx_metal_sampler.hpp) add_library(GFXMetal STATIC - ${SRC}) + ${SRC}) target_link_libraries(GFXMetal PUBLIC - GFX - Core - Log - metal-cpp) + GFX + Core + Log + metal-cpp) target_include_directories(GFXMetal PUBLIC - include - PRIVATE - src) + include + PRIVATE + src) set_engine_properties(GFXMetal) diff --git a/engine/gfx/metal/include/gfx_metal.hpp b/engine/gfx/metal/include/gfx_metal.hpp index cfae790..38e8864 100755 --- a/engine/gfx/metal/include/gfx_metal.hpp +++ b/engine/gfx/metal/include/gfx_metal.hpp @@ -8,38 +8,46 @@ class GFXMetal : public GFX { public: bool is_supported() override; - GFXContext required_context() override { return GFXContext::Metal; } - ShaderLanguage accepted_shader_language() override { return ShaderLanguage::MSL; } + + GFXContext required_context() override { + return GFXContext::Metal; + } + + ShaderLanguage accepted_shader_language() override { + return ShaderLanguage::MSL; + } + const char* get_name() override; - + bool supports_feature(GFXFeature feature) override; - + bool initialize(const GFXCreateInfo& createInfo) override; - void initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; + void + initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; void remove_view(platform::window_ptr identifier) override; // buffer operations GFXBuffer* create_buffer(void* data, GFXSize size, bool is_dynamic, GFXBufferUsage usage) override; void copy_buffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) override; - + void* get_buffer_contents(GFXBuffer* buffer) override; - + // texture operations GFXTexture* create_texture(const GFXTextureCreateInfo& info) override; void copy_texture(GFXTexture* texture, void* data, GFXSize size) override; void copy_texture(GFXTexture* from, GFXTexture* to) override; void copy_texture(GFXTexture* from, GFXBuffer* to) override; - + // sampler opeations GFXSampler* create_sampler(const GFXSamplerCreateInfo& info) override; // framebuffer operations GFXFramebuffer* create_framebuffer(const GFXFramebufferCreateInfo& info) override; - + // render pass operations GFXRenderPass* create_render_pass(const GFXRenderPassCreateInfo& info) override; - + // pipeline operations GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override; GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override; @@ -47,23 +55,23 @@ public: GFXSize get_alignment(GFXSize size) override; GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) override; - + void submit(GFXCommandBuffer* command_buffer, platform::window_ptr window) override; - + private: struct NativeMTLView { platform::window_ptr identifier = nullptr; MTL::PixelFormat format; }; - + std::vector nativeViews; - + NativeMTLView* getNativeView(platform::window_ptr identifier) { - for(auto& view : nativeViews) { - if(view->identifier == identifier) + for (auto& view : nativeViews) { + if (view->identifier == identifier) return view; } - + return nullptr; } diff --git a/engine/gfx/metal/src/gfx_metal.cpp b/engine/gfx/metal/src/gfx_metal.cpp index 28e1939..f0ad456 100755 --- a/engine/gfx/metal/src/gfx_metal.cpp +++ b/engine/gfx/metal/src/gfx_metal.cpp @@ -1,16 +1,16 @@ #include "gfx_metal.hpp" -#include "gfx_metal_buffer.hpp" -#include "gfx_metal_pipeline.hpp" -#include "gfx_commandbuffer.hpp" -#include "gfx_metal_texture.hpp" -#include "gfx_metal_renderpass.hpp" -#include "gfx_metal_framebuffer.hpp" -#include "gfx_metal_sampler.hpp" #include "file.hpp" +#include "gfx_commandbuffer.hpp" +#include "gfx_metal_buffer.hpp" +#include "gfx_metal_framebuffer.hpp" +#include "gfx_metal_pipeline.hpp" +#include "gfx_metal_renderpass.hpp" +#include "gfx_metal_sampler.hpp" +#include "gfx_metal_texture.hpp" #include "log.hpp" -#include "utility.hpp" #include "string_utils.hpp" +#include "utility.hpp" static inline bool debug_enabled = false; @@ -18,7 +18,7 @@ static inline std::array command_buffers; static inline std::array free_command_buffers; MTL::PixelFormat toPixelFormat(GFXPixelFormat format) { - switch(format) { + switch (format) { case GFXPixelFormat::R_32F: return MTL::PixelFormatR32Float; case GFXPixelFormat::R_16F: @@ -43,7 +43,7 @@ MTL::PixelFormat toPixelFormat(GFXPixelFormat format) { } MTL::BlendFactor toBlendFactor(GFXBlendFactor factor) { - switch(factor) { + switch (factor) { case GFXBlendFactor::One: return MTL::BlendFactorOne; case GFXBlendFactor::Zero: @@ -64,13 +64,12 @@ MTL::BlendFactor toBlendFactor(GFXBlendFactor factor) { } MTL::SamplerAddressMode toSamplingMode(SamplingMode mode) { - switch(mode) { + switch (mode) { case SamplingMode::Repeat: return MTL::SamplerAddressModeRepeat; case SamplingMode::ClampToEdge: return MTL::SamplerAddressModeClampToEdge; - case SamplingMode::ClampToBorder: - { + case SamplingMode::ClampToBorder: { #if defined(PLATFORM_IOS) || defined(PLATFORM_TVOS) return MTL::SamplerAddressModeRepeat; #else @@ -82,7 +81,7 @@ MTL::SamplerAddressMode toSamplingMode(SamplingMode mode) { #if !defined(PLATFORM_IOS) && !defined(PLATFORM_TVOS) inline MTL::SamplerBorderColor toBorderColor(GFXBorderColor color) { - switch(color) { + switch (color) { case GFXBorderColor::OpaqueWhite: return MTL::SamplerBorderColorOpaqueWhite; case GFXBorderColor::OpaqueBlack: @@ -92,7 +91,7 @@ inline MTL::SamplerBorderColor toBorderColor(GFXBorderColor color) { #endif MTL::CompareFunction toCompare(GFXCompareFunction function) { - switch(function) { + switch (function) { case GFXCompareFunction::Never: return MTL::CompareFunctionNever; case GFXCompareFunction::Less: @@ -113,7 +112,7 @@ MTL::CompareFunction toCompare(GFXCompareFunction function) { } MTL::SamplerMinMagFilter toFilter(GFXFilter filter) { - switch(filter) { + switch (filter) { case GFXFilter::Nearest: return MTL::SamplerMinMagFilterNearest; case GFXFilter::Linear: @@ -122,7 +121,7 @@ MTL::SamplerMinMagFilter toFilter(GFXFilter filter) { } MTL::Winding toWinding(GFXWindingMode mode) { - switch(mode) { + switch (mode) { case GFXWindingMode::Clockwise: return MTL::WindingClockwise; case GFXWindingMode::CounterClockwise: @@ -136,16 +135,16 @@ bool GFXMetal::is_supported() { bool GFXMetal::initialize(const GFXCreateInfo& createInfo) { debug_enabled = createInfo.api_validation_enabled; - + device = MTL::CreateSystemDefaultDevice(); - if(device) { + if (device) { command_queue = device->newCommandQueue(); - for(int i = 0; i < 15; i++) { + for (int i = 0; i < 15; i++) { command_buffers[i] = new GFXCommandBuffer(); free_command_buffers[i] = true; } - + return true; } else { return false; @@ -157,18 +156,22 @@ const char* GFXMetal::get_name() { } bool GFXMetal::supports_feature(const GFXFeature feature) { - if(feature == GFXFeature::CubemapArray) { + if (feature == GFXFeature::CubemapArray) { #if defined(PLATFORM_TVOS) return false; #else return true; #endif } - + return false; } -void GFXMetal::initialize_view(void* native_handle, const platform::window_ptr identifier, const uint32_t, const uint32_t) { +void GFXMetal::initialize_view( + void* native_handle, + const platform::window_ptr identifier, + const uint32_t, + const uint32_t) { auto native = new NativeMTLView(); native->identifier = identifier; @@ -190,7 +193,7 @@ void GFXMetal::remove_view(const platform::window_ptr identifier) { GFXBuffer* GFXMetal::create_buffer(void* data, const GFXSize size, const bool, const GFXBufferUsage) { auto buffer = new GFXMetalBuffer(); - if(data == nullptr) { + if (data == nullptr) { buffer->handle = device->newBuffer(size, MTL::ResourceOptionCPUCacheModeDefault); } else { buffer->handle = device->newBuffer(data, size, MTL::ResourceOptionCPUCacheModeDefault); @@ -205,15 +208,15 @@ void GFXMetal::copy_buffer(GFXBuffer* buffer, void* data, const GFXSize offset, auto metalBuffer = (GFXMetalBuffer*)buffer; auto src = reinterpret_cast(data); - auto dest = reinterpret_cast(metalBuffer->handle->contents()); - if(dest != nullptr) + auto dest = reinterpret_cast(metalBuffer->handle->contents()); + if (dest != nullptr) memcpy(dest + offset, src, size); } void* GFXMetal::get_buffer_contents(GFXBuffer* buffer) { auto metalBuffer = (GFXMetalBuffer*)buffer; - return reinterpret_cast(metalBuffer->handle->contents()); + return reinterpret_cast(metalBuffer->handle->contents()); } GFXTexture* GFXMetal::create_texture(const GFXTextureCreateInfo& info) { @@ -223,47 +226,43 @@ GFXTexture* GFXMetal::create_texture(const GFXTextureCreateInfo& info) { MTL::PixelFormat mtlFormat = toPixelFormat(info.format); - switch(info.type) { + switch (info.type) { case GFXTextureType::Single2D: textureDescriptor->setTextureType(MTL::TextureType2D); break; case GFXTextureType::Array2D: textureDescriptor->setTextureType(MTL::TextureType2DArray); break; - case GFXTextureType::Cubemap: - { + case GFXTextureType::Cubemap: { textureDescriptor->setTextureType(MTL::TextureTypeCube); texture->is_cubemap = true; - } - break; - case GFXTextureType::CubemapArray: - { + } break; + case GFXTextureType::CubemapArray: { textureDescriptor->setTextureType(MTL::TextureTypeCubeArray); texture->is_cubemap = true; - } - break; + } break; } - - if((info.usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) { + + if ((info.usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) { textureDescriptor->setStorageMode(MTL::StorageModePrivate); textureDescriptor->setUsage(textureDescriptor->usage() | MTL::TextureUsageRenderTarget); } else { #if defined(PLATFORM_IOS) || defined(PLATFORM_TVOS) textureDescriptor->setStorageMode(MTL::StorageModeShared); #else - if(info.format == GFXPixelFormat::DEPTH_32F) { + if (info.format == GFXPixelFormat::DEPTH_32F) { textureDescriptor->setStorageMode(MTL::StorageModePrivate); } else { textureDescriptor->setStorageMode(MTL::StorageModeManaged); } #endif } - - if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Sampled) { + + if ((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Sampled) { textureDescriptor->setUsage(textureDescriptor->usage() | MTL::TextureUsageShaderRead); } - - if((info.usage & GFXTextureUsage::ShaderWrite) == GFXTextureUsage::ShaderWrite) { + + if ((info.usage & GFXTextureUsage::ShaderWrite) == GFXTextureUsage::ShaderWrite) { textureDescriptor->setUsage(textureDescriptor->usage() | MTL::TextureUsageShaderWrite); } @@ -272,7 +271,7 @@ GFXTexture* GFXMetal::create_texture(const GFXTextureCreateInfo& info) { textureDescriptor->setHeight(info.height); textureDescriptor->setDepth(1); textureDescriptor->setArrayLength(info.array_length); - + texture->array_length = info.array_length; textureDescriptor->setMipmapLevelCount(info.mip_count); @@ -296,7 +295,7 @@ GFXTexture* GFXMetal::create_texture(const GFXTextureCreateInfo& info) { samplerDescriptor->setBorderColor(toBorderColor(info.border_color)); #endif - if(info.compare_enabled) + if (info.compare_enabled) samplerDescriptor->setCompareFunction(toCompare(info.compare_function)); texture->sampler = device->newSamplerState(samplerDescriptor); @@ -313,9 +312,9 @@ void GFXMetal::copy_texture(GFXTexture* texture, void* data, const GFXSize) { region.size.depth = 1; int byteSize = 1; - if(metalTexture->format == MTL::PixelFormatRGBA8Unorm) + if (metalTexture->format == MTL::PixelFormatRGBA8Unorm) byteSize = 4; - else if(metalTexture->format == MTL::PixelFormatRG8Unorm) + else if (metalTexture->format == MTL::PixelFormatRG8Unorm) byteSize = 2; metalTexture->handle->replaceRegion(region, 0, data, texture->width * byteSize); @@ -346,14 +345,15 @@ void GFXMetal::copy_texture(GFXTexture* from, GFXBuffer* to) { size.width = from->width; size.height = from->height; size.depth = 1; - + int byteSize = 1; - if(metalFromTexture->format == MTL::PixelFormatRGBA8Unorm) + if (metalFromTexture->format == MTL::PixelFormatRGBA8Unorm) byteSize = 4; - + MTL::CommandBuffer* commandBuffer = command_queue->commandBuffer(); MTL::BlitCommandEncoder* commandEncoder = commandBuffer->blitCommandEncoder(); - commandEncoder->copyFromTexture(metalFromTexture->handle, 0, 0, origin, size, metalToBuffer->handle, 0, metalFromTexture->width * byteSize, 0); + commandEncoder->copyFromTexture( + metalFromTexture->handle, 0, 0, origin, size, metalToBuffer->handle, 0, metalFromTexture->width * byteSize, 0); commandEncoder->endEncoding(); commandBuffer->commit(); commandBuffer->waitUntilCompleted(); @@ -361,7 +361,7 @@ void GFXMetal::copy_texture(GFXTexture* from, GFXBuffer* to) { GFXSampler* GFXMetal::create_sampler(const GFXSamplerCreateInfo& info) { auto sampler = new GFXMetalSampler(); - + MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init(); samplerDescriptor->setMinFilter(toFilter(info.min_filter)); samplerDescriptor->setMagFilter(toFilter(info.mag_filter)); @@ -369,23 +369,23 @@ GFXSampler* GFXMetal::create_sampler(const GFXSamplerCreateInfo& info) { samplerDescriptor->setTAddressMode(toSamplingMode(info.samplingMode)); samplerDescriptor->setMipFilter(MTL::SamplerMipFilterLinear); samplerDescriptor->setMaxAnisotropy(16); - + #if !defined(PLATFORM_IOS) && !defined(PLATFORM_TVOS) samplerDescriptor->setBorderColor(toBorderColor(info.border_color)); #endif - - if(info.compare_enabled) + + if (info.compare_enabled) samplerDescriptor->setCompareFunction(toCompare(info.compare_function)); sampler->handle = device->newSamplerState(samplerDescriptor); - + return sampler; } GFXFramebuffer* GFXMetal::create_framebuffer(const GFXFramebufferCreateInfo& info) { auto framebuffer = new GFXMetalFramebuffer(); - for(auto& attachment : info.attachments) + for (auto& attachment : info.attachments) framebuffer->attachments.push_back((GFXMetalTexture*)attachment); return framebuffer; @@ -394,7 +394,7 @@ GFXFramebuffer* GFXMetal::create_framebuffer(const GFXFramebufferCreateInfo& inf GFXRenderPass* GFXMetal::create_render_pass(const GFXRenderPassCreateInfo& info) { auto renderPass = new GFXMetalRenderPass(); - for(const auto& attachment : info.attachments) + for (const auto& attachment : info.attachments) renderPass->attachments.push_back(toPixelFormat(attachment)); return renderPass; @@ -402,15 +402,15 @@ GFXRenderPass* GFXMetal::create_render_pass(const GFXRenderPassCreateInfo& info) MTL::FunctionConstantValues* get_constant_values(GFXShaderConstants constants) { MTL::FunctionConstantValues* constantValues = MTL::FunctionConstantValues::alloc()->init(); - - for(auto& constant : constants) { - switch(constant.type) { + + for (auto& constant : constants) { + switch (constant.type) { case GFXShaderConstant::Type::Integer: constantValues->setConstantValue(&constant.value, MTL::DataTypeInt, constant.index); break; } } - + return constantValues; } @@ -419,81 +419,89 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI pipeline->label = info.label; NS::Error* error = nullptr; - + MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); - + const bool has_vertex_stage = !info.shaders.vertex_src.empty(); const bool has_fragment_stage = !info.shaders.fragment_src.empty(); MTL::Function* vertexFunc; - if(has_vertex_stage) { + if (has_vertex_stage) { MTL::Library* vertexLibrary; { std::string vertex_src; - if(info.shaders.vertex_src.is_string()) { + if (info.shaders.vertex_src.is_string()) { vertex_src = info.shaders.vertex_src.as_string(); } else { const auto vertex_path = info.shaders.vertex_src.as_path().string() + ".msl"; - + auto file = prism::open_file(prism::base_domain / vertex_path); - if(file != std::nullopt) { + if (file != std::nullopt) { vertex_src = file->read_as_string(); } else { prism::log("Failed to load vertex shader from {}!", vertex_path.data()); } } - vertexLibrary = device->newLibrary(NS::String::string(vertex_src.c_str(), NS::ASCIIStringEncoding), nullptr,&error); - if(vertexLibrary == nullptr) - prism::log("Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); - + vertexLibrary = + device->newLibrary(NS::String::string(vertex_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error); + if (vertexLibrary == nullptr) + prism::log( + "Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); + auto vertex_constants = get_constant_values(info.shaders.vertex_constants); - vertexFunc = vertexLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding), vertex_constants, (NS::Error**)nullptr); + vertexFunc = vertexLibrary->newFunction( + NS::String::string("main0", NS::ASCIIStringEncoding), vertex_constants, (NS::Error**)nullptr); - if(debug_enabled && info.shaders.vertex_src.is_path()) - vertexFunc->setLabel(NS::String::string(info.shaders.vertex_src.as_path().string().data(), NS::ASCIIStringEncoding)); + if (debug_enabled && info.shaders.vertex_src.is_path()) + vertexFunc->setLabel( + NS::String::string(info.shaders.vertex_src.as_path().string().data(), NS::ASCIIStringEncoding)); pipelineDescriptor->setVertexFunction(vertexFunc); } } MTL::Function* fragmentFunc; - if(has_fragment_stage) { + if (has_fragment_stage) { MTL::Library* fragmentLibrary; { std::string fragment_src; - if(info.shaders.fragment_src.is_string()) { + if (info.shaders.fragment_src.is_string()) { fragment_src = info.shaders.fragment_src.as_string(); } else { const auto fragment_path = info.shaders.fragment_src.as_path().string() + ".msl"; - + auto file = prism::open_file(prism::base_domain / fragment_path); - if(file != std::nullopt) { + if (file != std::nullopt) { fragment_src = file->read_as_string(); } else { prism::log("Failed to load fragment shader from {}!", fragment_path.data()); } } - fragmentLibrary = device->newLibrary(NS::String::string(fragment_src.c_str(), NS::ASCIIStringEncoding), nullptr,&error); - if(fragmentLibrary == nullptr) - prism::log("Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); + fragmentLibrary = + device->newLibrary(NS::String::string(fragment_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error); + if (fragmentLibrary == nullptr) + prism::log( + "Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); } - - auto fragment_constants = get_constant_values(info.shaders.fragment_constants); - - fragmentFunc = fragmentLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding), fragment_constants, (NS::Error**)nullptr); - if(debug_enabled && info.shaders.fragment_src.is_path()) - fragmentFunc->setLabel(NS::String::string(info.shaders.fragment_src.as_path().string().data(), NS::ASCIIStringEncoding)); + auto fragment_constants = get_constant_values(info.shaders.fragment_constants); + + fragmentFunc = fragmentLibrary->newFunction( + NS::String::string("main0", NS::ASCIIStringEncoding), fragment_constants, (NS::Error**)nullptr); + + if (debug_enabled && info.shaders.fragment_src.is_path()) + fragmentFunc->setLabel( + NS::String::string(info.shaders.fragment_src.as_path().string().data(), NS::ASCIIStringEncoding)); pipelineDescriptor->setFragmentFunction(fragmentFunc); } - + MTL::VertexDescriptor* descriptor = MTL::VertexDescriptor::alloc()->init(); - for(auto input : info.vertex_input.inputs) { + for (auto input : info.vertex_input.inputs) { MTL::VertexBufferLayoutDescriptor* inputDescriptor = descriptor->layouts()->object(30 - input.location); inputDescriptor->setStride(input.stride); inputDescriptor->setStepFunction(MTL::VertexStepFunctionPerVertex); @@ -506,9 +514,9 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI pipeline->vertexStrides.push_back(vs); } - for(auto attribute : info.vertex_input.attributes) { + for (auto attribute : info.vertex_input.attributes) { MTL::VertexFormat format = MTL::VertexFormatFloat3; - switch(attribute.format) { + switch (attribute.format) { case GFXVertexFormat::FLOAT2: format = MTL::VertexFormatFloat2; break; @@ -537,13 +545,14 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI pipelineDescriptor->setVertexDescriptor(descriptor); - if(info.render_pass != nullptr) { + if (info.render_pass != nullptr) { auto metalRenderPass = (GFXMetalRenderPass*)info.render_pass; unsigned int i = 0; - for(const auto& attachment : metalRenderPass->attachments) { - if(attachment != MTL::PixelFormatDepth32Float) { - MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(i++); + for (const auto& attachment : metalRenderPass->attachments) { + if (attachment != MTL::PixelFormatDepth32Float) { + MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = + pipelineDescriptor->colorAttachments()->object(i++); colorAttachmentDescriptor->setPixelFormat(attachment); colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending); @@ -558,7 +567,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI } } } else { - MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(0); + MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = + pipelineDescriptor->colorAttachments()->object(0); colorAttachmentDescriptor->setPixelFormat(nativeViews[0]->format); colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending); @@ -570,16 +580,17 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha)); } - if(debug_enabled) { + if (debug_enabled) { pipelineDescriptor->setLabel(NS::String::string(info.label.data(), NS::ASCIIStringEncoding)); pipeline->label = info.label; } pipeline->handle = device->newRenderPipelineState(pipelineDescriptor, &error); - if(!pipeline->handle) - prism::log("Metal render pipeline creation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); + if (!pipeline->handle) + prism::log( + "Metal render pipeline creation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); - switch(info.rasterization.primitive_type) { + switch (info.rasterization.primitive_type) { case GFXPrimitiveType::Triangle: pipeline->primitiveType = MTL::PrimitiveTypeTriangle; break; @@ -589,11 +600,11 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI } pipeline->winding_mode = info.rasterization.winding_mode; - + MTL::DepthStencilDescriptor* depthStencil = MTL::DepthStencilDescriptor::alloc()->init(); - if(info.depth.depth_mode != GFXDepthMode::None) { - switch(info.depth.depth_mode) { + if (info.depth.depth_mode != GFXDepthMode::None) { + switch (info.depth.depth_mode) { case GFXDepthMode::Less: depthStencil->setDepthCompareFunction(MTL::CompareFunctionLess); break; @@ -610,7 +621,7 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI pipeline->depthStencil = device->newDepthStencilState(depthStencil); - switch(info.rasterization.culling_mode) { + switch (info.rasterization.culling_mode) { case GFXCullingMode::Frontface: pipeline->cullMode = MTL::CullModeFront; break; @@ -622,52 +633,55 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI break; } - if(info.rasterization.polygon_type == GFXPolygonType::Line) + if (info.rasterization.polygon_type == GFXPolygonType::Line) pipeline->renderWire = true; - + return pipeline; } GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { auto pipeline = new GFXMetalPipeline(); - + NS::Error* error = nullptr; - + MTL::Library* computeLibrary; { std::string compute_src; - if(info.compute_src.is_string()) { + if (info.compute_src.is_string()) { compute_src = info.compute_src.as_string(); } else { const auto compute_path = info.compute_src.as_path().string() + ".msl"; - + auto file = prism::open_file(prism::base_domain / compute_path); - if(file != std::nullopt) { + if (file != std::nullopt) { compute_src = file->read_as_string(); } else { prism::log("Failed to load compute shader from {}!", compute_path.data()); } } - computeLibrary = device->newLibrary(NS::String::string(compute_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error); - if(!computeLibrary) - prism::log("Compute library compilation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); + computeLibrary = + device->newLibrary(NS::String::string(compute_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error); + if (!computeLibrary) + prism::log( + "Compute library compilation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); } - + MTL::Function* computeFunc = computeLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding)); MTL::ComputePipelineDescriptor* pipelineDescriptor = MTL::ComputePipelineDescriptor::alloc()->init(); pipelineDescriptor->setComputeFunction(computeFunc); - + pipeline->threadGroupSize = MTL::Size(info.workgroup_size_x, info.workgroup_size_y, info.workgroup_size_z); - - if(debug_enabled) { + + if (debug_enabled) { pipelineDescriptor->setLabel(NS::String::string(info.label.c_str(), NS::ASCIIStringEncoding)); pipeline->label = info.label; } - pipeline->compute_handle = device->newComputePipelineState(pipelineDescriptor, MTL::PipelineOptionNone, nullptr, &error); - if(!pipeline->compute_handle) + pipeline->compute_handle = + device->newComputePipelineState(pipelineDescriptor, MTL::PipelineOptionNone, nullptr, &error); + if (!pipeline->compute_handle) prism::log("Compute pipeline error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); computeLibrary->release(); @@ -685,15 +699,15 @@ GFXSize GFXMetal::get_alignment(GFXSize size) { GFXCommandBuffer* GFXMetal::acquire_command_buffer(bool for_presentation_use) { GFXCommandBuffer* cmdbuf = nullptr; - while(cmdbuf == nullptr) { - for(const auto [i, buffer_status] : utility::enumerate(free_command_buffers)) { - if(buffer_status) { + while (cmdbuf == nullptr) { + for (const auto [i, buffer_status] : utility::enumerate(free_command_buffers)) { + if (buffer_status) { GFXCommandBuffer* buffer = command_buffers[i]; - + free_command_buffers[i] = false; - + buffer->commands.clear(); - + return buffer; } } @@ -703,12 +717,12 @@ GFXCommandBuffer* GFXMetal::acquire_command_buffer(bool for_presentation_use) { } void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_ptr window) { - NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init(); + NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init(); NativeMTLView* native = getNativeView(window); CA::MetalDrawable* drawable = nullptr; - if(native != nullptr) { + if (native != nullptr) { drawable = (metal_next_image)platform::get_next_image(window); } @@ -734,14 +748,14 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p } current_encoder = CurrentEncoder::None; const auto needEncoder = [&](CurrentEncoder encoder, bool needs_reset = false) { - if(encoder != current_encoder || needs_reset) { - if(renderEncoder != nullptr) + if (encoder != current_encoder || needs_reset) { + if (renderEncoder != nullptr) renderEncoder->endEncoding(); - if(computeEncoder != nullptr) + if (computeEncoder != nullptr) computeEncoder->endEncoding(); - if(blitEncoder != nullptr) + if (blitEncoder != nullptr) blitEncoder->endEncoding(); renderEncoder = nullptr; @@ -749,26 +763,26 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p blitEncoder = nullptr; } - if(current_encoder == encoder && !needs_reset) + if (current_encoder == encoder && !needs_reset) return; - switch(encoder) { + switch (encoder) { case CurrentEncoder::None: break; - case CurrentEncoder::Render: - { + case CurrentEncoder::Render: { MTL::RenderPassDescriptor* descriptor = MTL::RenderPassDescriptor::alloc()->init(); - if(currentRenderPass != nullptr && currentFramebuffer != nullptr) { + if (currentRenderPass != nullptr && currentFramebuffer != nullptr) { unsigned int i = 0; - for(const auto& attachment : currentFramebuffer->attachments) { - if(attachment->format == MTL::PixelFormatDepth32Float) { + for (const auto& attachment : currentFramebuffer->attachments) { + if (attachment->format == MTL::PixelFormatDepth32Float) { MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = descriptor->depthAttachment(); depthAttachment->setTexture(attachment->handle); depthAttachment->setLoadAction(MTL::LoadActionClear); depthAttachment->setStoreAction(MTL::StoreActionStore); } else { - MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(i); + MTL::RenderPassColorAttachmentDescriptor* colorAttachment = + descriptor->colorAttachments()->object(i); colorAttachment->setTexture(attachment->handle); colorAttachment->setLoadAction(MTL::LoadActionClear); @@ -777,125 +791,139 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p } } } else { - MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(0); + MTL::RenderPassColorAttachmentDescriptor* colorAttachment = + descriptor->colorAttachments()->object(0); colorAttachment->setTexture(drawable->texture()); colorAttachment->setLoadAction(MTL::LoadActionClear); colorAttachment->setStoreAction(MTL::StoreActionStore); colorAttachment->setClearColor(currentClearColor); } - + renderEncoder = commandBuffer->renderCommandEncoder(descriptor); - if(currentViewport.width != 0.0f && currentViewport.height != 0.0f) + if (currentViewport.width != 0.0f && currentViewport.height != 0.0f) renderEncoder->setViewport(currentViewport); descriptor->release(); - } - break; - case CurrentEncoder::Compute: - { + } break; + case CurrentEncoder::Compute: { computeEncoder = commandBuffer->computeCommandEncoder(); - } - break; - case CurrentEncoder::Blit: - { + } break; + case CurrentEncoder::Blit: { blitEncoder = commandBuffer->blitCommandEncoder(); - } - break; + } break; } current_encoder = encoder; }; - for(auto command : command_buffer->commands) { - switch(command.type) { + for (auto command : command_buffer->commands) { + switch (command.type) { case GFXCommandType::Invalid: break; - case GFXCommandType::SetRenderPass: - { - currentClearColor = MTL::ClearColor(command.data.set_render_pass.clear_color.r, - command.data.set_render_pass.clear_color.g, - command.data.set_render_pass.clear_color.b, - command.data.set_render_pass.clear_color.a ); + case GFXCommandType::SetRenderPass: { + currentClearColor = MTL::ClearColor( + command.data.set_render_pass.clear_color.r, + command.data.set_render_pass.clear_color.g, + command.data.set_render_pass.clear_color.b, + command.data.set_render_pass.clear_color.a); currentFramebuffer = (GFXMetalFramebuffer*)command.data.set_render_pass.framebuffer; currentRenderPass = (GFXMetalRenderPass*)command.data.set_render_pass.render_pass; currentViewport = MTL::Viewport(); needEncoder(CurrentEncoder::Render, true); - } - break; - case GFXCommandType::SetGraphicsPipeline: - { + } break; + case GFXCommandType::SetGraphicsPipeline: { needEncoder(CurrentEncoder::Render); currentPipeline = (GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline; - - renderEncoder->setRenderPipelineState(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle); + + renderEncoder->setRenderPipelineState( + ((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle); renderEncoder->setDepthStencilState(currentPipeline->depthStencil); renderEncoder->setCullMode(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->cullMode); - renderEncoder->setFrontFacingWinding(toWinding(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->winding_mode)); + renderEncoder->setFrontFacingWinding( + toWinding(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->winding_mode)); - if(currentPipeline->renderWire) + if (currentPipeline->renderWire) renderEncoder->setTriangleFillMode(MTL::TriangleFillModeLines); else renderEncoder->setTriangleFillMode(MTL::TriangleFillModeFill); - } - break; - case GFXCommandType::SetComputePipeline: - { + } break; + case GFXCommandType::SetComputePipeline: { needEncoder(CurrentEncoder::Compute); currentPipeline = (GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline; - computeEncoder->setComputePipelineState(((GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline)->compute_handle); - } - break; - case GFXCommandType::SetVertexBuffer: - { + computeEncoder->setComputePipelineState( + ((GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline)->compute_handle); + } break; + case GFXCommandType::SetVertexBuffer: { needEncoder(CurrentEncoder::Render); - renderEncoder->setVertexBuffer(((GFXMetalBuffer*)command.data.set_vertex_buffer.buffer)->handle, command.data.set_vertex_buffer.offset, 30 -command.data.set_vertex_buffer.index); - } - break; - case GFXCommandType::SetIndexBuffer: - { + renderEncoder->setVertexBuffer( + ((GFXMetalBuffer*)command.data.set_vertex_buffer.buffer)->handle, + command.data.set_vertex_buffer.offset, + 30 - command.data.set_vertex_buffer.index); + } break; + case GFXCommandType::SetIndexBuffer: { needEncoder(CurrentEncoder::Render); currentIndexBuffer = (GFXMetalBuffer*)command.data.set_index_buffer.buffer; currentIndextype = command.data.set_index_buffer.index_type; - } - break; - case GFXCommandType::SetPushConstant: - { - if(current_encoder == CurrentEncoder::Render) { - renderEncoder->setVertexBytes(command.data.set_push_constant.bytes.data(), command.data.set_push_constant.size, currentPipeline->pushConstantIndex); - renderEncoder->setFragmentBytes(command.data.set_push_constant.bytes.data(), command.data.set_push_constant.size, currentPipeline->pushConstantIndex); - } else if(current_encoder == CurrentEncoder::Compute) { - computeEncoder->setBytes(command.data.set_push_constant.bytes.data(), command.data.set_push_constant.size, currentPipeline->pushConstantIndex); + } break; + case GFXCommandType::SetPushConstant: { + if (current_encoder == CurrentEncoder::Render) { + renderEncoder->setVertexBytes( + command.data.set_push_constant.bytes.data(), + command.data.set_push_constant.size, + currentPipeline->pushConstantIndex); + renderEncoder->setFragmentBytes( + command.data.set_push_constant.bytes.data(), + command.data.set_push_constant.size, + currentPipeline->pushConstantIndex); + } else if (current_encoder == CurrentEncoder::Compute) { + computeEncoder->setBytes( + command.data.set_push_constant.bytes.data(), + command.data.set_push_constant.size, + currentPipeline->pushConstantIndex); } - } - break; - case GFXCommandType::BindShaderBuffer: - { - if(current_encoder == CurrentEncoder::Render) { - renderEncoder->setVertexBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index); - renderEncoder->setFragmentBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index); - } else if(current_encoder == CurrentEncoder::Compute) { - computeEncoder->setBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index); + } break; + case GFXCommandType::BindShaderBuffer: { + if (current_encoder == CurrentEncoder::Render) { + renderEncoder->setVertexBuffer( + ((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, + command.data.bind_shader_buffer.offset, + command.data.bind_shader_buffer.index); + renderEncoder->setFragmentBuffer( + ((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, + command.data.bind_shader_buffer.offset, + command.data.bind_shader_buffer.index); + } else if (current_encoder == CurrentEncoder::Compute) { + computeEncoder->setBuffer( + ((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, + command.data.bind_shader_buffer.offset, + command.data.bind_shader_buffer.index); } - } - break; - case GFXCommandType::BindTexture: - { - if(current_encoder == CurrentEncoder::Render) { - if(command.data.bind_texture.texture != nullptr) { - renderEncoder->setVertexTexture(((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); - renderEncoder->setVertexSamplerState(((GFXMetalTexture*)command.data.bind_texture.texture)->sampler, command.data.bind_texture.index); + } break; + case GFXCommandType::BindTexture: { + if (current_encoder == CurrentEncoder::Render) { + if (command.data.bind_texture.texture != nullptr) { + renderEncoder->setVertexTexture( + ((GFXMetalTexture*)command.data.bind_texture.texture)->handle, + command.data.bind_texture.index); + renderEncoder->setVertexSamplerState( + ((GFXMetalTexture*)command.data.bind_texture.texture)->sampler, + command.data.bind_texture.index); - renderEncoder->setFragmentTexture(((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); - renderEncoder->setFragmentSamplerState(((GFXMetalTexture*)command.data.bind_texture.texture)->sampler, command.data.bind_texture.index); + renderEncoder->setFragmentTexture( + ((GFXMetalTexture*)command.data.bind_texture.texture)->handle, + command.data.bind_texture.index); + renderEncoder->setFragmentSamplerState( + ((GFXMetalTexture*)command.data.bind_texture.texture)->sampler, + command.data.bind_texture.index); } else { renderEncoder->setVertexTexture(nullptr, command.data.bind_texture.index); renderEncoder->setVertexSamplerState(nullptr, command.data.bind_texture.index); @@ -903,105 +931,97 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p renderEncoder->setFragmentTexture(nullptr, command.data.bind_texture.index); renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_texture.index); } - } else if(current_encoder == CurrentEncoder::Compute) { - computeEncoder->setTexture(((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); + } else if (current_encoder == CurrentEncoder::Compute) { + computeEncoder->setTexture( + ((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); } - } - break; - case GFXCommandType::BindSampler: - { + } break; + case GFXCommandType::BindSampler: { needEncoder(CurrentEncoder::Render); - if(command.data.bind_sampler.sampler != nullptr) { - renderEncoder->setFragmentSamplerState(((GFXMetalSampler*)command.data.bind_sampler.sampler)->handle, command.data.bind_sampler.index); + if (command.data.bind_sampler.sampler != nullptr) { + renderEncoder->setFragmentSamplerState( + ((GFXMetalSampler*)command.data.bind_sampler.sampler)->handle, command.data.bind_sampler.index); } else { renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_sampler.index); } - } - break; - case GFXCommandType::Draw: - { + } break; + case GFXCommandType::Draw: { needEncoder(CurrentEncoder::Render); - if(currentPipeline == nullptr) + if (currentPipeline == nullptr) continue; - renderEncoder->drawPrimitives(currentPipeline->primitiveType, - command.data.draw.vertex_offset, - command.data.draw.vertex_count, - command.data.draw.instance_count, - command.data.draw.base_instance); - } - break; - case GFXCommandType::DrawIndexed: - { + renderEncoder->drawPrimitives( + currentPipeline->primitiveType, + command.data.draw.vertex_offset, + command.data.draw.vertex_count, + command.data.draw.instance_count, + command.data.draw.base_instance); + } break; + case GFXCommandType::DrawIndexed: { needEncoder(CurrentEncoder::Render); - if(currentIndexBuffer == nullptr) + if (currentIndexBuffer == nullptr) continue; - if(currentPipeline == nullptr) + if (currentPipeline == nullptr) continue; MTL::IndexType indexType; int indexSize; - switch(currentIndextype) { - case IndexType::UINT16: - { + switch (currentIndextype) { + case IndexType::UINT16: { indexType = MTL::IndexTypeUInt16; indexSize = sizeof(uint16_t); - } - break; - case IndexType::UINT32: - { + } break; + case IndexType::UINT32: { indexType = MTL::IndexTypeUInt32; indexSize = sizeof(uint32_t); - } - break; + } break; } - for(auto& stride : currentPipeline->vertexStrides) - renderEncoder->setVertexBufferOffset(command.data.draw_indexed.vertex_offset * stride.stride, 30 - stride.location); + for (auto& stride : currentPipeline->vertexStrides) + renderEncoder->setVertexBufferOffset( + command.data.draw_indexed.vertex_offset * stride.stride, 30 - stride.location); - renderEncoder->drawIndexedPrimitives(currentPipeline->primitiveType, - command.data.draw_indexed.index_count, - indexType, - currentIndexBuffer->handle, - command.data.draw_indexed.first_index * indexSize); - } - break; - case GFXCommandType::MemoryBarrier: - { + renderEncoder->drawIndexedPrimitives( + currentPipeline->primitiveType, + command.data.draw_indexed.index_count, + indexType, + currentIndexBuffer->handle, + command.data.draw_indexed.first_index * indexSize); + } break; + case GFXCommandType::MemoryBarrier: { needEncoder(CurrentEncoder::Render); - #ifdef PLATFORM_MACOS - renderEncoder->memoryBarrier(MTL::BarrierScopeTextures, MTL::RenderStageFragment, MTL::RenderStageFragment); - #endif - } - break; - case GFXCommandType::CopyTexture: - { +#ifdef PLATFORM_MACOS + renderEncoder->memoryBarrier( + MTL::BarrierScopeTextures, MTL::RenderStageFragment, MTL::RenderStageFragment); +#endif + } break; + case GFXCommandType::CopyTexture: { needEncoder(CurrentEncoder::Blit); auto metalFromTexture = (GFXMetalTexture*)command.data.copy_texture.src; auto metalToTexture = (GFXMetalTexture*)command.data.copy_texture.dst; - if(metalFromTexture != nullptr && metalToTexture != nullptr) { - const int slice_offset = command.data.copy_texture.to_slice + command.data.copy_texture.to_layer * 6; + if (metalFromTexture != nullptr && metalToTexture != nullptr) { + const int slice_offset = + command.data.copy_texture.to_slice + command.data.copy_texture.to_layer * 6; - blitEncoder->copyFromTexture(metalFromTexture->handle, - 0, - 0, - MTL::Origin(0, 0, 0), - MTL::Size(command.data.copy_texture.width, command.data.copy_texture.height, 1), - metalToTexture->handle, - slice_offset, - command.data.copy_texture.to_level, - MTL::Origin(0, 0, 0)); + blitEncoder->copyFromTexture( + metalFromTexture->handle, + 0, + 0, + MTL::Origin(0, 0, 0), + MTL::Size(command.data.copy_texture.width, command.data.copy_texture.height, 1), + metalToTexture->handle, + slice_offset, + command.data.copy_texture.to_level, + MTL::Origin(0, 0, 0)); } - } - break; - case GFXCommandType::SetViewport: - { + } break; + case GFXCommandType::SetViewport: { needEncoder(CurrentEncoder::Render); MTL::Viewport viewport = {}; @@ -1014,10 +1034,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p renderEncoder->setViewport(viewport); currentViewport = viewport; - } - break; - case GFXCommandType::SetScissor: - { + } break; + case GFXCommandType::SetScissor: { needEncoder(CurrentEncoder::Render); MTL::ScissorRect rect = {}; @@ -1027,80 +1045,84 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p rect.height = command.data.set_scissor.rect.extent.height; renderEncoder->setScissorRect(rect); - } - break; + } break; case GFXCommandType::GenerateMipmaps: { needEncoder(CurrentEncoder::Blit); auto metalTexture = (GFXMetalTexture*)command.data.generate_mipmaps.texture; blitEncoder->generateMipmaps(metalTexture->handle); - } - break; + } break; case GFXCommandType::SetDepthBias: { needEncoder(CurrentEncoder::Render); - renderEncoder->setDepthBias(command.data.set_depth_bias.constant, command.data.set_depth_bias.slope_factor, command.data.set_depth_bias.clamp); - } - break; + renderEncoder->setDepthBias( + command.data.set_depth_bias.constant, + command.data.set_depth_bias.slope_factor, + command.data.set_depth_bias.clamp); + } break; case GFXCommandType::PushGroup: { - commandBuffer->pushDebugGroup(NS::String::string(command.data.push_group.name.data(), NS::ASCIIStringEncoding)); - } - break; + commandBuffer->pushDebugGroup( + NS::String::string(command.data.push_group.name.data(), NS::ASCIIStringEncoding)); + } break; case GFXCommandType::PopGroup: { commandBuffer->popDebugGroup(); - } - break; + } break; case GFXCommandType::InsertLabel: { - switch(current_encoder) { + switch (current_encoder) { case CurrentEncoder::Render: - renderEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); + renderEncoder->insertDebugSignpost( + NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); break; case CurrentEncoder::Blit: - blitEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); + blitEncoder->insertDebugSignpost( + NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); break; case CurrentEncoder::Compute: - computeEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); + computeEncoder->insertDebugSignpost( + NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); break; default: break; } - } - break; + } break; case GFXCommandType::Dispatch: { needEncoder(CurrentEncoder::Compute); - computeEncoder->dispatchThreadgroups(MTL::Size(command.data.dispatch.group_count_x, command.data.dispatch.group_count_y, command.data.dispatch.group_count_z), currentPipeline->threadGroupSize); - } - break; + computeEncoder->dispatchThreadgroups( + MTL::Size( + command.data.dispatch.group_count_x, + command.data.dispatch.group_count_y, + command.data.dispatch.group_count_z), + currentPipeline->threadGroupSize); + } break; case GFXCommandType::EndRenderPass: { currentFramebuffer = nullptr; currentRenderPass = nullptr; currentPipeline = nullptr; renderEncoder->endEncoding(); renderEncoder = nullptr; - } - break; - } + } break; + } } - if(renderEncoder != nullptr) + if (renderEncoder != nullptr) renderEncoder->endEncoding(); - if(blitEncoder != nullptr) + if (blitEncoder != nullptr) blitEncoder->endEncoding(); - - if(computeEncoder != nullptr) + + if (computeEncoder != nullptr) computeEncoder->endEncoding(); commandBuffer->addCompletedHandler([command_buffer](MTL::CommandBuffer* _) { - for(auto [i, buffer] : utility::enumerate(command_buffers)) { - if(buffer == command_buffer) + for (auto [i, buffer] : utility::enumerate(command_buffers)) { + if (buffer == command_buffer) free_command_buffers[i] = true; } }); - if(window != nullptr) { + if (window != nullptr) { commandBuffer->presentDrawable(drawable); commandBuffer->commit(); @@ -1108,6 +1130,6 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p } else { commandBuffer->commit(); } - + pPool->release(); } diff --git a/engine/gfx/metal/src/gfx_metal_pipeline.hpp b/engine/gfx/metal/src/gfx_metal_pipeline.hpp index adb51f4..367a0d3 100755 --- a/engine/gfx/metal/src/gfx_metal_pipeline.hpp +++ b/engine/gfx/metal/src/gfx_metal_pipeline.hpp @@ -7,10 +7,10 @@ class GFXMetalPipeline : public GFXPipeline { public: std::string label; - + MTL::RenderPipelineState* handle = nullptr; MTL::ComputePipelineState* compute_handle = nullptr; - + MTL::Size threadGroupSize; MTL::DepthStencilState* depthStencil = nullptr; @@ -22,11 +22,11 @@ public: struct VertexStride { int location, stride; }; - + std::vector vertexStrides; - + int pushConstantSize = 0; int pushConstantIndex = 0; - + bool renderWire = false; }; diff --git a/engine/gfx/metal/src/gfx_metal_texture.hpp b/engine/gfx/metal/src/gfx_metal_texture.hpp index bfe8cf7..6172726 100755 --- a/engine/gfx/metal/src/gfx_metal_texture.hpp +++ b/engine/gfx/metal/src/gfx_metal_texture.hpp @@ -10,7 +10,7 @@ public: int array_length = 1; bool is_cubemap = false; - + MTL::PixelFormat format; MTL::SamplerState* sampler; }; diff --git a/engine/gfx/public/gfx.hpp b/engine/gfx/public/gfx.hpp index eabb13c..511fc24 100755 --- a/engine/gfx/public/gfx.hpp +++ b/engine/gfx/public/gfx.hpp @@ -1,12 +1,12 @@ #pragma once #include -#include #include +#include -#include "shadercompiler.hpp" -#include "platform.hpp" #include "gfx_context.hpp" +#include "platform.hpp" +#include "shadercompiler.hpp" class GFXBuffer; class GFXPipeline; @@ -57,13 +57,13 @@ inline GFXTextureUsage operator&(const GFXTextureUsage a, const GFXTextureUsage } enum class GFXBufferUsage : int { - Storage, - Vertex, - Index + Storage, + Vertex, + Index }; enum class GFXBlendFactor : int { - One, + One, Zero, SrcColor, DstColor, @@ -149,7 +149,7 @@ struct GFXShaderConstant { enum class Type { Integer } type = Type::Integer; - + union { int value = 0; }; @@ -159,10 +159,10 @@ using GFXShaderConstants = std::vector; struct GFXGraphicsPipelineCreateInfo { std::string label; // only used for debug - + struct Shaders { ShaderSource vertex_src, fragment_src; - + GFXShaderConstants vertex_constants, fragment_constants; } shaders; @@ -209,10 +209,10 @@ struct GFXComputePipelineCreateInfo { struct ShaderBindings { std::vector push_constants; - + std::vector bindings; } shader_input; - + // TODO: extract this from the shader instead of hardcoding it twice (once in GLSL, and now here) int workgroup_size_x = 1, workgroup_size_y = 1, workgroup_size_z = 1; }; @@ -220,7 +220,7 @@ struct GFXComputePipelineCreateInfo { struct GFXFramebufferCreateInfo { std::string label; - GFXRenderPass* render_pass; + GFXRenderPass* render_pass; std::vector attachments; }; @@ -228,7 +228,7 @@ struct GFXRenderPassCreateInfo { std::string label; std::vector attachments; - + bool will_use_in_shader = false; }; @@ -263,7 +263,7 @@ struct GFXTextureCreateInfo { GFXTextureUsage usage; int array_length = 1; int mip_count = 1; - + // sampler GFXFilter min_filter = GFXFilter::Linear, mag_filter = GFXFilter::Linear; SamplingMode samplingMode = SamplingMode::Repeat; @@ -292,70 +292,113 @@ enum class GFXFeature { class GFX { public: - // check for runtime support - virtual bool is_supported() { return false; } - virtual GFXContext required_context() { return GFXContext::None; } - virtual ShaderLanguage accepted_shader_language() { return ShaderLanguage::GLSL; } - virtual const char* get_name() { return nullptr; } - - virtual bool supports_feature([[maybe_unused]] const GFXFeature feature) { return false; } + // check for runtime support + virtual bool is_supported() { + return false; + } - // try to initialize - virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) { return false; } + virtual GFXContext required_context() { + return GFXContext::None; + } + + virtual ShaderLanguage accepted_shader_language() { + return ShaderLanguage::GLSL; + } + + virtual const char* get_name() { + return nullptr; + } + + virtual bool supports_feature([[maybe_unused]] const GFXFeature feature) { + return false; + } + + // try to initialize + virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) { + return false; + } + + virtual void initialize_view( + [[maybe_unused]] void* native_handle, + [[maybe_unused]] const platform::window_ptr identifier, + [[maybe_unused]] const uint32_t width, + [[maybe_unused]] const uint32_t height) {} + + virtual void recreate_view( + [[maybe_unused]] const platform::window_ptr identifier, + [[maybe_unused]] const uint32_t width, + [[maybe_unused]] const uint32_t height) {} - virtual void initialize_view([[maybe_unused]] void* native_handle, - [[maybe_unused]] const platform::window_ptr identifier, - [[maybe_unused]] const uint32_t width, - [[maybe_unused]] const uint32_t height) {} - - virtual void recreate_view([[maybe_unused]] const platform::window_ptr identifier, - [[maybe_unused]] const uint32_t width, - [[maybe_unused]] const uint32_t height) {} - virtual void remove_view([[maybe_unused]] const platform::window_ptr identifier) {} // buffer operations - virtual GFXBuffer* create_buffer([[maybe_unused]] void* data, - [[maybe_unused]] const GFXSize size, - [[maybe_unused]] const bool is_dynamic, - [[maybe_unused]] const GFXBufferUsage usage) { return nullptr; } - virtual void copy_buffer([[maybe_unused]] GFXBuffer* buffer, - [[maybe_unused]] void* data, - [[maybe_unused]] const GFXSize offset, - [[maybe_unused]] const GFXSize size) { } + virtual GFXBuffer* create_buffer( + [[maybe_unused]] void* data, + [[maybe_unused]] const GFXSize size, + [[maybe_unused]] const bool is_dynamic, + [[maybe_unused]] const GFXBufferUsage usage) { + return nullptr; + } - virtual void* get_buffer_contents([[maybe_unused]] GFXBuffer* buffer) { return nullptr; } - virtual void release_buffer_contents([[maybe_unused]] GFXBuffer* buffer, - [[maybe_unused]] void* handle) {} + virtual void copy_buffer( + [[maybe_unused]] GFXBuffer* buffer, + [[maybe_unused]] void* data, + [[maybe_unused]] const GFXSize offset, + [[maybe_unused]] const GFXSize size) {} + + virtual void* get_buffer_contents([[maybe_unused]] GFXBuffer* buffer) { + return nullptr; + } + + virtual void release_buffer_contents([[maybe_unused]] GFXBuffer* buffer, [[maybe_unused]] void* handle) {} // texture operations - virtual GFXTexture* create_texture([[maybe_unused]] const GFXTextureCreateInfo& info) { return nullptr; } - virtual void copy_texture([[maybe_unused]] GFXTexture* texture, - [[maybe_unused]] void* data, - [[maybe_unused]] const GFXSize size) {} - virtual void copy_texture([[maybe_unused]] GFXTexture* from, - [[maybe_unused]] GFXTexture* to) {} - virtual void copy_texture([[maybe_unused]] GFXTexture* from, - [[maybe_unused]] GFXBuffer* to) {} - + virtual GFXTexture* create_texture([[maybe_unused]] const GFXTextureCreateInfo& info) { + return nullptr; + } + + virtual void copy_texture( + [[maybe_unused]] GFXTexture* texture, + [[maybe_unused]] void* data, + [[maybe_unused]] const GFXSize size) {} + + virtual void copy_texture([[maybe_unused]] GFXTexture* from, [[maybe_unused]] GFXTexture* to) {} + + virtual void copy_texture([[maybe_unused]] GFXTexture* from, [[maybe_unused]] GFXBuffer* to) {} + // sampler opeations - virtual GFXSampler* create_sampler([[maybe_unused]] const GFXSamplerCreateInfo& info) { return nullptr; } + virtual GFXSampler* create_sampler([[maybe_unused]] const GFXSamplerCreateInfo& info) { + return nullptr; + } // framebuffer operations - virtual GFXFramebuffer* create_framebuffer([[maybe_unused]] const GFXFramebufferCreateInfo& info) { return nullptr; } + virtual GFXFramebuffer* create_framebuffer([[maybe_unused]] const GFXFramebufferCreateInfo& info) { + return nullptr; + } // render pass operations - virtual GFXRenderPass* create_render_pass([[maybe_unused]] const GFXRenderPassCreateInfo& info) { return nullptr; } + virtual GFXRenderPass* create_render_pass([[maybe_unused]] const GFXRenderPassCreateInfo& info) { + return nullptr; + } // pipeline operations - virtual GFXPipeline* create_graphics_pipeline([[maybe_unused]] const GFXGraphicsPipelineCreateInfo& info) { return nullptr; } - virtual GFXPipeline* create_compute_pipeline([[maybe_unused]] const GFXComputePipelineCreateInfo& info) { return nullptr; } + virtual GFXPipeline* create_graphics_pipeline([[maybe_unused]] const GFXGraphicsPipelineCreateInfo& info) { + return nullptr; + } + + virtual GFXPipeline* create_compute_pipeline([[maybe_unused]] const GFXComputePipelineCreateInfo& info) { + return nullptr; + } // misc operations - virtual GFXSize get_alignment(const GFXSize size) { return size; } + virtual GFXSize get_alignment(const GFXSize size) { + return size; + } - virtual GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) { return nullptr; } - - virtual void submit([[maybe_unused]] GFXCommandBuffer* command_buffer, - [[maybe_unused]] const platform::window_ptr window) {} + virtual GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) { + return nullptr; + } + + virtual void + submit([[maybe_unused]] GFXCommandBuffer* command_buffer, [[maybe_unused]] const platform::window_ptr window) {} }; diff --git a/engine/gfx/public/gfx_buffer.hpp b/engine/gfx/public/gfx_buffer.hpp index 6a7ac1e..d111430 100755 --- a/engine/gfx/public/gfx_buffer.hpp +++ b/engine/gfx/public/gfx_buffer.hpp @@ -4,5 +4,4 @@ class GFXBuffer : public GFXObject { public: - }; diff --git a/engine/gfx/public/gfx_commandbuffer.hpp b/engine/gfx/public/gfx_commandbuffer.hpp index 29f10ad..8ef0058 100755 --- a/engine/gfx/public/gfx_commandbuffer.hpp +++ b/engine/gfx/public/gfx_commandbuffer.hpp @@ -1,9 +1,9 @@ #pragma once -#include -#include #include +#include #include +#include #include "common.hpp" @@ -17,9 +17,9 @@ struct GFXRenderPassBeginInfo { struct ClearColor { float r = 0.0f, g = 0.0f, b = 0.0f, a = 1.0f; } clear_color; - + prism::Rectangle render_area; - + GFXRenderPass* render_pass = nullptr; GFXFramebuffer* framebuffer = nullptr; }; @@ -66,58 +66,58 @@ enum class GFXCommandType { struct GFXDrawCommand { GFXCommandType type = GFXCommandType::Invalid; - + struct CommandData { GFXRenderPassBeginInfo set_render_pass; - + struct SetGraphicsPipelineData { GFXPipeline* pipeline = nullptr; } set_graphics_pipeline; - + struct SetComputePipelineData { GFXPipeline* pipeline = nullptr; } set_compute_pipeline; - + struct SetVertexData { GFXBuffer* buffer = nullptr; int offset = 0; int index = 0; } set_vertex_buffer; - + struct SetIndexData { GFXBuffer* buffer = nullptr; - IndexType index_type = IndexType::UINT32; + IndexType index_type = IndexType::UINT32; } set_index_buffer; - + struct SetPushData { std::vector bytes; size_t size = 0; } set_push_constant; - + struct BindShaderData { GFXBuffer* buffer = nullptr; int offset = 0; int index = 0; int size = 0; } bind_shader_buffer; - + struct BindTextureData { GFXTexture* texture = nullptr; int index = 0; } bind_texture; - + struct BindSamplerData { GFXSampler* sampler = nullptr; int index = 0; } bind_sampler; - + struct DrawData { uint32_t vertex_offset = 0; uint32_t vertex_count = 0; uint32_t base_instance = 0; uint32_t instance_count = 0; } draw; - + struct DrawIndexedData { uint32_t index_count = 0; uint32_t first_index = 0; @@ -126,40 +126,40 @@ struct GFXDrawCommand { } draw_indexed; struct CopyTextureData { - GFXTexture* src = nullptr, *dst = nullptr; + GFXTexture *src = nullptr, *dst = nullptr; int width = 0, height = 0; int to_slice = 0; int to_layer = 0; int to_level = 0; } copy_texture; - + struct SetViewportData { Viewport viewport; } set_viewport; - + struct SetScissorData { prism::Rectangle rect; } set_scissor; - + struct GenerateMipmapData { GFXTexture* texture = nullptr; int mip_count = 0; } generate_mipmaps; - + struct SetDepthBiasData { float constant = 0.0f; float clamp = 0.0f; float slope_factor = 0.0f; } set_depth_bias; - + struct PushGroupData { std::string_view name; } push_group; - + struct InsertLabelData { std::string_view name; } insert_label; - + struct DispatchData { uint32_t group_count_x = 0, group_count_y = 0, group_count_z = 0; } dispatch; @@ -172,56 +172,56 @@ public: GFXDrawCommand command; command.type = GFXCommandType::SetRenderPass; command.data.set_render_pass = info; - + commands.push_back(command); } - + void set_graphics_pipeline(GFXPipeline* pipeline) { GFXDrawCommand command; command.type = GFXCommandType::SetGraphicsPipeline; command.data.set_graphics_pipeline.pipeline = pipeline; - + commands.push_back(command); } - + void set_compute_pipeline(GFXPipeline* pipeline) { GFXDrawCommand command; command.type = GFXCommandType::SetComputePipeline; command.data.set_compute_pipeline.pipeline = pipeline; - + commands.push_back(command); } - + void set_vertex_buffer(GFXBuffer* buffer, int offset, int index) { GFXDrawCommand command; command.type = GFXCommandType::SetVertexBuffer; command.data.set_vertex_buffer.buffer = buffer; command.data.set_vertex_buffer.offset = offset; command.data.set_vertex_buffer.index = index; - + commands.push_back(command); } - + void set_index_buffer(GFXBuffer* buffer, IndexType indexType) { GFXDrawCommand command; command.type = GFXCommandType::SetIndexBuffer; command.data.set_index_buffer.buffer = buffer; - command.data.set_index_buffer.index_type = indexType; - + command.data.set_index_buffer.index_type = indexType; + commands.push_back(command); } - + void set_push_constant(const void* data, const size_t size) { GFXDrawCommand command; command.type = GFXCommandType::SetPushConstant; command.data.set_push_constant.size = size; command.data.set_push_constant.bytes.resize(size); - + memcpy(command.data.set_push_constant.bytes.data(), data, size); - + commands.push_back(command); } - + void bind_shader_buffer(GFXBuffer* buffer, int offset, int index, int size) { GFXDrawCommand command; command.type = GFXCommandType::BindShaderBuffer; @@ -230,58 +230,63 @@ public: command.data.bind_shader_buffer.index = index; command.data.bind_shader_buffer.size = size; - commands.push_back(command); } - + void bind_texture(GFXTexture* texture, int index) { GFXDrawCommand command; command.type = GFXCommandType::BindTexture; command.data.bind_texture.texture = texture; command.data.bind_texture.index = index; - + commands.push_back(command); } - + void bind_sampler(GFXSampler* sampler, const int index) { GFXDrawCommand command; command.type = GFXCommandType::BindSampler; command.data.bind_sampler.sampler = sampler; command.data.bind_sampler.index = index; - + commands.push_back(command); } - - void draw(const uint32_t offset, const uint32_t count, const uint32_t instance_base, const uint32_t instance_count) { + + void + draw(const uint32_t offset, const uint32_t count, const uint32_t instance_base, const uint32_t instance_count) { GFXDrawCommand command; command.type = GFXCommandType::Draw; command.data.draw.vertex_offset = offset; command.data.draw.vertex_count = count; command.data.draw.base_instance = instance_base; command.data.draw.instance_count = instance_count; - + commands.push_back(command); } - - void draw_indexed(const uint32_t indexCount, const uint32_t firstIndex, const int32_t vertexOffset, const uint32_t base_instance) { + + void draw_indexed( + const uint32_t indexCount, + const uint32_t firstIndex, + const int32_t vertexOffset, + const uint32_t 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); } - + void memory_barrier() { GFXDrawCommand command; command.type = GFXCommandType::MemoryBarrier; - + commands.push_back(command); } - - void copy_texture(GFXTexture* src, int width, int height, GFXTexture* dst, int to_slice, int to_layer, int to_level) { + + void + copy_texture(GFXTexture* src, int width, int height, GFXTexture* dst, int to_slice, int to_layer, int to_level) { GFXDrawCommand command; command.type = GFXCommandType::CopyTexture; command.data.copy_texture.src = src; @@ -291,18 +296,18 @@ public: command.data.copy_texture.to_slice = to_slice; command.data.copy_texture.to_layer = to_layer; command.data.copy_texture.to_level = to_level; - + commands.push_back(command); } - + void set_viewport(Viewport viewport) { GFXDrawCommand command; command.type = GFXCommandType::SetViewport; command.data.set_viewport.viewport = viewport; - + commands.push_back(command); } - + void set_scissor(const prism::Rectangle rect) { GFXDrawCommand command; command.type = GFXCommandType::SetScissor; @@ -310,65 +315,65 @@ public: commands.push_back(command); } - + void generate_mipmaps(GFXTexture* texture, int mip_count) { GFXDrawCommand command; command.type = GFXCommandType::GenerateMipmaps; command.data.generate_mipmaps.texture = texture; command.data.generate_mipmaps.mip_count = mip_count; - + commands.push_back(command); } - + void set_depth_bias(const float constant, const float clamp, const float slope) { GFXDrawCommand command; command.type = GFXCommandType::SetDepthBias; command.data.set_depth_bias.constant = constant; command.data.set_depth_bias.clamp = clamp; command.data.set_depth_bias.slope_factor = slope; - + commands.push_back(command); } - + void push_group(const std::string_view name) { GFXDrawCommand command; command.type = GFXCommandType::PushGroup; command.data.push_group.name = name; - + commands.push_back(command); } - + void pop_group() { GFXDrawCommand command; command.type = GFXCommandType::PopGroup; - + commands.push_back(command); } - + void insert_label(const std::string_view name) { GFXDrawCommand command; command.type = GFXCommandType::InsertLabel; command.data.insert_label.name = name; - + commands.push_back(command); } - + void dispatch(const uint32_t group_count_x, const uint32_t group_count_y, const uint32_t group_count_z) { GFXDrawCommand command; command.type = GFXCommandType::Dispatch; command.data.dispatch.group_count_x = group_count_x; command.data.dispatch.group_count_y = group_count_y; command.data.dispatch.group_count_z = group_count_z; - + commands.push_back(command); } - + void end_render_pass() { GFXDrawCommand command; command.type = GFXCommandType::EndRenderPass; - + commands.push_back(command); } - + std::vector commands; }; diff --git a/engine/gfx/public/gfx_framebuffer.hpp b/engine/gfx/public/gfx_framebuffer.hpp index 184a570..8c3adb5 100755 --- a/engine/gfx/public/gfx_framebuffer.hpp +++ b/engine/gfx/public/gfx_framebuffer.hpp @@ -4,5 +4,4 @@ class GFXFramebuffer : public GFXObject { public: - }; diff --git a/engine/gfx/public/gfx_renderpass.hpp b/engine/gfx/public/gfx_renderpass.hpp index 068eda0..0367ab9 100755 --- a/engine/gfx/public/gfx_renderpass.hpp +++ b/engine/gfx/public/gfx_renderpass.hpp @@ -4,5 +4,4 @@ class GFXRenderPass : public GFXObject { public: - }; diff --git a/engine/gfx/public/gfx_sampler.hpp b/engine/gfx/public/gfx_sampler.hpp index 3cee31a..354ca81 100755 --- a/engine/gfx/public/gfx_sampler.hpp +++ b/engine/gfx/public/gfx_sampler.hpp @@ -4,5 +4,4 @@ class GFXSampler : public GFXObject { public: - }; diff --git a/engine/gfx/vulkan/CMakeLists.txt b/engine/gfx/vulkan/CMakeLists.txt index 981ae28..47b3048 100755 --- a/engine/gfx/vulkan/CMakeLists.txt +++ b/engine/gfx/vulkan/CMakeLists.txt @@ -1,24 +1,24 @@ set(HEADERS - include/gfx_vulkan.hpp - src/gfx_vulkan_buffer.hpp - src/gfx_vulkan_pipeline.hpp - src/gfx_vulkan_texture.hpp - src/gfx_vulkan_framebuffer.hpp - src/gfx_vulkan_renderpass.hpp - src/gfx_vulkan_commandbuffer.hpp) + include/gfx_vulkan.hpp + src/gfx_vulkan_buffer.hpp + src/gfx_vulkan_pipeline.hpp + src/gfx_vulkan_texture.hpp + src/gfx_vulkan_framebuffer.hpp + src/gfx_vulkan_renderpass.hpp + src/gfx_vulkan_commandbuffer.hpp) add_library(GFXVulkan STATIC - src/gfx_vulkan.cpp - ${HEADERS}) + src/gfx_vulkan.cpp + ${HEADERS}) target_link_libraries(GFXVulkan PUBLIC - GFX - Vulkan::Vulkan - Core - Log) + GFX + Vulkan::Vulkan + Core + Log) target_include_directories(GFXVulkan PUBLIC - include - PRIVATE - src) + include + PRIVATE + src) set_target_properties(GFXVulkan PROPERTIES - CXX_STANDARD 17) + CXX_STANDARD 17) diff --git a/engine/gfx/vulkan/include/gfx_vulkan.hpp b/engine/gfx/vulkan/include/gfx_vulkan.hpp index a675930..ad8c952 100755 --- a/engine/gfx/vulkan/include/gfx_vulkan.hpp +++ b/engine/gfx/vulkan/include/gfx_vulkan.hpp @@ -2,8 +2,8 @@ #include -#include #include +#include #include "gfx.hpp" #include "gfx_vulkan_constants.hpp" @@ -12,23 +12,23 @@ class GFXVulkanCommandBuffer; struct NativeSurface { platform::window_ptr identifier = nullptr; - + uint32_t surfaceWidth = -1, surfaceHeight = -1; - + std::vector imageAvailableSemaphores; std::vector renderFinishedSemaphores; std::vector inFlightFences; size_t currentFrame = 0; - + VkSurfaceKHR surface = VK_NULL_HANDLE; VkSwapchainKHR swapchain = VK_NULL_HANDLE; VkExtent2D swapchainExtent = {}; - + std::vector swapchainImages; std::vector swapchainImageViews; - + VkRenderPass swapchainRenderPass = VK_NULL_HANDLE; - + std::vector swapchainFramebuffers; std::vector gfx_command_buffers; }; @@ -37,17 +37,27 @@ class GFXVulkanPipeline; class GFXVulkan : public GFX { public: - bool is_supported() override { return true; } - ShaderLanguage accepted_shader_language() override { return ShaderLanguage::SPIRV; } - GFXContext required_context() override { return GFXContext::Vulkan; } - const char* get_name() override; + bool is_supported() override { + return true; + } + + ShaderLanguage accepted_shader_language() override { + return ShaderLanguage::SPIRV; + } + + GFXContext required_context() override { + return GFXContext::Vulkan; + } + + const char* get_name() override; bool supports_feature(GFXFeature feature) override; bool initialize(const GFXCreateInfo& info) override; - void initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; - void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override; + void + initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; + void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override; // buffer operations GFXBuffer* create_buffer(void* data, GFXSize size, bool dynamic_data, GFXBufferUsage usage) override; @@ -62,73 +72,80 @@ public: void copy_texture(GFXTexture* from, GFXTexture* to) override; void copy_texture(GFXTexture* from, GFXBuffer* to) override; - // sampler operations - GFXSampler* create_sampler(const GFXSamplerCreateInfo& info) override; + // sampler operations + GFXSampler* create_sampler(const GFXSamplerCreateInfo& info) override; // framebuffer operations GFXFramebuffer* create_framebuffer(const GFXFramebufferCreateInfo& info) override; - // render pass operations - GFXRenderPass* create_render_pass(const GFXRenderPassCreateInfo& info) override; + // render pass operations + GFXRenderPass* create_render_pass(const GFXRenderPassCreateInfo& info) override; // pipeline operations GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override; GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override; // misc operations - GFXSize get_alignment(GFXSize size) override; + GFXSize get_alignment(GFXSize size) override; GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) override; void submit(GFXCommandBuffer* command_buffer, platform::window_ptr identifier) override; private: - void createInstance(std::vector layers, std::vector extensions); - void createLogicalDevice(std::vector extensions); - void createSwapchain(NativeSurface* native_surface, VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE); - void createDescriptorPool(); + void createInstance(std::vector layers, std::vector extensions); + void createLogicalDevice(std::vector extensions); + void createSwapchain(NativeSurface* native_surface, VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE); + void createDescriptorPool(); void createSyncPrimitives(NativeSurface* native_surface); - // dynamic descriptor sets - void resetDescriptorState(); - void cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSetLayout layout); + // dynamic descriptor sets + void resetDescriptorState(); + void cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSetLayout layout); uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline); - uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); - void transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout); - void inlineTransitionImageLayout(VkCommandBuffer command_buffer, - VkImage image, - VkFormat format, - VkImageAspectFlags aspect, - VkImageSubresourceRange range, - VkImageLayout oldLayout, - VkImageLayout newLayout, - VkPipelineStageFlags src_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - VkShaderModule createShaderModule(const uint32_t* code, int length); - VkCommandBuffer beginSingleTimeCommands(); - void endSingleTimeCommands(VkCommandBuffer commandBuffer); + uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); + void transitionImageLayout( + VkImage image, + VkFormat format, + VkImageAspectFlags aspect, + VkImageSubresourceRange range, + VkImageLayout oldLayout, + VkImageLayout newLayout); + void inlineTransitionImageLayout( + VkCommandBuffer command_buffer, + VkImage image, + VkFormat format, + VkImageAspectFlags aspect, + VkImageSubresourceRange range, + VkImageLayout oldLayout, + VkImageLayout newLayout, + VkPipelineStageFlags src_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + VkShaderModule createShaderModule(const uint32_t* code, int length); + VkCommandBuffer beginSingleTimeCommands(); + void endSingleTimeCommands(VkCommandBuffer commandBuffer); - VkInstance instance = VK_NULL_HANDLE; + VkInstance instance = VK_NULL_HANDLE; - VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; - VkDevice device = VK_NULL_HANDLE; + VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; + VkDevice device = VK_NULL_HANDLE; - VkQueue graphicsQueue = VK_NULL_HANDLE; - VkQueue presentQueue = VK_NULL_HANDLE; + VkQueue graphicsQueue = VK_NULL_HANDLE; + VkQueue presentQueue = VK_NULL_HANDLE; - VkCommandPool commandPool = VK_NULL_HANDLE; + VkCommandPool commandPool = VK_NULL_HANDLE; - VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; std::vector native_surfaces; - struct BoundShaderBuffer { - GFXBuffer* buffer = nullptr; - VkDeviceSize size = 0, offset = 0; - }; + struct BoundShaderBuffer { + GFXBuffer* buffer = nullptr; + VkDeviceSize size = 0, offset = 0; + }; - std::array boundShaderBuffers; - std::array boundTextures; - std::array boundSamplers; + std::array boundShaderBuffers; + std::array boundTextures; + std::array boundSamplers; }; diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index bf8f356..9cfb717 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -21,35 +21,35 @@ VkFormat toVkFormat(GFXPixelFormat format) { switch (format) { - case GFXPixelFormat::R_32F: - return VK_FORMAT_R32_SFLOAT; + case GFXPixelFormat::R_32F: + return VK_FORMAT_R32_SFLOAT; - case GFXPixelFormat::R_16F: - return VK_FORMAT_R16_SFLOAT; + case GFXPixelFormat::R_16F: + return VK_FORMAT_R16_SFLOAT; - case GFXPixelFormat::RGBA_32F: - return VK_FORMAT_R32G32B32A32_SFLOAT; + case GFXPixelFormat::RGBA_32F: + return VK_FORMAT_R32G32B32A32_SFLOAT; - case GFXPixelFormat::RGBA8_UNORM: - return VK_FORMAT_R8G8B8A8_UNORM; + case GFXPixelFormat::RGBA8_UNORM: + return VK_FORMAT_R8G8B8A8_UNORM; - case GFXPixelFormat::R8_UNORM: - return VK_FORMAT_R8_UNORM; + case GFXPixelFormat::R8_UNORM: + return VK_FORMAT_R8_UNORM; - case GFXPixelFormat::R8G8_UNORM: - return VK_FORMAT_R8G8_UNORM; + case GFXPixelFormat::R8G8_UNORM: + return VK_FORMAT_R8G8_UNORM; - case GFXPixelFormat::R8G8_SFLOAT: - return VK_FORMAT_R16G16_SFLOAT; + case GFXPixelFormat::R8G8_SFLOAT: + return VK_FORMAT_R16G16_SFLOAT; - case GFXPixelFormat::R8G8B8A8_UNORM: - return VK_FORMAT_R8G8B8A8_UNORM; + case GFXPixelFormat::R8G8B8A8_UNORM: + return VK_FORMAT_R8G8B8A8_UNORM; - case GFXPixelFormat::R16G16B16A16_SFLOAT: - return VK_FORMAT_R16G16B16A16_SFLOAT; + case GFXPixelFormat::R16G16B16A16_SFLOAT: + return VK_FORMAT_R16G16B16A16_SFLOAT; - case GFXPixelFormat::DEPTH_32F: - return VK_FORMAT_D32_SFLOAT; + case GFXPixelFormat::DEPTH_32F: + return VK_FORMAT_D32_SFLOAT; } return VK_FORMAT_UNDEFINED; @@ -57,18 +57,18 @@ VkFormat toVkFormat(GFXPixelFormat format) { VkFormat toVkFormat(GFXVertexFormat format) { switch (format) { - case GFXVertexFormat::FLOAT2: - return VK_FORMAT_R32G32_SFLOAT; - case GFXVertexFormat::FLOAT3: - return VK_FORMAT_R32G32B32_SFLOAT; - case GFXVertexFormat::FLOAT4: - return VK_FORMAT_R32G32B32A32_SFLOAT; - case GFXVertexFormat::INT: - return VK_FORMAT_R8_SINT; - case GFXVertexFormat::INT4: - return VK_FORMAT_R32G32B32A32_SINT; - case GFXVertexFormat::UNORM4: - return VK_FORMAT_R8G8B8A8_UNORM; + case GFXVertexFormat::FLOAT2: + return VK_FORMAT_R32G32_SFLOAT; + case GFXVertexFormat::FLOAT3: + return VK_FORMAT_R32G32B32_SFLOAT; + case GFXVertexFormat::FLOAT4: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case GFXVertexFormat::INT: + return VK_FORMAT_R8_SINT; + case GFXVertexFormat::INT4: + return VK_FORMAT_R32G32B32A32_SINT; + case GFXVertexFormat::UNORM4: + return VK_FORMAT_R8G8B8A8_UNORM; } return VK_FORMAT_UNDEFINED; @@ -76,22 +76,22 @@ VkFormat toVkFormat(GFXVertexFormat format) { VkBlendFactor toVkFactor(GFXBlendFactor factor) { switch (factor) { - case GFXBlendFactor::Zero: - return VK_BLEND_FACTOR_ZERO; - case GFXBlendFactor::One: - return VK_BLEND_FACTOR_ONE; - case GFXBlendFactor::OneMinusSrcAlpha: - return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - case GFXBlendFactor::OneMinusSrcColor: - return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; - case GFXBlendFactor::SrcAlpha: - return VK_BLEND_FACTOR_SRC_ALPHA; - case GFXBlendFactor::DstAlpha: - return VK_BLEND_FACTOR_DST_ALPHA; - case GFXBlendFactor::SrcColor: - return VK_BLEND_FACTOR_SRC_COLOR; - case GFXBlendFactor::DstColor: - return VK_BLEND_FACTOR_DST_COLOR; + case GFXBlendFactor::Zero: + return VK_BLEND_FACTOR_ZERO; + case GFXBlendFactor::One: + return VK_BLEND_FACTOR_ONE; + case GFXBlendFactor::OneMinusSrcAlpha: + return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + case GFXBlendFactor::OneMinusSrcColor: + return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + case GFXBlendFactor::SrcAlpha: + return VK_BLEND_FACTOR_SRC_ALPHA; + case GFXBlendFactor::DstAlpha: + return VK_BLEND_FACTOR_DST_ALPHA; + case GFXBlendFactor::SrcColor: + return VK_BLEND_FACTOR_SRC_COLOR; + case GFXBlendFactor::DstColor: + return VK_BLEND_FACTOR_DST_COLOR; } return VK_BLEND_FACTOR_ONE; @@ -99,12 +99,12 @@ VkBlendFactor toVkFactor(GFXBlendFactor factor) { VkSamplerAddressMode toSamplerMode(SamplingMode mode) { switch (mode) { - case SamplingMode::Repeat: - return VK_SAMPLER_ADDRESS_MODE_REPEAT; - case SamplingMode::ClampToBorder: - return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; - case SamplingMode::ClampToEdge: - return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case SamplingMode::Repeat: + return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case SamplingMode::ClampToBorder: + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + case SamplingMode::ClampToEdge: + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; } return VK_SAMPLER_ADDRESS_MODE_REPEAT; @@ -112,10 +112,10 @@ VkSamplerAddressMode toSamplerMode(SamplingMode mode) { inline VkFilter toFilter(GFXFilter filter) { switch (filter) { - case GFXFilter::Nearest: - return VK_FILTER_NEAREST; - case GFXFilter::Linear: - return VK_FILTER_LINEAR; + case GFXFilter::Nearest: + return VK_FILTER_NEAREST; + case GFXFilter::Linear: + return VK_FILTER_LINEAR; } return VK_FILTER_LINEAR; @@ -123,10 +123,10 @@ inline VkFilter toFilter(GFXFilter filter) { inline VkBorderColor toBorderColor(GFXBorderColor color) { switch (color) { - case GFXBorderColor::OpaqueBlack: - return VK_BORDER_COLOR_INT_OPAQUE_BLACK; - case GFXBorderColor::OpaqueWhite: - return VK_BORDER_COLOR_INT_OPAQUE_WHITE; + case GFXBorderColor::OpaqueBlack: + return VK_BORDER_COLOR_INT_OPAQUE_BLACK; + case GFXBorderColor::OpaqueWhite: + return VK_BORDER_COLOR_INT_OPAQUE_WHITE; } return VK_BORDER_COLOR_INT_OPAQUE_BLACK; @@ -134,46 +134,45 @@ inline VkBorderColor toBorderColor(GFXBorderColor color) { VkCompareOp toCompareFunc(GFXCompareFunction func) { switch (func) { - case GFXCompareFunction::Never: - return VK_COMPARE_OP_NEVER; - break; - case GFXCompareFunction::Less: - return VK_COMPARE_OP_LESS; - break; - case GFXCompareFunction::Equal: - return VK_COMPARE_OP_EQUAL; - break; - case GFXCompareFunction::LessOrEqual: - return VK_COMPARE_OP_LESS_OR_EQUAL; - break; - case GFXCompareFunction::Greater: - return VK_COMPARE_OP_GREATER; - break; - case GFXCompareFunction::NotEqual: - return VK_COMPARE_OP_NOT_EQUAL; - break; - case GFXCompareFunction::GreaterOrEqual: - return VK_COMPARE_OP_GREATER_OR_EQUAL; - break; - case GFXCompareFunction::Always: - return VK_COMPARE_OP_ALWAYS; - break; + case GFXCompareFunction::Never: + return VK_COMPARE_OP_NEVER; + break; + case GFXCompareFunction::Less: + return VK_COMPARE_OP_LESS; + break; + case GFXCompareFunction::Equal: + return VK_COMPARE_OP_EQUAL; + break; + case GFXCompareFunction::LessOrEqual: + return VK_COMPARE_OP_LESS_OR_EQUAL; + break; + case GFXCompareFunction::Greater: + return VK_COMPARE_OP_GREATER; + break; + case GFXCompareFunction::NotEqual: + return VK_COMPARE_OP_NOT_EQUAL; + break; + case GFXCompareFunction::GreaterOrEqual: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + break; + case GFXCompareFunction::Always: + return VK_COMPARE_OP_ALWAYS; + break; } } -VKAPI_ATTR VkBool32 VKAPI_CALL -DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageType, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, - void* pUserData) { +VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { prism::log("{}", pCallbackData->pMessage); return VK_FALSE; } -VkResult name_object(VkDevice device, VkObjectType type, uint64_t object, - std::string_view name) { +VkResult name_object(VkDevice device, VkObjectType type, uint64_t object, std::string_view name) { if (object == 0x0) { prism::log("Failed to name object {}", name); return VK_ERROR_DEVICE_LOST; @@ -185,25 +184,21 @@ VkResult name_object(VkDevice device, VkObjectType type, uint64_t object, info.pObjectName = name.data(); info.objectHandle = object; - auto func = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr( - device, "vkSetDebugUtilsObjectNameEXT"); + auto func = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(device, "vkSetDebugUtilsObjectNameEXT"); if (func != nullptr) return func(device, &info); else return VK_ERROR_EXTENSION_NOT_PRESENT; } -void cmd_debug_marker_begin(VkDevice device, VkCommandBuffer command_buffer, - VkDebugUtilsLabelEXT marker_info) { - auto func = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr( - device, "vkCmdBeginDebugUtilsLabelEXT"); +void cmd_debug_marker_begin(VkDevice device, VkCommandBuffer command_buffer, VkDebugUtilsLabelEXT marker_info) { + auto func = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdBeginDebugUtilsLabelEXT"); if (func != nullptr) func(command_buffer, &marker_info); } void cmd_debug_marker_end(VkDevice device, VkCommandBuffer command_buffer) { - auto func = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetDeviceProcAddr( - device, "vkCmdEndDebugUtilsLabelEXT"); + auto func = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdEndDebugUtilsLabelEXT"); if (func != nullptr) func(command_buffer); } @@ -214,13 +209,10 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) { #endif uint32_t extensionPropertyCount = 0; - vkEnumerateInstanceExtensionProperties(nullptr, &extensionPropertyCount, - nullptr); + vkEnumerateInstanceExtensionProperties(nullptr, &extensionPropertyCount, nullptr); - std::vector extensionProperties( - extensionPropertyCount); - vkEnumerateInstanceExtensionProperties(nullptr, &extensionPropertyCount, - extensionProperties.data()); + std::vector extensionProperties(extensionPropertyCount); + vkEnumerateInstanceExtensionProperties(nullptr, &extensionPropertyCount, extensionProperties.data()); std::vector enabledExtensions = {}; for (auto prop : extensionProperties) { @@ -231,9 +223,7 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) { auto ctx_info = (vulkan_information*)platform::get_context_information(); auto required_extensions = ctx_info->surface_extensions; - enabledExtensions.insert(enabledExtensions.end(), - required_extensions.begin(), - required_extensions.end()); + enabledExtensions.insert(enabledExtensions.end(), required_extensions.begin(), required_extensions.end()); createInstance({}, enabledExtensions); createLogicalDevice({VK_KHR_SWAPCHAIN_EXTENSION_NAME}); @@ -242,9 +232,11 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) { return true; } -void GFXVulkan::initialize_view(void* native_handle, - const platform::window_ptr identifier, - const uint32_t width, const uint32_t height) { +void GFXVulkan::initialize_view( + void* native_handle, + const platform::window_ptr identifier, + const uint32_t width, + const uint32_t height) { vkDeviceWaitIdle(device); auto surface = new NativeSurface(); @@ -258,8 +250,7 @@ void GFXVulkan::initialize_view(void* native_handle, native_surfaces.push_back(surface); } -void GFXVulkan::recreate_view(const platform::window_ptr identifier, - const uint32_t width, const uint32_t height) { +void GFXVulkan::recreate_view(const platform::window_ptr identifier, const uint32_t width, const uint32_t height) { vkDeviceWaitIdle(device); NativeSurface* found_surface = nullptr; @@ -276,9 +267,8 @@ void GFXVulkan::recreate_view(const platform::window_ptr identifier, } } -GFXBuffer* GFXVulkan::create_buffer(void* data, const GFXSize size, - const bool dynamic_data, - const GFXBufferUsage usage) { +GFXBuffer* +GFXVulkan::create_buffer(void* data, const GFXSize size, const bool dynamic_data, const GFXBufferUsage usage) { auto buffer = new GFXVulkanBuffer(); vkDeviceWaitIdle(device); @@ -310,10 +300,8 @@ GFXBuffer* GFXVulkan::create_buffer(void* data, const GFXSize size, VkMemoryAllocateInfo allocInfo = {}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = - findMemoryType(memRequirements.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + allocInfo.memoryTypeIndex = findMemoryType( + memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); vkAllocateMemory(device, &allocInfo, nullptr, &buffer->memory); @@ -329,13 +317,11 @@ GFXBuffer* GFXVulkan::create_buffer(void* data, const GFXSize size, return buffer; } -void GFXVulkan::copy_buffer(GFXBuffer* buffer, void* data, GFXSize offset, - GFXSize size) { +void GFXVulkan::copy_buffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) { auto vulkanBuffer = (GFXVulkanBuffer*)buffer; void* mapped_data = nullptr; - vkMapMemory(device, vulkanBuffer->memory, offset, - vulkanBuffer->size - offset, 0, &mapped_data); + vkMapMemory(device, vulkanBuffer->memory, offset, vulkanBuffer->size - offset, 0, &mapped_data); if (mapped_data == nullptr) return; @@ -355,8 +341,7 @@ void* GFXVulkan::get_buffer_contents(GFXBuffer* buffer) { auto vulkanBuffer = (GFXVulkanBuffer*)buffer; void* mapped_data; - vkMapMemory(device, vulkanBuffer->memory, 0, VK_WHOLE_SIZE, 0, - &mapped_data); + vkMapMemory(device, vulkanBuffer->memory, 0, VK_WHOLE_SIZE, 0, &mapped_data); return mapped_data; } @@ -385,8 +370,7 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { VkImageTiling imageTiling; imageTiling = VK_IMAGE_TILING_OPTIMAL; - const auto check_flag = [](const GFXTextureUsage usage, - const GFXTextureUsage flag) { + const auto check_flag = [](const GFXTextureUsage usage, const GFXTextureUsage flag) { return (usage & flag) == flag; }; @@ -441,14 +425,12 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; - if (info.type == GFXTextureType::Cubemap || - info.type == GFXTextureType::CubemapArray) + if (info.type == GFXTextureType::Cubemap || info.type == GFXTextureType::CubemapArray) imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; vkCreateImage(device, &imageInfo, nullptr, &texture->handle); - name_object(device, VK_OBJECT_TYPE_IMAGE, (uint64_t)texture->handle, - info.label); + name_object(device, VK_OBJECT_TYPE_IMAGE, (uint64_t)texture->handle, info.label); texture->width = info.width; texture->height = info.height; @@ -456,7 +438,7 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { texture->aspect = imageAspect; if (check_flag(info.usage, GFXTextureUsage::Attachment)) { - if(check_flag(info.usage, GFXTextureUsage::Sampled)) { + if (check_flag(info.usage, GFXTextureUsage::Sampled)) { if (info.format == GFXPixelFormat::DEPTH_32F) { texture->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; } else { @@ -469,8 +451,8 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } } - } else if (check_flag(info.usage, GFXTextureUsage::Storage) && - check_flag(info.usage, GFXTextureUsage::ShaderWrite)) { + } else if ( + check_flag(info.usage, GFXTextureUsage::Storage) && check_flag(info.usage, GFXTextureUsage::ShaderWrite)) { texture->layout = VK_IMAGE_LAYOUT_GENERAL; } else if (check_flag(info.usage, GFXTextureUsage::Sampled)) { texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -487,8 +469,7 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { VkMemoryAllocateInfo allocInfo = {}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = findMemoryType( - memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); vkAllocateMemory(device, &allocInfo, nullptr, &texture->memory); @@ -503,8 +484,7 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { texture->range = range; - transitionImageLayout(texture->handle, imageFormat, imageAspect, range, - VK_IMAGE_LAYOUT_UNDEFINED, texture->layout); + transitionImageLayout(texture->handle, imageFormat, imageAspect, range, VK_IMAGE_LAYOUT_UNDEFINED, texture->layout); // create image view VkImageViewCreateInfo viewInfo = {}; @@ -512,18 +492,18 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { viewInfo.image = texture->handle; switch (info.type) { - case GFXTextureType::Single2D: - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - break; - case GFXTextureType::Array2D: - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - break; - case GFXTextureType::Cubemap: - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE; - break; - case GFXTextureType::CubemapArray: - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; - break; + case GFXTextureType::Single2D: + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + break; + case GFXTextureType::Array2D: + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + break; + case GFXTextureType::Cubemap: + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE; + break; + case GFXTextureType::CubemapArray: + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + break; } viewInfo.format = imageFormat; viewInfo.subresourceRange = range; @@ -577,10 +557,8 @@ void GFXVulkan::copy_texture(GFXTexture* texture, void* data, GFXSize size) { VkMemoryAllocateInfo allocInfo = {}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = - findMemoryType(memRequirements.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + allocInfo.memoryTypeIndex = findMemoryType( + memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); vkAllocateMemory(device, &allocInfo, nullptr, &stagingBufferMemory); @@ -601,26 +579,33 @@ void GFXVulkan::copy_texture(GFXTexture* texture, void* data, GFXSize size) { range.baseArrayLayer = 0; range.layerCount = 1; - inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, - vulkanTexture->format, vulkanTexture->aspect, - range, VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + inlineTransitionImageLayout( + commandBuffer, + vulkanTexture->handle, + vulkanTexture->format, + vulkanTexture->aspect, + range, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkBufferImageCopy region = {}; region.imageSubresource.aspectMask = vulkanTexture->aspect; region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; - region.imageExtent = {(uint32_t)vulkanTexture->width, - (uint32_t)vulkanTexture->height, 1}; + region.imageExtent = {(uint32_t)vulkanTexture->width, (uint32_t)vulkanTexture->height, 1}; - vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, vulkanTexture->handle, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + vkCmdCopyBufferToImage( + commandBuffer, stagingBuffer, vulkanTexture->handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - inlineTransitionImageLayout(commandBuffer, vulkanTexture->handle, - vulkanTexture->format, vulkanTexture->aspect, - range, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + inlineTransitionImageLayout( + commandBuffer, + vulkanTexture->handle, + vulkanTexture->format, + vulkanTexture->aspect, + range, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); endSingleTimeCommands(commandBuffer); } @@ -640,12 +625,10 @@ void GFXVulkan::copy_texture(GFXTexture* from, GFXBuffer* to) { region.imageSubresource.mipLevel = 0; region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; - region.imageExtent = {(uint32_t)vulkanTexture->width, - (uint32_t)vulkanTexture->height, 1}; + region.imageExtent = {(uint32_t)vulkanTexture->width, (uint32_t)vulkanTexture->height, 1}; - vkCmdCopyImageToBuffer(commandBuffer, vulkanTexture->handle, - vulkanTexture->layout, vulkanBuffer->handle, 1, - ®ion); + vkCmdCopyImageToBuffer( + commandBuffer, vulkanTexture->handle, vulkanTexture->layout, vulkanBuffer->handle, 1, ®ion); endSingleTimeCommands(commandBuffer); } @@ -674,8 +657,7 @@ GFXSampler* GFXVulkan::create_sampler(const GFXSamplerCreateInfo& info) { return sampler; } -GFXFramebuffer* -GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& info) { +GFXFramebuffer* GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& info) { auto framebuffer = new GFXVulkanFramebuffer(); vkDeviceWaitIdle(device); @@ -693,16 +675,13 @@ GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& info) { framebufferInfo.renderPass = renderPass->handle; framebufferInfo.attachmentCount = static_cast(attachments.size()); framebufferInfo.pAttachments = attachments.data(); - framebufferInfo.width = - ((GFXVulkanTexture*)info.attachments[0])->width; // FIXME: eww!! + framebufferInfo.width = ((GFXVulkanTexture*)info.attachments[0])->width; // FIXME: eww!! framebufferInfo.height = ((GFXVulkanTexture*)info.attachments[0])->height; framebufferInfo.layers = 1; - vkCreateFramebuffer(device, &framebufferInfo, nullptr, - &framebuffer->handle); + vkCreateFramebuffer(device, &framebufferInfo, nullptr, &framebuffer->handle); - name_object(device, VK_OBJECT_TYPE_FRAMEBUFFER, - (uint64_t)framebuffer->handle, info.label); + name_object(device, VK_OBJECT_TYPE_FRAMEBUFFER, (uint64_t)framebuffer->handle, info.label); framebuffer->width = ((GFXVulkanTexture*)info.attachments[0])->width; framebuffer->height = ((GFXVulkanTexture*)info.attachments[0])->height; @@ -710,8 +689,7 @@ GFXVulkan::create_framebuffer(const GFXFramebufferCreateInfo& info) { return framebuffer; } -GFXRenderPass* -GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { +GFXRenderPass* GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { auto renderPass = new GFXVulkanRenderPass(); vkDeviceWaitIdle(device); @@ -720,8 +698,6 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { std::vector references; std::vector dependencies; - - bool hasDepthAttachment = false; VkAttachmentDescription depthAttachment; VkAttachmentReference depthAttachmentRef; @@ -742,27 +718,22 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { if (info.will_use_in_shader) { if (isDepthAttachment) { - attachment.finalLayout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; } else { - attachment.finalLayout = - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } } else { if (isDepthAttachment) - attachment.finalLayout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; else - attachment.finalLayout = - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } VkAttachmentReference attachmentRef = {}; attachmentRef.attachment = i; if (isDepthAttachment) - attachmentRef.layout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; else attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -776,7 +747,7 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { references.push_back(attachmentRef); } - if(isDepthAttachment) { + if (isDepthAttachment) { VkSubpassDependency implicitBeginDependency; implicitBeginDependency.srcSubpass = VK_SUBPASS_EXTERNAL; implicitBeginDependency.dstSubpass = 0; @@ -847,8 +818,7 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass->handle); - name_object(device, VK_OBJECT_TYPE_RENDER_PASS, - (uint64_t)renderPass->handle, info.label); + name_object(device, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)renderPass->handle, info.label); renderPass->numAttachments = static_cast(descriptions.size()); renderPass->hasDepthAttachment = hasDepthAttachment; @@ -856,14 +826,12 @@ GFXVulkan::create_render_pass(const GFXRenderPassCreateInfo& info) { return renderPass; } -GFXPipeline* -GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { +GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { auto pipeline = new GFXVulkanPipeline(); vkDeviceWaitIdle(device); - VkShaderModule vertex_module = VK_NULL_HANDLE, - fragment_module = VK_NULL_HANDLE; + VkShaderModule vertex_module = VK_NULL_HANDLE, fragment_module = VK_NULL_HANDLE; const bool has_vertex_stage = !info.shaders.vertex_src.empty(); const bool has_fragment_stage = !info.shaders.fragment_src.empty(); @@ -876,131 +844,112 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { VkSpecializationInfo fragment_specialization_info; std::vector fragment_map_entries; - const auto fill_map_entries = - [](const GFXShaderConstants& constants, - std::vector& entries) { - for (int i = 0; i < constants.size(); i++) { - // TODO: we only support int specializations (which is okay - // right now) - VkSpecializationMapEntry entry = {}; - entry.constantID = constants[i].index; - entry.size = sizeof(int); - entry.offset = sizeof(int) * i; + const auto fill_map_entries = [](const GFXShaderConstants& constants, + std::vector& entries) { + for (int i = 0; i < constants.size(); i++) { + // TODO: we only support int specializations (which is okay + // right now) + VkSpecializationMapEntry entry = {}; + entry.constantID = constants[i].index; + entry.size = sizeof(int); + entry.offset = sizeof(int) * i; - entries.push_back(entry); - } - }; + entries.push_back(entry); + } + }; std::vector vertex_data; std::vector fragment_data; if (has_vertex_stage) { - const bool vertex_use_shader_source = - !info.shaders.vertex_src.is_path(); + const bool vertex_use_shader_source = !info.shaders.vertex_src.is_path(); if (vertex_use_shader_source) { auto vertex_shader_vector = info.shaders.vertex_src.as_bytecode(); - vertex_module = createShaderModule(vertex_shader_vector.data(), - vertex_shader_vector.size() * - sizeof(uint32_t)); + vertex_module = + createShaderModule(vertex_shader_vector.data(), vertex_shader_vector.size() * sizeof(uint32_t)); } else { - auto vertex_shader = prism::open_file( - prism::base_domain / - (info.shaders.vertex_src.as_path().string() + ".spv"), - true); + auto vertex_shader = + prism::open_file(prism::base_domain / (info.shaders.vertex_src.as_path().string() + ".spv"), true); vertex_shader->read_all(); - vertex_module = createShaderModule( - vertex_shader->cast_data(), vertex_shader->size()); + vertex_module = createShaderModule(vertex_shader->cast_data(), vertex_shader->size()); } if (!vertex_use_shader_source) - name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, - (uint64_t)vertex_module, - info.shaders.vertex_src.as_path().string()); + name_object( + device, + VK_OBJECT_TYPE_SHADER_MODULE, + (uint64_t)vertex_module, + info.shaders.vertex_src.as_path().string()); VkPipelineShaderStageCreateInfo vertShaderStageInfo = {}; - vertShaderStageInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vertShaderStageInfo.module = vertex_module; vertShaderStageInfo.pName = "main"; if (!info.shaders.vertex_constants.empty()) { fill_map_entries(info.shaders.vertex_constants, vertex_map_entries); - vertex_specialization_info.mapEntryCount = - vertex_map_entries.size(); + vertex_specialization_info.mapEntryCount = vertex_map_entries.size(); vertex_specialization_info.pMapEntries = vertex_map_entries.data(); for (auto constant : info.shaders.vertex_constants) { vertex_data.push_back(constant.value); } - vertex_specialization_info.dataSize = - vertex_data.size() * sizeof(int); + vertex_specialization_info.dataSize = vertex_data.size() * sizeof(int); vertex_specialization_info.pData = vertex_data.data(); - vertShaderStageInfo.pSpecializationInfo = - &vertex_specialization_info; + vertShaderStageInfo.pSpecializationInfo = &vertex_specialization_info; } shaderStages.push_back(vertShaderStageInfo); } if (has_fragment_stage) { - const bool fragment_use_shader_source = - !info.shaders.fragment_src.is_path(); + const bool fragment_use_shader_source = !info.shaders.fragment_src.is_path(); if (fragment_use_shader_source) { - auto fragment_shader_vector = - info.shaders.fragment_src.as_bytecode(); - - fragment_module = createShaderModule(fragment_shader_vector.data(), - fragment_shader_vector.size() * - sizeof(uint32_t)); - } else { - auto fragment_shader = prism::open_file( - prism::base_domain / - (info.shaders.fragment_src.as_path().string() + ".spv"), - true); - fragment_shader->read_all(); + auto fragment_shader_vector = info.shaders.fragment_src.as_bytecode(); fragment_module = - createShaderModule(fragment_shader->cast_data(), - fragment_shader->size()); + createShaderModule(fragment_shader_vector.data(), fragment_shader_vector.size() * sizeof(uint32_t)); + } else { + auto fragment_shader = + prism::open_file(prism::base_domain / (info.shaders.fragment_src.as_path().string() + ".spv"), true); + fragment_shader->read_all(); + + fragment_module = createShaderModule(fragment_shader->cast_data(), fragment_shader->size()); } if (!fragment_use_shader_source) - name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, - (uint64_t)fragment_module, - info.shaders.fragment_src.as_path().string()); + name_object( + device, + VK_OBJECT_TYPE_SHADER_MODULE, + (uint64_t)fragment_module, + info.shaders.fragment_src.as_path().string()); VkPipelineShaderStageCreateInfo fragShaderStageInfo = {}; - fragShaderStageInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fragShaderStageInfo.module = fragment_module; fragShaderStageInfo.pName = "main"; if (!info.shaders.fragment_constants.empty()) { - fill_map_entries(info.shaders.fragment_constants, - fragment_map_entries); - fragment_specialization_info.mapEntryCount = - fragment_map_entries.size(); - fragment_specialization_info.pMapEntries = - fragment_map_entries.data(); + fill_map_entries(info.shaders.fragment_constants, fragment_map_entries); + fragment_specialization_info.mapEntryCount = fragment_map_entries.size(); + fragment_specialization_info.pMapEntries = fragment_map_entries.data(); for (auto constant : info.shaders.fragment_constants) { fragment_data.push_back(constant.value); } - fragment_specialization_info.dataSize = - fragment_data.size() * sizeof(int); + fragment_specialization_info.dataSize = fragment_data.size() * sizeof(int); fragment_specialization_info.pData = fragment_data.data(); - fragShaderStageInfo.pSpecializationInfo = - &fragment_specialization_info; + fragShaderStageInfo.pSpecializationInfo = &fragment_specialization_info; } shaderStages.push_back(fragShaderStageInfo); @@ -1030,18 +979,14 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { // fixed functions VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; - vertexInputInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputInfo.pVertexBindingDescriptions = inputs.data(); - vertexInputInfo.vertexBindingDescriptionCount = - static_cast(inputs.size()); + vertexInputInfo.vertexBindingDescriptionCount = static_cast(inputs.size()); vertexInputInfo.pVertexAttributeDescriptions = attributes.data(); - vertexInputInfo.vertexAttributeDescriptionCount = - static_cast(attributes.size()); + vertexInputInfo.vertexAttributeDescriptionCount = static_cast(attributes.size()); VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; - inputAssembly.sType = - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; if (info.rasterization.primitive_type == GFXPrimitiveType::TriangleStrip) @@ -1053,93 +998,82 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { viewportState.scissorCount = 1; VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.lineWidth = 1.0f; switch (info.rasterization.culling_mode) { - case GFXCullingMode::Backface: - rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - break; - case GFXCullingMode::Frontface: - rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT; - break; - case GFXCullingMode::None: - rasterizer.cullMode = VK_CULL_MODE_NONE; + case GFXCullingMode::Backface: + rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; + break; + case GFXCullingMode::Frontface: + rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT; + break; + case GFXCullingMode::None: + rasterizer.cullMode = VK_CULL_MODE_NONE; } switch (info.rasterization.winding_mode) { - case GFXWindingMode::Clockwise: - rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; - break; - case GFXWindingMode::CounterClockwise: - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - break; + case GFXWindingMode::Clockwise: + rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + break; + case GFXWindingMode::CounterClockwise: + rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + break; } if (info.rasterization.polygon_type == GFXPolygonType::Line) rasterizer.polygonMode = VK_POLYGON_MODE_LINE; VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; colorBlendAttachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; if (info.blending.enable_blending) { colorBlendAttachment.blendEnable = VK_TRUE; - colorBlendAttachment.srcColorBlendFactor = - toVkFactor(info.blending.src_rgb); - colorBlendAttachment.dstColorBlendFactor = - toVkFactor(info.blending.dst_rgb); - colorBlendAttachment.srcAlphaBlendFactor = - toVkFactor(info.blending.src_alpha); - colorBlendAttachment.dstAlphaBlendFactor = - toVkFactor(info.blending.dst_alpha); + colorBlendAttachment.srcColorBlendFactor = toVkFactor(info.blending.src_rgb); + colorBlendAttachment.dstColorBlendFactor = toVkFactor(info.blending.dst_rgb); + colorBlendAttachment.srcAlphaBlendFactor = toVkFactor(info.blending.src_alpha); + colorBlendAttachment.dstAlphaBlendFactor = toVkFactor(info.blending.dst_alpha); } VkPipelineColorBlendStateCreateInfo colorBlending = {}; - colorBlending.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlending.attachmentCount = 1; colorBlending.pAttachments = &colorBlendAttachment; VkPipelineDepthStencilStateCreateInfo depthStencil = {}; - depthStencil.sType = - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; if (info.depth.depth_mode != GFXDepthMode::None) { depthStencil.depthTestEnable = VK_TRUE; depthStencil.depthWriteEnable = VK_TRUE; switch (info.depth.depth_mode) { - case GFXDepthMode::Less: - depthStencil.depthCompareOp = VK_COMPARE_OP_LESS; - break; - case GFXDepthMode::LessOrEqual: - depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; - break; - case GFXDepthMode::Greater: - depthStencil.depthCompareOp = VK_COMPARE_OP_GREATER; - break; - case GFXDepthMode::None: - break; + case GFXDepthMode::Less: + depthStencil.depthCompareOp = VK_COMPARE_OP_LESS; + break; + case GFXDepthMode::LessOrEqual: + depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + break; + case GFXDepthMode::Greater: + depthStencil.depthCompareOp = VK_COMPARE_OP_GREATER; + break; + case GFXDepthMode::None: + break; } } - std::vector dynamicStates = {VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - VK_DYNAMIC_STATE_DEPTH_BIAS}; + std::vector dynamicStates = { + VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_DEPTH_BIAS}; VkPipelineDynamicStateCreateInfo dynamicState = {}; dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicState.dynamicStateCount = - static_cast(dynamicStates.size()); + dynamicState.dynamicStateCount = static_cast(dynamicStates.size()); dynamicState.pDynamicStates = dynamicStates.data(); // create push constants @@ -1148,8 +1082,7 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { VkPushConstantRange range; range.offset = pushConstant.offset; range.size = pushConstant.size; - range.stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; pushConstants.push_back(range); } @@ -1163,29 +1096,26 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; switch (binding.type) { - case GFXBindingType::StorageBuffer: - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - break; - case GFXBindingType::Texture: { - descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - pipeline->bindings_marked_as_normal_images.push_back( - binding.binding); - } break; - case GFXBindingType::StorageImage: { - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - pipeline->bindings_marked_as_storage_images.push_back( - binding.binding); - } break; - case GFXBindingType::SampledImage: { - descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - pipeline->bindings_marked_as_sampled_images.push_back( - binding.binding); - } break; - case GFXBindingType::Sampler: - descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; - break; - case GFXBindingType::PushConstant: - break; + case GFXBindingType::StorageBuffer: + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + break; + case GFXBindingType::Texture: { + descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + pipeline->bindings_marked_as_normal_images.push_back(binding.binding); + } break; + case GFXBindingType::StorageImage: { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + pipeline->bindings_marked_as_storage_images.push_back(binding.binding); + } break; + case GFXBindingType::SampledImage: { + descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + pipeline->bindings_marked_as_sampled_images.push_back(binding.binding); + } break; + case GFXBindingType::Sampler: + descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + break; + case GFXBindingType::PushConstant: + break; } VkDescriptorSetLayoutBinding layoutBinding = {}; @@ -1198,26 +1128,21 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { } VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {}; - layoutCreateInfo.sType = - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layoutCreateInfo.bindingCount = - static_cast(layoutBindings.size()); + layoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layoutCreateInfo.bindingCount = static_cast(layoutBindings.size()); layoutCreateInfo.pBindings = layoutBindings.data(); - vkCreateDescriptorSetLayout(device, &layoutCreateInfo, nullptr, - &pipeline->descriptorLayout); + vkCreateDescriptorSetLayout(device, &layoutCreateInfo, nullptr, &pipeline->descriptorLayout); // create layout VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.pushConstantRangeCount = - static_cast(pushConstants.size()); + pipelineLayoutInfo.pushConstantRangeCount = static_cast(pushConstants.size()); pipelineLayoutInfo.pPushConstantRanges = pushConstants.data(); pipelineLayoutInfo.pSetLayouts = &pipeline->descriptorLayout; pipelineLayoutInfo.setLayoutCount = 1; - vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, - &pipeline->layout); + vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipeline->layout); // create pipeline VkGraphicsPipelineCreateInfo pipelineInfo = {}; @@ -1234,31 +1159,25 @@ GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { pipelineInfo.layout = pipeline->layout; if (info.render_pass != nullptr) { - pipelineInfo.renderPass = - ((GFXVulkanRenderPass*)info.render_pass)->handle; + pipelineInfo.renderPass = ((GFXVulkanRenderPass*)info.render_pass)->handle; } else { pipelineInfo.renderPass = native_surfaces[0]->swapchainRenderPass; } - if (info.render_pass != nullptr && - ((GFXVulkanRenderPass*)info.render_pass)->hasDepthAttachment) + if (info.render_pass != nullptr && ((GFXVulkanRenderPass*)info.render_pass)->hasDepthAttachment) pipelineInfo.pDepthStencilState = &depthStencil; - vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, - &pipeline->handle); + vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline->handle); pipeline->label = info.label; - name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, - pipeline->label); - name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, - (uint64_t)pipeline->layout, pipeline->label); + name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, pipeline->label); + name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)pipeline->layout, pipeline->label); return pipeline; } -GFXPipeline* -GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { +GFXPipeline* GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { auto pipeline = new GFXVulkanPipeline(); vkDeviceWaitIdle(device); @@ -1270,23 +1189,17 @@ GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { if (use_shader_source) { auto shader_vector = info.compute_src.as_bytecode(); - compute_module = createShaderModule( - shader_vector.data(), shader_vector.size() * sizeof(uint32_t)); + compute_module = createShaderModule(shader_vector.data(), shader_vector.size() * sizeof(uint32_t)); } else { - auto shader = - prism::open_file(prism::base_domain / - (info.compute_src.as_path().string() + ".spv"), - true); + auto shader = prism::open_file(prism::base_domain / (info.compute_src.as_path().string() + ".spv"), true); shader->read_all(); - compute_module = - createShaderModule(shader->cast_data(), shader->size()); + compute_module = createShaderModule(shader->cast_data(), shader->size()); } if (!use_shader_source) - name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, - (uint64_t)compute_module, - info.compute_src.as_path().string()); + name_object( + device, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)compute_module, info.compute_src.as_path().string()); VkPipelineShaderStageCreateInfo shaderStageInfo = {}; shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -1314,29 +1227,26 @@ GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; switch (binding.type) { - case GFXBindingType::StorageBuffer: - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - break; - case GFXBindingType::Texture: { - descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - pipeline->bindings_marked_as_normal_images.push_back( - binding.binding); - } break; - case GFXBindingType::StorageImage: { - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - pipeline->bindings_marked_as_storage_images.push_back( - binding.binding); - } break; - case GFXBindingType::SampledImage: { - descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - pipeline->bindings_marked_as_sampled_images.push_back( - binding.binding); - } break; - case GFXBindingType::Sampler: - descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; - break; - case GFXBindingType::PushConstant: - break; + case GFXBindingType::StorageBuffer: + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + break; + case GFXBindingType::Texture: { + descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + pipeline->bindings_marked_as_normal_images.push_back(binding.binding); + } break; + case GFXBindingType::StorageImage: { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + pipeline->bindings_marked_as_storage_images.push_back(binding.binding); + } break; + case GFXBindingType::SampledImage: { + descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + pipeline->bindings_marked_as_sampled_images.push_back(binding.binding); + } break; + case GFXBindingType::Sampler: + descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + break; + case GFXBindingType::PushConstant: + break; } VkDescriptorSetLayoutBinding layoutBinding = {}; @@ -1349,26 +1259,21 @@ GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { } VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {}; - layoutCreateInfo.sType = - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layoutCreateInfo.bindingCount = - static_cast(layoutBindings.size()); + layoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layoutCreateInfo.bindingCount = static_cast(layoutBindings.size()); layoutCreateInfo.pBindings = layoutBindings.data(); - vkCreateDescriptorSetLayout(device, &layoutCreateInfo, nullptr, - &pipeline->descriptorLayout); + vkCreateDescriptorSetLayout(device, &layoutCreateInfo, nullptr, &pipeline->descriptorLayout); // create layout VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.pushConstantRangeCount = - static_cast(pushConstants.size()); + pipelineLayoutInfo.pushConstantRangeCount = static_cast(pushConstants.size()); pipelineLayoutInfo.pPushConstantRanges = pushConstants.data(); pipelineLayoutInfo.pSetLayouts = &pipeline->descriptorLayout; pipelineLayoutInfo.setLayoutCount = 1; - vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, - &pipeline->layout); + vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipeline->layout); // create pipeline VkComputePipelineCreateInfo pipelineInfo = {}; @@ -1376,15 +1281,12 @@ GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { pipelineInfo.stage = shaderStageInfo; pipelineInfo.layout = pipeline->layout; - vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, - &pipeline->handle); + vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline->handle); pipeline->label = info.label; - name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, - pipeline->label); - name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, - (uint64_t)pipeline->layout, pipeline->label); + name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, pipeline->label); + name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)pipeline->layout, pipeline->label); return pipeline; } @@ -1392,8 +1294,7 @@ GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { GFXSize GFXVulkan::get_alignment(GFXSize size) { VkPhysicalDeviceProperties properties; vkGetPhysicalDeviceProperties(physicalDevice, &properties); - VkDeviceSize minUboAlignment = - properties.limits.minStorageBufferOffsetAlignment; + VkDeviceSize minUboAlignment = properties.limits.minStorageBufferOffsetAlignment; return (size + minUboAlignment / 2) & ~int(minUboAlignment - 1); } @@ -1412,16 +1313,12 @@ GFXCommandBuffer* GFXVulkan::acquire_command_buffer(bool for_presentation_use) { return cmdbuf; } else { - native_surfaces[0] - ->gfx_command_buffers[native_surfaces[0]->currentFrame] - ->commands.clear(); - return native_surfaces[0] - ->gfx_command_buffers[native_surfaces[0]->currentFrame]; + native_surfaces[0]->gfx_command_buffers[native_surfaces[0]->currentFrame]->commands.clear(); + return native_surfaces[0]->gfx_command_buffers[native_surfaces[0]->currentFrame]; } } -void GFXVulkan::submit(GFXCommandBuffer* command_buffer, - const platform::window_ptr identifier) { +void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_ptr identifier) { NativeSurface* current_surface = nullptr; for (auto surface : native_surfaces) { if (surface->identifier == identifier) @@ -1431,16 +1328,19 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, uint32_t imageIndex = 0; if (identifier != nullptr && current_surface != nullptr) { vkWaitForFences( - device, 1, + device, + 1, ¤t_surface->inFlightFences[current_surface->currentFrame], - VK_TRUE, std::numeric_limits::max()); + VK_TRUE, + std::numeric_limits::max()); VkResult result = vkAcquireNextImageKHR( - device, current_surface->swapchain, + device, + current_surface->swapchain, std::numeric_limits::max(), - current_surface - ->imageAvailableSemaphores[current_surface->currentFrame], - VK_NULL_HANDLE, &imageIndex); + current_surface->imageAvailableSemaphores[current_surface->currentFrame], + VK_NULL_HANDLE, + &imageIndex); if (result == VK_ERROR_OUT_OF_DATE_KHR) return; } @@ -1464,29 +1364,27 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, uint64_t lastDescriptorHash = 0; bool is_compute = false; - const auto try_bind_descriptor = [cmd, this, ¤tPipeline, - &lastDescriptorHash, - &is_compute]() -> bool { + const auto try_bind_descriptor = [cmd, this, ¤tPipeline, &lastDescriptorHash, &is_compute]() -> bool { if (currentPipeline == nullptr) return false; if (lastDescriptorHash != getDescriptorHash(currentPipeline)) { - if (!currentPipeline->cachedDescriptorSets.count( - getDescriptorHash(currentPipeline))) - cacheDescriptorState(currentPipeline, - currentPipeline->descriptorLayout); + if (!currentPipeline->cachedDescriptorSets.count(getDescriptorHash(currentPipeline))) + cacheDescriptorState(currentPipeline, currentPipeline->descriptorLayout); - auto& descriptor_set = - currentPipeline - ->cachedDescriptorSets[getDescriptorHash(currentPipeline)]; + auto& descriptor_set = currentPipeline->cachedDescriptorSets[getDescriptorHash(currentPipeline)]; if (descriptor_set == VK_NULL_HANDLE) return false; vkCmdBindDescriptorSets( cmd, - is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE - : VK_PIPELINE_BIND_POINT_GRAPHICS, - currentPipeline->layout, 0, 1, &descriptor_set, 0, nullptr); + is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, + currentPipeline->layout, + 0, + 1, + &descriptor_set, + 0, + nullptr); lastDescriptorHash = getDescriptorHash(currentPipeline); } @@ -1496,429 +1394,459 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, for (const auto& command : command_buffer->commands) { switch (command.type) { - case GFXCommandType::SetRenderPass: { - // end the previous render pass - if (currentRenderPass != VK_NULL_HANDLE) { - vkCmdEndRenderPass(cmd); - } + case GFXCommandType::SetRenderPass: { + // end the previous render pass + if (currentRenderPass != VK_NULL_HANDLE) { + vkCmdEndRenderPass(cmd); + } - auto renderPass = - (GFXVulkanRenderPass*)command.data.set_render_pass.render_pass; - auto framebuffer = - (GFXVulkanFramebuffer*)command.data.set_render_pass.framebuffer; + auto renderPass = (GFXVulkanRenderPass*)command.data.set_render_pass.render_pass; + auto framebuffer = (GFXVulkanFramebuffer*)command.data.set_render_pass.framebuffer; - if (renderPass != nullptr) { - currentRenderPass = renderPass->handle; - } else { - currentRenderPass = current_surface->swapchainRenderPass; - } + if (renderPass != nullptr) { + currentRenderPass = renderPass->handle; + } else { + currentRenderPass = current_surface->swapchainRenderPass; + } - VkRenderPassBeginInfo renderPassInfo = {}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassInfo.renderPass = currentRenderPass; + VkRenderPassBeginInfo renderPassInfo = {}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassInfo.renderPass = currentRenderPass; - if (framebuffer != nullptr) { - renderPassInfo.framebuffer = framebuffer->handle; + if (framebuffer != nullptr) { + renderPassInfo.framebuffer = framebuffer->handle; + VkViewport viewport = {}; + viewport.y = static_cast(framebuffer->height); + viewport.width = static_cast(framebuffer->width); + viewport.height = -static_cast(framebuffer->height); + viewport.maxDepth = 1.0f; + + vkCmdSetViewport(cmd, 0, 1, &viewport); + + VkRect2D scissor = {}; + scissor.extent.width = framebuffer->width; + scissor.extent.height = framebuffer->height; + + vkCmdSetScissor(cmd, 0, 1, &scissor); + } else if (current_surface != nullptr) { + renderPassInfo.framebuffer = current_surface->swapchainFramebuffers[imageIndex]; + + VkViewport viewport = {}; + viewport.y = static_cast(current_surface->surfaceHeight); + viewport.width = static_cast(current_surface->surfaceWidth); + viewport.height = -static_cast(current_surface->surfaceHeight); + viewport.maxDepth = 1.0f; + + vkCmdSetViewport(cmd, 0, 1, &viewport); + + VkRect2D scissor = {}; + scissor.extent.width = current_surface->surfaceWidth; + scissor.extent.height = current_surface->surfaceHeight; + + vkCmdSetScissor(cmd, 0, 1, &scissor); + } + + renderPassInfo.renderArea.offset = { + command.data.set_render_pass.render_area.offset.x, + command.data.set_render_pass.render_area.offset.y}; + renderPassInfo.renderArea.extent = { + command.data.set_render_pass.render_area.extent.width, + command.data.set_render_pass.render_area.extent.height}; + + std::vector clearColors; + if (renderPass != nullptr) { + clearColors.resize(renderPass->numAttachments); + } else { + clearColors.resize(1); + } + + clearColors[0].color.float32[0] = command.data.set_render_pass.clear_color.r; + clearColors[0].color.float32[1] = command.data.set_render_pass.clear_color.g; + clearColors[0].color.float32[2] = command.data.set_render_pass.clear_color.b; + clearColors[0].color.float32[3] = command.data.set_render_pass.clear_color.a; + + if (renderPass != nullptr) { + if (renderPass->depth_attachment != -1) + clearColors[renderPass->depth_attachment].depthStencil.depth = 1.0f; + } + + renderPassInfo.clearValueCount = static_cast(clearColors.size()); + renderPassInfo.pClearValues = clearColors.data(); + + vkCmdBeginRenderPass(cmd, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); + + currentPipeline = nullptr; + } break; + case GFXCommandType::SetGraphicsPipeline: { + currentPipeline = (GFXVulkanPipeline*)command.data.set_graphics_pipeline.pipeline; + if (currentPipeline != nullptr) { + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, currentPipeline->handle); + + resetDescriptorState(); + lastDescriptorHash = 0; + } + + is_compute = false; + } break; + case GFXCommandType::SetComputePipeline: { + currentPipeline = (GFXVulkanPipeline*)command.data.set_compute_pipeline.pipeline; + if (currentPipeline != nullptr) { + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, currentPipeline->handle); + + resetDescriptorState(); + lastDescriptorHash = 0; + } + + is_compute = true; + } break; + case GFXCommandType::SetVertexBuffer: { + VkBuffer buffer = ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer)->handle; + VkDeviceSize offset = command.data.set_vertex_buffer.offset; + + vkCmdBindVertexBuffers(cmd, command.data.set_vertex_buffer.index, 1, &buffer, &offset); + } break; + case GFXCommandType::SetIndexBuffer: { + VkIndexType indexType = VK_INDEX_TYPE_UINT32; + if (command.data.set_index_buffer.index_type == IndexType::UINT16) + indexType = VK_INDEX_TYPE_UINT16; + + vkCmdBindIndexBuffer( + cmd, ((GFXVulkanBuffer*)command.data.set_index_buffer.buffer)->handle, 0, indexType); + } break; + case GFXCommandType::SetPushConstant: { + VkShaderStageFlags applicableStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + if (is_compute) + applicableStages = VK_SHADER_STAGE_COMPUTE_BIT; + + if (currentPipeline != nullptr) + vkCmdPushConstants( + cmd, + currentPipeline->layout, + applicableStages, + 0, + command.data.set_push_constant.size, + command.data.set_push_constant.bytes.data()); + } break; + case GFXCommandType::BindShaderBuffer: { + BoundShaderBuffer bsb; + bsb.buffer = command.data.bind_shader_buffer.buffer; + bsb.offset = command.data.bind_shader_buffer.offset; + bsb.size = command.data.bind_shader_buffer.size; + + boundShaderBuffers[command.data.bind_shader_buffer.index] = bsb; + } break; + case GFXCommandType::BindTexture: { + boundTextures[command.data.bind_texture.index] = command.data.bind_texture.texture; + } break; + case GFXCommandType::BindSampler: { + boundSamplers[command.data.bind_sampler.index] = command.data.bind_sampler.sampler; + } break; + case GFXCommandType::Draw: { + if (try_bind_descriptor()) { + vkCmdDraw( + cmd, + command.data.draw.vertex_count, + command.data.draw.instance_count, + command.data.draw.vertex_offset, + command.data.draw.base_instance); + } + } break; + case GFXCommandType::DrawIndexed: { + if (try_bind_descriptor()) { + vkCmdDrawIndexed( + cmd, + command.data.draw_indexed.index_count, + 1, + command.data.draw_indexed.first_index, + command.data.draw_indexed.vertex_offset, + command.data.draw_indexed.base_instance); + } + } break; + case GFXCommandType::SetDepthBias: { + vkCmdSetDepthBias( + cmd, + command.data.set_depth_bias.constant, + command.data.set_depth_bias.clamp, + command.data.set_depth_bias.slope_factor); + } break; + case GFXCommandType::CopyTexture: { + auto src = (GFXVulkanTexture*)command.data.copy_texture.src; + auto dst = (GFXVulkanTexture*)command.data.copy_texture.dst; + + const int slice_offset = command.data.copy_texture.to_slice + command.data.copy_texture.to_layer * 6; + + VkImageSubresourceRange dstRange = {}; + dstRange.layerCount = 1; + dstRange.baseArrayLayer = slice_offset; + dstRange.baseMipLevel = command.data.copy_texture.to_level; + dstRange.levelCount = 1; + dstRange.aspectMask = dst->aspect; + + inlineTransitionImageLayout( + cmd, + src->handle, + src->format, + src->aspect, + src->range, + src->layout, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + inlineTransitionImageLayout( + cmd, + dst->handle, + dst->format, + dst->aspect, + dstRange, + dst->layout, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkImageCopy region = {}; + region.extent.width = static_cast(command.data.copy_texture.width); + region.extent.height = static_cast(command.data.copy_texture.height); + region.extent.depth = 1.0f; + + region.srcSubresource.layerCount = 1; + region.srcSubresource.aspectMask = src->aspect; + + region.dstSubresource.baseArrayLayer = dstRange.baseArrayLayer; + region.dstSubresource.mipLevel = dstRange.baseMipLevel; + region.dstSubresource.aspectMask = dstRange.aspectMask; + region.dstSubresource.layerCount = dstRange.layerCount; + + vkCmdCopyImage( + cmd, + src->handle, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst->handle, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + ®ion); + + inlineTransitionImageLayout( + cmd, + src->handle, + src->format, + src->aspect, + src->range, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + src->layout); + inlineTransitionImageLayout( + cmd, + dst->handle, + dst->format, + dst->aspect, + dstRange, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + dst->layout); + } break; + case GFXCommandType::SetViewport: { VkViewport viewport = {}; - viewport.y = static_cast(framebuffer->height); - viewport.width = static_cast(framebuffer->width); - viewport.height = -static_cast(framebuffer->height); + viewport.x = command.data.set_viewport.viewport.x; + viewport.y = command.data.set_viewport.viewport.height - command.data.set_viewport.viewport.y; + viewport.width = command.data.set_viewport.viewport.width; + viewport.height = -command.data.set_viewport.viewport.height; viewport.maxDepth = 1.0f; vkCmdSetViewport(cmd, 0, 1, &viewport); VkRect2D scissor = {}; - scissor.extent.width = framebuffer->width; - scissor.extent.height = framebuffer->height; + scissor.extent.width = command.data.set_viewport.viewport.width; + scissor.extent.height = command.data.set_viewport.viewport.height; vkCmdSetScissor(cmd, 0, 1, &scissor); - } else if (current_surface != nullptr) { - renderPassInfo.framebuffer = - current_surface->swapchainFramebuffers[imageIndex]; - - VkViewport viewport = {}; - viewport.y = static_cast(current_surface->surfaceHeight); - viewport.width = - static_cast(current_surface->surfaceWidth); - viewport.height = - -static_cast(current_surface->surfaceHeight); - viewport.maxDepth = 1.0f; - - vkCmdSetViewport(cmd, 0, 1, &viewport); - + } break; + case GFXCommandType::SetScissor: { VkRect2D scissor = {}; - scissor.extent.width = current_surface->surfaceWidth; - scissor.extent.height = current_surface->surfaceHeight; + scissor.offset.x = command.data.set_scissor.rect.offset.x; + scissor.offset.y = command.data.set_scissor.rect.offset.y; + scissor.extent.width = command.data.set_scissor.rect.extent.width; + scissor.extent.height = command.data.set_scissor.rect.extent.height; vkCmdSetScissor(cmd, 0, 1, &scissor); - } - - renderPassInfo.renderArea.offset = { - command.data.set_render_pass.render_area.offset.x, - command.data.set_render_pass.render_area.offset.y}; - renderPassInfo.renderArea.extent = { - command.data.set_render_pass.render_area.extent.width, - command.data.set_render_pass.render_area.extent.height}; - - std::vector clearColors; - if (renderPass != nullptr) { - clearColors.resize(renderPass->numAttachments); - } else { - clearColors.resize(1); - } - - clearColors[0].color.float32[0] = - command.data.set_render_pass.clear_color.r; - clearColors[0].color.float32[1] = - command.data.set_render_pass.clear_color.g; - clearColors[0].color.float32[2] = - command.data.set_render_pass.clear_color.b; - clearColors[0].color.float32[3] = - command.data.set_render_pass.clear_color.a; - - if (renderPass != nullptr) { - if (renderPass->depth_attachment != -1) - clearColors[renderPass->depth_attachment] - .depthStencil.depth = 1.0f; - } - - renderPassInfo.clearValueCount = - static_cast(clearColors.size()); - renderPassInfo.pClearValues = clearColors.data(); - - vkCmdBeginRenderPass(cmd, &renderPassInfo, - VK_SUBPASS_CONTENTS_INLINE); - - currentPipeline = nullptr; - } break; - case GFXCommandType::SetGraphicsPipeline: { - currentPipeline = - (GFXVulkanPipeline*)command.data.set_graphics_pipeline.pipeline; - if (currentPipeline != nullptr) { - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, - currentPipeline->handle); - - resetDescriptorState(); - lastDescriptorHash = 0; - } - - is_compute = false; - } break; - case GFXCommandType::SetComputePipeline: { - currentPipeline = - (GFXVulkanPipeline*)command.data.set_compute_pipeline.pipeline; - if (currentPipeline != nullptr) { - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, - currentPipeline->handle); - - resetDescriptorState(); - lastDescriptorHash = 0; - } - - is_compute = true; - } break; - case GFXCommandType::SetVertexBuffer: { - VkBuffer buffer = - ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer) - ->handle; - VkDeviceSize offset = command.data.set_vertex_buffer.offset; - - vkCmdBindVertexBuffers(cmd, command.data.set_vertex_buffer.index, 1, - &buffer, &offset); - } break; - case GFXCommandType::SetIndexBuffer: { - VkIndexType indexType = VK_INDEX_TYPE_UINT32; - if (command.data.set_index_buffer.index_type == IndexType::UINT16) - indexType = VK_INDEX_TYPE_UINT16; - - vkCmdBindIndexBuffer( - cmd, - ((GFXVulkanBuffer*)command.data.set_index_buffer.buffer) - ->handle, - 0, indexType); - } break; - case GFXCommandType::SetPushConstant: { - VkShaderStageFlags applicableStages = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; - if (is_compute) - applicableStages = VK_SHADER_STAGE_COMPUTE_BIT; - - if (currentPipeline != nullptr) - vkCmdPushConstants(cmd, currentPipeline->layout, - applicableStages, 0, - command.data.set_push_constant.size, - command.data.set_push_constant.bytes.data()); - } break; - case GFXCommandType::BindShaderBuffer: { - BoundShaderBuffer bsb; - bsb.buffer = command.data.bind_shader_buffer.buffer; - bsb.offset = command.data.bind_shader_buffer.offset; - bsb.size = command.data.bind_shader_buffer.size; - - boundShaderBuffers[command.data.bind_shader_buffer.index] = bsb; - } break; - case GFXCommandType::BindTexture: { - boundTextures[command.data.bind_texture.index] = - command.data.bind_texture.texture; - } break; - case GFXCommandType::BindSampler: { - boundSamplers[command.data.bind_sampler.index] = - command.data.bind_sampler.sampler; - } break; - case GFXCommandType::Draw: { - if (try_bind_descriptor()) { - vkCmdDraw(cmd, command.data.draw.vertex_count, - command.data.draw.instance_count, - command.data.draw.vertex_offset, - command.data.draw.base_instance); - } - } break; - case GFXCommandType::DrawIndexed: { - if (try_bind_descriptor()) { - vkCmdDrawIndexed(cmd, command.data.draw_indexed.index_count, 1, - command.data.draw_indexed.first_index, - command.data.draw_indexed.vertex_offset, - command.data.draw_indexed.base_instance); - } - } break; - case GFXCommandType::SetDepthBias: { - vkCmdSetDepthBias(cmd, command.data.set_depth_bias.constant, - command.data.set_depth_bias.clamp, - command.data.set_depth_bias.slope_factor); - } break; - case GFXCommandType::CopyTexture: { - auto src = (GFXVulkanTexture*)command.data.copy_texture.src; - auto dst = (GFXVulkanTexture*)command.data.copy_texture.dst; - - const int slice_offset = command.data.copy_texture.to_slice + - command.data.copy_texture.to_layer * 6; - - VkImageSubresourceRange dstRange = {}; - dstRange.layerCount = 1; - dstRange.baseArrayLayer = slice_offset; - dstRange.baseMipLevel = command.data.copy_texture.to_level; - dstRange.levelCount = 1; - dstRange.aspectMask = dst->aspect; - - inlineTransitionImageLayout(cmd, src->handle, src->format, - src->aspect, src->range, src->layout, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - inlineTransitionImageLayout(cmd, dst->handle, dst->format, - dst->aspect, dstRange, dst->layout, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - VkImageCopy region = {}; - region.extent.width = - static_cast(command.data.copy_texture.width); - region.extent.height = - static_cast(command.data.copy_texture.height); - region.extent.depth = 1.0f; - - region.srcSubresource.layerCount = 1; - region.srcSubresource.aspectMask = src->aspect; - - region.dstSubresource.baseArrayLayer = dstRange.baseArrayLayer; - region.dstSubresource.mipLevel = dstRange.baseMipLevel; - region.dstSubresource.aspectMask = dstRange.aspectMask; - region.dstSubresource.layerCount = dstRange.layerCount; - - vkCmdCopyImage(cmd, src->handle, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst->handle, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - - inlineTransitionImageLayout( - cmd, src->handle, src->format, src->aspect, src->range, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src->layout); - inlineTransitionImageLayout( - cmd, dst->handle, dst->format, dst->aspect, dstRange, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst->layout); - } break; - case GFXCommandType::SetViewport: { - VkViewport viewport = {}; - viewport.x = command.data.set_viewport.viewport.x; - viewport.y = command.data.set_viewport.viewport.height - - command.data.set_viewport.viewport.y; - viewport.width = command.data.set_viewport.viewport.width; - viewport.height = -command.data.set_viewport.viewport.height; - viewport.maxDepth = 1.0f; - - vkCmdSetViewport(cmd, 0, 1, &viewport); - - VkRect2D scissor = {}; - scissor.extent.width = command.data.set_viewport.viewport.width; - scissor.extent.height = command.data.set_viewport.viewport.height; - - vkCmdSetScissor(cmd, 0, 1, &scissor); - } break; - case GFXCommandType::SetScissor: { - VkRect2D scissor = {}; - scissor.offset.x = command.data.set_scissor.rect.offset.x; - scissor.offset.y = command.data.set_scissor.rect.offset.y; - scissor.extent.width = command.data.set_scissor.rect.extent.width; - scissor.extent.height = command.data.set_scissor.rect.extent.height; - - vkCmdSetScissor(cmd, 0, 1, &scissor); - } break; - case GFXCommandType::EndRenderPass: { - if (currentRenderPass != nullptr) { - vkCmdEndRenderPass(cmd); - currentRenderPass = nullptr; - } - } break; - case GFXCommandType::Dispatch: { - if (try_bind_descriptor()) { - for (auto binding : - currentPipeline->bindings_marked_as_storage_images) { - auto tex = (GFXVulkanTexture*)boundTextures[binding]; - inlineTransitionImageLayout( - cmd, tex->handle, tex->format, tex->aspect, tex->range, - tex->current_layout, VK_IMAGE_LAYOUT_GENERAL); + } break; + case GFXCommandType::EndRenderPass: { + if (currentRenderPass != nullptr) { + vkCmdEndRenderPass(cmd); + currentRenderPass = nullptr; } + } break; + case GFXCommandType::Dispatch: { + if (try_bind_descriptor()) { + for (auto binding : currentPipeline->bindings_marked_as_storage_images) { + auto tex = (GFXVulkanTexture*)boundTextures[binding]; + inlineTransitionImageLayout( + cmd, + tex->handle, + tex->format, + tex->aspect, + tex->range, + tex->current_layout, + VK_IMAGE_LAYOUT_GENERAL); + } - vkCmdDispatch(cmd, command.data.dispatch.group_count_x, - command.data.dispatch.group_count_y, - command.data.dispatch.group_count_z); + vkCmdDispatch( + cmd, + command.data.dispatch.group_count_x, + command.data.dispatch.group_count_y, + command.data.dispatch.group_count_z); - for (auto binding : - currentPipeline->bindings_marked_as_storage_images) { - auto tex = (GFXVulkanTexture*)boundTextures[binding]; + for (auto binding : currentPipeline->bindings_marked_as_storage_images) { + auto tex = (GFXVulkanTexture*)boundTextures[binding]; - const auto check_flag = [](const GFXTextureUsage usage, - const GFXTextureUsage flag) { - return (usage & flag) == flag; - }; + const auto check_flag = [](const GFXTextureUsage usage, const GFXTextureUsage flag) { + return (usage & flag) == flag; + }; - VkImageLayout next_layout = tex->layout; - if (check_flag(tex->usage, GFXTextureUsage::Sampled) && - !check_flag(tex->usage, GFXTextureUsage::Attachment)) - next_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkImageLayout next_layout = tex->layout; + if (check_flag(tex->usage, GFXTextureUsage::Sampled) && + !check_flag(tex->usage, GFXTextureUsage::Attachment)) + next_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - inlineTransitionImageLayout( - cmd, tex->handle, tex->format, tex->aspect, tex->range, - VK_IMAGE_LAYOUT_GENERAL, next_layout); + inlineTransitionImageLayout( + cmd, + tex->handle, + tex->format, + tex->aspect, + tex->range, + VK_IMAGE_LAYOUT_GENERAL, + next_layout); - tex->current_layout = next_layout; + tex->current_layout = next_layout; + } } - } - } break; - case GFXCommandType::PushGroup: { - VkDebugUtilsLabelEXT marker_info = {}; - marker_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; - marker_info.pLabelName = command.data.push_group.name.data(); + } break; + case GFXCommandType::PushGroup: { + VkDebugUtilsLabelEXT marker_info = {}; + marker_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + marker_info.pLabelName = command.data.push_group.name.data(); - cmd_debug_marker_begin(device, cmd, marker_info); - } break; - case GFXCommandType::PopGroup: { - cmd_debug_marker_end(device, cmd); - } break; - case GFXCommandType::GenerateMipmaps: { - auto texture = dynamic_cast( - command.data.generate_mipmaps.texture); + cmd_debug_marker_begin(device, cmd, marker_info); + } break; + case GFXCommandType::PopGroup: { + cmd_debug_marker_end(device, cmd); + } break; + case GFXCommandType::GenerateMipmaps: { + auto texture = dynamic_cast(command.data.generate_mipmaps.texture); - for (int l = 0; l < texture->range.layerCount; l++) { - int mip_width = texture->width; - int mip_height = texture->height; + for (int l = 0; l < texture->range.layerCount; l++) { + int mip_width = texture->width; + int mip_height = texture->height; - // prepare source level - { + // prepare source level + { + VkImageSubresourceRange range = {}; + range.layerCount = 1; + range.baseArrayLayer = l; + range.baseMipLevel = 0; + range.levelCount = 1; + range.aspectMask = texture->aspect; + + // change previous mip level to SRC for copy + inlineTransitionImageLayout( + cmd, + texture->handle, + texture->format, + texture->aspect, + range, + texture->layout, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + } + + for (int i = 1; i < command.data.generate_mipmaps.mip_count; i++) { + VkImageSubresourceRange range = {}; + range.layerCount = 1; + range.baseArrayLayer = l; + range.baseMipLevel = i; + range.levelCount = 1; + range.aspectMask = texture->aspect; + + // change mip level to DST for copy + inlineTransitionImageLayout( + cmd, + texture->handle, + texture->format, + texture->aspect, + range, + texture->layout, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkImageBlit blit = {}; + blit.srcOffsets[1] = {mip_width, mip_height, 1}; + blit.srcSubresource.aspectMask = texture->aspect; + blit.srcSubresource.mipLevel = i - 1; + blit.srcSubresource.baseArrayLayer = l; + blit.srcSubresource.layerCount = 1; + + blit.dstOffsets[1] = { + mip_width > 1 ? mip_width / 2 : 1, mip_height > 1 ? mip_height / 2 : 1, 1}; + blit.dstSubresource.aspectMask = texture->aspect; + blit.dstSubresource.mipLevel = i; + blit.dstSubresource.baseArrayLayer = l; + blit.dstSubresource.layerCount = 1; + + // blit from src->dst + vkCmdBlitImage( + cmd, + texture->handle, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + texture->handle, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + &blit, + VK_FILTER_LINEAR); + + // change THIS mip level to SRC because we will use it in + // the next for copying + inlineTransitionImageLayout( + cmd, + texture->handle, + texture->format, + texture->aspect, + range, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + if (mip_width > 1) + mip_width /= 2; + + if (mip_height > 1) + mip_height /= 2; + } + + // transitions all from src->previous layout VkImageSubresourceRange range = {}; range.layerCount = 1; range.baseArrayLayer = l; range.baseMipLevel = 0; - range.levelCount = 1; + range.levelCount = command.data.generate_mipmaps.mip_count; range.aspectMask = texture->aspect; - // change previous mip level to SRC for copy inlineTransitionImageLayout( - cmd, texture->handle, texture->format, texture->aspect, - range, texture->layout, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + cmd, + texture->handle, + texture->format, + texture->aspect, + range, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + texture->layout); } - - for (int i = 1; i < command.data.generate_mipmaps.mip_count; - i++) { - VkImageSubresourceRange range = {}; - range.layerCount = 1; - range.baseArrayLayer = l; - range.baseMipLevel = i; - range.levelCount = 1; - range.aspectMask = texture->aspect; - - // change mip level to DST for copy - inlineTransitionImageLayout( - cmd, texture->handle, texture->format, texture->aspect, - range, texture->layout, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - VkImageBlit blit = {}; - blit.srcOffsets[1] = {mip_width, mip_height, 1}; - blit.srcSubresource.aspectMask = texture->aspect; - blit.srcSubresource.mipLevel = i - 1; - blit.srcSubresource.baseArrayLayer = l; - blit.srcSubresource.layerCount = 1; - - blit.dstOffsets[1] = {mip_width > 1 ? mip_width / 2 : 1, - mip_height > 1 ? mip_height / 2 : 1, - 1}; - blit.dstSubresource.aspectMask = texture->aspect; - blit.dstSubresource.mipLevel = i; - blit.dstSubresource.baseArrayLayer = l; - blit.dstSubresource.layerCount = 1; - - // blit from src->dst - vkCmdBlitImage(cmd, texture->handle, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - texture->handle, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, - &blit, VK_FILTER_LINEAR); - - // change THIS mip level to SRC because we will use it in - // the next for copying - inlineTransitionImageLayout( - cmd, texture->handle, texture->format, texture->aspect, - range, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - - if (mip_width > 1) - mip_width /= 2; - - if (mip_height > 1) - mip_height /= 2; - } - - // transitions all from src->previous layout - VkImageSubresourceRange range = {}; - range.layerCount = 1; - range.baseArrayLayer = l; - range.baseMipLevel = 0; - range.levelCount = command.data.generate_mipmaps.mip_count; - range.aspectMask = texture->aspect; - - inlineTransitionImageLayout( - cmd, texture->handle, texture->format, texture->aspect, - range, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - texture->layout); - } - } break; - case GFXCommandType::MemoryBarrier: - { - vkCmdPipelineBarrier(cmd, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - 0, - 0, - nullptr, - 0, - 0, - 0, - nullptr); - } - break; - default: - prism::log("Unhandled GFX Command Type {}", - utility::enum_to_string(command.type)); - break; + } break; + case GFXCommandType::MemoryBarrier: { + vkCmdPipelineBarrier( + cmd, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, + 0, + nullptr, + 0, + 0, + 0, + nullptr); + } break; + default: + prism::log("Unhandled GFX Command Type {}", utility::enum_to_string(command.type)); + break; } } @@ -1941,31 +1869,22 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkSemaphore waitSemaphores[] = { - current_surface - ->imageAvailableSemaphores[current_surface->currentFrame]}; - VkPipelineStageFlags waitStages[] = { - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSemaphore waitSemaphores[] = {current_surface->imageAvailableSemaphores[current_surface->currentFrame]}; + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmd; - VkSemaphore signalSemaphores[] = { - current_surface - ->renderFinishedSemaphores[current_surface->currentFrame]}; + VkSemaphore signalSemaphores[] = {current_surface->renderFinishedSemaphores[current_surface->currentFrame]}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; - vkResetFences( - device, 1, - ¤t_surface->inFlightFences[current_surface->currentFrame]); + vkResetFences(device, 1, ¤t_surface->inFlightFences[current_surface->currentFrame]); if (vkQueueSubmit( - graphicsQueue, 1, &submitInfo, - current_surface - ->inFlightFences[current_surface->currentFrame]) != + graphicsQueue, 1, &submitInfo, current_surface->inFlightFences[current_surface->currentFrame]) != VK_SUCCESS) return; @@ -1982,12 +1901,13 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, vkQueuePresentKHR(presentQueue, &presentInfo); - current_surface->currentFrame = - (current_surface->currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; + current_surface->currentFrame = (current_surface->currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; } } -const char* GFXVulkan::get_name() { return "Vulkan"; } +const char* GFXVulkan::get_name() { + return "Vulkan"; +} bool GFXVulkan::supports_feature(const GFXFeature feature) { if (feature == GFXFeature::CubemapArray) @@ -1997,14 +1917,14 @@ bool GFXVulkan::supports_feature(const GFXFeature feature) { } VkResult CreateDebugUtilsMessengerEXT( - VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, + VkInstance instance, + const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pCallback) { // Note: It seems that static_cast<...> doesn't work. Use the C-style forced // cast. - auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( - instance, "vkCreateDebugUtilsMessengerEXT"); + auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); if (func != nullptr) { return func(instance, pCreateInfo, pAllocator, pCallback); } else { @@ -2012,16 +1932,12 @@ VkResult CreateDebugUtilsMessengerEXT( } } -void GFXVulkan::createInstance(std::vector layers, - std::vector extensions) { +void GFXVulkan::createInstance(std::vector layers, std::vector extensions) { VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = {}; - debugCreateInfo.sType = - VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; debugCreateInfo.messageSeverity = - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - debugCreateInfo.messageType = - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + debugCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; debugCreateInfo.pfnUserCallback = DebugCallback; VkApplicationInfo appInfo = {}; @@ -2044,8 +1960,7 @@ void GFXVulkan::createInstance(std::vector layers, vkCreateInstance(&createInfo, nullptr, &instance); VkDebugUtilsMessengerEXT callback; - CreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, nullptr, - &callback); + CreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, nullptr, &callback); } void GFXVulkan::createLogicalDevice(std::vector extensions) { @@ -2066,12 +1981,10 @@ void GFXVulkan::createLogicalDevice(std::vector extensions) { physicalDevice = devices[0]; uint32_t extensionCount = 0; - vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, - &extensionCount, nullptr); + vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, nullptr); std::vector extensionProperties(extensionCount); - vkEnumerateDeviceExtensionProperties( - physicalDevice, nullptr, &extensionCount, extensionProperties.data()); + vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, extensionProperties.data()); // we want to choose the portability subset on platforms that // support it, this is a requirement of the portability spec @@ -2084,17 +1997,14 @@ void GFXVulkan::createLogicalDevice(std::vector extensions) { // create logical device uint32_t queueFamilyCount = 0; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, - nullptr); + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr); std::vector queueFamilies(queueFamilyCount); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, - queueFamilies.data()); + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data()); int i = 0; for (const auto& queueFamily : queueFamilies) { - if (queueFamily.queueCount > 0 && - queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { graphicsFamilyIndex = i; } @@ -2144,8 +2054,7 @@ void GFXVulkan::createLogicalDevice(std::vector extensions) { VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.pQueueCreateInfos = queueCreateInfos.data(); - createInfo.queueCreateInfoCount = - static_cast(queueCreateInfos.size()); + createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); createInfo.ppEnabledExtensionNames = extensions.data(); createInfo.enabledExtensionCount = static_cast(extensions.size()); @@ -2160,8 +2069,7 @@ void GFXVulkan::createLogicalDevice(std::vector extensions) { enabledFeatures.imageCubeArray = true; VkPhysicalDeviceVulkan11Features enabled11Features = {}; - enabled11Features.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + enabled11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; enabled11Features.shaderDrawParameters = true; VkPhysicalDeviceFeatures2 enabledFeatures2 = {}; @@ -2186,46 +2094,38 @@ void GFXVulkan::createLogicalDevice(std::vector extensions) { vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool); } -void GFXVulkan::createSwapchain(NativeSurface* native_surface, - VkSwapchainKHR oldSwapchain) { +void GFXVulkan::createSwapchain(NativeSurface* native_surface, VkSwapchainKHR oldSwapchain) { if (native_surface->surface == VK_NULL_HANDLE) { auto surface_creation_info = new vulkan_surface_creation_info(); surface_creation_info->instance = instance; - auto vk_surface = (vulkan_surface*)platform::create_surface( - native_surface->identifier, surface_creation_info); + auto vk_surface = (vulkan_surface*)platform::create_surface(native_surface->identifier, surface_creation_info); native_surface->surface = vk_surface->surface; } // TODO: fix this pls VkBool32 supported; - vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, 0, - native_surface->surface, &supported); + vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, 0, native_surface->surface, &supported); // query swapchain support VkSurfaceCapabilitiesKHR capabilities; - vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - physicalDevice, native_surface->surface, &capabilities); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, native_surface->surface, &capabilities); std::vector formats; uint32_t formatCount; - vkGetPhysicalDeviceSurfaceFormatsKHR( - physicalDevice, native_surface->surface, &formatCount, nullptr); + vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, native_surface->surface, &formatCount, nullptr); formats.resize(formatCount); - vkGetPhysicalDeviceSurfaceFormatsKHR( - physicalDevice, native_surface->surface, &formatCount, formats.data()); + vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, native_surface->surface, &formatCount, formats.data()); std::vector presentModes; uint32_t presentModeCount; - vkGetPhysicalDeviceSurfacePresentModesKHR( - physicalDevice, native_surface->surface, &presentModeCount, nullptr); + vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, native_surface->surface, &presentModeCount, nullptr); presentModes.resize(presentModeCount); vkGetPhysicalDeviceSurfacePresentModesKHR( - physicalDevice, native_surface->surface, &presentModeCount, - presentModes.data()); + physicalDevice, native_surface->surface, &presentModeCount, presentModes.data()); // choosing swapchain features VkSurfaceFormatKHR swapchainSurfaceFormat = formats[0]; @@ -2244,8 +2144,7 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, } uint32_t imageCount = capabilities.minImageCount + 1; - if (capabilities.maxImageCount > 0 && - imageCount > capabilities.maxImageCount) { + if (capabilities.maxImageCount > 0 && imageCount > capabilities.maxImageCount) { imageCount = capabilities.maxImageCount; } @@ -2267,8 +2166,7 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, createInfo.clipped = VK_TRUE; createInfo.oldSwapchain = oldSwapchain; - vkCreateSwapchainKHR(device, &createInfo, nullptr, - &native_surface->swapchain); + vkCreateSwapchainKHR(device, &createInfo, nullptr, &native_surface->swapchain); if (oldSwapchain != VK_NULL_HANDLE) { vkDestroySwapchainKHR(device, oldSwapchain, nullptr); @@ -2278,15 +2176,12 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, native_surface->swapchainExtent.height = native_surface->surfaceHeight; // get swapchain images - vkGetSwapchainImagesKHR(device, native_surface->swapchain, &imageCount, - nullptr); + vkGetSwapchainImagesKHR(device, native_surface->swapchain, &imageCount, nullptr); native_surface->swapchainImages.resize(imageCount); - vkGetSwapchainImagesKHR(device, native_surface->swapchain, &imageCount, - native_surface->swapchainImages.data()); + vkGetSwapchainImagesKHR(device, native_surface->swapchain, &imageCount, native_surface->swapchainImages.data()); // create swapchain image views - native_surface->swapchainImageViews.resize( - native_surface->swapchainImages.size()); + native_surface->swapchainImageViews.resize(native_surface->swapchainImages.size()); for (size_t i = 0; i < native_surface->swapchainImages.size(); i++) { VkImageViewCreateInfo view_create_info = {}; @@ -2298,15 +2193,13 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - view_create_info.subresourceRange.aspectMask = - VK_IMAGE_ASPECT_COLOR_BIT; + view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view_create_info.subresourceRange.baseMipLevel = 0; view_create_info.subresourceRange.levelCount = 1; view_create_info.subresourceRange.baseArrayLayer = 0; view_create_info.subresourceRange.layerCount = 1; - vkCreateImageView(device, &view_create_info, nullptr, - &native_surface->swapchainImageViews[i]); + vkCreateImageView(device, &view_create_info, nullptr, &native_surface->swapchainImageViews[i]); } // create render pass @@ -2347,12 +2240,10 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, renderPassInfo.dependencyCount = 1; renderPassInfo.pDependencies = &dependency; - vkCreateRenderPass(device, &renderPassInfo, nullptr, - &native_surface->swapchainRenderPass); + vkCreateRenderPass(device, &renderPassInfo, nullptr, &native_surface->swapchainRenderPass); // create swapchain framebuffers - native_surface->swapchainFramebuffers.resize( - native_surface->swapchainImageViews.size()); + native_surface->swapchainFramebuffers.resize(native_surface->swapchainImageViews.size()); for (size_t i = 0; i < native_surface->swapchainImageViews.size(); i++) { VkImageView attachments[] = {native_surface->swapchainImageViews[i]}; @@ -2366,14 +2257,12 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, framebufferInfo.height = native_surface->surfaceHeight; framebufferInfo.layers = 1; - vkCreateFramebuffer(device, &framebufferInfo, nullptr, - &native_surface->swapchainFramebuffers[i]); + vkCreateFramebuffer(device, &framebufferInfo, nullptr, &native_surface->swapchainFramebuffers[i]); } // allocate command buffers native_surface->gfx_command_buffers.resize(MAX_FRAMES_IN_FLIGHT); - for (auto [i, cmdbuf] : - utility::enumerate(native_surface->gfx_command_buffers)) { + for (auto [i, cmdbuf] : utility::enumerate(native_surface->gfx_command_buffers)) { cmdbuf = new GFXVulkanCommandBuffer(); VkCommandBufferAllocateInfo allocInfo = {}; @@ -2384,15 +2273,17 @@ void GFXVulkan::createSwapchain(NativeSurface* native_surface, vkAllocateCommandBuffers(device, &allocInfo, &cmdbuf->handle); - name_object(device, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdbuf->handle, - ("main cmd buf " + std::to_string(i)).c_str()); + name_object( + device, + VK_OBJECT_TYPE_COMMAND_BUFFER, + (uint64_t)cmdbuf->handle, + ("main cmd buf " + std::to_string(i)).c_str()); } } void GFXVulkan::createDescriptorPool() { const std::array poolSizes = { - {{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 5000}, - {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 5000}}}; + {{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 5000}, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 5000}}}; VkDescriptorPoolCreateInfo poolInfo = {}; poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; @@ -2416,12 +2307,9 @@ void GFXVulkan::createSyncPrimitives(NativeSurface* native_surface) { fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { - vkCreateSemaphore(device, &semaphoreInfo, nullptr, - &native_surface->imageAvailableSemaphores[i]); - vkCreateSemaphore(device, &semaphoreInfo, nullptr, - &native_surface->renderFinishedSemaphores[i]); - vkCreateFence(device, &fenceCreateInfo, nullptr, - &native_surface->inFlightFences[i]); + vkCreateSemaphore(device, &semaphoreInfo, nullptr, &native_surface->imageAvailableSemaphores[i]); + vkCreateSemaphore(device, &semaphoreInfo, nullptr, &native_surface->renderFinishedSemaphores[i]); + vkCreateFence(device, &fenceCreateInfo, nullptr, &native_surface->inFlightFences[i]); } } @@ -2436,8 +2324,7 @@ void GFXVulkan::resetDescriptorState() { sampler = nullptr; } -void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, - VkDescriptorSetLayout layout) { +void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSetLayout layout) { uint64_t hash = getDescriptorHash(pipeline); // create set object @@ -2449,16 +2336,13 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, allocInfo.descriptorSetCount = 1; allocInfo.pSetLayouts = &layout; - VkResult error = - vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); - if (error != VK_SUCCESS || - descriptorSet == VK_NULL_HANDLE) { // todo: lol we should really check - // why this fails sometimes + VkResult error = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); + if (error != VK_SUCCESS || descriptorSet == VK_NULL_HANDLE) { // todo: lol we should really check + // why this fails sometimes return; } - name_object(device, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)descriptorSet, - pipeline->label); + name_object(device, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)descriptorSet, pipeline->label); // update set for (auto [i, buffer] : utility::enumerate(boundShaderBuffers)) { @@ -2491,11 +2375,9 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, imageInfo.imageView = vulkanTexture->view; imageInfo.sampler = vulkanTexture->sampler; - if ((vulkanTexture->usage & GFXTextureUsage::Attachment) == - GFXTextureUsage::Attachment) { + if ((vulkanTexture->usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) { if (vulkanTexture->format == VK_FORMAT_D32_SFLOAT) { - imageInfo.imageLayout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; } } @@ -2505,18 +2387,13 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, descriptorWrite.dstBinding = i; descriptorWrite.descriptorCount = 1; - if (utility::contains(pipeline->bindings_marked_as_storage_images, - i)) { - descriptorWrite.descriptorType = - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + if (utility::contains(pipeline->bindings_marked_as_storage_images, i)) { + descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - } else if (utility::contains( - pipeline->bindings_marked_as_sampled_images, i)) { - descriptorWrite.descriptorType = - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + } else if (utility::contains(pipeline->bindings_marked_as_sampled_images, i)) { + descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; } else { - descriptorWrite.descriptorType = - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; } descriptorWrite.pImageInfo = &imageInfo; @@ -2568,15 +2445,12 @@ uint64_t GFXVulkan::getDescriptorHash(GFXVulkanPipeline* pipeline) { return hash; } -uint32_t GFXVulkan::findMemoryType(uint32_t typeFilter, - VkMemoryPropertyFlags properties) { +uint32_t GFXVulkan::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) { VkPhysicalDeviceMemoryProperties memProperties; vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { - if ((typeFilter & (1 << i)) && - (memProperties.memoryTypes[i].propertyFlags & properties) == - properties) { + if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { return i; } } @@ -2584,24 +2458,30 @@ uint32_t GFXVulkan::findMemoryType(uint32_t typeFilter, return -1; } -void GFXVulkan::transitionImageLayout(VkImage image, VkFormat format, - VkImageAspectFlags aspect, - VkImageSubresourceRange range, - VkImageLayout oldLayout, - VkImageLayout newLayout) { +void GFXVulkan::transitionImageLayout( + VkImage image, + VkFormat format, + VkImageAspectFlags aspect, + VkImageSubresourceRange range, + VkImageLayout oldLayout, + VkImageLayout newLayout) { VkCommandBuffer commandBuffer = beginSingleTimeCommands(); - inlineTransitionImageLayout(commandBuffer, image, format, aspect, range, - oldLayout, newLayout); + inlineTransitionImageLayout(commandBuffer, image, format, aspect, range, oldLayout, newLayout); endSingleTimeCommands(commandBuffer); } void GFXVulkan::inlineTransitionImageLayout( - VkCommandBuffer commandBuffer, VkImage image, VkFormat format, - VkImageAspectFlags aspect, VkImageSubresourceRange range, - VkImageLayout oldLayout, VkImageLayout newLayout, - VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask) { + VkCommandBuffer commandBuffer, + VkImage image, + VkFormat format, + VkImageAspectFlags aspect, + VkImageSubresourceRange range, + VkImageLayout oldLayout, + VkImageLayout newLayout, + VkPipelineStageFlags src_stage_mask, + VkPipelineStageFlags dst_stage_mask) { VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.oldLayout = oldLayout; @@ -2613,42 +2493,40 @@ void GFXVulkan::inlineTransitionImageLayout( barrier.subresourceRange.aspectMask = aspect; switch (oldLayout) { - case VK_IMAGE_LAYOUT_UNDEFINED: - barrier.srcAccessMask = 0; - break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - break; - case VK_IMAGE_LAYOUT_GENERAL: - barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - break; - default: - break; + case VK_IMAGE_LAYOUT_UNDEFINED: + barrier.srcAccessMask = 0; + break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + case VK_IMAGE_LAYOUT_GENERAL: + barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + break; + default: + break; } switch (newLayout) { - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - break; - case VK_IMAGE_LAYOUT_GENERAL: - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - break; - default: - break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + case VK_IMAGE_LAYOUT_GENERAL: + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + default: + break; } - vkCmdPipelineBarrier(commandBuffer, src_stage_mask, dst_stage_mask, 0, 0, - nullptr, 0, nullptr, 1, &barrier); + vkCmdPipelineBarrier(commandBuffer, src_stage_mask, dst_stage_mask, 0, 0, nullptr, 0, nullptr, 1, &barrier); } -VkShaderModule GFXVulkan::createShaderModule(const uint32_t* code, - const int length) { +VkShaderModule GFXVulkan::createShaderModule(const uint32_t* code, const int length) { VkShaderModuleCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.codeSize = length; diff --git a/engine/gfx/vulkan/src/gfx_vulkan_buffer.hpp b/engine/gfx/vulkan/src/gfx_vulkan_buffer.hpp index 30e118a..abc8901 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan_buffer.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_buffer.hpp @@ -9,7 +9,7 @@ class GFXVulkanBuffer : public GFXBuffer { public: VkBuffer handle = VK_NULL_HANDLE; VkDeviceMemory memory = VK_NULL_HANDLE; - - VkDeviceSize size = 0; + + VkDeviceSize size = 0; uint32_t frame_index = 0; }; diff --git a/engine/gfx/vulkan/src/gfx_vulkan_framebuffer.hpp b/engine/gfx/vulkan/src/gfx_vulkan_framebuffer.hpp index fdf1a60..ca04139 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan_framebuffer.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_framebuffer.hpp @@ -6,7 +6,7 @@ class GFXVulkanFramebuffer : public GFXFramebuffer { public: - VkFramebuffer handle = VK_NULL_HANDLE; - + VkFramebuffer handle = VK_NULL_HANDLE; + int width = 0, height = 0; }; diff --git a/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp b/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp index 97cabc6..e07a0fb 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_pipeline.hpp @@ -8,16 +8,16 @@ class GFXVulkanTexture; class GFXVulkanPipeline : public GFXPipeline { public: - std::string label; + std::string label; - VkPipeline handle = VK_NULL_HANDLE; - VkPipelineLayout layout = VK_NULL_HANDLE; + VkPipeline handle = VK_NULL_HANDLE; + VkPipelineLayout layout = VK_NULL_HANDLE; - VkDescriptorSetLayout descriptorLayout = VK_NULL_HANDLE; + VkDescriptorSetLayout descriptorLayout = VK_NULL_HANDLE; std::vector bindings_marked_as_normal_images; std::vector bindings_marked_as_storage_images; - std::vector bindings_marked_as_sampled_images; + std::vector bindings_marked_as_sampled_images; // dynamic descriptor sets std::map cachedDescriptorSets; diff --git a/engine/gfx/vulkan/src/gfx_vulkan_renderpass.hpp b/engine/gfx/vulkan/src/gfx_vulkan_renderpass.hpp index 361d992..0c79067 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan_renderpass.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_renderpass.hpp @@ -6,10 +6,10 @@ class GFXVulkanRenderPass : public GFXRenderPass { public: - VkRenderPass handle = VK_NULL_HANDLE; + VkRenderPass handle = VK_NULL_HANDLE; - unsigned int numAttachments = 0; + unsigned int numAttachments = 0; int depth_attachment = -1; - - bool hasDepthAttachment = false; + + bool hasDepthAttachment = false; }; diff --git a/engine/gfx/vulkan/src/gfx_vulkan_sampler.hpp b/engine/gfx/vulkan/src/gfx_vulkan_sampler.hpp index 72d06f9..56a56a1 100644 --- a/engine/gfx/vulkan/src/gfx_vulkan_sampler.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_sampler.hpp @@ -4,7 +4,7 @@ #include "gfx_sampler.hpp" -class GFXVulkanSampler: public GFXSampler { +class GFXVulkanSampler : public GFXSampler { public: - VkSampler sampler = VK_NULL_HANDLE; + VkSampler sampler = VK_NULL_HANDLE; }; diff --git a/engine/gfx/vulkan/src/gfx_vulkan_texture.hpp b/engine/gfx/vulkan/src/gfx_vulkan_texture.hpp index c1f1acc..34b1381 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan_texture.hpp +++ b/engine/gfx/vulkan/src/gfx_vulkan_texture.hpp @@ -6,17 +6,17 @@ class GFXVulkanTexture : public GFXTexture { public: - VkImage handle = VK_NULL_HANDLE; - VkDeviceMemory memory = VK_NULL_HANDLE; - VkImageView view = VK_NULL_HANDLE; - VkSampler sampler = VK_NULL_HANDLE; + VkImage handle = VK_NULL_HANDLE; + VkDeviceMemory memory = VK_NULL_HANDLE; + VkImageView view = VK_NULL_HANDLE; + VkSampler sampler = VK_NULL_HANDLE; - int width = 0, height = 0; + int width = 0, height = 0; - VkFormat format = VK_FORMAT_UNDEFINED; - VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; - VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED; - VkImageAspectFlagBits aspect; + VkFormat format = VK_FORMAT_UNDEFINED; + VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; + VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED; + VkImageAspectFlagBits aspect; VkImageSubresourceRange range; GFXTextureUsage usage; diff --git a/engine/log/CMakeLists.txt b/engine/log/CMakeLists.txt index cd18263..964940d 100755 --- a/engine/log/CMakeLists.txt +++ b/engine/log/CMakeLists.txt @@ -1,6 +1,6 @@ set(SRC - include/log.hpp - src/log.cpp) + include/log.hpp + src/log.cpp) add_library(Log STATIC ${SRC}) target_include_directories(Log PUBLIC include) diff --git a/engine/log/include/log.hpp b/engine/log/include/log.hpp index 300ed14..e31f76e 100755 --- a/engine/log/include/log.hpp +++ b/engine/log/include/log.hpp @@ -11,8 +11,7 @@ namespace prism { log_output += str + "\n"; } - template - inline void log(const S& format, Args&&... args) { + template inline void log(const S& format, Args&&... args) { vlog(format, fmt::make_args_checked(format, args...)); } -} \ No newline at end of file +} // namespace prism \ No newline at end of file diff --git a/engine/math/CMakeLists.txt b/engine/math/CMakeLists.txt index 447d62b..68dbb28 100755 --- a/engine/math/CMakeLists.txt +++ b/engine/math/CMakeLists.txt @@ -1,14 +1,14 @@ set(SRC - include/math.hpp - include/matrix.hpp - include/transform.hpp - include/vector.hpp - include/quaternion.hpp - include/plane.hpp - include/aabb.hpp + include/math.hpp + include/matrix.hpp + include/transform.hpp + include/vector.hpp + include/quaternion.hpp + include/plane.hpp + include/aabb.hpp - src/transform.cpp - src/math.cpp include/ray.hpp) + src/transform.cpp + src/math.cpp include/ray.hpp) add_library(Math STATIC ${SRC}) target_include_directories(Math PUBLIC include) diff --git a/engine/math/include/aabb.hpp b/engine/math/include/aabb.hpp index 2538380..d22a82a 100644 --- a/engine/math/include/aabb.hpp +++ b/engine/math/include/aabb.hpp @@ -13,13 +13,13 @@ namespace prism { /// Creates an array of 8 points, each of these being one extreme of the bounding box.. inline std::array get_points(const aabb& aabb) { return { - float3(aabb.min.x, aabb.min.y, aabb.min.z), - float3(aabb.max.x, aabb.min.y, aabb.min.z), - float3(aabb.min.x, aabb.max.y, aabb.min.z), - float3(aabb.max.x, aabb.max.y, aabb.min.z), - float3(aabb.min.x, aabb.min.y, aabb.max.z), - float3(aabb.max.x, aabb.min.y, aabb.max.z), - float3(aabb.min.x, aabb.max.y, aabb.max.z), - float3(aabb.max.x, aabb.max.y, aabb.max.z)}; + float3(aabb.min.x, aabb.min.y, aabb.min.z), + float3(aabb.max.x, aabb.min.y, aabb.min.z), + float3(aabb.min.x, aabb.max.y, aabb.min.z), + float3(aabb.max.x, aabb.max.y, aabb.min.z), + float3(aabb.min.x, aabb.min.y, aabb.max.z), + float3(aabb.max.x, aabb.min.y, aabb.max.z), + float3(aabb.min.x, aabb.max.y, aabb.max.z), + float3(aabb.max.x, aabb.max.y, aabb.max.z)}; } -} \ No newline at end of file +} // namespace prism \ No newline at end of file diff --git a/engine/math/include/math.hpp b/engine/math/include/math.hpp index 6e797c2..a39782c 100755 --- a/engine/math/include/math.hpp +++ b/engine/math/include/math.hpp @@ -1,26 +1,23 @@ #pragma once #include "matrix.hpp" +#include "ray.hpp" #include "transform.hpp" #include "vector.hpp" -#include "ray.hpp" constexpr double PI = 3.141592653589793; -template -constexpr inline T radians(const T degrees) { +template constexpr inline T radians(const T degrees) { return degrees / static_cast(180) * static_cast(PI); } -template -constexpr inline T degrees(const T radians) { +template constexpr inline T degrees(const T radians) { return radians / static_cast(PI) * static_cast(180); } -template -constexpr inline bool nearly_equal(const T a, const T b) { - return std::nextafter(a, std::numeric_limits::lowest()) <= b - && std::nextafter(a, std::numeric_limits::max()) >= b; +template constexpr inline bool nearly_equal(const T a, const T b) { + return std::nextafter(a, std::numeric_limits::lowest()) <= b && + std::nextafter(a, std::numeric_limits::max()) >= b; } Matrix4x4 matrix_from_quat(Quaternion quat); diff --git a/engine/math/include/matrix.hpp b/engine/math/include/matrix.hpp index cc94414..3e47339 100755 --- a/engine/math/include/matrix.hpp +++ b/engine/math/include/matrix.hpp @@ -5,32 +5,40 @@ // m = rows // n = columns // row major storage mode? -template -class Matrix { +template class Matrix { public: constexpr Matrix(const T diagonal = T(1)) { - for(std::size_t i = 0; i < (M * N); i++) + for (std::size_t i = 0; i < (M * N); i++) unordered_data[i] = ((i / M) == (i % N) ? diagonal : T(0)); } - - constexpr Matrix(const prism::float4 m1_, const prism::float4 m2_, const prism::float4 m3_, const prism::float4 m4_) { + + constexpr Matrix( + const prism::float4 m1_, + const prism::float4 m2_, + const prism::float4 m3_, + const prism::float4 m4_) { columns[0] = m1_; columns[1] = m2_; columns[2] = m3_; columns[3] = m4_; } - + constexpr inline void operator*=(Matrix rhs); using VectorType = prism::Vector; - - constexpr VectorType& operator[](const size_t index) { return columns[index]; } - constexpr VectorType operator[](const size_t index) const { return columns[index]; } + + constexpr VectorType& operator[](const size_t index) { + return columns[index]; + } + + constexpr VectorType operator[](const size_t index) const { + return columns[index]; + } union { VectorType columns[M]; - T data[M][N]; - T unordered_data[M * N] = {}; + T data[M][N]; + T unordered_data[M * N] = {}; }; }; @@ -39,20 +47,20 @@ using Matrix3x3 = Matrix; constexpr inline Matrix4x4 operator*(const Matrix4x4 lhs, const Matrix4x4 rhs) { Matrix4x4 tmp(0.0f); - for(int j = 0; j < 4; j++) { - for(int i = 0; i < 4; i++) { - for(int k = 0; k < 4; k++) + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + for (int k = 0; k < 4; k++) tmp.data[j][i] += lhs.data[k][i] * rhs.data[j][k]; } } - + return tmp; } constexpr inline prism::float4 operator*(const Matrix4x4 lhs, const prism::float4 rhs) { prism::float4 tmp; - for(int r = 0; r < 4; r++) { - for(int c = 0; c < 4; c++) + for (int r = 0; r < 4; r++) { + for (int c = 0; c < 4; c++) tmp[r] += lhs.data[c][r] * rhs.data[c]; } @@ -61,13 +69,13 @@ constexpr inline prism::float4 operator*(const Matrix4x4 lhs, const prism::float constexpr inline Matrix4x4 operator/(const Matrix4x4 lhs, const float rhs) { Matrix4x4 tmp(0.0f); - for(int j = 0; j < 4; j++) { - for(int i = 0; i < 4; i++) { - for(int k = 0; k < 4; k++) + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + for (int k = 0; k < 4; k++) tmp.data[k][i] = lhs.data[k][i] / rhs; } } - + return tmp; } @@ -79,9 +87,11 @@ constexpr inline Matrix4x4 operator*(const Matrix4x4 lhs, const float rhs) { tmp.data[k][i] = lhs.data[k][i] * rhs; } } - + return tmp; } template -constexpr void Matrix::operator*=(const Matrix rhs) { *this = *this * rhs; } +constexpr void Matrix::operator*=(const Matrix rhs) { + *this = *this * rhs; +} diff --git a/engine/math/include/plane.hpp b/engine/math/include/plane.hpp index 2c0aa3b..a6012b1 100755 --- a/engine/math/include/plane.hpp +++ b/engine/math/include/plane.hpp @@ -9,22 +9,17 @@ struct Plane { }; inline Plane normalize(const Plane& plane) { - const float magnitude = std::sqrt(plane.a * plane.a + - plane.b * plane.b + - plane.c * plane.c); - + const float magnitude = std::sqrt(plane.a * plane.a + plane.b * plane.b + plane.c * plane.c); + Plane normalized_plane = plane; normalized_plane.a = plane.a / magnitude; normalized_plane.b = plane.b / magnitude; normalized_plane.c = plane.c / magnitude; normalized_plane.d = plane.d / magnitude; - + return normalized_plane; } inline float distance_to_point(const Plane& plane, const prism::float3& point) { - return plane.a * point.x + - plane.b * point.y + - plane.c * point.z + - plane.d; + return plane.a * point.x + plane.b * point.y + plane.c * point.z + plane.d; } diff --git a/engine/math/include/quaternion.hpp b/engine/math/include/quaternion.hpp index e314bb3..7017ee9 100755 --- a/engine/math/include/quaternion.hpp +++ b/engine/math/include/quaternion.hpp @@ -5,11 +5,11 @@ class Quaternion { public: constexpr Quaternion(const float v = 0.0f) : w(1.0f), x(v), y(v), z(v) {} - + constexpr Quaternion(const float x, const float y, const float z, const float w) : w(w), x(x), y(y), z(z) {} - + float w, x, y, z; -}; +}; constexpr inline Quaternion operator*(const Quaternion lhs, const float rhs) { Quaternion tmp(lhs); @@ -17,7 +17,7 @@ constexpr inline Quaternion operator*(const Quaternion lhs, const float rhs) { tmp.y *= rhs; tmp.z *= rhs; tmp.w *= rhs; - + return tmp; } @@ -25,7 +25,7 @@ constexpr inline prism::float3 operator*(const Quaternion& lhs, const prism::flo const prism::float3 quatVector = prism::float3(lhs.x, lhs.y, lhs.z); const prism::float3 uv = cross(quatVector, rhs); const prism::float3 uuv = cross(quatVector, uv); - + return rhs + ((uv * lhs.w) + uuv) * 2.0f; } @@ -43,37 +43,34 @@ inline float length(const Quaternion& quat) { inline Quaternion normalize(const Quaternion& quat) { const float l = length(quat); - + return quat * (1.0f / l); } constexpr inline Quaternion lerp(const Quaternion& a, const Quaternion& b, const float time) { float cosom = dot(a, b); - + Quaternion end = b; - if(cosom < 0.0f) { + if (cosom < 0.0f) { cosom = -cosom; end.x = -end.x; end.y = -end.y; end.z = -end.z; end.w = -end.w; } - + float sclp = 0.0f, sclq = 0.0f; - if((1.0f - cosom) > 0.0001f) { + if ((1.0f - cosom) > 0.0001f) { const float omega = std::acos(cosom); const float sinom = std::sin(omega); - sclp = std::sin((1.0f - time) * omega) / sinom; - sclq = std::sin(time* omega) / sinom; + sclp = std::sin((1.0f - time) * omega) / sinom; + sclq = std::sin(time * omega) / sinom; } else { sclp = 1.0f - time; sclq = time; } - - return {sclp * a.x + sclq * end.x, - sclp * a.y + sclq * end.y, - sclp * a.z + sclq * end.z, - sclp * a.w + sclq * end.w}; + + return {sclp * a.x + sclq * end.x, sclp * a.y + sclq * end.y, sclp * a.z + sclq * end.z, sclp * a.w + sclq * end.w}; } constexpr inline Quaternion operator*(const Quaternion lhs, const Quaternion rhs) { @@ -82,6 +79,6 @@ constexpr inline Quaternion operator*(const Quaternion lhs, const Quaternion rhs tmp.x = lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y; tmp.y = lhs.w * rhs.y + lhs.y * rhs.w + lhs.z * rhs.x - lhs.x * rhs.z; tmp.z = lhs.w * rhs.z + lhs.z * rhs.w + lhs.x * rhs.y - lhs.y * rhs.x; - + return tmp; } diff --git a/engine/math/include/ray.hpp b/engine/math/include/ray.hpp index e9ae9e2..3a6ab7a 100644 --- a/engine/math/include/ray.hpp +++ b/engine/math/include/ray.hpp @@ -9,4 +9,4 @@ namespace prism { }; float closest_distance_between_lines(ray& l1, ray& l2); -} \ No newline at end of file +} // namespace prism \ No newline at end of file diff --git a/engine/math/include/transform.hpp b/engine/math/include/transform.hpp index 4ffab2c..8b8515f 100755 --- a/engine/math/include/transform.hpp +++ b/engine/math/include/transform.hpp @@ -1,8 +1,8 @@ #pragma once #include "matrix.hpp" -#include "vector.hpp" #include "quaternion.hpp" +#include "vector.hpp" namespace prism { Matrix4x4 perspective(float field_of_view, float aspect, float z_near, float z_far); @@ -15,5 +15,5 @@ namespace prism { Matrix4x4 translate(Matrix4x4 matrix, float3 translation); Matrix4x4 rotate(Matrix4x4 matrix, float angle, float3 axis); - Matrix4x4 scale(Matrix4x4 matrix, float3 scale); -} + Matrix4x4 scale(Matrix4x4 matrix, float3 scale); +} // namespace prism diff --git a/engine/math/include/vector.hpp b/engine/math/include/vector.hpp index 7dfadb4..277f35c 100755 --- a/engine/math/include/vector.hpp +++ b/engine/math/include/vector.hpp @@ -1,62 +1,50 @@ #pragma once +#include #include #include #include -#include namespace prism { - #define DEFINE_OPERATORS(Size) \ - constexpr Vector(const T scalar = T(0)) { \ - for(std::size_t i = 0; i < (Size); i++) \ - data[i] = scalar; \ - } \ - constexpr T& operator[](const size_t index) { \ - return data[index]; \ - } \ - constexpr T operator[](const size_t index) const { \ - return data[index]; \ - } \ - constexpr Vector& operator+=(const Vector rhs) { \ - for(std::size_t i = 0; i < (Size); i++)\ - data[i] += rhs[i]; \ - return *this; \ - } \ - constexpr Vector& operator-=(const Vector rhs) { \ - for(std::size_t i = 0; i < (Size); i++)\ - data[i] -= rhs[i]; \ - return *this; \ - } \ - constexpr Vector& operator*=(const Vector rhs) { \ - for(std::size_t i = 0; i < (Size); i++) \ - data[i] *= rhs[i]; \ - return *this; \ - } \ - constexpr Vector& operator/=(const T scalar) { \ - for(std::size_t i = 0; i < (Size); i++) \ - data[i] /= scalar; \ - return *this; \ - } \ - constexpr T* ptr() const { \ - return data.data(); \ - } \ - constexpr T* ptr() { \ - return data.data(); \ - } \ - constexpr Vector operator- () const { \ - Vector vec; \ - for(std::size_t i = 0; i < (Size); i++) \ - vec[i] = -data[i]; \ - return vec; \ +#define DEFINE_OPERATORS(Size) \ + constexpr Vector(const T scalar = T(0)) { \ + for (std::size_t i = 0; i < (Size); i++) \ + data[i] = scalar; \ + } \ + constexpr T& operator[](const size_t index) { return data[index]; } \ + constexpr T operator[](const size_t index) const { return data[index]; } \ + constexpr Vector& operator+=(const Vector rhs) { \ + for (std::size_t i = 0; i < (Size); i++) \ + data[i] += rhs[i]; \ + return *this; \ + } \ + constexpr Vector& operator-=(const Vector rhs) { \ + for (std::size_t i = 0; i < (Size); i++) \ + data[i] -= rhs[i]; \ + return *this; \ + } \ + constexpr Vector& operator*=(const Vector rhs) { \ + for (std::size_t i = 0; i < (Size); i++) \ + data[i] *= rhs[i]; \ + return *this; \ + } \ + constexpr Vector& operator/=(const T scalar) { \ + for (std::size_t i = 0; i < (Size); i++) \ + data[i] /= scalar; \ + return *this; \ + } \ + constexpr T* ptr() const { return data.data(); } \ + constexpr T* ptr() { return data.data(); } \ + constexpr Vector operator-() const { \ + Vector vec; \ + for (std::size_t i = 0; i < (Size); i++) \ + vec[i] = -data[i]; \ + return vec; \ } - template - struct Vector { - std::array data; - }; + template struct Vector { std::array data; }; - template - struct Vector<2, T> { + template struct Vector<2, T> { constexpr Vector(const T x_, const T y_) { x = x_; y = y_; @@ -73,8 +61,7 @@ namespace prism { }; }; - template - struct Vector<3, T> { + template struct Vector<3, T> { constexpr Vector(const T x_, const T y_, const T z_) { x = x_; y = y_; @@ -92,8 +79,7 @@ namespace prism { }; }; - template - struct alignas(16) Vector<4, T> { + template struct alignas(16) Vector<4, T> { constexpr Vector(const T x_, const T y_, const T z_, const T w_) { x = x_; y = y_; @@ -101,7 +87,7 @@ namespace prism { w = w_; } - constexpr Vector(const Vector<3, T> &v, const float w = 0.0f) : x(v.x), y(v.y), z(v.z), w(w) {} + constexpr Vector(const Vector<3, T>& v, const float w = 0.0f) : x(v.x), y(v.y), z(v.z), w(w) {} DEFINE_OPERATORS(4) @@ -123,8 +109,7 @@ namespace prism { using float3 = Vector<3, float>; using float4 = Vector<4, float>; - template - constexpr inline T dot(const Vector lhs, const Vector rhs) { + template constexpr inline T dot(const Vector lhs, const Vector rhs) { T product = T(0.0); for (std::size_t i = 0; i < N; i++) @@ -133,8 +118,7 @@ namespace prism { return product; } - template - constexpr inline T length(const Vector vec) { + template constexpr inline T length(const Vector vec) { return sqrtf(dot(vec, vec)); } @@ -147,8 +131,7 @@ namespace prism { return vec; } - template - constexpr inline Vector normalize(const Vector vec) { + template constexpr inline Vector normalize(const Vector vec) { Vector result; const float len = length(vec); @@ -170,15 +153,14 @@ namespace prism { return std::sqrt((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ)); } - template - constexpr inline T norm(const Vector vec) { + template constexpr inline T norm(const Vector vec) { T val = T(0); for (std::size_t i = 0; i < N; i++) val += abs(vec[i]); return sqrtf(dot(vec, vec)); } -} +} // namespace prism template constexpr inline bool operator==(const prism::Vector lhs, const prism::Vector rhs) { diff --git a/engine/math/src/math.cpp b/engine/math/src/math.cpp index 3282255..714110f 100755 --- a/engine/math/src/math.cpp +++ b/engine/math/src/math.cpp @@ -10,20 +10,20 @@ Matrix4x4 matrix_from_quat(const Quaternion quat) { const float qwx = quat.w * quat.x; const float qwy = quat.w * quat.y; const float qwz = quat.w * quat.z; - + Matrix4x4 result(1.0f); result[0][0] = 1.0f - 2.0f * (qyy + qzz); result[0][1] = 2.0f * (qxy + qwz); result[0][2] = 2.0f * (qxz - qwy); - + result[1][0] = 2.0f * (qxy - qwz); result[1][1] = 1.0f - 2.0f * (qxx + qzz); result[1][2] = 2.0f * (qyz + qwx); - + result[2][0] = 2.0f * (qxz + qwy); result[2][1] = 2.0f * (qyz - qwx); result[2][2] = 1.0f - 2.0f * (qxx + qyy); - + return result; } @@ -32,28 +32,28 @@ Quaternion quat_from_matrix(const Matrix3x3 m) { const float fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2]; const float fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1]; const float fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2]; - + int biggestIndex = 0; float fourBiggestSquaredMinus1 = fourWSquaredMinus1; - if(fourXSquaredMinus1 > fourBiggestSquaredMinus1) { + if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) { fourBiggestSquaredMinus1 = fourXSquaredMinus1; biggestIndex = 1; } - - if(fourYSquaredMinus1 > fourBiggestSquaredMinus1) { + + if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) { fourBiggestSquaredMinus1 = fourYSquaredMinus1; biggestIndex = 2; } - - if(fourZSquaredMinus1 > fourBiggestSquaredMinus1) { + + if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) { fourBiggestSquaredMinus1 = fourZSquaredMinus1; biggestIndex = 3; } - + const float biggestVal = sqrt(fourBiggestSquaredMinus1 + 1.0f) * 0.5f; const float mult = 0.25f / biggestVal; - - switch(biggestIndex) { + + switch (biggestIndex) { case 0: return {(m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult, biggestVal}; case 1: @@ -74,31 +74,31 @@ Quaternion euler_to_quat(const prism::float3 angle) { const float sr = sinf(angle.x * 0.5f); const float cp = cosf(angle.y * 0.5f); const float sp = sinf(angle.y * 0.5f); - + const float cpcy = cp * cy; const float spcy = sp * cy; const float cpsy = cp * sy; const float spsy = sp * sy; - + Quaternion result; result.w = cr * cpcy + sr * spsy; result.x = sr * cpcy - cr * spsy; result.y = cr * spcy + sr * cpsy; result.z = cr * cpsy - sr * spcy; - + return normalize(result); } prism::float3 quat_to_euler(const Quaternion q) { const float roll = atan2(2.0f * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z); - + const float y = 2.0f * (q.y * q.z + q.w * q.x); const float x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z; - + const float pitch = atan2(y, x); - + const float yaw = asinf(-2.0f * (q.x * q.z - q.w * q.y)); - + return {pitch, yaw, roll}; } @@ -106,67 +106,67 @@ Matrix4x4 inverse(const Matrix4x4 m) { const float Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; const float Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; const float Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; - + const float Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; const float Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; const float Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; - + const float Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; const float Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; const float Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; - + const float Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; const float Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; const float Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; - + const float Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; const float Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; const float Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; - + const float Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; const float Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; const float Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; - + const prism::float4 Fac0(Coef00, Coef00, Coef02, Coef03); const prism::float4 Fac1(Coef04, Coef04, Coef06, Coef07); const prism::float4 Fac2(Coef08, Coef08, Coef10, Coef11); const prism::float4 Fac3(Coef12, Coef12, Coef14, Coef15); const prism::float4 Fac4(Coef16, Coef16, Coef18, Coef19); const prism::float4 Fac5(Coef20, Coef20, Coef22, Coef23); - + const prism::float4 Vec0(m[1][0], m[0][0], m[0][0], m[0][0]); const prism::float4 Vec1(m[1][1], m[0][1], m[0][1], m[0][1]); const prism::float4 Vec2(m[1][2], m[0][2], m[0][2], m[0][2]); const prism::float4 Vec3(m[1][3], m[0][3], m[0][3], m[0][3]); - + const prism::float4 Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2); const prism::float4 Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4); const prism::float4 Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5); const prism::float4 Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5); - + const prism::float4 SignA(+1, -1, +1, -1); const prism::float4 SignB(-1, +1, -1, +1); const Matrix4x4 Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB); - + const prism::float4 Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]); - + const prism::float4 Dot0(m[0] * Row0); const float Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w); - + const float OneOverDeterminant = 1.0f / Dot1; - + return Inverse * OneOverDeterminant; } Quaternion angle_axis(const float angle, const prism::float3 axis) { const float s = sinf(angle * 0.5f); - + Quaternion result; result.w = cosf(angle * 0.5f); result.x = axis.x * s; result.y = axis.y * s; result.z = axis.z * s; - + return result; } diff --git a/engine/math/src/transform.cpp b/engine/math/src/transform.cpp index 4418ab8..2681a43 100755 --- a/engine/math/src/transform.cpp +++ b/engine/math/src/transform.cpp @@ -18,7 +18,7 @@ Matrix4x4 prism::perspective(const float field_of_view, const float aspect, cons result[2][2] = z_far / (z_far - z_near); result[2][3] = 1.0f; result[3][2] = -(z_far * z_near) / (z_far - z_near); - + return result; } @@ -35,7 +35,7 @@ Matrix4x4 prism::infinite_perspective(const float field_of_view, const float asp result[2][2] = 1.0f - std::numeric_limits::epsilon(); // prevent NaN result[2][3] = 1.0f; result[3][2] = -(2.0 - std::numeric_limits::epsilon()) * z_near; - + return result; } @@ -46,7 +46,7 @@ Matrix4x4 prism::orthographic(float left, float right, float bottom, float top, result[2][2] = 1.0f / (zFar - zNear); result[3][0] = -(right + left) / (right - left); result[3][1] = -(top + bottom) / (top - bottom); - result[3][2] = - zNear / (zFar - zNear); + result[3][2] = -zNear / (zFar - zNear); return result; } @@ -55,7 +55,7 @@ Matrix4x4 prism::look_at(const float3 eye, const float3 center, const float3 up) const float3 f = normalize(center - eye); const float3 s = normalize(cross(up, f)); const float3 u = cross(f, s); - + Matrix4x4 result(1.0f); result[0][0] = s.x; result[1][0] = s.y; @@ -69,14 +69,14 @@ Matrix4x4 prism::look_at(const float3 eye, const float3 center, const float3 up) result[3][0] = -dot(s, eye); result[3][1] = -dot(u, eye); result[3][2] = -dot(f, eye); - + return result; } Matrix4x4 prism::translate(const Matrix4x4 matrix, const float3 translation) { Matrix4x4 result(1.0f); result[3] = float4(translation, 1.0); - + return matrix * result; } @@ -106,7 +106,7 @@ Matrix4x4 prism::rotate(const Matrix4x4 matrix, const float angle, const float3 result[1] = matrix[0] * Rotate[1][0] + matrix[1] * Rotate[1][1] + matrix[2] * Rotate[1][2]; result[2] = matrix[0] * Rotate[2][0] + matrix[1] * Rotate[2][1] + matrix[2] * Rotate[2][2]; result[3] = matrix[3]; - + return result; } @@ -115,17 +115,17 @@ Matrix4x4 prism::scale(const Matrix4x4 matrix, const float3 scale) { result[0][0] = scale.x; result[1][1] = scale.y; result[2][2] = scale.z; - + return matrix * result; } Quaternion prism::quat_look_at(const float3 eye, const float3 center, const float3 up) { const float3 direction = normalize(center - eye); - + Matrix3x3 result(1.0f); result[2] = direction; result[0] = normalize(cross(up, result[2])); result[1] = cross(result[2], result[0]); - + return quat_from_matrix(result); } diff --git a/engine/platform/CMakeLists.txt b/engine/platform/CMakeLists.txt index 62587df..933c50c 100755 --- a/engine/platform/CMakeLists.txt +++ b/engine/platform/CMakeLists.txt @@ -1,10 +1,10 @@ -if(ENABLE_VULKAN) +if (ENABLE_VULKAN) set(EXTRA_LIBRARIES Vulkan::Vulkan ${EXTRA_LIBRARIES}) -endif() +endif () -if(ENABLE_METAL) +if (ENABLE_METAL) set(EXTRA_LIBRARIES metal-cpp ${EXTRA_LIBRARIES}) -endif() +endif () add_library(Platform INTERFACE) target_include_directories(Platform INTERFACE include) diff --git a/engine/platform/include/file.hpp b/engine/platform/include/file.hpp index da1dc91..d57bee4 100755 --- a/engine/platform/include/file.hpp +++ b/engine/platform/include/file.hpp @@ -1,11 +1,11 @@ #pragma once -#include -#include -#include -#include #include #include +#include +#include +#include +#include #include "log.hpp" #include "path.hpp" @@ -20,23 +20,20 @@ namespace prism { class file { public: explicit file(FILE* handle) : handle(handle) {} - - file(file&& f) noexcept : - mem(std::move(f.mem)), - handle(std::exchange(f.handle, nullptr)), - data(std::move(f.data)) {} - + + file(file&& f) noexcept + : mem(std::move(f.mem)), handle(std::exchange(f.handle, nullptr)), data(std::move(f.data)) {} + ~file() { - if(handle != nullptr) + if (handle != nullptr) fclose(handle); } - + /** Loads a type. @param t The pointer to the type. @param s If not 0, the size to load is derived from sizeof(T). */ - template - void read(T* t, const size_t s = 0) { + template void read(T* t, const size_t s = 0) { fread(t, s == 0 ? sizeof(T) : s, 1, handle); } @@ -49,7 +46,7 @@ namespace prism { unsigned int length = 0; read(&length); - if(length > 0) { + if (length > 0) { str.resize(length); read(str.data(), sizeof(char) * length); @@ -65,10 +62,9 @@ namespace prism { data.resize(_size); fread(data.data(), _size, 1, handle); } - + /// If the file is loaded in memory, cast the underlying data. - template - T* cast_data() { + template T* cast_data() { return reinterpret_cast(data.data()); } @@ -91,18 +87,18 @@ namespace prism { mem = std::make_unique(char_data, char_data + size()); return std::istream(mem.get()); } - + private: struct membuf : std::streambuf { inline membuf(char* begin, char* end) { this->setg(begin, begin, end); } }; - + std::unique_ptr mem; - + FILE* handle = nullptr; - + std::vector data; }; @@ -117,8 +113,8 @@ namespace prism { /// Converts an absolute path to a domain relative path. path get_relative_path(domain domain, const path& domain_relative_path); - /// Returns the path to a writeable directory. - path get_writeable_directory(); + /// Returns the path to a writeable directory. + path get_writeable_directory(); /** Opens a file handle. @@ -128,11 +124,11 @@ namespace prism { @return An optional with a value if the file was loaded correctly, otherwise it's empty. */ std::optional open_file(const path& file_path, bool binary_mode = false); - + path root_path(const path& path); path get_file_path(const path& path); - + inline path base_domain = "/base", game_domain = "/game"; -} +} // namespace prism inline std::array domain_data; diff --git a/engine/platform/include/platform.hpp b/engine/platform/include/platform.hpp index 67ef680..26e16b0 100755 --- a/engine/platform/include/platform.hpp +++ b/engine/platform/include/platform.hpp @@ -77,8 +77,8 @@ enum class PlatformTheme { // note: a platform may be built with support for a specific context (e.g. ENABLE_VULKAN, ENABLE_DIRECTX, etc) // this only determines it at build-time, not at runtime. #ifdef ENABLE_VULKAN -#include -#include + #include + #include struct vulkan_information { std::vector surface_extensions; @@ -100,8 +100,8 @@ struct directx_surface_creation_info { #endif #ifdef ENABLE_METAL -#include -#include + #include + #include struct metal_surface_creation_info { MTL::Device* device; @@ -140,9 +140,9 @@ namespace platform { void initialize_context(GFXContext context); /* - * This is used in specific cases where the gfx backend may need to know important information before window creation. - * A good example is the surface extension required by a specific window backend, but this is between initialize_context - * and create_surface calls. + * This is used in specific cases where the gfx backend may need to know important information before window + * creation. A good example is the surface extension required by a specific window backend, but this is between + * initialize_context and create_surface calls. * * the returned structs are in a naming scheme of X_information. */ @@ -152,8 +152,10 @@ namespace platform { @param title The title of the window. @param rect The requested size and position of the window. @param flags The requested window flags. - @note Depending on the platform, some of these parameters might be unused. The best practice is to always assume that none of them may be used. - @note On platforms that do not support the Windowing feature, calling open_window more than once is not supported. In this case, the same identifier is returned. + @note Depending on the platform, some of these parameters might be unused. The best practice is to always assume + that none of them may be used. + @note On platforms that do not support the Windowing feature, calling open_window more than once is not supported. + In this case, the same identifier is returned. @return A valid window identifier. */ window_ptr open_window(std::string_view title, prism::Rectangle rect, WindowFlags flags); @@ -171,8 +173,8 @@ namespace platform { void* create_surface(window_ptr window, void* surface_creation_info); /* - * This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable] underneath - * can be no-op for contexts such as vulkan which can happen within it's own API. + * This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable] + * underneath can be no-op for contexts such as vulkan which can happen within it's own API. * * the return type is named as X_next_image. may be null. */ @@ -201,7 +203,8 @@ namespace platform { /// Get the window size, note that in hidpi scenarios this is the non-scaled resolution. prism::Extent get_window_size(window_ptr window); - /// Get the window's drawable size. Always use this instead of manually multiplying the window size by the content scale. + /// Get the window's drawable size. Always use this instead of manually multiplying the window size by the content + /// scale. prism::Extent get_window_drawable_size(window_ptr window); /// Query whether or not the window is focused. @@ -249,8 +252,9 @@ namespace platform { /// On platforms that support moue capture, this will lock the mouse cursor to the window and hide it. void capture_mouse(bool capture); - // TODO: right now the OS intercepting and saying "We dont want text input anymore" ala software keyboards is NOT supported yet + // TODO: right now the OS intercepting and saying "We dont want text input anymore" ala software keyboards is NOT + // supported yet void begin_text_input(); void end_text_input(); -} +} // namespace platform diff --git a/engine/renderer/CMakeLists.txt b/engine/renderer/CMakeLists.txt index 10feab0..e63a536 100755 --- a/engine/renderer/CMakeLists.txt +++ b/engine/renderer/CMakeLists.txt @@ -1,37 +1,37 @@ set(SRC - include/renderer.hpp - include/pass.hpp - include/shadowpass.hpp - include/imguipass.hpp - include/smaapass.hpp - include/scenecapture.hpp - include/materialcompiler.hpp - include/dofpass.hpp - include/frustum.hpp - include/render_options.hpp - include/rendertarget.hpp + include/renderer.hpp + include/pass.hpp + include/shadowpass.hpp + include/imguipass.hpp + include/smaapass.hpp + include/scenecapture.hpp + include/materialcompiler.hpp + include/dofpass.hpp + include/frustum.hpp + include/render_options.hpp + include/rendertarget.hpp - src/renderer.cpp - src/shadowpass.cpp - src/imguipass.cpp - src/smaapass.cpp - src/scenecapture.cpp - src/materialcompiler.cpp - src/dofpass.cpp - src/frustum.cpp) + src/renderer.cpp + src/shadowpass.cpp + src/imguipass.cpp + src/smaapass.cpp + src/scenecapture.cpp + src/materialcompiler.cpp + src/dofpass.cpp + src/frustum.cpp) add_library(Renderer STATIC ${SRC}) target_link_libraries(Renderer - PUBLIC - GFX - Math - PRIVATE - stb - Math - Utility - imgui - SMAA::SMAA - ShaderCompiler - Core) + PUBLIC + GFX + Math + PRIVATE + stb + Math + Utility + imgui + SMAA::SMAA + ShaderCompiler + Core) target_include_directories(Renderer PUBLIC include) set_engine_properties(Renderer) \ No newline at end of file diff --git a/engine/renderer/include/dofpass.hpp b/engine/renderer/include/dofpass.hpp index 14da041..0130471 100755 --- a/engine/renderer/include/dofpass.hpp +++ b/engine/renderer/include/dofpass.hpp @@ -15,17 +15,17 @@ namespace prism { class DoFPass { public: DoFPass(GFX* gfx); - + void render(GFXCommandBuffer* command_buffer, Scene& scene); - + GFXTexture* far_field = nullptr; GFXTexture* normal_field = nullptr; - + GFXFramebuffer* far_framebuffer = nullptr; GFXFramebuffer* normal_framebuffer = nullptr; - + GFXRenderPass* renderpass = nullptr; - + private: GFXPipeline* pipeline = nullptr; }; diff --git a/engine/renderer/include/frustum.hpp b/engine/renderer/include/frustum.hpp index 8c4ee94..f6f7d3a 100755 --- a/engine/renderer/include/frustum.hpp +++ b/engine/renderer/include/frustum.hpp @@ -2,13 +2,13 @@ #include +#include "aabb.hpp" +#include "asset_types.hpp" +#include "components.hpp" #include "frustum.hpp" #include "matrix.hpp" -#include "vector.hpp" -#include "components.hpp" -#include "aabb.hpp" #include "plane.hpp" -#include "asset_types.hpp" +#include "vector.hpp" class Scene; diff --git a/engine/renderer/include/imguipass.hpp b/engine/renderer/include/imguipass.hpp index 7ac8b8a..de22b4a 100755 --- a/engine/renderer/include/imguipass.hpp +++ b/engine/renderer/include/imguipass.hpp @@ -2,8 +2,8 @@ #include -#include "pass.hpp" #include "file.hpp" +#include "pass.hpp" class GFXBuffer; class GFXCommandBuffer; @@ -14,7 +14,7 @@ struct ImDrawData; class ImGuiPass : public Pass { public: void initialize() override; - + void create_render_target_resources(RenderTarget& target) override; void render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, platform::window_ptr index) override; @@ -25,7 +25,7 @@ private: void update_buffers(RenderTarget& target, const ImDrawData& draw_data); std::unique_ptr font_file; - + GFXPipeline* pipeline = nullptr; GFXTexture* font_texture = nullptr; }; diff --git a/engine/renderer/include/materialcompiler.hpp b/engine/renderer/include/materialcompiler.hpp index af2c10b..5a3fc4f 100755 --- a/engine/renderer/include/materialcompiler.hpp +++ b/engine/renderer/include/materialcompiler.hpp @@ -15,12 +15,14 @@ constexpr int bone_buffer_index = 10; class MaterialCompiler { public: - GFXPipeline* create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false, bool cubemap = false); + GFXPipeline* + create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false, bool cubemap = false); GFXPipeline* create_skinned_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false); // generates static and skinned versions of the pipeline provided - std::tuple create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only = false); - + std::tuple + create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only = false); + ShaderSource compile_material_fragment(Material& material, bool use_ibl = true); }; diff --git a/engine/renderer/include/pass.hpp b/engine/renderer/include/pass.hpp index 351d79a..2428fb4 100755 --- a/engine/renderer/include/pass.hpp +++ b/engine/renderer/include/pass.hpp @@ -16,16 +16,19 @@ class RenderTarget; class Pass { public: virtual ~Pass() = default; - + virtual void initialize() {} - + virtual void create_render_target_resources([[maybe_unused]] RenderTarget& target) {} - virtual void render_scene([[maybe_unused]] Scene& scene, - [[maybe_unused]] GFXCommandBuffer* commandBuffer) {} - virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer, - [[maybe_unused]] RenderTarget& target, - [[maybe_unused]] platform::window_ptr index) {} - - virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { return nullptr; } + virtual void render_scene([[maybe_unused]] Scene& scene, [[maybe_unused]] GFXCommandBuffer* commandBuffer) {} + + virtual void render_post( + [[maybe_unused]] GFXCommandBuffer* commandBuffer, + [[maybe_unused]] RenderTarget& target, + [[maybe_unused]] platform::window_ptr index) {} + + virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { + return nullptr; + } }; diff --git a/engine/renderer/include/render_options.hpp b/engine/renderer/include/render_options.hpp index 0008fea..98d6a73 100755 --- a/engine/renderer/include/render_options.hpp +++ b/engine/renderer/include/render_options.hpp @@ -23,18 +23,18 @@ struct RenderOptions { DisplayColorSpace display_color_space = DisplayColorSpace::SRGB; TonemapOperator tonemapping = TonemapOperator::Linear; float exposure = 1.0f; - + float min_luminance = -8.0f; float max_luminance = 3.0f; - + bool enable_depth_of_field = false; float depth_of_field_strength = 3.0f; - + bool dynamic_resolution = false; double render_scale = 1.0f; - + int shadow_resolution = 2048; - + bool enable_aa = true; bool enable_ibl = true; bool enable_normal_mapping = true; diff --git a/engine/renderer/include/renderer.hpp b/engine/renderer/include/renderer.hpp index a2f160e..0e93890 100755 --- a/engine/renderer/include/renderer.hpp +++ b/engine/renderer/include/renderer.hpp @@ -1,19 +1,19 @@ #pragma once -#include -#include #include #include +#include +#include -#include "pass.hpp" +#include "common.hpp" #include "matrix.hpp" #include "object.hpp" -#include "common.hpp" -#include "render_options.hpp" +#include "pass.hpp" #include "path.hpp" -#include "shadercompiler.hpp" -#include "rendertarget.hpp" #include "platform.hpp" +#include "render_options.hpp" +#include "rendertarget.hpp" +#include "shadercompiler.hpp" class GFX; class GFXBuffer; @@ -58,14 +58,19 @@ namespace prism { void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, platform::window_ptr index); - void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, - prism::Extent extent, RenderTarget& target, controller_continuity &continuity); + void render_camera( + GFXCommandBuffer* command_buffer, + Scene& scene, + Object camera_object, + Camera& camera, + prism::Extent extent, + RenderTarget& target, + controller_continuity& continuity); void create_mesh_pipeline(Material& material) const; // passes - template - T* addPass(Args &&... args) { + template T* addPass(Args&&... args) { auto t = std::make_unique(args...); t->initialize(); @@ -93,7 +98,7 @@ namespace prism { ShaderSource register_shader(std::string_view shader_file); - void associate_shader_reload(std::string_view shader_file, const std::function &reload_function); + void associate_shader_reload(std::string_view shader_file, const std::function& reload_function); void reload_shader(std::string_view shader_file, std::string_view shader_source); @@ -142,7 +147,7 @@ namespace prism { GFXRenderPass* brdf_render_pass = nullptr; // histogram compute - GFXPipeline* histogram_pipeline = nullptr, *histogram_average_pipeline = nullptr; + GFXPipeline *histogram_pipeline = nullptr, *histogram_average_pipeline = nullptr; GFXBuffer* histogram_buffer = nullptr; GFXTexture* average_luminance_texture = nullptr; @@ -151,4 +156,4 @@ namespace prism { std::vector> passes; }; -} \ No newline at end of file +} // namespace prism \ No newline at end of file diff --git a/engine/renderer/include/rendertarget.hpp b/engine/renderer/include/rendertarget.hpp index 464733d..f0363d3 100755 --- a/engine/renderer/include/rendertarget.hpp +++ b/engine/renderer/include/rendertarget.hpp @@ -12,21 +12,22 @@ constexpr int RT_MAX_FRAMES_IN_FLIGHT = 3; class RenderTarget { public: prism::Extent extent; - + [[nodiscard]] prism::Extent get_render_extent() const { - return {static_cast(std::max(int(extent.width * render_options.render_scale), 1)), + return { + static_cast(std::max(int(extent.width * render_options.render_scale), 1)), static_cast(std::max(int(extent.height * render_options.render_scale), 1))}; } - + // offscreen GFXTexture* offscreenColorTexture = nullptr; GFXTexture* offscreenDepthTexture = nullptr; - + GFXFramebuffer* offscreenFramebuffer = nullptr; - + // mesh GFXBuffer* sceneBuffer = nullptr; - + // smaa GFXTexture* edge_texture = nullptr; GFXTexture* blend_texture = nullptr; @@ -37,13 +38,13 @@ public: // intermediary GFXTexture* mid_texture = nullptr; GFXFramebuffer* mid_framebuffer = nullptr; - + // imgui GFXBuffer* vertex_buffer[RT_MAX_FRAMES_IN_FLIGHT] = {}; int current_vertex_size[RT_MAX_FRAMES_IN_FLIGHT] = {}; - + GFXBuffer* index_buffer[RT_MAX_FRAMES_IN_FLIGHT] = {}; int current_index_size[RT_MAX_FRAMES_IN_FLIGHT] = {}; - + uint32_t current_frame = 0; }; diff --git a/engine/renderer/include/scenecapture.hpp b/engine/renderer/include/scenecapture.hpp index 036feb6..793632c 100755 --- a/engine/renderer/include/scenecapture.hpp +++ b/engine/renderer/include/scenecapture.hpp @@ -17,22 +17,23 @@ const int irradiance_cubemap_resolution = 32; class SceneCapture { public: explicit SceneCapture(GFX* gfx); - + void create_scene_resources(Scene& scene); - + void render(GFXCommandBuffer* command_buffer, Scene* scene); - - GFXPipeline* irradiancePipeline, *prefilterPipeline = nullptr, *skyPipeline = nullptr; - GFXRenderPass* renderPass = nullptr, *irradianceRenderPass = nullptr; - + + GFXPipeline *irradiancePipeline, *prefilterPipeline = nullptr, *skyPipeline = nullptr; + GFXRenderPass *renderPass = nullptr, *irradianceRenderPass = nullptr; + GFXTexture* environmentCube = nullptr; - GFXTexture* offscreenTexture = nullptr, *irradianceOffscreenTexture = nullptr, *prefilteredOffscreenTexture = nullptr; + GFXTexture *offscreenTexture = nullptr, *irradianceOffscreenTexture = nullptr, + *prefilteredOffscreenTexture = nullptr; GFXTexture* offscreenDepth = nullptr; - GFXFramebuffer* offscreenFramebuffer = nullptr, *irradianceFramebuffer = nullptr, *prefilteredFramebuffer = nullptr; - + GFXFramebuffer *offscreenFramebuffer = nullptr, *irradianceFramebuffer = nullptr, *prefilteredFramebuffer = nullptr; + GFXBuffer* sceneBuffer = nullptr; - + void createSkyResources(); void createIrradianceResources(); void createPrefilterResources(); diff --git a/engine/renderer/include/shadowpass.hpp b/engine/renderer/include/shadowpass.hpp index c72bda0..4ef4e96 100755 --- a/engine/renderer/include/shadowpass.hpp +++ b/engine/renderer/include/shadowpass.hpp @@ -1,8 +1,8 @@ #pragma once +#include "components.hpp" #include "math.hpp" #include "object.hpp" -#include "components.hpp" class GFX; class GFXCommandBuffer; @@ -18,39 +18,47 @@ struct CameraFrustum; class ShadowPass { public: explicit ShadowPass(GFX* gfx); - + void create_scene_resources(Scene& scene); - + void render(GFXCommandBuffer* command_buffer, Scene& scene); - + private: - void render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, Matrix4x4 light_matrix, Matrix4x4 model, prism::float3 light_position, Light::Type type, const CameraFrustum& frustum, int base_instance); - + void render_meshes( + GFXCommandBuffer* command_buffer, + Scene& scene, + Matrix4x4 light_matrix, + Matrix4x4 model, + prism::float3 light_position, + Light::Type type, + const CameraFrustum& frustum, + int base_instance); + void render_sun(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light); void render_spot(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light); void render_point(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light); - + int last_point_light = 0; int last_spot_light = 0; - + void create_render_passes(); void create_pipelines(); void create_offscreen_resources(); - + GFXRenderPass* render_pass = nullptr; GFXRenderPass* cube_render_pass = nullptr; - + GFXTexture* offscreen_color_texture = nullptr; GFXTexture* offscreen_depth = nullptr; GFXFramebuffer* offscreen_framebuffer = nullptr; GFXBuffer* point_location_buffer = nullptr; prism::float4* point_location_map = nullptr; - + // sun GFXPipeline* static_sun_pipeline = nullptr; GFXPipeline* skinned_sun_pipeline = nullptr; - + // spot GFXPipeline* static_spot_pipeline = nullptr; GFXPipeline* skinned_spot_pipeline = nullptr; diff --git a/engine/renderer/include/smaapass.hpp b/engine/renderer/include/smaapass.hpp index f22608f..b492828 100755 --- a/engine/renderer/include/smaapass.hpp +++ b/engine/renderer/include/smaapass.hpp @@ -18,9 +18,9 @@ namespace prism { class SMAAPass { public: explicit SMAAPass(GFX* gfx); - + void create_render_target_resources(RenderTarget& target); - + void render(GFXCommandBuffer* command_buffer, RenderTarget& target); private: @@ -30,9 +30,9 @@ private: GFXTexture* area_image = nullptr; GFXTexture* search_image = nullptr; - + GFXRenderPass* render_pass = nullptr; - + GFXPipeline* edge_pipeline = nullptr; GFXPipeline* blend_pipeline = nullptr; }; diff --git a/engine/renderer/src/dofpass.cpp b/engine/renderer/src/dofpass.cpp index 73407f4..effa16d 100755 --- a/engine/renderer/src/dofpass.cpp +++ b/engine/renderer/src/dofpass.cpp @@ -1,50 +1,47 @@ #include "dofpass.hpp" -#include "renderer.hpp" +#include "asset.hpp" +#include "engine.hpp" #include "gfx.hpp" #include "gfx_commandbuffer.hpp" -#include "engine.hpp" -#include "asset.hpp" +#include "renderer.hpp" AssetPtr aperture_texture; DoFPass::DoFPass(GFX* gfx) { aperture_texture = assetm->get(prism::base_domain / "textures/aperture.png"); - + GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "Depth of Field"; renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F); - + renderpass = gfx->create_render_pass(renderPassInfo); - - //const auto extent = renderer->get_render_extent(); + + // const auto extent = renderer->get_render_extent(); const auto extent = prism::Extent(); - + GFXShaderConstant width_constant = {}; width_constant.value = extent.width; - + GFXShaderConstant height_constant = {}; height_constant.index = 1; height_constant.value = extent.height; - + GFXGraphicsPipelineCreateInfo create_info = {}; create_info.shaders.vertex_src = ShaderSource(prism::path("shaders/dof.vert")); create_info.shaders.vertex_constants = {width_constant, height_constant}; create_info.shaders.fragment_src = ShaderSource(prism::path("shaders/dof.frag")); - + create_info.shader_input.bindings = { {0, GFXBindingType::StorageImage}, {1, GFXBindingType::Texture}, {3, GFXBindingType::Texture}, - {2, GFXBindingType::PushConstant} - }; + {2, GFXBindingType::PushConstant}}; + + create_info.shader_input.push_constants = {{sizeof(prism::float4), 0}}; - create_info.shader_input.push_constants = { - {sizeof(prism::float4), 0} - }; - create_info.render_pass = renderpass; - + create_info.blending.enable_blending = true; create_info.blending.src_rgb = GFXBlendFactor::SrcColor; create_info.blending.dst_rgb = GFXBlendFactor::One; @@ -52,7 +49,7 @@ DoFPass::DoFPass(GFX* gfx) { create_info.blending.dst_alpha = GFXBlendFactor::One; pipeline = gfx->create_graphics_pipeline(create_info); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "Normal Field"; textureInfo.width = extent.width; @@ -60,69 +57,69 @@ DoFPass::DoFPass(GFX* gfx) { textureInfo.format = GFXPixelFormat::RGBA_32F; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; textureInfo.samplingMode = SamplingMode::ClampToEdge; - + normal_field = gfx->create_texture(textureInfo); textureInfo.label = "Far Field"; far_field = gfx->create_texture(textureInfo); - + GFXFramebufferCreateInfo framebufferInfo = {}; framebufferInfo.render_pass = renderpass; - framebufferInfo.attachments = { normal_field }; - + framebufferInfo.attachments = {normal_field}; + normal_framebuffer = gfx->create_framebuffer(framebufferInfo); - - framebufferInfo.attachments = { far_field }; - + + framebufferInfo.attachments = {far_field}; + far_framebuffer = gfx->create_framebuffer(framebufferInfo); } void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) { - //const auto render_extent = renderer->get_render_extent(); + // const auto render_extent = renderer->get_render_extent(); const auto extent = prism::Extent(); const auto render_extent = prism::Extent(); - + // render far field GFXRenderPassBeginInfo beginInfo = {}; beginInfo.framebuffer = far_framebuffer; beginInfo.render_pass = renderpass; command_buffer->set_render_pass(beginInfo); - + Viewport viewport = {}; viewport.width = render_extent.width; viewport.height = render_extent.height; - + command_buffer->set_viewport(viewport); - + command_buffer->set_graphics_pipeline(pipeline); - - //command_buffer->bind_texture(renderer->offscreenColorTexture, 0); - //command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); + + // command_buffer->bind_texture(renderer->offscreenColorTexture, 0); + // command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); command_buffer->bind_texture(aperture_texture->handle, 3); - //const auto extent = renderer->get_render_extent(); + // const auto extent = renderer->get_render_extent(); prism::float4 params(render_options.depth_of_field_strength, 0.0, 0.0, 0.0); - + command_buffer->set_push_constant(¶ms, sizeof(prism::float4)); - + command_buffer->draw(0, 4, 0, extent.width * extent.height); - + // render normal field beginInfo.framebuffer = normal_framebuffer; - + command_buffer->set_render_pass(beginInfo); - + command_buffer->set_graphics_pipeline(pipeline); - - //command_buffer->bind_texture(renderer->offscreenColorTexture, 0); - //command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); + + // command_buffer->bind_texture(renderer->offscreenColorTexture, 0); + // command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); command_buffer->bind_texture(aperture_texture->handle, 2); params.y = 1; - + command_buffer->set_push_constant(¶ms, sizeof(prism::float4)); - + command_buffer->draw(0, 4, 0, extent.width * extent.height); } diff --git a/engine/renderer/src/frustum.cpp b/engine/renderer/src/frustum.cpp index 12af9d3..84378cc 100644 --- a/engine/renderer/src/frustum.cpp +++ b/engine/renderer/src/frustum.cpp @@ -4,58 +4,58 @@ CameraFrustum extract_frustum(const Matrix4x4 combined) { CameraFrustum frustum; - + // left plane frustum.planes[0].a = combined.data[0][3] + combined.data[0][0]; frustum.planes[0].b = combined.data[1][3] + combined.data[1][0]; frustum.planes[0].c = combined.data[2][3] + combined.data[2][0]; frustum.planes[0].d = combined.data[3][3] + combined.data[3][0]; - + // right plane frustum.planes[1].a = combined.data[0][3] - combined.data[0][0]; frustum.planes[1].b = combined.data[1][3] - combined.data[1][0]; frustum.planes[1].c = combined.data[2][3] - combined.data[2][0]; frustum.planes[1].d = combined.data[3][3] - combined.data[3][0]; - + // top plane frustum.planes[2].a = combined.data[0][3] - combined.data[0][1]; frustum.planes[2].b = combined.data[1][3] - combined.data[1][1]; frustum.planes[2].c = combined.data[2][3] - combined.data[2][1]; frustum.planes[2].d = combined.data[3][3] - combined.data[3][1]; - + // bottom plane frustum.planes[3].a = combined.data[0][3] + combined.data[0][1]; frustum.planes[3].b = combined.data[1][3] + combined.data[1][1]; frustum.planes[3].c = combined.data[2][3] + combined.data[2][1]; frustum.planes[3].d = combined.data[3][3] + combined.data[3][1]; - + // near plane frustum.planes[4].a = combined.data[0][2]; frustum.planes[4].b = combined.data[1][2]; frustum.planes[4].c = combined.data[2][2]; frustum.planes[4].d = combined.data[3][2]; - + // far plane frustum.planes[5].a = combined.data[0][3] - combined.data[0][2]; frustum.planes[5].b = combined.data[1][3] - combined.data[1][2]; frustum.planes[5].c = combined.data[2][3] - combined.data[2][2]; frustum.planes[5].d = combined.data[3][3] - combined.data[3][2]; - + return frustum; } CameraFrustum camera_extract_frustum(Scene& scene, prism::Object cam) { const auto camera_component = scene.get(cam); const Matrix4x4 combined = camera_component.perspective * camera_component.view; - + return extract_frustum(combined); } CameraFrustum normalize_frustum(const CameraFrustum& frustum) { CameraFrustum normalized_frustum; - for(int i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) normalized_frustum.planes[i] = normalize(frustum.planes[i]); - + return normalized_frustum; } @@ -65,24 +65,24 @@ bool test_point_plane(const Plane& plane, const prism::float3& point) { bool test_point_frustum(const CameraFrustum& frustum, const prism::float3& point) { bool inside_frustum = false; - - for(int i = 0; i < 6; i++) + + for (int i = 0; i < 6; i++) inside_frustum |= !test_point_plane(frustum.planes[i], point); - + return !inside_frustum; } bool test_aabb_frustum(const CameraFrustum& frustum, const prism::aabb& aabb) { - for(int i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) { int out = 0; - - for(const auto point : get_points(aabb)) + + for (const auto point : get_points(aabb)) out += (distance_to_point(frustum.planes[i], point) < 0.0) ? 1 : 0; - - if(out == 8) + + if (out == 8) return false; } - + return true; } @@ -92,6 +92,6 @@ prism::aabb get_aabb_for_part(const Transform& transform, const Mesh::Part& part aabb.max = transform.get_world_position() + part.bounding_box.max; aabb.min *= transform.scale; aabb.max *= transform.scale; - + return aabb; } diff --git a/engine/renderer/src/imguipass.cpp b/engine/renderer/src/imguipass.cpp index 90bda4f..45d0520 100755 --- a/engine/renderer/src/imguipass.cpp +++ b/engine/renderer/src/imguipass.cpp @@ -2,11 +2,11 @@ #include +#include "assertions.hpp" #include "engine.hpp" #include "gfx.hpp" #include "gfx_commandbuffer.hpp" #include "log.hpp" -#include "assertions.hpp" #include "renderer.hpp" void ImGuiPass::initialize() { @@ -20,7 +20,7 @@ void ImGuiPass::initialize() { } void ImGuiPass::create_render_target_resources(RenderTarget& target) { - if(pipeline == nullptr) { + if (pipeline == nullptr) { GFXGraphicsPipelineCreateInfo createInfo; createInfo.label = "ImGui"; createInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/imgui.vert")); @@ -53,18 +53,13 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) { createInfo.blending.enable_blending = true; createInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha; - createInfo.blending.src_alpha= GFXBlendFactor::SrcAlpha; + createInfo.blending.src_alpha = GFXBlendFactor::SrcAlpha; createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha; createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha; - createInfo.shader_input.push_constants = { - {sizeof(Matrix4x4), 0} - }; + createInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}}; - createInfo.shader_input.bindings = { - {1, GFXBindingType::PushConstant}, - {2, GFXBindingType::Texture} - }; + createInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}}; pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo); } @@ -72,61 +67,74 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) { void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const platform::window_ptr index) { ImDrawData* draw_data = nullptr; - if(!(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) { + if (!(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) { draw_data = ImGui::GetDrawData(); } else { auto viewport = ImGui::FindViewportByPlatformHandle(index); - if(viewport != nullptr) + if (viewport != nullptr) draw_data = viewport->DrawData; } - - if(draw_data == nullptr) + + if (draw_data == nullptr) return; - + const int framebuffer_width = static_cast(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); const int framebuffer_height = static_cast(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); - + if (framebuffer_width <= 0 || framebuffer_height <= 0) return; command_buffer->set_graphics_pipeline(pipeline); - if(draw_data->TotalVtxCount > 0) + if (draw_data->TotalVtxCount > 0) update_buffers(target, *draw_data); - const Matrix4x4 projection = prism::orthographic(draw_data->DisplayPos.x, - draw_data->DisplayPos.x + draw_data->DisplaySize.x, - draw_data->DisplayPos.y + draw_data->DisplaySize.y, - draw_data->DisplayPos.y, - 0.0f, - 1.0f); - + const Matrix4x4 projection = prism::orthographic( + draw_data->DisplayPos.x, + draw_data->DisplayPos.x + draw_data->DisplaySize.x, + draw_data->DisplayPos.y + draw_data->DisplaySize.y, + draw_data->DisplayPos.y, + 0.0f, + 1.0f); + command_buffer->set_push_constant(&projection, sizeof(Matrix4x4)); - + const ImVec2 clip_offset = draw_data->DisplayPos; const ImVec2 clip_scale = draw_data->FramebufferScale; int vertex_offset = 0; int index_offset = 0; - for(int n = 0; n < draw_data->CmdListsCount; n++) { + for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; - for(int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if(pcmd->TextureId != nullptr) + if (pcmd->TextureId != nullptr) command_buffer->bind_texture((GFXTexture*)pcmd->TextureId, 2); - - if(pcmd->UserCallback != nullptr) { + + if (pcmd->UserCallback != nullptr) { pcmd->UserCallback(cmd_list, pcmd); } else { - ImVec2 clip_min((pcmd->ClipRect.x - clip_offset.x) * clip_scale.x, (pcmd->ClipRect.y - clip_offset.y) * clip_scale.y); - ImVec2 clip_max((pcmd->ClipRect.z - clip_offset.x) * clip_scale.x, (pcmd->ClipRect.w - clip_offset.y) * clip_scale.y); + ImVec2 clip_min( + (pcmd->ClipRect.x - clip_offset.x) * clip_scale.x, + (pcmd->ClipRect.y - clip_offset.y) * clip_scale.y); + ImVec2 clip_max( + (pcmd->ClipRect.z - clip_offset.x) * clip_scale.x, + (pcmd->ClipRect.w - clip_offset.y) * clip_scale.y); // Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds - if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } - if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } - if (clip_max.x > framebuffer_width) { clip_max.x = (float)framebuffer_width; } - if (clip_max.y > framebuffer_height) { clip_max.y = (float)framebuffer_height; } + if (clip_min.x < 0.0f) { + clip_min.x = 0.0f; + } + if (clip_min.y < 0.0f) { + clip_min.y = 0.0f; + } + if (clip_max.x > framebuffer_width) { + clip_max.x = (float)framebuffer_width; + } + if (clip_max.y > framebuffer_height) { + clip_max.y = (float)framebuffer_height; + } if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) continue; @@ -138,14 +146,14 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y); command_buffer->set_scissor(scissor); - + command_buffer->set_vertex_buffer(target.vertex_buffer[target.current_frame], 0, 0); - command_buffer->set_index_buffer(target.index_buffer[target.current_frame], sizeof(ImDrawIdx) == 2 ? IndexType::UINT16 : IndexType::UINT32); - - command_buffer->draw_indexed(pcmd->ElemCount, - (index_offset + pcmd->IdxOffset), - (vertex_offset + pcmd->VtxOffset), 0); + command_buffer->set_index_buffer( + target.index_buffer[target.current_frame], + sizeof(ImDrawIdx) == 2 ? IndexType::UINT16 : IndexType::UINT32); + command_buffer->draw_indexed( + pcmd->ElemCount, (index_offset + pcmd->IdxOffset), (vertex_offset + pcmd->VtxOffset), 0); } } @@ -156,17 +164,18 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ void ImGuiPass::load_font(const std::string_view filename) { Expects(!filename.empty()); - + ImGuiIO& io = ImGui::GetIO(); - if(io.Fonts->Fonts.empty()) { + if (io.Fonts->Fonts.empty()) { auto file = prism::open_file(prism::base_domain / filename); - if(file != std::nullopt) { + if (file != std::nullopt) { font_file = std::make_unique(std::move(file.value())); font_file->read_all(); - - io.Fonts->AddFontFromMemoryTTF(font_file->cast_data(), font_file->size(), 15.0f * platform::get_monitor_dpi()); + + io.Fonts->AddFontFromMemoryTTF( + font_file->cast_data(), font_file->size(), 15.0f * platform::get_monitor_dpi()); ImGui::GetIO().FontGlobalScale = 1.0f / platform::get_monitor_dpi(); } else { prism::log("Failed to load font file for imgui!"); @@ -181,34 +190,38 @@ void ImGuiPass::create_font_texture() { unsigned char* pixels = nullptr; int width = -1, height = -1; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - + GFXTextureCreateInfo createInfo = {}; createInfo.label = "ImGui Font"; createInfo.width = width; createInfo.height = height; createInfo.format = GFXPixelFormat::RGBA8_UNORM; createInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; - + font_texture = engine->get_gfx()->create_texture(createInfo); engine->get_gfx()->copy_texture(font_texture, pixels, width * height * 4); - + io.Fonts->TexID = reinterpret_cast(font_texture); } void ImGuiPass::update_buffers(RenderTarget& target, const ImDrawData& draw_data) { const int new_vertex_size = draw_data.TotalVtxCount * sizeof(ImDrawVert); const int new_index_size = draw_data.TotalIdxCount * sizeof(ImDrawIdx); - + Expects(new_vertex_size > 0); Expects(new_index_size > 0); - - if(target.vertex_buffer[target.current_frame] == nullptr || target.current_vertex_size[target.current_frame] < new_vertex_size) { - target.vertex_buffer[target.current_frame] = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex); + + if (target.vertex_buffer[target.current_frame] == nullptr || + target.current_vertex_size[target.current_frame] < new_vertex_size) { + target.vertex_buffer[target.current_frame] = + engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex); target.current_vertex_size[target.current_frame] = new_vertex_size; } - - if(target.index_buffer[target.current_frame] == nullptr || target.current_index_size[target.current_frame] < new_index_size) { - target.index_buffer[target.current_frame] = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index); + + if (target.index_buffer[target.current_frame] == nullptr || + target.current_index_size[target.current_frame] < new_index_size) { + target.index_buffer[target.current_frame] = + engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index); target.current_index_size[target.current_frame] = new_index_size; } @@ -216,13 +229,13 @@ void ImGuiPass::update_buffers(RenderTarget& target, const ImDrawData& draw_data auto vtx_map = engine->get_gfx()->get_buffer_contents(target.vertex_buffer[target.current_frame]); auto idx_map = engine->get_gfx()->get_buffer_contents(target.index_buffer[target.current_frame]); - if(vtx_map == nullptr || idx_map == nullptr) + if (vtx_map == nullptr || idx_map == nullptr) return; auto vtx_dst = (ImDrawVert*)vtx_map; auto idx_dst = (ImDrawIdx*)idx_map; - for(int i = 0; i < draw_data.CmdListsCount; i++) { + for (int i = 0; i < draw_data.CmdListsCount; i++) { const ImDrawList* cmd_list = draw_data.CmdLists[i]; memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); diff --git a/engine/renderer/src/materialcompiler.cpp b/engine/renderer/src/materialcompiler.cpp index a56132b..9eedb06 100755 --- a/engine/renderer/src/materialcompiler.cpp +++ b/engine/renderer/src/materialcompiler.cpp @@ -1,37 +1,43 @@ #include "materialcompiler.hpp" +#include "engine.hpp" #include "file.hpp" #include "log.hpp" -#include "engine.hpp" -#include "string_utils.hpp" -#include "shadercompiler.hpp" #include "renderer.hpp" +#include "shadercompiler.hpp" +#include "string_utils.hpp" ShaderSource get_shader(const std::string& filename, bool skinned, bool cubemap) { auto shader_file = prism::open_file(prism::base_domain / filename); - if(!shader_file.has_value()) { + if (!shader_file.has_value()) { prism::log("Failed to open shader file {}!", filename); return {}; } ShaderStage stage; - if(filename.find("vert") != std::string::npos) { + if (filename.find("vert") != std::string::npos) { stage = ShaderStage::Vertex; } else { stage = ShaderStage::Fragment; } CompileOptions options; - if(skinned) + if (skinned) options.add_definition("BONE"); - if(cubemap) + if (cubemap) options.add_definition("CUBEMAP"); - return *shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(shader_file->read_as_string()), engine->get_gfx()->accepted_shader_language(), options); + return *shader_compiler.compile( + ShaderLanguage::GLSL, + stage, + ShaderSource(shader_file->read_as_string()), + engine->get_gfx()->accepted_shader_language(), + options); } -GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) { +GFXPipeline* +MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) { // take vertex src const std::string vertex_path = fmt::format("{}.glsl", createInfo.shaders.vertex_src.as_path().string()); @@ -43,30 +49,24 @@ GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateI createInfo.shaders.vertex_src = get_shader(vertex_path, false, cubemap); - if(positions_only) { - createInfo.vertex_input.inputs = { - {position_buffer_index, sizeof(prism::float3)} - }; + if (positions_only) { + createInfo.vertex_input.inputs = {{position_buffer_index, sizeof(prism::float3)}}; - createInfo.vertex_input.attributes = { - {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3} - }; + createInfo.vertex_input.attributes = {{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}}; } else { createInfo.vertex_input.inputs = { {position_buffer_index, sizeof(prism::float3)}, {normal_buffer_index, sizeof(prism::float3)}, {texcoord_buffer_index, sizeof(prism::float2)}, {tangent_buffer_index, sizeof(prism::float3)}, - {bitangent_buffer_index, sizeof(prism::float3)} - }; + {bitangent_buffer_index, sizeof(prism::float3)}}; createInfo.vertex_input.attributes = { {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}, {normal_buffer_index, 1, 0, GFXVertexFormat::FLOAT3}, {texcoord_buffer_index, 2, 0, GFXVertexFormat::FLOAT2}, {tangent_buffer_index, 3, 0, GFXVertexFormat::FLOAT3}, - {bitangent_buffer_index, 4, 0, GFXVertexFormat::FLOAT3} - }; + {bitangent_buffer_index, 4, 0, GFXVertexFormat::FLOAT3}}; } return engine->get_gfx()->create_graphics_pipeline(createInfo); @@ -80,19 +80,16 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate createInfo.shaders.vertex_src = get_shader(vertex_path, true, false); - createInfo.shader_input.bindings.push_back({ 14, GFXBindingType::StorageBuffer }); + createInfo.shader_input.bindings.push_back({14, GFXBindingType::StorageBuffer}); - if(positions_only) { + if (positions_only) { createInfo.vertex_input.inputs = { - {position_buffer_index, sizeof(prism::float3)}, - {bone_buffer_index, sizeof(BoneVertexData)} - }; + {position_buffer_index, sizeof(prism::float3)}, {bone_buffer_index, sizeof(BoneVertexData)}}; createInfo.vertex_input.attributes = { {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}, {bone_buffer_index, 4, offsetof(BoneVertexData, ids), GFXVertexFormat::INT4}, - {bone_buffer_index, 5, offsetof(BoneVertexData, weights), GFXVertexFormat::FLOAT4} - }; + {bone_buffer_index, 5, offsetof(BoneVertexData, weights), GFXVertexFormat::FLOAT4}}; } else { createInfo.vertex_input.inputs = { {position_buffer_index, sizeof(prism::float3)}, @@ -100,8 +97,7 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate {texcoord_buffer_index, sizeof(prism::float2)}, {tangent_buffer_index, sizeof(prism::float3)}, {bitangent_buffer_index, sizeof(prism::float3)}, - {bone_buffer_index, sizeof(BoneVertexData)} - }; + {bone_buffer_index, sizeof(BoneVertexData)}}; createInfo.vertex_input.attributes = { {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}, @@ -117,7 +113,8 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate return engine->get_gfx()->create_graphics_pipeline(createInfo); } -std::tuple MaterialCompiler::create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only) { +std::tuple +MaterialCompiler::create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only) { auto st = create_static_pipeline(createInfo, positions_only); auto ss = create_skinned_pipeline(createInfo, positions_only); @@ -125,7 +122,7 @@ std::tuple MaterialCompiler::create_pipeline_permuta } constexpr std::string_view struct_info = -R"(layout (constant_id = 0) const int max_materials = 25; + R"(layout (constant_id = 0) const int max_materials = 25; layout (constant_id = 1) const int max_lights = 25; layout (constant_id = 2) const int max_spot_lights = 4; layout (constant_id = 3) const int max_probes = 4; @@ -159,12 +156,12 @@ layout(push_constant) uniform PushConstant {{ )"; ShaderSource MaterialCompiler::compile_material_fragment(Material& material, bool use_ibl) { - if(!render_options.enable_ibl) + if (!render_options.enable_ibl) use_ibl = false; auto src = fmt::memory_buffer(); - switch(render_options.shadow_filter) { + switch (render_options.shadow_filter) { case ShadowFilter::None: format_to(std::back_inserter(src), "#define SHADOW_FILTER_NONE\n"); break; @@ -176,31 +173,35 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo break; } - format_to(std::back_inserter(src), + format_to( + std::back_inserter(src), R"(layout (location = 0) in vec3 in_frag_pos; layout(location = 1) in vec3 in_normal; layout(location = 2) in vec2 in_uv; layout(location = 0) out vec4 frag_output; )"); - if(render_options.enable_point_shadows) { - format_to(std::back_inserter(src), - R"(#define POINT_SHADOWS_SUPPORTED + if (render_options.enable_point_shadows) { + format_to( + std::back_inserter(src), + R"(#define POINT_SHADOWS_SUPPORTED layout (binding = 3) uniform samplerCubeArray point_shadow; )"); } format_to(std::back_inserter(src), struct_info); - if(use_ibl) { - format_to(std::back_inserter(src), + if (use_ibl) { + format_to( + std::back_inserter(src), R"(layout (binding = 7) uniform samplerCubeArray irrandianceSampler; layout (binding = 8) uniform samplerCubeArray prefilterSampler; layout (binding = 9) uniform sampler2D brdfSampler; )"); } - format_to(std::back_inserter(src), + format_to( + std::back_inserter(src), R"(layout(location = 4) in vec4 fragPosLightSpace; layout(location = 5) in mat3 in_tbn; layout(location = 14) in vec4 fragPostSpotLightSpace[max_spot_lights]; @@ -213,20 +214,21 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo // insert samplers as needed int sampler_index = 10; - if(material.colorProperty.type == DataType::AssetTexture) { + if (material.colorProperty.type == DataType::AssetTexture) { material.bound_textures[sampler_index] = material.colorProperty.value_tex; format_to(std::back_inserter(src), "layout(binding = {}) uniform sampler2D colorTexture;\n", sampler_index++); } - if(material.normalProperty.type == DataType::AssetTexture) { + if (material.normalProperty.type == DataType::AssetTexture) { material.bound_textures[sampler_index] = material.normalProperty.value_tex; format_to(std::back_inserter(src), "layout(binding = {}) uniform sampler2D normalTexture;\n", sampler_index++); } - if(use_ibl) { - format_to(std::back_inserter(src), + if (use_ibl) { + format_to( + std::back_inserter(src), R"(vec3 get_reflect(int i, vec3 final_normal) {{ const vec3 direction = normalize(in_frag_pos - scene.camPos.xyz); const vec3 reflection = reflect(direction, normalize(final_normal)); @@ -243,8 +245,9 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo )"); } - if(render_options.enable_normal_shadowing) { - format_to(std::back_inserter(src), + if (render_options.enable_normal_shadowing) { + format_to( + std::back_inserter(src), R"(float calculate_normal_lighting(in sampler2D normal_map, const vec3 normal, const vec3 light_dir) {{ float height_scale = 0.8; float sample_count = 100.0; @@ -278,8 +281,9 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo )"); } - if(use_ibl) { - format_to(std::back_inserter(src), + if (use_ibl) { + format_to( + std::back_inserter(src), R"(vec3 ibl(const int probe, const ComputedSurfaceInfo surface_info, const float intensity) {{ const vec3 F = fresnel_schlick_roughness(surface_info.NdotV, surface_info.F0, surface_info.roughness); const vec3 R = get_reflect(probe, surface_info.N); @@ -293,25 +297,32 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo )"); } - format_to(std::back_inserter(src), "void main() {{\n"); + format_to(std::back_inserter(src), "void main() {{\n"); - if(material.colorProperty.type == DataType::Vector3) { - format_to(std::back_inserter(src), "vec3 Color = vec3({}, {}, {});\n", material.colorProperty.value.x, material.colorProperty.value.y, material.colorProperty.value.z); - } else if(material.colorProperty.type == DataType::AssetTexture) { + if (material.colorProperty.type == DataType::Vector3) { + format_to( + std::back_inserter(src), + "vec3 Color = vec3({}, {}, {});\n", + material.colorProperty.value.x, + material.colorProperty.value.y, + material.colorProperty.value.z); + } else if (material.colorProperty.type == DataType::AssetTexture) { format_to(std::back_inserter(src), "vec3 Color = texture(colorTexture, in_uv).rgb;\n"); - } else if(material.colorProperty.type == DataType::Float) { - format_to(std::back_inserter(src),"vec3 Color = vec3({}});\n", material.colorProperty.float_value); + } else if (material.colorProperty.type == DataType::Float) { + format_to(std::back_inserter(src), "vec3 Color = vec3({}});\n", material.colorProperty.float_value); } - format_to(std::back_inserter(src), - R"(vec3 final_diffuse_color = from_srgb_to_linear(Color); + format_to( + std::back_inserter(src), + R"(vec3 final_diffuse_color = from_srgb_to_linear(Color); float final_roughness = scene.materials[inMaterialIndex].info.y; float final_metallic = scene.materials[inMaterialIndex].info.x; )"); - if(material.normalProperty.type == DataType::AssetTexture) { - format_to(std::back_inserter(src), - R"(vec3 final_normal = texture(normalTexture, in_uv).rgb; + if (material.normalProperty.type == DataType::AssetTexture) { + format_to( + std::back_inserter(src), + R"(vec3 final_normal = texture(normalTexture, in_uv).rgb; final_normal = final_normal * 2.0 - 1.0; final_normal = in_tbn * final_normal; )"); @@ -319,8 +330,9 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo format_to(std::back_inserter(src), "vec3 final_normal = in_normal;\n"); } - format_to(std::back_inserter(src), - R"(ComputedSurfaceInfo surface_info = compute_surface(final_diffuse_color.rgb, final_normal, final_metallic, final_roughness); + format_to( + std::back_inserter(src), + R"(ComputedSurfaceInfo surface_info = compute_surface(final_diffuse_color.rgb, final_normal, final_metallic, final_roughness); vec3 Lo = vec3(0); for(int i = 0; i < scene.numLights; i++) {{ const int type = int(scene.lights[i].positionType.w); @@ -339,16 +351,22 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo SurfaceBRDF surface_brdf = brdf(light_info.direction, surface_info); )"); - if(render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture && render_options.enable_normal_shadowing) { - format_to(std::back_inserter(src), "light_info.radiance *= calculate_normal_lighting(normalTexture, final_normal, light_info.direction);\n"); + if (render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture && + render_options.enable_normal_shadowing) { + format_to( + std::back_inserter(src), + "light_info.radiance *= calculate_normal_lighting(normalTexture, final_normal, light_info.direction);\n"); } - format_to(std::back_inserter(src), "Lo += ((surface_brdf.specular + surface_brdf.diffuse) * light_info.radiance * surface_brdf.NdotL) * scene.lights[i].colorSize.rgb;\n \ + format_to( + std::back_inserter(src), + "Lo += ((surface_brdf.specular + surface_brdf.diffuse) * light_info.radiance * surface_brdf.NdotL) * scene.lights[i].colorSize.rgb;\n \ }}\n"); - if(use_ibl) { - format_to(std::back_inserter(src), - R"(vec3 ambient = vec3(0.0); + if (use_ibl) { + format_to( + std::back_inserter(src), + R"(vec3 ambient = vec3(0.0); float sum = 0.0; for(int i = 0; i < max_probes; i++) {{ if(scene.probes[i].position.w == 1) {{ @@ -376,5 +394,9 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo format_to(std::back_inserter(src), "}}\n"); - return *shader_compiler.compile(ShaderLanguage::GLSL, ShaderStage::Fragment, ShaderSource(to_string(src)), engine->get_gfx()->accepted_shader_language()); + return *shader_compiler.compile( + ShaderLanguage::GLSL, + ShaderStage::Fragment, + ShaderSource(to_string(src)), + engine->get_gfx()->accepted_shader_language()); } diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index fe902b3..fa60a97 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -1,22 +1,22 @@ #include "renderer.hpp" -#include "gfx_commandbuffer.hpp" -#include "math.hpp" +#include "assertions.hpp" +#include "debug.hpp" +#include "dofpass.hpp" #include "file.hpp" -#include "scene.hpp" -#include "vector.hpp" -#include "imguipass.hpp" +#include "frustum.hpp" #include "gfx.hpp" +#include "gfx_commandbuffer.hpp" +#include "imguipass.hpp" +#include "materialcompiler.hpp" +#include "math.hpp" #include "pass.hpp" +#include "scene.hpp" +#include "scenecapture.hpp" +#include "shadercompiler.hpp" #include "shadowpass.hpp" #include "smaapass.hpp" -#include "scenecapture.hpp" -#include "materialcompiler.hpp" -#include "assertions.hpp" -#include "dofpass.hpp" -#include "frustum.hpp" -#include "shadercompiler.hpp" -#include "debug.hpp" +#include "vector.hpp" using prism::renderer; @@ -59,7 +59,7 @@ struct SkyPushConstant { renderer::renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) { Expects(gfx != nullptr); - + shader_compiler.set_include_path(prism::get_domain_path(prism::domain::base).string() + "/shaders"); create_dummy_texture(); @@ -68,12 +68,12 @@ renderer::renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) { shadow_pass = std::make_unique(gfx); scene_capture = std::make_unique(gfx); smaa_pass = std::make_unique(gfx); - - if(enable_imgui) + + if (enable_imgui) addPass(); generate_brdf(); - + GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "Offscreen"; renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F); @@ -94,28 +94,26 @@ renderer::~renderer() = default; RenderTarget* renderer::allocate_render_target(const prism::Extent extent) { auto target = new RenderTarget(); - + resize_render_target(*target, extent); - + render_targets.push_back(target); - + return target; } void renderer::resize_render_target(RenderTarget& target, const prism::Extent extent) { target.extent = extent; - + create_render_target_resources(target); smaa_pass->create_render_target_resources(target); create_post_pipelines(); - for(auto& pass : passes) + for (auto& pass : passes) pass->create_render_target_resources(target); } -void renderer::recreate_all_render_targets() { - -} +void renderer::recreate_all_render_targets() {} void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, platform::window_ptr index) { const auto extent = target.extent; @@ -133,7 +131,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->set_viewport(viewport); - for (auto &pass: passes) + for (auto& pass : passes) pass->render_post(commandbuffer, target, index); return; @@ -163,20 +161,20 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->set_render_pass(beginInfo); - const auto &cameras = scene->get_all(); - for (auto&[obj, camera]: cameras) { + const auto& cameras = scene->get_all(); + for (auto& [obj, camera] : cameras) { const bool requires_limited_perspective = render_options.enable_depth_of_field; if (requires_limited_perspective) { - camera.perspective = prism::perspective(radians(camera.fov), - static_cast(render_extent.width) / - static_cast(render_extent.height), - camera.near, - 100.0f); + camera.perspective = prism::perspective( + radians(camera.fov), + static_cast(render_extent.width) / static_cast(render_extent.height), + camera.near, + 100.0f); } else { - camera.perspective = prism::infinite_perspective(radians(camera.fov), - static_cast(render_extent.width) / - static_cast(render_extent.height), - camera.near); + camera.perspective = prism::infinite_perspective( + radians(camera.fov), + static_cast(render_extent.width) / static_cast(render_extent.height), + camera.near); } camera.view = inverse(scene->get(obj).model); @@ -209,33 +207,30 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->set_compute_pipeline(histogram_pipeline); commandbuffer->bind_texture(target.offscreenColorTexture, 0); - commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, - sizeof(uint32_t) * 256); + commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256); - const float lum_range = - render_options.max_luminance - render_options.min_luminance; + const float lum_range = render_options.max_luminance - render_options.min_luminance; - prism::float4 params = - prism::float4(render_options.min_luminance, 1.0f / lum_range, - static_cast(render_extent.width), - static_cast(render_extent.height)); + prism::float4 params = prism::float4( + render_options.min_luminance, + 1.0f / lum_range, + static_cast(render_extent.width), + static_cast(render_extent.height)); commandbuffer->set_push_constant(¶ms, sizeof(prism::float4)); commandbuffer->dispatch( - static_cast( - std::ceil(static_cast(render_extent.width) / 16.0f)), - static_cast( - std::ceil(static_cast(render_extent.height) / 16.0f)), + static_cast(std::ceil(static_cast(render_extent.width) / 16.0f)), + static_cast(std::ceil(static_cast(render_extent.height) / 16.0f)), 1); commandbuffer->set_compute_pipeline(histogram_average_pipeline); - commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, - sizeof(uint32_t) * 256); + commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256); params = prism::float4( - render_options.min_luminance, lum_range, + render_options.min_luminance, + lum_range, std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), static_cast(render_extent.width * render_extent.height)); @@ -250,14 +245,18 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge pc.options.x = render_options.enable_aa; pc.options.z = render_options.exposure; - if(render_options.enable_depth_of_field) + if (render_options.enable_depth_of_field) pc.options.w = 2; pc.transform_ops.x = static_cast(render_options.display_color_space); pc.transform_ops.y = static_cast(render_options.tonemapping); const auto [width, height] = render_extent; - pc.viewport = prism::float4(1.0f / static_cast(width), 1.0f / static_cast(height), static_cast(width), static_cast(height)); + pc.viewport = prism::float4( + 1.0f / static_cast(width), + 1.0f / static_cast(height), + static_cast(width), + static_cast(height)); // continue post processing // first we want to manually "expose" the scene, otherwise AA wouldn't work properly @@ -284,7 +283,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->bind_texture(average_luminance_texture, 6); - if(render_options.enable_depth_of_field) + if (render_options.enable_depth_of_field) commandbuffer->bind_texture(dof_pass->far_field, 7); else commandbuffer->bind_texture(dummy_texture, 7); @@ -325,7 +324,7 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge commandbuffer->bind_texture(dummy_texture, 3); } - if(auto texture = get_requested_texture(PassTextureType::SelectionSobel)) + if (auto texture = get_requested_texture(PassTextureType::SelectionSobel)) commandbuffer->bind_texture(texture, 5); else commandbuffer->bind_texture(dummy_texture, 5); @@ -338,113 +337,125 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge } commandbuffer->push_group("Extra Passes"); - - for(auto& pass : passes) + + for (auto& pass : passes) pass->render_post(commandbuffer, target, index); - + commandbuffer->pop_group(); target.current_frame = (target.current_frame + 1) % RT_MAX_FRAMES_IN_FLIGHT; } -void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, prism::Extent extent, RenderTarget& target, controller_continuity& continuity) { +void renderer::render_camera( + GFXCommandBuffer* command_buffer, + Scene& scene, + Object camera_object, + Camera& camera, + prism::Extent extent, + RenderTarget& target, + controller_continuity& continuity) { // frustum test const auto frustum = normalize_frustum(camera_extract_frustum(scene, camera_object)); - + SceneInformation sceneInfo = {}; sceneInfo.lightspace = scene.lightSpace; sceneInfo.options = prism::float4(1, 0, 0, 0); sceneInfo.camPos = scene.get(camera_object).get_world_position(); - sceneInfo.camPos.w = 2.0f * camera.near * std::tan(camera.fov * 0.5f) * (static_cast(extent.width) / static_cast(extent.height)); - sceneInfo.vp = camera.perspective * camera.view; + sceneInfo.camPos.w = 2.0f * camera.near * std::tan(camera.fov * 0.5f) * + (static_cast(extent.width) / static_cast(extent.height)); + sceneInfo.vp = camera.perspective * camera.view; int last_point_light = 0; - for(const auto& [obj, light] : scene.get_all()) { + for (const auto& [obj, light] : scene.get_all()) { SceneLight sl; sl.positionType = prism::float4(scene.get(obj).get_world_position(), static_cast(light.type)); prism::float3 front = prism::float3(0.0f, 0.0f, 1.0f) * scene.get(obj).rotation; - + sl.directionPower = prism::float4(-front, light.power); sl.colorSize = prism::float4(utility::from_srgb_to_linear(light.color), radians(light.spot_size)); sl.shadowsEnable = prism::float4(light.enable_shadows, radians(light.size), last_point_light, 0); - if(light.enable_shadows) + if (light.enable_shadows) last_point_light++; sceneInfo.lights[sceneInfo.numLights++] = sl; } - - for(int i = 0; i < max_spot_shadows; i++) + + for (int i = 0; i < max_spot_shadows; i++) sceneInfo.spotLightSpaces[i] = scene.spotLightSpaces[i]; - + int last_probe = 0; - for(const auto& [obj, probe] : scene.get_all()) { + for (const auto& [obj, probe] : scene.get_all()) { SceneProbe p; p.position = prism::float4(scene.get(obj).position, probe.is_sized ? 1.0f : 2.0f); p.size = prism::float4(probe.size, probe.intensity); - + sceneInfo.probes[last_probe++] = p; } - + int numMaterialsInBuffer = 0; std::map material_indices; - + const auto& meshes = scene.get_all(); - for(const auto& [obj, mesh] : meshes) { - if(!mesh.mesh) + for (const auto& [obj, mesh] : meshes) { + if (!mesh.mesh) continue; - - if(mesh.materials.empty()) + + if (mesh.materials.empty()) continue; - - for(auto& material : mesh.materials) { - if(!material) + + for (auto& material : mesh.materials) { + if (!material) continue; - - if(material->static_pipeline == nullptr || material->skinned_pipeline == nullptr) + + if (material->static_pipeline == nullptr || material->skinned_pipeline == nullptr) create_mesh_pipeline(*material.handle); - - if(!material_indices.count(material.handle)) { + + if (!material_indices.count(material.handle)) { sceneInfo.materials[numMaterialsInBuffer].info.x = material->metallic; sceneInfo.materials[numMaterialsInBuffer].info.y = material->roughness; material_indices[material.handle] = numMaterialsInBuffer++; } } - + struct PushConstant { Matrix4x4 m; } pc; - + pc.m = scene.get(obj).model; - + command_buffer->set_vertex_buffer(mesh.mesh->position_buffer, 0, position_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->normal_buffer, 0, normal_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->texture_coord_buffer, 0, texcoord_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->tangent_buffer, 0, tangent_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->bitangent_buffer, 0, bitangent_buffer_index); - - if(!mesh.mesh->bones.empty()) + + if (!mesh.mesh->bones.empty()) command_buffer->set_vertex_buffer(mesh.mesh->bone_buffer, 0, bone_buffer_index); - + command_buffer->set_index_buffer(mesh.mesh->index_buffer, IndexType::UINT32); - - for(const auto& part : mesh.mesh->parts) { + + for (const auto& part : mesh.mesh->parts) { const int material_index = part.material_override == -1 ? 0 : part.material_override; - - if(material_index >= mesh.materials.size()) + + if (material_index >= mesh.materials.size()) continue; - - if(mesh.materials[material_index].handle == nullptr || mesh.materials[material_index]->static_pipeline == nullptr) + + if (mesh.materials[material_index].handle == nullptr || + mesh.materials[material_index]->static_pipeline == nullptr) continue; - - if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) + + if (render_options.enable_frustum_culling && + !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) continue; - - command_buffer->set_graphics_pipeline(mesh.mesh->bones.empty() ? mesh.materials[material_index]->static_pipeline : mesh.materials[material_index]->skinned_pipeline); - + + command_buffer->set_graphics_pipeline( + mesh.mesh->bones.empty() ? mesh.materials[material_index]->static_pipeline + : mesh.materials[material_index]->skinned_pipeline); + command_buffer->bind_shader_buffer(target.sceneBuffer, 0, 1, sizeof(SceneInformation)); command_buffer->bind_texture(scene.depthTexture, 2); @@ -454,43 +465,47 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj command_buffer->bind_texture(scene.prefilteredCubeArray, 8); command_buffer->bind_texture(brdf_texture, 9); - if(!mesh.mesh->bones.empty()) + if (!mesh.mesh->bones.empty()) command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 14, sizeof(Matrix4x4) * 128); - + command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - - for(const auto& [index, texture] : mesh.materials[material_index]->bound_textures) { + + for (const auto& [index, texture] : mesh.materials[material_index]->bound_textures) { GFXTexture* texture_to_bind = dummy_texture; - if(texture) + if (texture) texture_to_bind = texture->handle; - + command_buffer->bind_texture(texture_to_bind, index); } - - command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, material_indices.at(*mesh.materials[material_index])); + + command_buffer->draw_indexed( + part.index_count, + part.index_offset, + part.vertex_offset, + material_indices.at(*mesh.materials[material_index])); } } - + SkyPushConstant pc; pc.view = matrix_from_quat(scene.get(camera_object).rotation); pc.aspect = static_cast(extent.width) / static_cast(extent.height); - - for(const auto& [obj, light] : scene.get_all()) { - if(light.type == Light::Type::Sun) + + for (const auto& [obj, light] : scene.get_all()) { + if (light.type == Light::Type::Sun) pc.sun_position_fov = prism::float4(scene.get(obj).get_world_position(), radians(camera.fov)); } - + command_buffer->set_graphics_pipeline(sky_pipeline); - + command_buffer->set_push_constant(&pc, sizeof(SkyPushConstant)); - + command_buffer->draw(0, 4, 0, 1); - - if(render_options.enable_extra_passes) { - for(auto& pass : passes) + + if (render_options.enable_extra_passes) { + for (auto& pass : passes) pass->render_scene(scene, command_buffer); } - + gfx->copy_buffer(target.sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation)); } @@ -498,34 +513,34 @@ void renderer::create_mesh_pipeline(Material& material) const { GFXShaderConstant materials_constant = {}; materials_constant.type = GFXShaderConstant::Type::Integer; materials_constant.value = max_scene_materials; - + GFXShaderConstant lights_constant = {}; lights_constant.index = 1; lights_constant.type = GFXShaderConstant::Type::Integer; lights_constant.value = max_scene_lights; - + GFXShaderConstant spot_lights_constant = {}; spot_lights_constant.index = 2; spot_lights_constant.type = GFXShaderConstant::Type::Integer; spot_lights_constant.value = max_spot_shadows; - + GFXShaderConstant probes_constant = {}; probes_constant.index = 3; probes_constant.type = GFXShaderConstant::Type::Integer; probes_constant.value = max_environment_probes; - + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Mesh " + material.path; pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/mesh.vert")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/mesh.frag")); - - pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; - pipelineInfo.shaders.fragment_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; - - pipelineInfo.shader_input.push_constants = { - {sizeof(Matrix4x4), 0} - }; - + + pipelineInfo.shaders.vertex_constants = { + materials_constant, lights_constant, spot_lights_constant, probes_constant}; + pipelineInfo.shaders.fragment_constants = { + materials_constant, lights_constant, spot_lights_constant, probes_constant}; + + pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}}; + pipelineInfo.shader_input.bindings = { {1, GFXBindingType::StorageBuffer}, {0, GFXBindingType::PushConstant}, @@ -534,15 +549,14 @@ void renderer::create_mesh_pipeline(Material& material) const { {6, GFXBindingType::Texture}, {7, GFXBindingType::Texture}, {8, GFXBindingType::Texture}, - {9, GFXBindingType::Texture} - }; - + {9, GFXBindingType::Texture}}; + pipelineInfo.render_pass = offscreen_render_pass; pipelineInfo.depth.depth_mode = GFXDepthMode::Less; pipelineInfo.rasterization.culling_mode = GFXCullingMode::Backface; pipelineInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha; pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha; - + pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material); for (auto [index, texture] : material.bound_textures) { @@ -552,16 +566,17 @@ void renderer::create_mesh_pipeline(Material& material) const { pipelineInfo.shader_input.bindings.push_back(binding); } - + auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo); - + material.static_pipeline = static_pipeline; material.skinned_pipeline = skinned_pipeline; - + pipelineInfo.render_pass = scene_capture->renderPass; - - pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material, false); // scene capture does not use IBL - + + pipelineInfo.shaders.fragment_src = + material_compiler.compile_material_fragment(material, false); // scene capture does not use IBL + pipelineInfo.shader_input.push_constants[0].size += sizeof(Matrix4x4); material.capture_pipeline = material_compiler.create_static_pipeline(pipelineInfo, false, true); @@ -592,8 +607,7 @@ void renderer::create_render_target_resources(RenderTarget& target) { textureInfo.width = extent.width; textureInfo.height = extent.height; textureInfo.format = GFXPixelFormat::RGBA_32F; - textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | - GFXTextureUsage::Storage; + textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | GFXTextureUsage::Storage; textureInfo.samplingMode = SamplingMode::ClampToEdge; target.offscreenColorTexture = gfx->create_texture(textureInfo); @@ -630,28 +644,26 @@ void renderer::create_render_target_resources(RenderTarget& target) { target.mid_framebuffer = gfx->create_framebuffer(framebufferInfo); } - + target.sceneBuffer = gfx->create_buffer(nullptr, sizeof(SceneInformation), true, GFXBufferUsage::Storage); } void renderer::create_post_pipelines() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Post"; - + pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/post.vert")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/post.frag")); - + pipelineInfo.shader_input.bindings = { {0, GFXBindingType::PushConstant}, {1, GFXBindingType::Texture}, // colorSampler {3, GFXBindingType::Texture}, // blendSampler - {5, GFXBindingType::Texture} // sobelSampler - }; - - pipelineInfo.shader_input.push_constants = { - {sizeof(PostPushConstants), 0} + {5, GFXBindingType::Texture} // sobelSampler }; + pipelineInfo.shader_input.push_constants = {{sizeof(PostPushConstants), 0}}; + post_pipeline = gfx->create_graphics_pipeline(pipelineInfo); pipelineInfo.label = "Expose"; @@ -663,7 +675,7 @@ void renderer::create_post_pipelines() { {0, GFXBindingType::PushConstant}, {1, GFXBindingType::Texture}, // colorSampler {6, GFXBindingType::Texture}, // averageLuminanceSampler - {7, GFXBindingType::Texture} // farFieldSampler + {7, GFXBindingType::Texture} // farFieldSampler }; expose_pipeline = gfx->create_graphics_pipeline(pipelineInfo); @@ -677,13 +689,9 @@ void renderer::create_sky_pipeline() { pipelineInfo.shaders.vertex_src = register_shader("shaders/sky.vert"); pipelineInfo.shaders.fragment_src = register_shader("shaders/sky.frag"); - pipelineInfo.shader_input.bindings = { - {0, GFXBindingType::PushConstant} - }; + pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}}; - pipelineInfo.shader_input.push_constants = { - {sizeof(SkyPushConstant), 0} - }; + pipelineInfo.shader_input.push_constants = {{sizeof(SkyPushConstant), 0}}; pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; @@ -697,17 +705,17 @@ void renderer::generate_brdf() { renderPassInfo.will_use_in_shader = true; brdf_render_pass = gfx->create_render_pass(renderPassInfo); - + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "BRDF"; - + pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/brdf.vert")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/brdf.frag")); - + pipelineInfo.render_pass = brdf_render_pass; brdf_pipeline = gfx->create_graphics_pipeline(pipelineInfo); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "BRDF LUT"; textureInfo.format = GFXPixelFormat::R8G8_SFLOAT; @@ -716,33 +724,33 @@ void renderer::generate_brdf() { textureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::Attachment; brdf_texture = gfx->create_texture(textureInfo); - + GFXFramebufferCreateInfo framebufferInfo = {}; framebufferInfo.attachments = {brdf_texture}; framebufferInfo.render_pass = brdf_render_pass; brdf_framebuffer = gfx->create_framebuffer(framebufferInfo); - + // render GFXCommandBuffer* command_buffer = gfx->acquire_command_buffer(false); - + GFXRenderPassBeginInfo beginInfo = {}; beginInfo.render_pass = brdf_render_pass; beginInfo.framebuffer = brdf_framebuffer; beginInfo.render_area.extent = {brdf_resolution, brdf_resolution}; - + command_buffer->set_render_pass(beginInfo); - + command_buffer->set_graphics_pipeline(brdf_pipeline); - + Viewport viewport = {}; viewport.width = brdf_resolution; viewport.height = brdf_resolution; - + command_buffer->set_viewport(viewport); - + command_buffer->draw(0, 4, 0, 1); - + gfx->submit(command_buffer, nullptr); } @@ -752,91 +760,93 @@ void renderer::create_histogram_resources() { create_info.compute_src = ShaderSource(prism::path("shaders/histogram.comp")); create_info.workgroup_size_x = 16; create_info.workgroup_size_y = 16; - - create_info.shader_input.bindings = { - {0, GFXBindingType::StorageImage}, - {1, GFXBindingType::StorageBuffer}, - {2, GFXBindingType::PushConstant} - }; - create_info.shader_input.push_constants = { - {sizeof(prism::float4), 0} - }; - + create_info.shader_input.bindings = { + {0, GFXBindingType::StorageImage}, {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::PushConstant}}; + + create_info.shader_input.push_constants = {{sizeof(prism::float4), 0}}; + histogram_pipeline = gfx->create_compute_pipeline(create_info); create_info.label = "Histogram Average"; create_info.compute_src = ShaderSource(prism::path("shaders/histogram-average.comp")); create_info.workgroup_size_x = 256; create_info.workgroup_size_y = 1; - + histogram_average_pipeline = gfx->create_compute_pipeline(create_info); histogram_buffer = gfx->create_buffer(nullptr, sizeof(uint32_t) * 256, false, GFXBufferUsage::Storage); - + GFXTextureCreateInfo texture_info = {}; texture_info.label = "Average Luminance Store"; texture_info.width = 1; texture_info.height = 1; texture_info.format = GFXPixelFormat::R_16F; texture_info.usage = GFXTextureUsage::Sampled | GFXTextureUsage::ShaderWrite | GFXTextureUsage::Storage; - + average_luminance_texture = gfx->create_texture(texture_info); } ShaderSource renderer::register_shader(const std::string_view shader_file) { - if(!reloading_shader) { + if (!reloading_shader) { RegisteredShader shader; shader.filename = shader_file; - + registered_shaders.push_back(shader); } - + std::string found_shader_source; - for(auto& shader : registered_shaders) { - if(shader.filename == shader_file) { + for (auto& shader : registered_shaders) { + if (shader.filename == shader_file) { found_shader_source = shader.injected_shader_source; } } - + prism::path base_shader_path = get_shader_source_directory(); - + // if shader editor system is not initialized, use prebuilt shaders - if(base_shader_path.empty()) + if (base_shader_path.empty()) return ShaderSource(prism::path(shader_file)); - + shader_compiler.set_include_path(base_shader_path.string()); - + prism::path shader_path = prism::path(shader_file); - + ShaderStage stage = ShaderStage::Vertex; - if(shader_path.extension() == ".vert") + if (shader_path.extension() == ".vert") stage = ShaderStage::Vertex; - else if(shader_path.extension() == ".frag") + else if (shader_path.extension() == ".frag") stage = ShaderStage::Fragment; - if(found_shader_source.empty()) { - auto file = prism::open_file(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); - - return shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(file->read_as_string()), gfx->accepted_shader_language()).value(); + if (found_shader_source.empty()) { + auto file = prism::open_file( + base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); + + return shader_compiler + .compile(ShaderLanguage::GLSL, stage, ShaderSource(file->read_as_string()), gfx->accepted_shader_language()) + .value(); } else { - return shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(found_shader_source), gfx->accepted_shader_language()).value(); + return shader_compiler + .compile(ShaderLanguage::GLSL, stage, ShaderSource(found_shader_source), gfx->accepted_shader_language()) + .value(); } } -void renderer::associate_shader_reload(const std::string_view shader_file, const std::function& reload_function) { - if(reloading_shader) +void renderer::associate_shader_reload( + const std::string_view shader_file, + const std::function& reload_function) { + if (reloading_shader) return; - - for(auto& shader : registered_shaders) { - if(shader.filename == shader_file) + + for (auto& shader : registered_shaders) { + if (shader.filename == shader_file) shader.reload_function = reload_function; } } void renderer::reload_shader(const std::string_view shader_file, const std::string_view shader_source) { - for(auto& shader : registered_shaders) { - if(shader.filename == shader_file) { + for (auto& shader : registered_shaders) { + if (shader.filename == shader_file) { shader.injected_shader_source = shader_source; reloading_shader = true; shader.reload_function(); diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index 80524a1..0dde45a 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -1,14 +1,14 @@ #include "scenecapture.hpp" -#include "gfx_commandbuffer.hpp" -#include "scene.hpp" -#include "gfx.hpp" -#include "engine.hpp" -#include "renderer.hpp" -#include "shadowpass.hpp" -#include "materialcompiler.hpp" -#include "frustum.hpp" #include "asset.hpp" +#include "engine.hpp" +#include "frustum.hpp" +#include "gfx.hpp" +#include "gfx_commandbuffer.hpp" +#include "materialcompiler.hpp" +#include "renderer.hpp" +#include "scene.hpp" +#include "shadowpass.hpp" struct PushConstant { Matrix4x4 m, v; @@ -56,19 +56,19 @@ struct FilterPushConstant { const int mipLevels = 5; const std::array sceneTransforms = { - prism::look_at(prism::float3(0), prism::float3(-1.0, 0.0, 0.0), prism::float3(0.0, -1.0, 0.0)), // right - prism::look_at(prism::float3(0), prism::float3(1.0, 0.0, 0.0), prism::float3(0.0, -1.0, 0.0)), // left - prism::look_at(prism::float3(0), prism::float3(0.0, -1.0, 0.0), prism::float3(0.0, 0.0, -1.0)), // top - prism::look_at(prism::float3(0), prism::float3(0.0, 1.0, 0.0), prism::float3(0.0, 0.0, 1.0)), // bottom - prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, 1.0), prism::float3(0.0, -1.0, 0.0)), // back - prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, -1.0), prism::float3(0.0, -1.0, 0.0)) // front + prism::look_at(prism::float3(0), prism::float3(-1.0, 0.0, 0.0), prism::float3(0.0, -1.0, 0.0)), // right + prism::look_at(prism::float3(0), prism::float3(1.0, 0.0, 0.0), prism::float3(0.0, -1.0, 0.0)), // left + prism::look_at(prism::float3(0), prism::float3(0.0, -1.0, 0.0), prism::float3(0.0, 0.0, -1.0)), // top + prism::look_at(prism::float3(0), prism::float3(0.0, 1.0, 0.0), prism::float3(0.0, 0.0, 1.0)), // bottom + prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, 1.0), prism::float3(0.0, -1.0, 0.0)), // back + prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, -1.0), prism::float3(0.0, -1.0, 0.0)) // front }; inline AssetPtr cubeMesh; SceneCapture::SceneCapture(GFX* gfx) { cubeMesh = assetm->get(prism::base_domain / "models/cube.model"); - + // render pass GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "Scene Capture Cube"; @@ -77,7 +77,7 @@ SceneCapture::SceneCapture(GFX* gfx) { renderPassInfo.will_use_in_shader = true; renderPass = gfx->create_render_pass(renderPassInfo); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "Scene Capture Color"; textureInfo.width = scene_cubemap_resolution; @@ -85,9 +85,9 @@ SceneCapture::SceneCapture(GFX* gfx) { textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::TransferSrc | GFXTextureUsage::Sampled; textureInfo.samplingMode = SamplingMode::ClampToEdge; - + offscreenTexture = gfx->create_texture(textureInfo); - + GFXTextureCreateInfo depthTextureInfo = {}; depthTextureInfo.label = "Scene Capture Depth"; depthTextureInfo.width = scene_cubemap_resolution; @@ -95,29 +95,30 @@ SceneCapture::SceneCapture(GFX* gfx) { depthTextureInfo.format = GFXPixelFormat::DEPTH_32F; depthTextureInfo.usage = GFXTextureUsage::Attachment; depthTextureInfo.samplingMode = SamplingMode::ClampToEdge; - + offscreenDepth = gfx->create_texture(depthTextureInfo); - + GFXFramebufferCreateInfo info; info.attachments = {offscreenTexture, offscreenDepth}; info.render_pass = renderPass; - + offscreenFramebuffer = gfx->create_framebuffer(info); - + GFXTextureCreateInfo cubeTextureInfo = {}; cubeTextureInfo.label = "Scene Capture Cubemap"; cubeTextureInfo.type = GFXTextureType::Cubemap; cubeTextureInfo.width = scene_cubemap_resolution; cubeTextureInfo.height = scene_cubemap_resolution; cubeTextureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; - cubeTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst | GFXTextureUsage::TransferSrc; // dst used for cubemap copy, src used for mipmap gen + cubeTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst | + GFXTextureUsage::TransferSrc; // dst used for cubemap copy, src used for mipmap gen cubeTextureInfo.samplingMode = SamplingMode::ClampToEdge; cubeTextureInfo.mip_count = mipLevels; - + environmentCube = gfx->create_texture(cubeTextureInfo); - + sceneBuffer = gfx->create_buffer(nullptr, sizeof(SceneInformation), true, GFXBufferUsage::Storage); - + createSkyResources(); createIrradianceResources(); createPrefilterResources(); @@ -125,8 +126,8 @@ SceneCapture::SceneCapture(GFX* gfx) { void SceneCapture::create_scene_resources(Scene& scene) { auto gfx = engine->get_gfx(); - - if(gfx->supports_feature(GFXFeature::CubemapArray)) { + + if (gfx->supports_feature(GFXFeature::CubemapArray)) { GFXTextureCreateInfo cubeTextureInfo = {}; cubeTextureInfo.label = "Irriadiance Cubemap"; cubeTextureInfo.type = GFXTextureType::CubemapArray; @@ -136,9 +137,9 @@ void SceneCapture::create_scene_resources(Scene& scene) { cubeTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst; cubeTextureInfo.samplingMode = SamplingMode::ClampToEdge; cubeTextureInfo.array_length = max_environment_probes; - + scene.irradianceCubeArray = gfx->create_texture(cubeTextureInfo); - + cubeTextureInfo = {}; cubeTextureInfo.label = "Prefiltered Cubemap"; cubeTextureInfo.type = GFXTextureType::CubemapArray; @@ -149,143 +150,146 @@ void SceneCapture::create_scene_resources(Scene& scene) { cubeTextureInfo.samplingMode = SamplingMode::ClampToEdge; cubeTextureInfo.array_length = max_environment_probes; cubeTextureInfo.mip_count = mipLevels; - + scene.prefilteredCubeArray = gfx->create_texture(cubeTextureInfo); } } void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { - if(scene->probe_refresh_timer > 0) { + if (scene->probe_refresh_timer > 0) { scene->probe_refresh_timer--; return; } int last_probe = 0; auto probes = scene->get_all(); - for(auto [obj, probe] : probes) { - if(last_probe > max_environment_probes) + for (auto [obj, probe] : probes) { + if (last_probe > max_environment_probes) return; - - if(scene->environment_dirty[last_probe]) { + + if (scene->environment_dirty[last_probe]) { std::map material_indices; int numMaterialsInBuffer = 0; - + const prism::float3 lightPos = scene->get(obj).get_world_position(); - + const Matrix4x4 projection = prism::infinite_perspective(radians(90.0f), 1.0f, 0.1f); const Matrix4x4 model = prism::translate(Matrix4x4(), prism::float3(-lightPos.x, -lightPos.y, -lightPos.z)); - + SceneInformation sceneInfo = {}; sceneInfo.lightspace = scene->lightSpace; sceneInfo.numLights = 0; sceneInfo.camPos = lightPos; sceneInfo.vp = projection; - - for(const auto [obj, light] : scene->get_all()) { + + for (const auto [obj, light] : scene->get_all()) { SceneLight sl; sl.positionType = prism::float4(scene->get(obj).get_world_position(), (int)light.type); prism::float3 front = prism::float3(0.0f, 0.0f, 1.0f) * scene->get(obj).rotation; - + sl.directionPower = prism::float4(-front, light.power); sl.colorSize = prism::float4(utility::from_srgb_to_linear(light.color), radians(light.spot_size)); sl.shadowsEnable = prism::float4(light.enable_shadows, radians(light.size), 0, 0); - + sceneInfo.lights[sceneInfo.numLights++] = sl; } - - for(int i = 0; i < max_spot_shadows; i++) + + for (int i = 0; i < max_spot_shadows; i++) sceneInfo.spotLightSpaces[i] = scene->spotLightSpaces[i]; - + const auto& meshes = scene->get_all(); - - for(const auto [obj, mesh] : meshes) { - if(!mesh.mesh) + + for (const auto [obj, mesh] : meshes) { + if (!mesh.mesh) continue; - - if(mesh.materials.empty()) + + if (mesh.materials.empty()) continue; - - for(const auto& material : mesh.materials) { - if(!material) + + for (const auto& material : mesh.materials) { + if (!material) continue; - - if(material->static_pipeline == nullptr || material->skinned_pipeline == nullptr) + + if (material->static_pipeline == nullptr || material->skinned_pipeline == nullptr) engine->get_renderer()->create_mesh_pipeline(*material.handle); - if(!material_indices.count(material.handle)) { + if (!material_indices.count(material.handle)) { material_indices[material.handle] = numMaterialsInBuffer++; } } } - + const auto render_face = [this, command_buffer, scene, &meshes, &model, &probe = probe](int face) { const auto frustum = normalize_frustum(extract_frustum(sceneTransforms[face])); - + GFXRenderPassBeginInfo info = {}; info.framebuffer = offscreenFramebuffer; info.render_pass = renderPass; info.render_area.extent = {scene_cubemap_resolution, scene_cubemap_resolution}; - + command_buffer->set_render_pass(info); - + Viewport viewport = {}; viewport.width = scene_cubemap_resolution; viewport.height = scene_cubemap_resolution; - + command_buffer->set_viewport(viewport); - - if(probe.is_sized) { - for(const auto [obj, mesh] : meshes) { - if(!mesh.mesh) + + if (probe.is_sized) { + for (const auto [obj, mesh] : meshes) { + if (!mesh.mesh) continue; - - if(mesh.materials.empty()) + + if (mesh.materials.empty()) continue; - + PushConstant pc; pc.m = scene->get(obj).model; pc.v = sceneTransforms[face] * model; - + command_buffer->set_vertex_buffer(mesh.mesh->position_buffer, 0, position_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->normal_buffer, 0, normal_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->texture_coord_buffer, 0, texcoord_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->tangent_buffer, 0, tangent_buffer_index); command_buffer->set_vertex_buffer(mesh.mesh->bitangent_buffer, 0, bitangent_buffer_index); - + command_buffer->set_index_buffer(mesh.mesh->index_buffer, IndexType::UINT32); - if(mesh.mesh->bones.empty()) { + if (mesh.mesh->bones.empty()) { for (auto& part : mesh.mesh->parts) { const int material_index = part.material_override == -1 ? 0 : part.material_override; - - if(material_index >= mesh.materials.size()) + + if (material_index >= mesh.materials.size()) continue; - - if(mesh.materials[material_index].handle == nullptr || mesh.materials[material_index]->static_pipeline == nullptr) + + if (mesh.materials[material_index].handle == nullptr || + mesh.materials[material_index]->static_pipeline == nullptr) continue; - - if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene->get(obj), part))) + + if (render_options.enable_frustum_culling && + !test_aabb_frustum(frustum, get_aabb_for_part(scene->get(obj), part))) continue; - + command_buffer->set_graphics_pipeline(mesh.materials[material_index]->capture_pipeline); - + command_buffer->bind_shader_buffer(sceneBuffer, 0, 1, sizeof(SceneInformation)); command_buffer->bind_texture(scene->depthTexture, 2); command_buffer->bind_texture(scene->pointLightArray, 3); command_buffer->bind_texture(scene->spotLightArray, 6); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - - for(auto& [index, texture] : mesh.materials[material_index]->bound_textures) { + + for (auto& [index, texture] : mesh.materials[material_index]->bound_textures) { GFXTexture* texture_to_bind = engine->get_renderer()->dummy_texture; - if(texture) + if (texture) texture_to_bind = texture->handle; - + command_buffer->bind_texture(texture_to_bind, index); } - - command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, 0); + + command_buffer->draw_indexed( + part.index_count, part.index_offset, part.vertex_offset, 0); } } } @@ -293,30 +297,32 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { // render sky SkyPushConstant pc; - + pc.view = sceneTransforms[face]; pc.aspect = 1.0f; - - for(auto& [obj, light] : scene->get_all()) { - if(light.type == Light::Type::Sun) - pc.sun_position_fov = prism::float4(scene->get(obj).get_world_position(), radians(90.0f)); + + for (auto& [obj, light] : scene->get_all()) { + if (light.type == Light::Type::Sun) + pc.sun_position_fov = + prism::float4(scene->get(obj).get_world_position(), radians(90.0f)); } - + command_buffer->set_graphics_pipeline(skyPipeline); - + command_buffer->set_push_constant(&pc, sizeof(SkyPushConstant)); - + command_buffer->draw(0, 4, 0, 1); - + command_buffer->end_render_pass(); - command_buffer->copy_texture(offscreenTexture, scene_cubemap_resolution, scene_cubemap_resolution, environmentCube, face, 0, 0); + command_buffer->copy_texture( + offscreenTexture, scene_cubemap_resolution, scene_cubemap_resolution, environmentCube, face, 0, 0); }; - + engine->get_gfx()->copy_buffer(sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation)); for (int face = 0; face < 6; face++) render_face(face); - + command_buffer->generate_mipmaps(environmentCube, mipLevels); // calculate irradiance @@ -325,15 +331,15 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { info.framebuffer = irradianceFramebuffer; info.render_pass = irradianceRenderPass; info.render_area.extent = {irradiance_cubemap_resolution, irradiance_cubemap_resolution}; - + command_buffer->set_render_pass(info); - + Viewport viewport = {}; viewport.width = irradiance_cubemap_resolution; viewport.height = irradiance_cubemap_resolution; - + command_buffer->set_viewport(viewport); - + Matrix4x4 mvp = projection * sceneTransforms[face]; command_buffer->set_graphics_pipeline(irradiancePipeline); @@ -343,42 +349,43 @@ 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, 0); - + command_buffer->end_render_pass(); - command_buffer->copy_texture(irradianceOffscreenTexture, - irradiance_cubemap_resolution, - irradiance_cubemap_resolution, - scene->irradianceCubeArray, - face, // slice - last_probe, // layer - 0); // level + command_buffer->copy_texture( + irradianceOffscreenTexture, + irradiance_cubemap_resolution, + irradiance_cubemap_resolution, + scene->irradianceCubeArray, + face, // slice + last_probe, // layer + 0); // level }; - + for (int face = 0; face < 6; face++) convulute_face(face); - + // prefilter const auto prefilter_face = [this, scene, command_buffer, &last_probe, projection](int face, int mip) { GFXRenderPassBeginInfo info = {}; info.framebuffer = prefilteredFramebuffer; info.render_pass = irradianceRenderPass; - + const uint32_t resolution = scene_cubemap_resolution * std::pow(0.5, mip); info.render_area.extent = {resolution, resolution}; - + command_buffer->set_render_pass(info); - + Viewport viewport = {}; viewport.width = resolution; viewport.height = resolution; - + command_buffer->set_viewport(viewport); - + command_buffer->set_vertex_buffer(cubeMesh->position_buffer, 0, 0); command_buffer->set_index_buffer(cubeMesh->index_buffer, IndexType::UINT32); - + FilterPushConstant pc; pc.mvp = projection * sceneTransforms[face]; pc.roughness = ((float)mip) / (float)(mipLevels - 1); @@ -386,23 +393,28 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) { command_buffer->set_graphics_pipeline(prefilterPipeline); command_buffer->bind_texture(environmentCube, 2); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - + command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); - + command_buffer->end_render_pass(); - command_buffer->copy_texture(prefilteredOffscreenTexture, - resolution, resolution, - scene->prefilteredCubeArray, face, last_probe, mip); + command_buffer->copy_texture( + prefilteredOffscreenTexture, + resolution, + resolution, + scene->prefilteredCubeArray, + face, + last_probe, + mip); }; - - for(int mip = 0; mip < mipLevels; mip++) { - for(int i = 0; i < 6; i++) + + for (int mip = 0; mip < mipLevels; mip++) { + for (int i = 0; i < 6; i++) prefilter_face(i, mip); } - + scene->environment_dirty[last_probe] = false; } - + last_probe++; } } @@ -411,26 +423,22 @@ void SceneCapture::createSkyResources() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Sky Scene Capture"; pipelineInfo.render_pass = renderPass; - + pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/sky.vert")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/sky.frag")); - - pipelineInfo.shader_input.bindings = { - {0, GFXBindingType::PushConstant} - }; - - pipelineInfo.shader_input.push_constants = { - {sizeof(SkyPushConstant), 0} - }; - + + pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}}; + + pipelineInfo.shader_input.push_constants = {{sizeof(SkyPushConstant), 0}}; + pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; - + skyPipeline = engine->get_gfx()->create_graphics_pipeline(pipelineInfo); } void SceneCapture::createIrradianceResources() { GFX* gfx = engine->get_gfx(); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "Irradiance Offscreen"; textureInfo.width = irradiance_cubemap_resolution; @@ -438,9 +446,9 @@ void SceneCapture::createIrradianceResources() { textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::TransferSrc; textureInfo.samplingMode = SamplingMode::ClampToEdge; - + irradianceOffscreenTexture = gfx->create_texture(textureInfo); - + GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "Irradiance"; renderPassInfo.attachments.push_back(GFXPixelFormat::R8G8B8A8_UNORM); @@ -451,41 +459,36 @@ void SceneCapture::createIrradianceResources() { GFXFramebufferCreateInfo info; info.attachments = {irradianceOffscreenTexture}; info.render_pass = irradianceRenderPass; - + irradianceFramebuffer = gfx->create_framebuffer(info); GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Irradiance Convolution"; pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/irradiance.vert")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/irradiance.frag")); - + GFXVertexInput input = {}; input.stride = sizeof(prism::float3); - + pipelineInfo.vertex_input.inputs.push_back(input); - + GFXVertexAttribute positionAttribute = {}; positionAttribute.format = GFXVertexFormat::FLOAT3; pipelineInfo.vertex_input.attributes.push_back(positionAttribute); - - pipelineInfo.shader_input.push_constants = { - {sizeof(Matrix4x4), 0} - }; - - pipelineInfo.shader_input.bindings = { - {1, GFXBindingType::PushConstant}, - {2, GFXBindingType::Texture} - }; - + + pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}}; + + pipelineInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}}; + pipelineInfo.render_pass = irradianceRenderPass; - + irradiancePipeline = gfx->create_graphics_pipeline(pipelineInfo); } void SceneCapture::createPrefilterResources() { GFX* gfx = engine->get_gfx(); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "Prefiltered Offscreen"; textureInfo.width = scene_cubemap_resolution; @@ -493,46 +496,41 @@ void SceneCapture::createPrefilterResources() { textureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::TransferSrc; textureInfo.samplingMode = SamplingMode::ClampToEdge; - + prefilteredOffscreenTexture = gfx->create_texture(textureInfo); - + GFXFramebufferCreateInfo info; info.attachments = {prefilteredOffscreenTexture}; info.render_pass = irradianceRenderPass; - + prefilteredFramebuffer = gfx->create_framebuffer(info); - + GFXShaderConstant size_constant = {}; size_constant.type = GFXShaderConstant::Type::Integer; size_constant.value = scene_cubemap_resolution; - + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Prefilter"; pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/filter.vert")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/filter.frag")); - + pipelineInfo.shaders.fragment_constants = {size_constant}; - + GFXVertexInput input; input.stride = sizeof(prism::float3); - + pipelineInfo.vertex_input.inputs.push_back(input); - + GFXVertexAttribute positionAttribute; positionAttribute.format = GFXVertexFormat::FLOAT3; - + pipelineInfo.vertex_input.attributes.push_back(positionAttribute); - - pipelineInfo.shader_input.push_constants = { - {sizeof(FilterPushConstant), 0} - }; - - pipelineInfo.shader_input.bindings = { - {0, GFXBindingType::PushConstant}, - {2, GFXBindingType::Texture} - }; - + + pipelineInfo.shader_input.push_constants = {{sizeof(FilterPushConstant), 0}}; + + pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}}; + pipelineInfo.render_pass = irradianceRenderPass; - + prefilterPipeline = gfx->create_graphics_pipeline(pipelineInfo); } diff --git a/engine/renderer/src/shadowpass.cpp b/engine/renderer/src/shadowpass.cpp index c6a5e09..65bbeb6 100755 --- a/engine/renderer/src/shadowpass.cpp +++ b/engine/renderer/src/shadowpass.cpp @@ -1,31 +1,31 @@ #include "shadowpass.hpp" -#include "gfx_commandbuffer.hpp" -#include "scene.hpp" -#include "gfx.hpp" -#include "engine.hpp" -#include "materialcompiler.hpp" #include "assertions.hpp" +#include "engine.hpp" #include "frustum.hpp" +#include "gfx.hpp" +#include "gfx_commandbuffer.hpp" +#include "materialcompiler.hpp" #include "renderer.hpp" +#include "scene.hpp" struct PushConstant { Matrix4x4 mvp, model; }; const std::array shadowTransforms = { - prism::look_at(prism::float3(0), prism::float3(1.0, 0.0, 0.0), prism::float3(0.0, 1.0, 0.0)), // right - prism::look_at(prism::float3(0), prism::float3(-1.0, 0.0, 0.0), prism::float3(0.0, 1.0, 0.0)), // left - prism::look_at(prism::float3(0), prism::float3(0.0, 1.0, 0.0), prism::float3(0.0, 0.0, -1.0)), // top - prism::look_at(prism::float3(0), prism::float3(0.0, -1.0, 0.0), prism::float3(0.0, 0.0, 1.0)), // bottom - prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, 1.0), prism::float3(0.0, 1.0, 0.0)), // back - prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, -1.0), prism::float3(0.0, 1.0, 0.0)) // front + prism::look_at(prism::float3(0), prism::float3(1.0, 0.0, 0.0), prism::float3(0.0, 1.0, 0.0)), // right + prism::look_at(prism::float3(0), prism::float3(-1.0, 0.0, 0.0), prism::float3(0.0, 1.0, 0.0)), // left + prism::look_at(prism::float3(0), prism::float3(0.0, 1.0, 0.0), prism::float3(0.0, 0.0, -1.0)), // top + prism::look_at(prism::float3(0), prism::float3(0.0, -1.0, 0.0), prism::float3(0.0, 0.0, 1.0)), // bottom + prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, 1.0), prism::float3(0.0, 1.0, 0.0)), // back + prism::look_at(prism::float3(0), prism::float3(0.0, 0.0, -1.0), prism::float3(0.0, 1.0, 0.0)) // front }; ShadowPass::ShadowPass(GFX* gfx) { Expects(gfx != nullptr); Expects(render_options.shadow_resolution > 0); - + create_render_passes(); create_pipelines(); create_offscreen_resources(); @@ -33,7 +33,7 @@ ShadowPass::ShadowPass(GFX* gfx) { void ShadowPass::create_scene_resources(Scene& scene) { auto gfx = engine->get_gfx(); - + // sun light { GFXTextureCreateInfo textureInfo = {}; @@ -46,16 +46,16 @@ void ShadowPass::create_scene_resources(Scene& scene) { textureInfo.border_color = GFXBorderColor::OpaqueWhite; scene.depthTexture = gfx->create_texture(textureInfo); - + GFXFramebufferCreateInfo info; info.attachments = {scene.depthTexture}; info.render_pass = render_pass; - + scene.framebuffer = gfx->create_framebuffer(info); } - + // point lights - if(gfx->supports_feature(GFXFeature::CubemapArray)) { + if (gfx->supports_feature(GFXFeature::CubemapArray)) { GFXTextureCreateInfo cubeTextureInfo = {}; cubeTextureInfo.label = "Point Light Array"; cubeTextureInfo.type = GFXTextureType::CubemapArray; @@ -69,7 +69,7 @@ void ShadowPass::create_scene_resources(Scene& scene) { scene.pointLightArray = gfx->create_texture(cubeTextureInfo); } - + // spot lights { GFXTextureCreateInfo spotTextureInfo = {}; @@ -91,17 +91,17 @@ void ShadowPass::render(GFXCommandBuffer* command_buffer, Scene& scene) { last_spot_light = 0; last_point_light = 0; - if(scene.shadow_refresh_timer > 0) { + if (scene.shadow_refresh_timer > 0) { scene.shadow_refresh_timer--; return; } - + auto lights = scene.get_all(); - for(auto [obj, light] : lights) { - if(!light.enable_shadows) + for (auto [obj, light] : lights) { + if (!light.enable_shadows) continue; - switch(light.type) { + switch (light.type) { case Light::Type::Sun: render_sun(command_buffer, scene, obj, light); break; @@ -115,21 +115,29 @@ 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 prism::float3, const Light::Type type, const CameraFrustum& frustum, const int base_instance) { - for(auto [obj, mesh] : scene.get_all()) { - if(!mesh.mesh) +void ShadowPass::render_meshes( + GFXCommandBuffer* command_buffer, + Scene& scene, + const Matrix4x4 light_matrix, + const Matrix4x4 model, + const prism::float3, + const Light::Type type, + const CameraFrustum& frustum, + const int base_instance) { + for (auto [obj, mesh] : scene.get_all()) { + if (!mesh.mesh) continue; - + command_buffer->set_vertex_buffer(mesh.mesh->position_buffer, 0, position_buffer_index); - + command_buffer->set_index_buffer(mesh.mesh->index_buffer, IndexType::UINT32); - + PushConstant pc; pc.mvp = light_matrix * model * scene.get(obj).model; pc.model = scene.get(obj).model; - - if(mesh.mesh->bones.empty()) { - switch(type) { + + if (mesh.mesh->bones.empty()) { + switch (type) { case Light::Type::Sun: command_buffer->set_graphics_pipeline(static_sun_pipeline); break; @@ -140,20 +148,21 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c command_buffer->set_graphics_pipeline(static_point_pipeline); break; } - + command_buffer->bind_shader_buffer(point_location_buffer, 0, 2, sizeof(prism::float4) * max_point_shadows); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); command_buffer->set_depth_bias(1.25f, 0.00f, 1.75f); for (auto& part : mesh.mesh->parts) { - if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) + 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, base_instance); } } else { - switch(type) { + switch (type) { case Light::Type::Sun: command_buffer->set_graphics_pipeline(skinned_sun_pipeline); break; @@ -166,16 +175,17 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c } command_buffer->bind_shader_buffer(point_location_buffer, 0, 2, sizeof(prism::float4) * max_point_shadows); - + command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - + command_buffer->set_vertex_buffer(mesh.mesh->bone_buffer, 0, bone_buffer_index); command_buffer->set_depth_bias(1.25f, 0.00f, 1.75f); for (auto& part : mesh.mesh->parts) { - if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) + if (render_options.enable_frustum_culling && + !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) continue; - + command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 14, sizeof(Matrix4x4) * 128); command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, base_instance); } @@ -184,36 +194,38 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c } void ShadowPass::render_sun(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light) { - if(scene.sun_light_dirty || light.use_dynamic_shadows) { + if (scene.sun_light_dirty || light.use_dynamic_shadows) { GFXRenderPassBeginInfo info = {}; info.framebuffer = scene.framebuffer; info.render_pass = render_pass; - info.render_area.extent = {static_cast(render_options.shadow_resolution), static_cast(render_options.shadow_resolution)}; - + info.render_area.extent = { + static_cast(render_options.shadow_resolution), + static_cast(render_options.shadow_resolution)}; + command_buffer->set_render_pass(info); - + Viewport viewport = {}; viewport.width = static_cast(render_options.shadow_resolution); viewport.height = static_cast(render_options.shadow_resolution); - + command_buffer->set_viewport(viewport); - + const prism::float3 lightPos = scene.get(light_object).position; - + const Matrix4x4 projection = prism::orthographic(-25.0f, 25.0f, -25.0f, 25.0f, 0.1f, 100.0f); const Matrix4x4 view = prism::look_at(lightPos, prism::float3(0), prism::float3(0, 1, 0)); - + const Matrix4x4 realMVP = projection * view; - + scene.lightSpace = projection; scene.lightSpace[1][1] *= -1; scene.lightSpace = scene.lightSpace * view; - + const auto frustum = normalize_frustum(extract_frustum(projection * view)); - - if(light.enable_shadows) + + if (light.enable_shadows) render_meshes(command_buffer, scene, realMVP, Matrix4x4(), lightPos, Light::Type::Sun, frustum, 0); - + scene.sun_light_dirty = false; command_buffer->end_render_pass(); @@ -221,96 +233,136 @@ void ShadowPass::render_sun(GFXCommandBuffer* command_buffer, Scene& scene, pris } void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light) { - if((last_spot_light + 1) == max_spot_shadows) + if ((last_spot_light + 1) == max_spot_shadows) return; - - if(scene.spot_light_dirty[last_spot_light] || light.use_dynamic_shadows) { + + if (scene.spot_light_dirty[last_spot_light] || light.use_dynamic_shadows) { GFXRenderPassBeginInfo info = {}; info.framebuffer = offscreen_framebuffer; info.render_pass = cube_render_pass; - info.render_area.extent = {static_cast(render_options.shadow_resolution), static_cast(render_options.shadow_resolution)}; - + info.render_area.extent = { + static_cast(render_options.shadow_resolution), + static_cast(render_options.shadow_resolution)}; + command_buffer->set_render_pass(info); - + Viewport viewport = {}; viewport.width = static_cast(render_options.shadow_resolution); viewport.height = static_cast(render_options.shadow_resolution); command_buffer->set_viewport(viewport); - + const Matrix4x4 perspective = prism::perspective(radians(90.0f), 1.0f, 0.1f, 100.0f); - + const Matrix4x4 realMVP = perspective * inverse(scene.get(light_object).model); - + scene.spotLightSpaces[last_spot_light] = perspective; scene.spotLightSpaces[last_spot_light][1][1] *= -1; - scene.spotLightSpaces[last_spot_light] = scene.spotLightSpaces[last_spot_light] * inverse(scene.get(light_object).model); - - 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, 0); - + scene.spotLightSpaces[last_spot_light] = + scene.spotLightSpaces[last_spot_light] * inverse(scene.get(light_object).model); + + 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, + 0); + command_buffer->end_render_pass(); - command_buffer->copy_texture(offscreen_depth, render_options.shadow_resolution, render_options.shadow_resolution, scene.spotLightArray, 0, last_spot_light, 0); - + command_buffer->copy_texture( + offscreen_depth, + render_options.shadow_resolution, + render_options.shadow_resolution, + scene.spotLightArray, + 0, + last_spot_light, + 0); + scene.spot_light_dirty[last_spot_light] = false; } - + last_spot_light++; } -void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light) { - if(!render_options.enable_point_shadows) - return; - - if((last_point_light + 1) == max_point_shadows) +void ShadowPass::render_point( + GFXCommandBuffer* command_buffer, + Scene& scene, + prism::Object light_object, + Light& light) { + if (!render_options.enable_point_shadows) return; - if(point_location_map == nullptr) + if ((last_point_light + 1) == max_point_shadows) return; - - if(scene.point_light_dirty[last_point_light] || light.use_dynamic_shadows) { + + if (point_location_map == nullptr) + return; + + if (scene.point_light_dirty[last_point_light] || light.use_dynamic_shadows) { const prism::float3 lightPos = scene.get(light_object).get_world_position(); (point_location_map + last_point_light)->xyz = lightPos; - for(int face = 0; face < 6; face++) { + for (int face = 0; face < 6; face++) { GFXRenderPassBeginInfo info = {}; info.framebuffer = offscreen_framebuffer; info.render_pass = cube_render_pass; - info.render_area.extent = {static_cast(render_options.shadow_resolution), static_cast(render_options.shadow_resolution)}; + info.render_area.extent = { + static_cast(render_options.shadow_resolution), + static_cast(render_options.shadow_resolution)}; command_buffer->set_render_pass(info); - + Viewport viewport = {}; viewport.width = static_cast(render_options.shadow_resolution); viewport.height = static_cast(render_options.shadow_resolution); - + command_buffer->set_viewport(viewport); const Matrix4x4 projection = prism::perspective(radians(90.0f), 1.0f, 0.1f, 100.0f); const Matrix4x4 model = inverse(scene.get(light_object).model); - + 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, last_point_light); - + + render_meshes( + command_buffer, + scene, + projection * shadowTransforms[face], + model, + lightPos, + Light::Type::Point, + frustum, + last_point_light); + command_buffer->end_render_pass(); - command_buffer->copy_texture(offscreen_color_texture, render_options.shadow_resolution, render_options.shadow_resolution, scene.pointLightArray, face, last_point_light, 0); + command_buffer->copy_texture( + offscreen_color_texture, + render_options.shadow_resolution, + render_options.shadow_resolution, + scene.pointLightArray, + face, + last_point_light, + 0); } - + scene.point_light_dirty[last_point_light] = false; } - + last_point_light++; } void ShadowPass::create_render_passes() { auto gfx = engine->get_gfx(); - + // render pass GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "Shadow"; @@ -318,12 +370,12 @@ void ShadowPass::create_render_passes() { renderPassInfo.will_use_in_shader = true; render_pass = gfx->create_render_pass(renderPassInfo); - + renderPassInfo.label = "Shadow Cube"; renderPassInfo.attachments.clear(); renderPassInfo.attachments.push_back(GFXPixelFormat::R_32F); renderPassInfo.attachments.push_back(GFXPixelFormat::DEPTH_32F); - + cube_render_pass = gfx->create_render_pass(renderPassInfo); } @@ -335,20 +387,15 @@ void ShadowPass::create_pipelines() { pipelineInfo.shaders.vertex_constants = {point_light_max_constant}; pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/shadow.vert")); - pipelineInfo.shaders.fragment_constants = { point_light_max_constant }; + pipelineInfo.shaders.fragment_constants = {point_light_max_constant}; pipelineInfo.shader_input.bindings = { - {0, GFXBindingType::PushConstant}, - {1, GFXBindingType::StorageBuffer}, - {2, GFXBindingType::StorageBuffer} - }; - - pipelineInfo.shader_input.push_constants = { - {sizeof(PushConstant), 0} - }; - + {0, GFXBindingType::PushConstant}, {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::StorageBuffer}}; + + pipelineInfo.shader_input.push_constants = {{sizeof(PushConstant), 0}}; + pipelineInfo.render_pass = render_pass; - + pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; // sun @@ -356,31 +403,31 @@ void ShadowPass::create_pipelines() { pipelineInfo.label = "Sun Shadow"; auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true); - + static_sun_pipeline = static_pipeline; skinned_sun_pipeline = skinned_pipeline; } - + // spot { pipelineInfo.label = "Spot Shadow"; pipelineInfo.render_pass = cube_render_pass; - + auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true); - + static_spot_pipeline = static_pipeline; skinned_spot_pipeline = skinned_pipeline; } - + // point { pipelineInfo.label = "Point Shadow"; pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/omnishadow.frag")); - + auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true); - + static_point_pipeline = static_pipeline; skinned_point_pipeline = skinned_pipeline; } @@ -388,7 +435,7 @@ void ShadowPass::create_pipelines() { void ShadowPass::create_offscreen_resources() { auto gfx = engine->get_gfx(); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "Shadow Color"; textureInfo.width = render_options.shadow_resolution; @@ -398,7 +445,7 @@ void ShadowPass::create_offscreen_resources() { textureInfo.samplingMode = SamplingMode::ClampToEdge; offscreen_color_texture = gfx->create_texture(textureInfo); - + GFXTextureCreateInfo depthTextureInfo = {}; depthTextureInfo.label = "Shadow Depth"; depthTextureInfo.width = render_options.shadow_resolution; @@ -406,15 +453,16 @@ void ShadowPass::create_offscreen_resources() { depthTextureInfo.format = GFXPixelFormat::DEPTH_32F; depthTextureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; depthTextureInfo.samplingMode = SamplingMode::ClampToEdge; - + offscreen_depth = gfx->create_texture(depthTextureInfo); - + GFXFramebufferCreateInfo info; info.attachments = {offscreen_color_texture, offscreen_depth}; info.render_pass = cube_render_pass; - + offscreen_framebuffer = gfx->create_framebuffer(info); - point_location_buffer = gfx->create_buffer(nullptr, sizeof(prism::float4) * max_point_shadows, false, GFXBufferUsage::Storage); + point_location_buffer = + gfx->create_buffer(nullptr, sizeof(prism::float4) * max_point_shadows, false, GFXBufferUsage::Storage); point_location_map = reinterpret_cast(gfx->get_buffer_contents(point_location_buffer)); } diff --git a/engine/renderer/src/smaapass.cpp b/engine/renderer/src/smaapass.cpp index d4f621e..9456b02 100755 --- a/engine/renderer/src/smaapass.cpp +++ b/engine/renderer/src/smaapass.cpp @@ -1,10 +1,10 @@ #include "smaapass.hpp" -#include "gfx_commandbuffer.hpp" -#include "renderer.hpp" +#include "assertions.hpp" #include "engine.hpp" #include "gfx.hpp" -#include "assertions.hpp" +#include "gfx_commandbuffer.hpp" +#include "renderer.hpp" #include #include @@ -19,27 +19,27 @@ SMAAPass::SMAAPass(GFX* gfx) { void SMAAPass::create_render_target_resources(RenderTarget& target) { auto gfx = engine->get_gfx(); - + GFXTextureCreateInfo textureInfo = {}; textureInfo.label = "SMAA Edge"; textureInfo.width = target.extent.width; textureInfo.height = target.extent.height; textureInfo.format = GFXPixelFormat::R16G16B16A16_SFLOAT; textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled; - + target.edge_texture = gfx->create_texture(textureInfo); - + textureInfo.label = "SMAA Blend"; target.blend_texture = gfx->create_texture(textureInfo); - + GFXFramebufferCreateInfo framebufferInfo = {}; framebufferInfo.attachments = {target.edge_texture}; framebufferInfo.render_pass = render_pass; - + target.edge_framebuffer = gfx->create_framebuffer(framebufferInfo); - + framebufferInfo.attachments = {target.blend_texture}; - + target.blend_framebuffer = gfx->create_framebuffer(framebufferInfo); } @@ -47,28 +47,32 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) { GFXRenderPassBeginInfo beginInfo = {}; beginInfo.render_area.extent = target.extent; beginInfo.render_pass = render_pass; - + struct PushConstant { prism::float4 viewport; } pc; - - pc.viewport = prism::float4(1.0f / static_cast(target.extent.width), 1.0f / static_cast(target.extent.height), target.extent.width, target.extent.height); + + pc.viewport = prism::float4( + 1.0f / static_cast(target.extent.width), + 1.0f / static_cast(target.extent.height), + target.extent.width, + target.extent.height); // edge { beginInfo.framebuffer = target.edge_framebuffer; command_buffer->set_render_pass(beginInfo); - + Viewport viewport = {}; viewport.width = target.extent.width; viewport.height = target.extent.height; - + command_buffer->set_viewport(viewport); - + command_buffer->set_graphics_pipeline(edge_pipeline); command_buffer->set_push_constant(&pc, sizeof(PushConstant)); - command_buffer->bind_texture(target.mid_texture, 0); // color + command_buffer->bind_texture(target.mid_texture, 0); // color command_buffer->bind_texture(target.offscreenDepthTexture, 1); // depth command_buffer->draw(0, 3, 0, 1); @@ -96,8 +100,8 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) { void SMAAPass::create_textures() { auto gfx = engine->get_gfx(); - - //load area image + + // load area image GFXTextureCreateInfo areaInfo = {}; areaInfo.label = "SMAA Area"; areaInfo.width = AREATEX_WIDTH; @@ -108,9 +112,9 @@ void SMAAPass::create_textures() { areaInfo.border_color = GFXBorderColor::OpaqueWhite; area_image = gfx->create_texture(areaInfo); - + gfx->copy_texture(area_image, (void*)areaTexBytes, AREATEX_SIZE); - + // load search image GFXTextureCreateInfo searchInfo = {}; searchInfo.label = "SMAA Search"; @@ -124,7 +128,7 @@ void SMAAPass::create_textures() { searchInfo.mag_filter = GFXFilter::Nearest; search_image = gfx->create_texture(searchInfo); - + gfx->copy_texture(search_image, (void*)searchTexBytes, SEARCHTEX_SIZE); } @@ -133,7 +137,7 @@ void SMAAPass::create_render_pass() { createInfo.label = "SMAA"; createInfo.attachments = {GFXPixelFormat::R16G16B16A16_SFLOAT}; createInfo.will_use_in_shader = true; - + render_pass = engine->get_gfx()->create_render_pass(createInfo); } @@ -144,25 +148,20 @@ void SMAAPass::create_pipelines() { createInfo.label = "SMAA Edge"; createInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/edge.vert")); createInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/edge.frag")); - + createInfo.render_pass = render_pass; - - createInfo.shader_input.push_constants = { - {sizeof(prism::float4), 0} - }; - + + createInfo.shader_input.push_constants = {{sizeof(prism::float4), 0}}; + createInfo.shader_input.bindings = { - {0, GFXBindingType::Texture}, - {1, GFXBindingType::Texture}, - {2, GFXBindingType::PushConstant} - }; - + {0, GFXBindingType::Texture}, {1, GFXBindingType::Texture}, {2, GFXBindingType::PushConstant}}; + edge_pipeline = gfx->create_graphics_pipeline(createInfo); - + createInfo.label = "SMAA Blend"; createInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/blend.vert")); createInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/blend.frag")); createInfo.shader_input.bindings.push_back({3, GFXBindingType::Texture}); - + blend_pipeline = gfx->create_graphics_pipeline(createInfo); } diff --git a/engine/shadercompiler/CMakeLists.txt b/engine/shadercompiler/CMakeLists.txt index 38dbda5..cf91c76 100755 --- a/engine/shadercompiler/CMakeLists.txt +++ b/engine/shadercompiler/CMakeLists.txt @@ -1,22 +1,22 @@ set(SRC - include/shadercompiler.hpp + include/shadercompiler.hpp - src/shadercompiler.cpp - src/includer.hpp - src/defaultresources.hpp) + src/shadercompiler.cpp + src/includer.hpp + src/defaultresources.hpp) add_library(ShaderCompiler STATIC ${SRC}) target_link_libraries(ShaderCompiler - PUBLIC - Platform - PRIVATE - Utility - Log - spirv-cross-core - spirv-cross-glsl - spirv-cross-msl - spirv-cross-hlsl - glslang - SPIRV) + PUBLIC + Platform + PRIVATE + Utility + Log + spirv-cross-core + spirv-cross-glsl + spirv-cross-msl + spirv-cross-hlsl + glslang + SPIRV) target_include_directories(ShaderCompiler PUBLIC include PRIVATE src) set_engine_properties(ShaderCompiler) diff --git a/engine/shadercompiler/include/shadercompiler.hpp b/engine/shadercompiler/include/shadercompiler.hpp index df54bd5..a73c2ae 100755 --- a/engine/shadercompiler/include/shadercompiler.hpp +++ b/engine/shadercompiler/include/shadercompiler.hpp @@ -1,10 +1,10 @@ #pragma once -#include -#include -#include -#include #include +#include +#include +#include +#include #include "file.hpp" @@ -30,9 +30,9 @@ public: void add_definition(const std::string_view name) { definitions.emplace_back(name); } - + std::vector definitions; - + /// When compiling MSL, the result may differ whether or not we're targetting non-Mac Metal platforms. bool is_apple_mobile = false; }; @@ -41,22 +41,25 @@ public: class ShaderSource { public: ShaderSource() : source(std::monostate()) {} + explicit ShaderSource(const std::string& source_string) : source(source_string) {} + explicit ShaderSource(const std::vector& source_bytecode) : source(source_bytecode) {} + explicit ShaderSource(const prism::path& shader_path) : source(shader_path) {} std::variant> source; - + /// Returns a view of the shader source as a path. [[nodiscard]] prism::path as_path() const { return std::get(source); } - + /// Returns a view of the shader source as plaintext. [[nodiscard]] std::string_view as_string() const { return std::get(source); } - + /// Returns a copy of the shader source as bytecode. [[nodiscard]] std::vector as_bytecode() const { return std::get>(source); @@ -65,11 +68,11 @@ public: [[nodiscard]] bool empty() const { return std::holds_alternative(source); } - + [[nodiscard]] bool is_path() const { return std::holds_alternative(source); } - + [[nodiscard]] bool is_string() const { return std::holds_alternative(source); } @@ -79,10 +82,10 @@ public: class ShaderCompiler { public: ShaderCompiler(); - + /// Sets the include directory used to search for files inside of #include directives. void set_include_path(std::string_view path); - + /** Compiles from one shader language to another shader language. @param from_language The language the shader passed by shader_source is written in. @@ -92,7 +95,12 @@ public: @param options Optional compilation parameters. @note Right now, only GLSL is supported as a source shader language. */ - std::optional compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, CompileOptions options = CompileOptions()); + std::optional compile( + ShaderLanguage from_language, + ShaderStage shader_stage, + const ShaderSource& shader_source, + ShaderLanguage to_language, + CompileOptions options = CompileOptions()); }; static inline ShaderCompiler shader_compiler; diff --git a/engine/shadercompiler/src/defaultresources.hpp b/engine/shadercompiler/src/defaultresources.hpp index 9cc12f5..2c12b89 100755 --- a/engine/shadercompiler/src/defaultresources.hpp +++ b/engine/shadercompiler/src/defaultresources.hpp @@ -1,109 +1,109 @@ #pragma once - const TBuiltInResource DefaultTBuiltInResource = { - /* .MaxLights = */ 32, - /* .MaxClipPlanes = */ 6, - /* .MaxTextureUnits = */ 32, - /* .MaxTextureCoords = */ 32, - /* .MaxVertexAttribs = */ 64, - /* .MaxVertexUniformComponents = */ 4096, - /* .MaxVaryingFloats = */ 64, - /* .MaxVertexTextureImageUnits = */ 32, - /* .MaxCombinedTextureImageUnits = */ 80, - /* .MaxTextureImageUnits = */ 32, - /* .MaxFragmentUniformComponents = */ 4096, - /* .MaxDrawBuffers = */ 32, - /* .MaxVertexUniformVectors = */ 128, - /* .MaxVaryingVectors = */ 8, - /* .MaxFragmentUniformVectors = */ 16, - /* .MaxVertexOutputVectors = */ 16, - /* .MaxFragmentInputVectors = */ 15, - /* .MinProgramTexelOffset = */ -8, - /* .MaxProgramTexelOffset = */ 7, - /* .MaxClipDistances = */ 8, - /* .MaxComputeWorkGroupCountX = */ 65535, - /* .MaxComputeWorkGroupCountY = */ 65535, - /* .MaxComputeWorkGroupCountZ = */ 65535, - /* .MaxComputeWorkGroupSizeX = */ 1024, - /* .MaxComputeWorkGroupSizeY = */ 1024, - /* .MaxComputeWorkGroupSizeZ = */ 64, - /* .MaxComputeUniformComponents = */ 1024, - /* .MaxComputeTextureImageUnits = */ 16, - /* .MaxComputeImageUniforms = */ 8, - /* .MaxComputeAtomicCounters = */ 8, - /* .MaxComputeAtomicCounterBuffers = */ 1, - /* .MaxVaryingComponents = */ 60, - /* .MaxVertexOutputComponents = */ 64, - /* .MaxGeometryInputComponents = */ 64, - /* .MaxGeometryOutputComponents = */ 128, - /* .MaxFragmentInputComponents = */ 128, - /* .MaxImageUnits = */ 8, - /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, - /* .MaxCombinedShaderOutputResources = */ 8, - /* .MaxImageSamples = */ 0, - /* .MaxVertexImageUniforms = */ 0, - /* .MaxTessControlImageUniforms = */ 0, - /* .MaxTessEvaluationImageUniforms = */ 0, - /* .MaxGeometryImageUniforms = */ 0, - /* .MaxFragmentImageUniforms = */ 8, - /* .MaxCombinedImageUniforms = */ 8, - /* .MaxGeometryTextureImageUnits = */ 16, - /* .MaxGeometryOutputVertices = */ 256, - /* .MaxGeometryTotalOutputComponents = */ 1024, - /* .MaxGeometryUniformComponents = */ 1024, - /* .MaxGeometryVaryingComponents = */ 64, - /* .MaxTessControlInputComponents = */ 128, - /* .MaxTessControlOutputComponents = */ 128, - /* .MaxTessControlTextureImageUnits = */ 16, - /* .MaxTessControlUniformComponents = */ 1024, - /* .MaxTessControlTotalOutputComponents = */ 4096, - /* .MaxTessEvaluationInputComponents = */ 128, - /* .MaxTessEvaluationOutputComponents = */ 128, - /* .MaxTessEvaluationTextureImageUnits = */ 16, - /* .MaxTessEvaluationUniformComponents = */ 1024, - /* .MaxTessPatchComponents = */ 120, - /* .MaxPatchVertices = */ 32, - /* .MaxTessGenLevel = */ 64, - /* .MaxViewports = */ 16, - /* .MaxVertexAtomicCounters = */ 0, - /* .MaxTessControlAtomicCounters = */ 0, - /* .MaxTessEvaluationAtomicCounters = */ 0, - /* .MaxGeometryAtomicCounters = */ 0, - /* .MaxFragmentAtomicCounters = */ 8, - /* .MaxCombinedAtomicCounters = */ 8, - /* .MaxAtomicCounterBindings = */ 1, - /* .MaxVertexAtomicCounterBuffers = */ 0, - /* .MaxTessControlAtomicCounterBuffers = */ 0, - /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, - /* .MaxGeometryAtomicCounterBuffers = */ 0, - /* .MaxFragmentAtomicCounterBuffers = */ 1, - /* .MaxCombinedAtomicCounterBuffers = */ 1, - /* .MaxAtomicCounterBufferSize = */ 16384, - /* .MaxTransformFeedbackBuffers = */ 4, - /* .MaxTransformFeedbackInterleavedComponents = */ 64, - /* .MaxCullDistances = */ 8, - /* .MaxCombinedClipAndCullDistances = */ 8, - /* .MaxSamples = */ 4, - /* .maxMeshOutputVerticesNV = */ 256, - /* .maxMeshOutputPrimitivesNV = */ 512, - /* .maxMeshWorkGroupSizeX_NV = */ 32, - /* .maxMeshWorkGroupSizeY_NV = */ 1, - /* .maxMeshWorkGroupSizeZ_NV = */ 1, - /* .maxTaskWorkGroupSizeX_NV = */ 32, - /* .maxTaskWorkGroupSizeY_NV = */ 1, - /* .maxTaskWorkGroupSizeZ_NV = */ 1, - /* .maxMeshViewCountNV = */ 4, - /* .maxDualSourceDrawBuffersEXT = */ 1, + /* .MaxLights = */ 32, + /* .MaxClipPlanes = */ 6, + /* .MaxTextureUnits = */ 32, + /* .MaxTextureCoords = */ 32, + /* .MaxVertexAttribs = */ 64, + /* .MaxVertexUniformComponents = */ 4096, + /* .MaxVaryingFloats = */ 64, + /* .MaxVertexTextureImageUnits = */ 32, + /* .MaxCombinedTextureImageUnits = */ 80, + /* .MaxTextureImageUnits = */ 32, + /* .MaxFragmentUniformComponents = */ 4096, + /* .MaxDrawBuffers = */ 32, + /* .MaxVertexUniformVectors = */ 128, + /* .MaxVaryingVectors = */ 8, + /* .MaxFragmentUniformVectors = */ 16, + /* .MaxVertexOutputVectors = */ 16, + /* .MaxFragmentInputVectors = */ 15, + /* .MinProgramTexelOffset = */ -8, + /* .MaxProgramTexelOffset = */ 7, + /* .MaxClipDistances = */ 8, + /* .MaxComputeWorkGroupCountX = */ 65535, + /* .MaxComputeWorkGroupCountY = */ 65535, + /* .MaxComputeWorkGroupCountZ = */ 65535, + /* .MaxComputeWorkGroupSizeX = */ 1024, + /* .MaxComputeWorkGroupSizeY = */ 1024, + /* .MaxComputeWorkGroupSizeZ = */ 64, + /* .MaxComputeUniformComponents = */ 1024, + /* .MaxComputeTextureImageUnits = */ 16, + /* .MaxComputeImageUniforms = */ 8, + /* .MaxComputeAtomicCounters = */ 8, + /* .MaxComputeAtomicCounterBuffers = */ 1, + /* .MaxVaryingComponents = */ 60, + /* .MaxVertexOutputComponents = */ 64, + /* .MaxGeometryInputComponents = */ 64, + /* .MaxGeometryOutputComponents = */ 128, + /* .MaxFragmentInputComponents = */ 128, + /* .MaxImageUnits = */ 8, + /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .MaxCombinedShaderOutputResources = */ 8, + /* .MaxImageSamples = */ 0, + /* .MaxVertexImageUniforms = */ 0, + /* .MaxTessControlImageUniforms = */ 0, + /* .MaxTessEvaluationImageUniforms = */ 0, + /* .MaxGeometryImageUniforms = */ 0, + /* .MaxFragmentImageUniforms = */ 8, + /* .MaxCombinedImageUniforms = */ 8, + /* .MaxGeometryTextureImageUnits = */ 16, + /* .MaxGeometryOutputVertices = */ 256, + /* .MaxGeometryTotalOutputComponents = */ 1024, + /* .MaxGeometryUniformComponents = */ 1024, + /* .MaxGeometryVaryingComponents = */ 64, + /* .MaxTessControlInputComponents = */ 128, + /* .MaxTessControlOutputComponents = */ 128, + /* .MaxTessControlTextureImageUnits = */ 16, + /* .MaxTessControlUniformComponents = */ 1024, + /* .MaxTessControlTotalOutputComponents = */ 4096, + /* .MaxTessEvaluationInputComponents = */ 128, + /* .MaxTessEvaluationOutputComponents = */ 128, + /* .MaxTessEvaluationTextureImageUnits = */ 16, + /* .MaxTessEvaluationUniformComponents = */ 1024, + /* .MaxTessPatchComponents = */ 120, + /* .MaxPatchVertices = */ 32, + /* .MaxTessGenLevel = */ 64, + /* .MaxViewports = */ 16, + /* .MaxVertexAtomicCounters = */ 0, + /* .MaxTessControlAtomicCounters = */ 0, + /* .MaxTessEvaluationAtomicCounters = */ 0, + /* .MaxGeometryAtomicCounters = */ 0, + /* .MaxFragmentAtomicCounters = */ 8, + /* .MaxCombinedAtomicCounters = */ 8, + /* .MaxAtomicCounterBindings = */ 1, + /* .MaxVertexAtomicCounterBuffers = */ 0, + /* .MaxTessControlAtomicCounterBuffers = */ 0, + /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, + /* .MaxGeometryAtomicCounterBuffers = */ 0, + /* .MaxFragmentAtomicCounterBuffers = */ 1, + /* .MaxCombinedAtomicCounterBuffers = */ 1, + /* .MaxAtomicCounterBufferSize = */ 16384, + /* .MaxTransformFeedbackBuffers = */ 4, + /* .MaxTransformFeedbackInterleavedComponents = */ 64, + /* .MaxCullDistances = */ 8, + /* .MaxCombinedClipAndCullDistances = */ 8, + /* .MaxSamples = */ 4, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, - /* .limits = */ { - /* .nonInductiveForLoops = */ 1, - /* .whileLoops = */ 1, - /* .doWhileLoops = */ 1, - /* .generalUniformIndexing = */ 1, - /* .generalAttributeMatrixVectorIndexing = */ 1, - /* .generalVaryingIndexing = */ 1, - /* .generalSamplerIndexing = */ 1, - /* .generalVariableIndexing = */ 1, - /* .generalConstantMatrixVectorIndexing = */ 1, -}}; + /* .limits = */ + { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, + }}; diff --git a/engine/shadercompiler/src/includer.hpp b/engine/shadercompiler/src/includer.hpp index 6114ae1..d348945 100755 --- a/engine/shadercompiler/src/includer.hpp +++ b/engine/shadercompiler/src/includer.hpp @@ -36,10 +36,10 @@ #pragma once -#include -#include -#include #include +#include +#include +#include #include @@ -48,19 +48,14 @@ // Can be overridden to customize. class DirStackFileIncluder : public glslang::TShader::Includer { public: - DirStackFileIncluder() : externalLocalDirectoryCount(0) { } + DirStackFileIncluder() : externalLocalDirectoryCount(0) {} - IncludeResult* includeLocal(const char* headerName, - const char* includerName, - size_t inclusionDepth) override - { + IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override { return readLocalPath(headerName, includerName, (int)inclusionDepth); } - IncludeResult* includeSystem(const char* headerName, - const char* /*includerName*/, - size_t /*inclusionDepth*/) override - { + IncludeResult* + includeSystem(const char* headerName, const char* /*includerName*/, size_t /*inclusionDepth*/) override { return readSystemPath(headerName); } @@ -70,16 +65,14 @@ public: // is checked. // - This only applies to the "local" form of #include. // - Makes its own copy of the path. - virtual void pushExternalLocalDirectory(const std::string& dir) - { + virtual void pushExternalLocalDirectory(const std::string& dir) { directoryStack.push_back(dir); externalLocalDirectoryCount = (int)directoryStack.size(); } - void releaseInclude(IncludeResult* result) override - { + void releaseInclude(IncludeResult* result) override { if (result != nullptr) { - delete [] static_cast(result->userData); + delete[] static_cast(result->userData); delete result; } } @@ -93,8 +86,7 @@ protected: // Search for a valid "local" path based on combining the stack of include // directories and the nominal name of the header. - virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) - { + virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) { // Discard popped include directories, and // initialize when at parse-time first level. directoryStack.resize(depth + externalLocalDirectoryCount); @@ -117,15 +109,13 @@ protected: // Search for a valid path. // Not implemented yet; returning nullptr signals failure to find. - virtual IncludeResult* readSystemPath(const char* /*headerName*/) const - { + virtual IncludeResult* readSystemPath(const char* /*headerName*/) const { return nullptr; } // Do actual reading of the file, filling in a new include result. - virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const - { - char* content = new tUserDataElement [length]; + virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const { + char* content = new tUserDataElement[length]; file.seekg(0, file.beg); file.read(content, length); return new IncludeResult(path, content, length, content); @@ -134,7 +124,7 @@ protected: // If no path markers, return current working directory. // Otherwise, strip file name and return path leading up to it. virtual std::string getDirectory(const std::string) const { - //return file::get_domain_path(file::domain::Internal).string(); + // return file::get_domain_path(file::domain::Internal).string(); return ""; } }; diff --git a/engine/shadercompiler/src/shadercompiler.cpp b/engine/shadercompiler/src/shadercompiler.cpp index eb9ef83..b036e1e 100755 --- a/engine/shadercompiler/src/shadercompiler.cpp +++ b/engine/shadercompiler/src/shadercompiler.cpp @@ -1,13 +1,13 @@ #include "shadercompiler.hpp" -#include #include +#include -#include "log.hpp" -#include "string_utils.hpp" -#include "includer.hpp" #include "defaultresources.hpp" +#include "includer.hpp" +#include "log.hpp" #include "spirv_hlsl.hpp" +#include "string_utils.hpp" static inline std::vector include_path; @@ -19,50 +19,51 @@ void ShaderCompiler::set_include_path(const std::string_view path) { include_path.emplace_back(path.data()); } -std::vector compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { +std::vector compile_glsl_to_spv( + const std::string_view source_string, + const EShLanguage shader_language, + const CompileOptions& options) { 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"; - - for(auto& definition : options.definitions) + + for (auto& definition : options.definitions) newString += "#define " + definition + "\n"; - + newString += "#line 1\n"; - + newString += source_string; const char* InputCString = newString.c_str(); - + glslang::TShader shader(shader_language); shader.setStrings(&InputCString, 1); int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 - shader.setEnvInput(glslang::EShSourceGlsl, - shader_language, - glslang::EShClientVulkan, - ClientInputSemanticsVersion); + shader.setEnvInput(glslang::EShSourceGlsl, shader_language, glslang::EShClientVulkan, ClientInputSemanticsVersion); // we are targeting vulkan 1.1, so that uses SPIR-V 1.3 shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); - shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); DirStackFileIncluder file_includer; - for(const auto& path : include_path) + for (const auto& path : include_path) file_includer.pushExternalLocalDirectory(path); if (!shader.parse(&DefaultTBuiltInResource, 100, false, EShMsgDefault, file_includer)) { prism::log("{}", shader.getInfoLog()); - + return {}; } - + glslang::TProgram Program; Program.addShader(&shader); - - if(!Program.link(EShMsgDefault)) { - prism::log("Failed to link shader: {} {} {}", source_string.data(), shader.getInfoLog(), shader.getInfoDebugLog()); - + + if (!Program.link(EShMsgDefault)) { + prism::log( + "Failed to link shader: {} {} {}", source_string.data(), shader.getInfoLog(), shader.getInfoDebugLog()); + return {}; } @@ -73,18 +74,23 @@ std::vector compile_glsl_to_spv(const std::string_view source_string, spvOptions.generateDebugInfo = true; glslang::GlslangToSpv(*Program.getIntermediate(shader_language), SpirV, &logger, &spvOptions); - + return SpirV; } -std::optional ShaderCompiler::compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, CompileOptions options) { - if(from_language != ShaderLanguage::GLSL) { +std::optional ShaderCompiler::compile( + const ShaderLanguage from_language, + const ShaderStage shader_stage, + const ShaderSource& shader_source, + const ShaderLanguage to_language, + CompileOptions options) { + if (from_language != ShaderLanguage::GLSL) { prism::log("Non-supported input language!"); return std::nullopt; } - + EShLanguage lang = EShLangMiss; - switch(shader_stage) { + switch (shader_stage) { case ShaderStage::Vertex: lang = EShLangVertex; break; @@ -97,12 +103,12 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la } auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options); - if(spirv.empty()) { + if (spirv.empty()) { prism::log("SPIRV generation failed!"); return std::nullopt; } - - switch(to_language) { + + switch (to_language) { case ShaderLanguage::GLSL: return ShaderSource(shader_source); case ShaderLanguage::SPIRV: @@ -111,7 +117,7 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la spirv_cross::CompilerMSL msl(std::move(spirv)); spirv_cross::CompilerMSL::Options opts; - if(options.is_apple_mobile) { + if (options.is_apple_mobile) { opts.platform = spirv_cross::CompilerMSL::Options::Platform::iOS; } else { opts.platform = spirv_cross::CompilerMSL::Options::Platform::macOS; diff --git a/engine/tests/CMakeLists.txt b/engine/tests/CMakeLists.txt index 2cca27d..1f29dc2 100644 --- a/engine/tests/CMakeLists.txt +++ b/engine/tests/CMakeLists.txt @@ -1,7 +1,7 @@ -add_executable(Tests - tests.cpp - string_tests.cpp - utility_tests.cpp) +add_executable(Tests + tests.cpp + string_tests.cpp + utility_tests.cpp) target_link_libraries(Tests PUBLIC doctest Utility) set_output_dir(Tests) set_engine_properties(Tests) diff --git a/engine/tests/string_tests.cpp b/engine/tests/string_tests.cpp index 8f29a28..a2849d0 100644 --- a/engine/tests/string_tests.cpp +++ b/engine/tests/string_tests.cpp @@ -6,21 +6,21 @@ TEST_SUITE_BEGIN("String Utilities"); TEST_CASE("Remove substring") { std::string str = "foobar"; - + CHECK(remove_substring(str, "foo") == "bar"); CHECK(remove_substring(str, "bar") == "foo"); } TEST_CASE("Replace substring") { std::string str = "foobar"; - + CHECK(replace_substring(str, "foo", "bar") == "barbar"); CHECK(replace_substring(str, "bar", "foo") == "foofoo"); } TEST_CASE("String contains") { std::string str = "foobar"; - + CHECK(string_contains(str, "foo") == true); CHECK(string_contains(str, "bar") == true); CHECK(string_contains(str, "farboo") == false); @@ -28,7 +28,7 @@ TEST_CASE("String contains") { TEST_CASE("String starts with") { std::string str = "(win)and(lose)"; - + CHECK(string_starts_with(str, "(") == true); CHECK(string_starts_with(str, "(win)") == true); CHECK(string_starts_with(str, "(lose)") == false); @@ -36,12 +36,12 @@ TEST_CASE("String starts with") { TEST_CASE("Tokenize") { std::string first_case = "1,2,3"; - + CHECK(tokenize(first_case) == std::vector({"1", "2", "3"})); - + SUBCASE("Alternative delimiters") { std::string second_case = "1-2-3"; - + CHECK(tokenize(second_case, "-") == std::vector({"1", "2", "3"})); } } diff --git a/engine/tests/utility_tests.cpp b/engine/tests/utility_tests.cpp index 32b0aa3..0f73681 100644 --- a/engine/tests/utility_tests.cpp +++ b/engine/tests/utility_tests.cpp @@ -9,7 +9,7 @@ TEST_CASE("Enum to string") { A, B }; - + CHECK(utility::enum_to_string(TestEnum::A) == "A"); CHECK(utility::enum_to_string(TestEnum::B) == "B"); } diff --git a/engine/utility/CMakeLists.txt b/engine/utility/CMakeLists.txt index d0bd632..37ea11b 100755 --- a/engine/utility/CMakeLists.txt +++ b/engine/utility/CMakeLists.txt @@ -1,13 +1,13 @@ set(SRC - include/utility.hpp - include/json_conversions.hpp - include/string_utils.hpp - include/timer.hpp - include/common.hpp - include/assertions.hpp - include/path.hpp - - src/string_utils.cpp) + include/utility.hpp + include/json_conversions.hpp + include/string_utils.hpp + include/timer.hpp + include/common.hpp + include/assertions.hpp + include/path.hpp + + src/string_utils.cpp) add_library(Utility ${SRC}) target_link_libraries(Utility PUBLIC Math magic_enum) diff --git a/engine/utility/include/common.hpp b/engine/utility/include/common.hpp index 61ce94a..ef78709 100755 --- a/engine/utility/include/common.hpp +++ b/engine/utility/include/common.hpp @@ -6,6 +6,7 @@ namespace prism { /// A 2D extent. struct Extent { Extent() : width(0), height(0) {} + Extent(const uint32_t width, const uint32_t height) : width(width), height(height) {} uint32_t width = 0, height = 0; @@ -14,6 +15,7 @@ namespace prism { /// A 2D offset. struct Offset { Offset() : x(0), y(0) {} + Offset(const int32_t x, const int32_t y) : x(x), y(y) {} int32_t x = 0, y = 0; @@ -22,10 +24,13 @@ namespace prism { /// A 2D rectangle defined by a offset and an etent. struct Rectangle { Rectangle() = default; + Rectangle(const Offset offset, const Extent extent) : offset(offset), extent(extent) {} - Rectangle(const int32_t x, const int32_t y, const uint32_t width, const uint32_t height) : offset(x, y), extent(width, height) {} + + Rectangle(const int32_t x, const int32_t y, const uint32_t width, const uint32_t height) + : offset(x, y), extent(width, height) {} Offset offset; Extent extent; }; -} +} // namespace prism diff --git a/engine/utility/include/json_conversions.hpp b/engine/utility/include/json_conversions.hpp index 03f9d67..7811de9 100755 --- a/engine/utility/include/json_conversions.hpp +++ b/engine/utility/include/json_conversions.hpp @@ -2,22 +2,22 @@ #include -#include "vector.hpp" #include "quaternion.hpp" +#include "vector.hpp" namespace prism { - inline void to_json(nlohmann::json &j, const float3 &p) { + inline void to_json(nlohmann::json& j, const float3& p) { j["x"] = p.x; j["y"] = p.y; j["z"] = p.z; } - inline void from_json(const nlohmann::json &j, float3 &p) { + inline void from_json(const nlohmann::json& j, float3& p) { p.x = j["x"]; p.y = j["y"]; p.z = j["z"]; } -} +} // namespace prism inline void to_json(nlohmann::json& j, const Quaternion& p) { j["x"] = p.x; diff --git a/engine/utility/include/path.hpp b/engine/utility/include/path.hpp index 0e82120..886bb74 100755 --- a/engine/utility/include/path.hpp +++ b/engine/utility/include/path.hpp @@ -9,10 +9,9 @@ namespace prism { // some stdlibs such as apple's clang fail to provide this :-/ namespace std { - template <> - struct hash { + template<> struct hash { std::size_t operator()(const prism::path& k) const { return (std::hash()(k.string())); } }; -} \ No newline at end of file +} // namespace std \ No newline at end of file diff --git a/engine/utility/include/timer.hpp b/engine/utility/include/timer.hpp index 6f93024..7bffa6b 100755 --- a/engine/utility/include/timer.hpp +++ b/engine/utility/include/timer.hpp @@ -4,11 +4,11 @@ struct Timer { std::function callback; - + float duration = 0.0f; - + float current_time = 0.0f; - + bool remove_on_trigger = true; bool continue_during_pause = true; }; diff --git a/engine/utility/include/utility.hpp b/engine/utility/include/utility.hpp index ba500b5..9fea22f 100755 --- a/engine/utility/include/utility.hpp +++ b/engine/utility/include/utility.hpp @@ -3,34 +3,30 @@ #include #include -#include +#include #include #include -#include +#include #include "vector.hpp" namespace utility { - template - std::string enum_to_string(const Enum e) { + template std::string enum_to_string(const Enum e) { const std::string_view name = magic_enum::enum_name(e); - + std::string s = name.data(); return s.substr(0, name.length()); } - template - void erase_if(std::vector& vec, const F& f) { - vec.erase(std::remove_if(vec.begin(), vec.end(), f), vec.end()); + template void erase_if(std::vector& vec, const F& f) { + vec.erase(std::remove_if(vec.begin(), vec.end(), f), vec.end()); } - template - void erase(T& vec, const V& t) { + template void erase(T& vec, const V& t) { vec.erase(std::remove(vec.begin(), vec.end(), t), vec.end()); } - template - void erase_at(std::vector& vec, const int index) { + template void erase_at(std::vector& vec, const int index) { vec.erase(vec.begin() + index); } @@ -46,46 +42,60 @@ namespace utility { return get_random(0, max); } - template - inline auto get_random(const std::vector& vec) { + template inline auto get_random(const std::vector& vec) { return vec[get_random(static_cast(vec.size() - 1))]; } - template - inline auto get_random(const std::array& vec) { + template inline auto get_random(const std::array& vec) { return vec[get_random(static_cast(vec.size() - 1))]; } - template - inline auto get_random(const std::unordered_map& map) { + template inline auto get_random(const std::unordered_map& map) { const auto item = map.begin(); std::advance(item, get_random(static_cast(map.size() - 1))); return item; } - template())), class = decltype(std::end(std::declval()))> - constexpr auto enumerate(T&& iterable) - { + template< + class T, + class TIter = decltype(std::begin(std::declval())), + class = decltype(std::end(std::declval()))> + constexpr auto enumerate(T&& iterable) { struct iterator { size_t i; TIter iter; - bool operator != (const iterator & other) const { return iter != other.iter; } - void operator ++ () { ++i; ++iter; } - auto operator * () const { return std::tie(i, *iter); } + + bool operator!=(const iterator& other) const { + return iter != other.iter; + } + + void operator++() { + ++i; + ++iter; + } + + auto operator*() const { + return std::tie(i, *iter); + } }; - + struct iterable_wrapper { T iterable; - auto begin() { return iterator{ 0, std::begin(iterable) }; } - auto end() { return iterator{ 0, std::end(iterable) }; } + + auto begin() { + return iterator{0, std::begin(iterable)}; + } + + auto end() { + return iterator{0, std::end(iterable)}; + } }; - - return iterable_wrapper{ std::forward(iterable) }; + + return iterable_wrapper{std::forward(iterable)}; } - - template - inline bool contains(const std::vector& vec, const V& val) { + + template inline bool contains(const std::vector& vec, const V& val) { return std::count(vec.begin(), vec.end(), val); } @@ -93,7 +103,7 @@ namespace utility { inline uint32_t pack_u32(const uint16_t a, const uint16_t b) { return (b << 16) | a; } - + /// Converts a floating-point to a fixed 16-bit unsigned integer. inline uint16_t to_fixed(const float f) { return static_cast(32.0f * f + 0.5f); @@ -101,8 +111,8 @@ namespace utility { inline prism::float3 from_srgb_to_linear(const prism::float3 sRGB) { prism::float3 linear = sRGB; - for(auto& component : linear.data) { - if(component > 0.04045f) { + for (auto& component : linear.data) { + if (component > 0.04045f) { component = std::pow((component + 0.055) / (1.055), 2.4f); } else if (component <= 0.04045) { component /= 12.92f; @@ -112,8 +122,7 @@ namespace utility { return linear; } - template - inline void move_to_front(std::vector& vec, F func) { + template inline void move_to_front(std::vector& vec, F func) { auto result = std::find_if(vec.begin(), vec.end(), func); if (result != vec.end()) { auto value = *result; @@ -121,4 +130,4 @@ namespace utility { vec.insert(vec.begin(), value); } } -} +} // namespace utility diff --git a/engine/utility/src/string_utils.cpp b/engine/utility/src/string_utils.cpp index 56d7bdb..337c79e 100644 --- a/engine/utility/src/string_utils.cpp +++ b/engine/utility/src/string_utils.cpp @@ -4,25 +4,26 @@ std::string remove_substring(const std::string_view string, const std::string_view substring) { std::string result(string); - + const auto substring_length = substring.length(); - for(auto i = result.find(substring); i != std::string::npos; i = result.find(substring)) + for (auto i = result.find(substring); i != std::string::npos; i = result.find(substring)) result.erase(i, substring_length); - + return result; } -std::string replace_substring(const std::string_view string, const std::string_view substring, const std::string_view replacement) { +std::string +replace_substring(const std::string_view string, const std::string_view substring, const std::string_view replacement) { std::string result(string); - + const auto substring_length = substring.length(); size_t i = 0; - while((i = result.find(substring, i)) != std::string::npos) { + while ((i = result.find(substring, i)) != std::string::npos) { result.erase(i, substring_length); result.insert(i, replacement); i += replacement.length(); } - + return result; } @@ -31,30 +32,31 @@ bool string_contains(const std::string_view a, const std::string_view b) { } bool string_starts_with(const std::string_view haystack, const std::string_view needle) { - return needle.length() <= haystack.length() - && std::equal(needle.begin(), needle.end(), haystack.begin()); + return needle.length() <= haystack.length() && std::equal(needle.begin(), needle.end(), haystack.begin()); } bool is_numeric(const std::string_view string) { - return std::find_if(string.begin(), string.end(), [](unsigned char c) { return !std::isdigit(c); }) == string.end(); + return std::find_if(string.begin(), string.end(), [](unsigned char c) { + return !std::isdigit(c); + }) == string.end(); } std::vector tokenize(const std::string_view string, const std::string_view& delimiters) { std::vector tokens; - + const size_t length = string.length(); size_t lastPos = 0; - - while(lastPos < length + 1) { + + while (lastPos < length + 1) { size_t pos = string.find_first_of(delimiters, lastPos); - if(pos == std::string_view::npos) + if (pos == std::string_view::npos) pos = length; - - if(pos != lastPos) + + if (pos != lastPos) tokens.emplace_back(string.data() + lastPos, pos - lastPos); - + lastPos = pos + 1; } - + return tokens; }