From 143586824414e6033b186504372afa350eff0168 Mon Sep 17 00:00:00 2001 From: mrq Date: Sun, 16 Aug 2020 00:00:00 -0500 Subject: [PATCH] Commit for 2020.08.16.7z --- bin/data/shaders/display.subpass.frag.glsl | 2 +- client/main.cpp | 3 + engine/inc/uf/ext/openvr/openvr.h | 1 + engine/inc/uf/ext/vulkan/graphic.h | 3 + engine/inc/uf/ext/vulkan/graphic.inl | 1 + engine/inc/uf/ext/vulkan/rendermode.h | 4 +- .../inc/uf/ext/vulkan/rendermodes/deferred.h | 2 +- .../uf/ext/vulkan/rendermodes/rendertarget.h | 2 +- .../rendermodes/stereoscopic_deferred.h | 8 +- engine/inc/uf/ext/vulkan/texture.h | 5 + engine/inc/uf/utils/graphic/mesh.h | 22 +++ engine/inc/uf/utils/graphic/mesh.inl | 10 +- engine/src/ext/openvr/openvr.cpp | 63 +++--- engine/src/ext/vulkan/buffer.cpp | 21 +- engine/src/ext/vulkan/graphic.cpp | 148 +++++++++++--- engine/src/ext/vulkan/rendermode.cpp | 6 + .../src/ext/vulkan/rendermodes/deferred.cpp | 185 +++++++----------- .../ext/vulkan/rendermodes/rendertarget.cpp | 59 +++++- .../rendermodes/stereoscopic_deferred.cpp | 140 +++++++------ engine/src/ext/vulkan/texture.cpp | 12 ++ engine/src/utils/camera/camera.cpp | 4 +- engine/src/utils/graphic/mesh.cpp | 18 +- ext/gui/gui.cpp | 41 ++-- ext/main.cpp | 9 +- ext/scenes/test/terrain/marching.cpp | 5 +- ext/scenes/world/portal/portal.cpp | 38 ++-- ext/scenes/world/terrain/region.cpp | 2 +- ext/scenes/world/world.cpp | 32 ++- 28 files changed, 538 insertions(+), 308 deletions(-) diff --git a/bin/data/shaders/display.subpass.frag.glsl b/bin/data/shaders/display.subpass.frag.glsl index ae02e6c1..e2cabe0d 100644 --- a/bin/data/shaders/display.subpass.frag.glsl +++ b/bin/data/shaders/display.subpass.frag.glsl @@ -78,9 +78,9 @@ void phong( Light light, vec4 albedoSpecular, inout vec3 i ) { } void main() { + vec4 albedoSpecular = subpassLoad(samplerAlbedo); position.eye = subpassLoad(samplerPosition).rgb; normal.eye = subpassLoad(samplerNormal).rgb; - vec4 albedoSpecular = subpassLoad(samplerAlbedo); vec3 fragColor = albedoSpecular.rgb * ubo.ambient.rgb; bool lit = false; diff --git a/client/main.cpp b/client/main.cpp index bbd180c4..ea73f94a 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -45,6 +45,9 @@ int main(int argc, char** argv){ throw e; } catch ( std::exception& e ) { uf::iostream << "EXCEPTION ERROR: " << e.what() << "\n"; + std::abort(); + raise(SIGSEGV); + throw e; } catch ( bool handled ) { if (!handled) uf::iostream << "UNHANDLED ERROR: " << "???" << "\n"; } catch ( ... ) { diff --git a/engine/inc/uf/ext/openvr/openvr.h b/engine/inc/uf/ext/openvr/openvr.h index 16e026d4..0f059f45 100644 --- a/engine/inc/uf/ext/openvr/openvr.h +++ b/engine/inc/uf/ext/openvr/openvr.h @@ -34,6 +34,7 @@ namespace ext { extern UF_API uint8_t renderPass; extern UF_API float width, height; extern UF_API bool enabled; + extern UF_API bool swapEyes; bool UF_API initialize( int stage = 0 ); void UF_API tick(); diff --git a/engine/inc/uf/ext/vulkan/graphic.h b/engine/inc/uf/ext/vulkan/graphic.h index 5bf0cd18..c24d3084 100644 --- a/engine/inc/uf/ext/vulkan/graphic.h +++ b/engine/inc/uf/ext/vulkan/graphic.h @@ -64,6 +64,7 @@ namespace ext { struct UF_API Graphic : public Buffers { struct Descriptor { std::string renderMode = ""; + uint32_t renderTarget = 0; uint32_t subpass = 0; uf::BaseGeometry geometry; @@ -71,6 +72,7 @@ namespace ext { VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPolygonMode fill = VK_POLYGON_MODE_FILL; + VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT; float lineWidth = 1.0f; VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE; struct { @@ -97,6 +99,7 @@ namespace ext { bool hasPipeline( Descriptor& descriptor ); void initializePipeline(); Pipeline& initializePipeline( Descriptor& descriptor, bool update = true ); + Pipeline& getPipeline(); Pipeline& getPipeline( Descriptor& descriptor ); void record( VkCommandBuffer commandBuffer ); diff --git a/engine/inc/uf/ext/vulkan/graphic.inl b/engine/inc/uf/ext/vulkan/graphic.inl index 514ffa74..1a34378b 100644 --- a/engine/inc/uf/ext/vulkan/graphic.inl +++ b/engine/inc/uf/ext/vulkan/graphic.inl @@ -1,6 +1,7 @@ template void ext::vulkan::Graphic::initializeGeometry( uf::BaseMesh& mesh ) { if ( mesh.indices.empty() ) mesh.initialize(); + mesh.updateDescriptor(); // already generated, check if we can just update if ( descriptor.indices > 0 ) { diff --git a/engine/inc/uf/ext/vulkan/rendermode.h b/engine/inc/uf/ext/vulkan/rendermode.h index 29cb7fbb..cb0bb824 100644 --- a/engine/inc/uf/ext/vulkan/rendermode.h +++ b/engine/inc/uf/ext/vulkan/rendermode.h @@ -12,7 +12,7 @@ namespace ext { pod::Vector4f clearColor = {0, 0, 0, 1}; Device* device = VK_NULL_HANDLE; - ext::vulkan::RenderTarget renderTarget; + RenderTarget renderTarget; VkSemaphore renderCompleteSemaphore; std::vector fences; @@ -22,6 +22,8 @@ namespace ext { // RAII virtual std::string getType() const; const std::string& getName() const; + virtual RenderTarget& getRenderTarget(size_t = 0); + virtual const RenderTarget& getRenderTarget(size_t = 0) const; virtual void initialize( Device& device ); virtual void createCommandBuffers(); diff --git a/engine/inc/uf/ext/vulkan/rendermodes/deferred.h b/engine/inc/uf/ext/vulkan/rendermodes/deferred.h index 31df7155..377b49f1 100644 --- a/engine/inc/uf/ext/vulkan/rendermodes/deferred.h +++ b/engine/inc/uf/ext/vulkan/rendermodes/deferred.h @@ -6,7 +6,7 @@ namespace ext { namespace vulkan { struct UF_API DeferredRenderMode : public ext::vulkan::RenderMode { - ext::vulkan::DeferredRenderingGraphic blitter; + ext::vulkan::Graphic blitter; // RAII virtual std::string getType() const; diff --git a/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h b/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h index 57307a15..49651d98 100644 --- a/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h +++ b/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h @@ -6,7 +6,7 @@ namespace ext { namespace vulkan { struct UF_API RenderTargetRenderMode : public ext::vulkan::RenderMode { - ext::vulkan::RenderTargetGraphic blitter; + ext::vulkan::Graphic blitter; VkFence fence; VkCommandBuffer commandBuffer; diff --git a/engine/inc/uf/ext/vulkan/rendermodes/stereoscopic_deferred.h b/engine/inc/uf/ext/vulkan/rendermodes/stereoscopic_deferred.h index 2aefa52e..65c822ae 100644 --- a/engine/inc/uf/ext/vulkan/rendermodes/stereoscopic_deferred.h +++ b/engine/inc/uf/ext/vulkan/rendermodes/stereoscopic_deferred.h @@ -11,14 +11,16 @@ namespace ext { ext::vulkan::RenderTarget right; } renderTargets; struct { - ext::vulkan::DeferredRenderingGraphic left; - ext::vulkan::DeferredRenderingGraphic right; + ext::vulkan::Graphic left; + ext::vulkan::Graphic right; } blitters; - ext::vulkan::DeferredRenderingGraphic blitter; + ext::vulkan::Graphic blitter; StereoscopicDeferredRenderMode(); // RAII virtual std::string getType() const; + virtual ext::vulkan::RenderTarget& getRenderTarget(size_t = 0); + virtual const ext::vulkan::RenderTarget& getRenderTarget(size_t = 0) const; virtual void createCommandBuffers( const std::vector& graphics ); virtual void initialize( Device& device ); diff --git a/engine/inc/uf/ext/vulkan/texture.h b/engine/inc/uf/ext/vulkan/texture.h index 9650aa85..cb99af6f 100644 --- a/engine/inc/uf/ext/vulkan/texture.h +++ b/engine/inc/uf/ext/vulkan/texture.h @@ -3,10 +3,13 @@ #include #include +#include + namespace ext { namespace vulkan { struct UF_API Sampler { Device* device = NULL; + VkSampler sampler; VkDescriptorImageInfo descriptor; VkFilter filter = VK_FILTER_LINEAR; @@ -16,6 +19,7 @@ namespace ext { }; struct UF_API Texture { Device* device = nullptr; + VkImage image; VkImageView view; VkImageLayout imageLayout; @@ -106,6 +110,7 @@ namespace ext { VkQueue copyQueue, VkFormat format = VK_FORMAT_R8G8B8A8_UNORM ); + void aliasAttachment( const RenderTarget::Attachment& attachment, bool = true ); }; } } \ No newline at end of file diff --git a/engine/inc/uf/utils/graphic/mesh.h b/engine/inc/uf/utils/graphic/mesh.h index e6ef8b93..a1bd7501 100644 --- a/engine/inc/uf/utils/graphic/mesh.h +++ b/engine/inc/uf/utils/graphic/mesh.h @@ -52,6 +52,18 @@ namespace pod { } bool operator!=( const Vertex_3F2F& that ) const { return !(*this == that); } }; + struct /*UF_API*/ Vertex_2F2F { + alignas(8) pod::Vector2f position; + alignas(8) pod::Vector2f uv; + + static UF_API std::vector descriptor; + + bool operator==( const Vertex_2F2F& that ) const { + return this->position == that.position && + this->uv == that.uv; + } + bool operator!=( const Vertex_2F2F& that ) const { return !(*this == that); } + }; struct /*UF_API*/ Vertex_3F { alignas(16) pod::Vector3f position; @@ -94,6 +106,15 @@ namespace std { return seed; } }; + template<> struct hash { + size_t operator()(pod::Vertex_2F2F const& vertex) const { + std::size_t seed = 2 + 2; + std::hash hasher; + for ( size_t i = 0; i < 2; ++i ) seed ^= hasher( vertex.position[i] ) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + for ( size_t i = 0; i < 2; ++i ) seed ^= hasher( vertex.uv[i] ) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } + }; template<> struct hash { size_t operator()(pod::Vertex_3F const& vertex) const { std::size_t seed = 3; @@ -122,6 +143,7 @@ namespace uf { ~BaseMesh(); void initialize( bool compress = true ); + void updateDescriptor(); void destroy(); }; } diff --git a/engine/inc/uf/utils/graphic/mesh.inl b/engine/inc/uf/utils/graphic/mesh.inl index 3123b071..76979295 100644 --- a/engine/inc/uf/utils/graphic/mesh.inl +++ b/engine/inc/uf/utils/graphic/mesh.inl @@ -1,9 +1,7 @@ template void uf::BaseMesh::initialize( bool compress ) { // this->destroy(false); - sizes.vertex = sizeof(vertex_t); - sizes.indices = sizeof(indices_t); - attributes = vertex_t::descriptor; + this->updateDescriptor(); if ( compress ) { std::unordered_map unique; @@ -30,6 +28,12 @@ void uf::BaseMesh::initialize( bool compress ) { } } template +void uf::BaseMesh::updateDescriptor() { + sizes.vertex = sizeof(vertex_t); + sizes.indices = sizeof(indices_t); + attributes = vertex_t::descriptor; +} +template void uf::BaseMesh::destroy() { this->indices.clear(); this->vertices.clear(); diff --git a/engine/src/ext/openvr/openvr.cpp b/engine/src/ext/openvr/openvr.cpp index 4e9927d2..dde862ee 100644 --- a/engine/src/ext/openvr/openvr.cpp +++ b/engine/src/ext/openvr/openvr.cpp @@ -13,6 +13,7 @@ uint8_t ext::openvr::renderPass = 0; float ext::openvr::width = 0; float ext::openvr::height = 0; bool ext::openvr::enabled = false; +bool ext::openvr::swapEyes = false; #define VR_CHECK_INPUT_RESULT(f)\ if ( f != vr::VRInputError_None ) {\ @@ -71,7 +72,7 @@ namespace { uf::Serializer state; pod::Matrix4t<> matrix; pod::Matrix4t<> tip; - uf::Graphic mesh; + uf::Graphic graphic; } left, right; } controllers; } devices; @@ -186,30 +187,10 @@ bool ext::openvr::initialize( int stage ) { split = uf::string::split( shortname, "." ); if ( split.front() == "hapticVibration" ) { std::cout << "Registered hook for haptic: " << ("VR:Haptics."+split.back()) << std::endl; - - uf::hooks.addHook( "VR:Haptics."+split.back(), [](const std::string& event)->std::string{ + uf::hooks.addHook( "VR:Haptics."+split.back(), [&](const std::string& event)->std::string{ uf::Serializer json = event; - std::string name; - std::string side = json["side"].asString(); - uf::Serializer manifest; - manifest.readFromFile(ext::openvr::driver.manifest); - { - for ( auto i = 0; i < manifest["actions"].size(); ++i ) { - std::string handleName = manifest["actions"][i]["name"].asString(); - std::vector split = uf::string::split( handleName, "/" ); - std::string shortname = split.back(); - if ( shortname != "hapticVibration." + side ) continue; - name = handleName; - break; - } - } - if ( name == "" ) return "false"; - vr::VRActionHandle_t& handle = handles.actions[name]; - auto err = vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ); - if ( err != vr::VRInputError_None ) { - std::cout << err << std::endl; + if ( vr::VRInputError_None != vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ) ) return "false"; - } return "true"; }); } @@ -240,12 +221,8 @@ bool ext::openvr::initialize( int stage ) { return true; } void ext::openvr::terminate() { -/* - ::devices.controllers.left.mesh.graphic.destroy(); - ::devices.controllers.right.mesh.graphic.destroy(); - ::devices.controllers.left.mesh.destroy(); - ::devices.controllers.right.mesh.destroy(); -*/ + ::devices.controllers.left.graphic.destroy(); + ::devices.controllers.right.graphic.destroy(); vr::VR_Shutdown(); ext::openvr::context = NULL; } @@ -306,7 +283,7 @@ void ext::openvr::tick() { } // grab texture size_t len = queued.texture->unWidth * queued.texture->unHeight * 4; - mesh.initialize(); + graphic.initialize(); graphic.initializeGeometry(mesh); auto& texture = graphic.material.textures.emplace_back(); @@ -457,7 +434,7 @@ bool ext::openvr::requestRenderModel( const std::string& name ) { ::queuedRenderModels[name]; return false; } -void ext::openvr::submit() { bool invert = false; +void ext::openvr::submit() { bool invert = swapEyes; ext::vulkan::StereoscopicDeferredRenderMode* renderMode = (ext::vulkan::StereoscopicDeferredRenderMode*) &ext::vulkan::getRenderMode(""); @@ -546,7 +523,17 @@ pod::Vector3f ext::openvr::hmdPosition( vr::Hmd_Eye eye ) { return hmdPosition() + hmdEyePosition( eye ); } pod::Quaternion<> ext::openvr::hmdQuaternion() { - return uf::quaternion::fromMatrix( hmdHeadPositionMatrix() ); // * pod::Vector4f{ 1, 1, -1, -1 }; + pod::Matrix4t<> mat = hmdHeadPositionMatrix(); + pod::Quaternion<> q; + q.w = sqrt(fmax(0, 1 + mat[(4*0)+0] + mat[(4*1)+1] + mat[(4*2)+2])) / 2; + q.x = sqrt(fmax(0, 1 + mat[(4*0)+0] - mat[(4*1)+1] - mat[(4*2)+2])) / 2; + q.y = sqrt(fmax(0, 1 - mat[(4*0)+0] + mat[(4*1)+1] - mat[(4*2)+2])) / 2; + q.z = sqrt(fmax(0, 1 - mat[(4*0)+0] - mat[(4*1)+1] + mat[(4*2)+2])) / 2; + + q.x = copysign(q.x, mat[(4*1)+2] - mat[(4*2)+1]); + q.y = copysign(q.y, mat[(4*2)+0] - mat[(4*0)+2]); + q.z = copysign(q.z, mat[(4*0)+1] - mat[(4*1)+0]); + return q; // * pod::Vector4f{ 1, 1, -1, -1 }; } pod::Matrix4t<> ext::openvr::hmdViewMatrix( vr::Hmd_Eye eye, const pod::Matrix4f& mv ) { return hmdEyePositionMatrix( eye ) * uf::matrix::translate( uf::matrix::identity(), hmdPosition() ) * uf::matrix::inverse( uf::quaternion::matrix( ext::openvr::hmdQuaternion() * pod::Vector4f{ 1, 1, -1, -1 } ) ) * mv; @@ -641,7 +628,17 @@ pod::Vector3f ext::openvr::controllerPosition( vr::Controller_Hand hand, bool ti }; } pod::Quaternion<> ext::openvr::controllerQuaternion( vr::Controller_Hand hand, bool tip ) { - return uf::quaternion::fromMatrix( controllerMatrix( hand, tip ) ) * pod::Vector4f{ 1, 1, -1, 1 }; + pod::Matrix4t<> mat = controllerMatrix( hand, tip ); + pod::Quaternion<> q; + q.w = sqrt(fmax(0, 1 + mat[(4*0)+0] + mat[(4*1)+1] + mat[(4*2)+2])) / 2; + q.x = sqrt(fmax(0, 1 + mat[(4*0)+0] - mat[(4*1)+1] - mat[(4*2)+2])) / 2; + q.y = sqrt(fmax(0, 1 - mat[(4*0)+0] + mat[(4*1)+1] - mat[(4*2)+2])) / 2; + q.z = sqrt(fmax(0, 1 - mat[(4*0)+0] - mat[(4*1)+1] + mat[(4*2)+2])) / 2; + + q.x = copysign(q.x, mat[(4*1)+2] - mat[(4*2)+1]); + q.y = copysign(q.y, mat[(4*2)+0] - mat[(4*0)+2]); + q.z = copysign(q.z, mat[(4*0)+1] - mat[(4*1)+0]); + return q * pod::Vector4f{ 1, 1, -1, 1 }; } pod::Matrix4t<> ext::openvr::controllerTranslationMatrix( vr::Controller_Hand hand, bool tip ) { return uf::matrix::translate( uf::matrix::identity(), controllerPosition( hand, tip ) ); diff --git a/engine/src/ext/vulkan/buffer.cpp b/engine/src/ext/vulkan/buffer.cpp index 233e513b..41285702 100644 --- a/engine/src/ext/vulkan/buffer.cpp +++ b/engine/src/ext/vulkan/buffer.cpp @@ -158,9 +158,9 @@ void ext::vulkan::Buffers::destroy() { } size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage ) { - Buffer buffer; +// Buffer buffer; size_t index = buffers.size(); -// Buffer& buffer = buffers.emplace_back(); + Buffer& buffer = buffers.emplace_back(); // Stage if ( !stage ) { @@ -170,9 +170,9 @@ size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length, buffer, length )); - size_t index = buffers.size(); - buffers.push_back( std::move(buffer) ); - this->updateBuffer( data, length, index, stage ); + this->updateBuffer( data, length, buffer, stage ); + // size_t index = buffers.size(); + // buffers.push_back( std::move(buffer) ); return index; } @@ -202,7 +202,7 @@ size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length, device->flushCommandBuffer(copyCmd, queue, true); staging.destroy(); - buffers.push_back( std::move(buffer) ); +// buffers.push_back( std::move(buffer) ); return index; } void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, size_t index, bool stage ) { @@ -210,6 +210,15 @@ void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, size_t return updateBuffer( data, length, buffer, stage ); } void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, Buffer& buffer, bool stage ) { +// assert(buffer.allocationInfo.size == length); + + if ( buffer.allocationInfo.size != length ) { +// std::cout << "Mismatch buffer update: " << buffer.allocationInfo.size << " vs " << length << ", resetting for safety..." << std::endl; +// assert(buffer.allocationInfo.size > length); + length = buffer.allocationInfo.size; + } + + if ( !stage ) { VK_CHECK_RESULT(buffer.map()); memcpy(buffer.mapped, data, length); diff --git a/engine/src/ext/vulkan/graphic.cpp b/engine/src/ext/vulkan/graphic.cpp index b9a6a848..08c61ea2 100644 --- a/engine/src/ext/vulkan/graphic.cpp +++ b/engine/src/ext/vulkan/graphic.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st this->device = &device; std::string spirv; + { std::ifstream is(this->filename = filename, std::ios::binary | std::ios::in | std::ios::ate); if ( !is.is_open() ) { @@ -31,6 +33,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st assert(spirv.size() > 0); } + { VkShaderModuleCreateInfo moduleCreateInfo = {}; @@ -40,6 +43,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &module)); } + { descriptor.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; descriptor.stage = stage; @@ -48,6 +52,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st assert(descriptor.module != VK_NULL_HANDLE); } + // do reflection { spirv_cross::Compiler comp( (uint32_t*) &spirv[0], spirv.size() / 4 ); @@ -55,6 +60,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st auto parseResource = [&]( const spirv_cross::Resource& resource, VkDescriptorType type ) { // comp.get_decoration(resource.id, spv::DecorationDescriptorSet); + switch ( type ) { case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: { } break; @@ -66,10 +72,11 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st } break; } descriptorSetLayoutBindings.push_back(ext::vulkan::initializers::descriptorSetLayoutBinding( type, stage, comp.get_decoration(resource.id, spv::DecorationBinding) ) ); + }; - - // std::cout << "Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding) << std::endl; - #define LOOP_RESOURCES( key, type ) for ( const auto& resource : res.key ) {\ + + // std::cout << "Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding) << std::endl; + #define LOOP_RESOURCES( key, type ) for ( const auto& resource : res.key ) {\ parseResource( resource, type );\ } LOOP_RESOURCES( sampled_images, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ); @@ -81,6 +88,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st LOOP_RESOURCES( storage_buffers, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ); #undef LOOP_RESOURCES + for ( const auto& resource : res.push_constant_buffers ) { auto& pushConstant = pushConstants.emplace_back(); const auto& type = comp.get_type(resource.base_type_id); @@ -88,12 +96,12 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st pushConstant.create( size ); } + size_t specializationSize = 0; for ( const auto& constant : comp.get_specialization_constants() ) { const auto& value = comp.get_constant(constant.id); const auto& type = comp.get_type(value.constant_type); - size_t size = comp.get_declared_struct_size(type); - // default: value.scalar_i32() + size_t size = 4; //comp.get_declared_struct_size(type); VkSpecializationMapEntry specializationMapEntry; specializationMapEntry.constantID = constant.constant_id; @@ -105,19 +113,59 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st if ( specializationSize > 0 ) { specializationConstants.create( specializationSize ); - specializationInfo = {}; - specializationInfo.dataSize = specializationSize; - specializationInfo.mapEntryCount = specializationMapEntries.size(); - specializationInfo.pMapEntries = specializationMapEntries.data(); - specializationInfo.pData = (void*) specializationConstants; - descriptor.pSpecializationInfo = &specializationInfo; - } + uint8_t* s = (uint8_t*) (void*) specializationConstants; + size_t offset = 0; + for ( const auto& constant : comp.get_specialization_constants() ) { + const auto& value = comp.get_constant(constant.id); + const auto& type = comp.get_type(value.constant_type); + size_t size = 4; + uint8_t buffer[size]; + switch ( type.basetype ) { + case spirv_cross::SPIRType::UInt: { + auto v = value.scalar(); + memcpy( &buffer[0], &v, sizeof(v) ); + } break; + case spirv_cross::SPIRType::Int: { + auto v = value.scalar_i32(); + memcpy( &buffer[0], &v, sizeof(v) ); + } break; + case spirv_cross::SPIRType::Float: { + auto v = value.scalar_f32(); + memcpy( &buffer[0], &v, sizeof(v) ); + } break; + case spirv_cross::SPIRType::Boolean: { + auto v = value.scalar()!=0; + memcpy( &buffer[0], &v, sizeof(v) ); + } break; + } + + memcpy( &s[offset], &buffer, size ); + offset += size; + } + + { + specializationInfo = {}; + specializationInfo.dataSize = specializationSize; + specializationInfo.mapEntryCount = specializationMapEntries.size(); + specializationInfo.pMapEntries = specializationMapEntries.data(); + specializationInfo.pData = s; + descriptor.pSpecializationInfo = &specializationInfo; + } + } /* */ // LOOP_RESOURCES( stage_inputs, VkVertexInputAttributeDescription ); // LOOP_RESOURCES( stage_outputs, VkPipelineColorBlendAttachmentState ); } - // update uniform buffers + + // organize layouts + { + std::sort( descriptorSetLayoutBindings.begin(), descriptorSetLayoutBindings.end(), [&]( const VkDescriptorSetLayoutBinding& l, const VkDescriptorSetLayoutBinding& r ){ + return l.binding < r.binding; + } ); + } + + // update uniform buffers for ( auto& uniform : uniforms ) { pod::Userdata& userdata = uniform.data(); initializeBuffer( @@ -128,6 +176,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st false ); } + } void ext::vulkan::Shader::destroy() { @@ -150,7 +199,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) { assert( graphic.material.shaders.size() > 0 ); RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true); - + auto& renderTarget = renderMode.getRenderTarget( graphic.descriptor.renderTarget ); { std::vector descriptorSetLayoutBindings; std::vector pushConstantRanges; @@ -217,19 +266,33 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) { ); VkPipelineRasterizationStateCreateInfo rasterizationState = ext::vulkan::initializers::pipelineRasterizationStateCreateInfo( graphic.descriptor.fill, - VK_CULL_MODE_BACK_BIT, // VK_CULL_MODE_NONE, + graphic.descriptor.cullMode, // VK_CULL_MODE_NONE, graphic.descriptor.frontFace, 0 ); rasterizationState.lineWidth = graphic.descriptor.lineWidth; std::vector blendAttachmentStates; - auto& subpass = renderMode.renderTarget.passes[graphic.descriptor.subpass]; + auto& subpass = renderTarget.passes[graphic.descriptor.subpass]; for ( auto& color : subpass.colors ) { VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState( 0xf, - VK_FALSE + VK_TRUE ); + blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; + blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; + /* + if ( !blendAttachmentStates.empty() ) { + VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState( + 0xf, + VK_FALSE + ); + } + */ blendAttachmentStates.push_back(blendAttachmentState); } VkPipelineColorBlendStateCreateInfo colorBlendState = ext::vulkan::initializers::pipelineColorBlendStateCreateInfo( @@ -292,7 +355,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) { VkGraphicsPipelineCreateInfo pipelineCreateInfo = ext::vulkan::initializers::pipelineCreateInfo( pipelineLayout, - renderMode.renderTarget.renderPass, + renderTarget.renderPass, 0 ); pipelineCreateInfo.pVertexInputState = &vertexInputState; @@ -314,9 +377,18 @@ void ext::vulkan::Pipeline::record( Graphic& graphic, VkCommandBuffer commandBuf for ( auto& shader : graphic.material.shaders ) { size_t offset = 0; for ( auto& pushConstant : shader.pushConstants ) { + struct PushConstant { + uint32_t pass; + } p = { ext::openvr::renderPass }; + /* pod::Userdata& userdata = pushConstant.data(); + { + pushConstant.get() = { 0 };//ext::openvr::renderPass }; + } vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, offset, userdata.len, userdata.data ); offset += userdata.len; + */ + vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, 0, sizeof(p), &p ); } } // Bind descriptor sets describing shader binding points @@ -335,10 +407,12 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) { } RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true); - auto& subpass = renderMode.renderTarget.passes[graphic.descriptor.subpass]; + auto& renderTarget = renderMode.getRenderTarget(graphic.descriptor.renderTarget ); + + auto& subpass = renderTarget.passes[graphic.descriptor.subpass]; for ( auto& input : subpass.inputs ) { inputDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( - renderMode.renderTarget.attachments[input.attachment].view, + renderTarget.attachments[input.attachment].view, input.layout )); } @@ -420,6 +494,7 @@ void ext::vulkan::Material::initialize( Device& device ) { } void ext::vulkan::Material::destroy() { if ( aliased ) return; + for ( auto& texture : textures ) texture.destroy(); for ( auto& shader : shaders ) shader.destroy(); for ( auto& sampler : samplers ) sampler.destroy(); @@ -431,20 +506,26 @@ void ext::vulkan::Material::destroy() { void ext::vulkan::Material::attachShader( const std::string& filename, VkShaderStageFlagBits stage ) { auto& shader = shaders.emplace_back(); shader.initialize( *device, filename, stage ); -/* - Shader shader; - shader.initialize( *device, filename, stage ); - shaders.push_back( std::move( shader ) ); -*/ + + // check how many samplers requested + for ( auto& layout : shader.descriptorSetLayoutBindings ) { + if ( layout.descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER ) continue; + Sampler& sampler = samplers.emplace_back(); + sampler.initialize( *device ); + } } void ext::vulkan::Material::initializeShaders( const std::vector>& layout ) { shaders.clear(); shaders.reserve( layout.size() ); - for ( auto& request : layout ) attachShader( request.first, request.second ); + for ( auto& request : layout ) { + attachShader( request.first, request.second ); + } } void ext::vulkan::Graphic::initialize( const std::string& renderModeName ) { RenderMode& renderMode = ext::vulkan::getRenderMode(renderModeName, true); + this->descriptor.renderMode = renderModeName; + material.initialize( *renderMode.device ); ext::vulkan::Buffers::initialize( *renderMode.device ); @@ -468,14 +549,20 @@ ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( Descriptor& des bool ext::vulkan::Graphic::hasPipeline( Descriptor& descriptor ) { return pipelines.count( descriptor.hash() ) > 0; } +ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() { + return getPipeline( descriptor ); +} ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( Descriptor& descriptor ) { if ( !hasPipeline(descriptor) ) return initializePipeline( descriptor ); return pipelines[descriptor.hash()]; } void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) { - if ( !this->hasPipeline( descriptor ) ) return; + if ( !this->hasPipeline( descriptor ) ) { + std::cout << this << ": has no valid pipeline" << std::endl; + return; + } - auto& pipeline = this->getPipeline( descriptor ); + auto& pipeline = this->getPipeline(); assert( buffers.size() >= 2 ); Buffer& vertexBuffer = buffers.at(0); @@ -515,6 +602,7 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const { uf::Serializer serializer; serializer["subpass"] = subpass; + serializer["renderTarget"] = renderTarget; serializer["geometry"]["sizes"]["vertex"] = geometry.sizes.vertex; serializer["geometry"]["sizes"]["indices"] = geometry.sizes.indices; @@ -527,6 +615,7 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const { } } serializer["topology"] = topology; + serializer["cullMode"] = cullMode; serializer["fill"] = fill; serializer["lineWidth"] = lineWidth; serializer["frontFace"] = frontFace; @@ -534,7 +623,6 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const { serializer["depthTest"]["write"] = depthTest.write; serializer["depthTest"]["operation"] = depthTest.operation; -// std::cout << this << ": " << indices << ": " << subpass << ": " << serializer << std::endl; - +// std::cout << this << ": " << indices << ": " << renderMode << ": " << subpass << ": " << serializer << std::endl; return uf::string::sha256( serializer.serialize() ); } \ No newline at end of file diff --git a/engine/src/ext/vulkan/rendermode.cpp b/engine/src/ext/vulkan/rendermode.cpp index 6a659641..8dfa3340 100644 --- a/engine/src/ext/vulkan/rendermode.cpp +++ b/engine/src/ext/vulkan/rendermode.cpp @@ -20,6 +20,12 @@ std::string ext::vulkan::RenderMode::getType() const { const std::string& ext::vulkan::RenderMode::getName() const { return this->name; } +ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) { + return renderTarget; +} +const ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) const { + return renderTarget; +} void ext::vulkan::RenderMode::createCommandBuffers() { std::vector graphics; diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index 31469cdc..81ff6400 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -10,9 +10,6 @@ #include #include -namespace { - ext::vulkan::Graphic newBlitter; -} std::string ext::vulkan::DeferredRenderMode::getType() const { return "Deferred"; @@ -62,129 +59,75 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { } } renderTarget.initialize( device ); -/* + { - ::blitter.descriptor.subpass = 1; - ::blitter.initialize(); - ::blitter.material.shader.initializeShaders({ + uf::BaseMesh mesh; + /* + mesh.vertices = { + { {-1.0f, 1.0f}, {0.0f, 0.0f}, }, + { {-1.0f, -1.0f}, {0.0f, 1.0f}, }, + { {1.0f, -1.0f}, {1.0f, 1.0f}, }, + + { {-1.0f, 1.0f}, {0.0f, 0.0f}, }, + { {1.0f, -1.0f}, {1.0f, 1.0f}, }, + { {1.0f, 1.0f}, {1.0f, 0.0f}, } + }; + */ + mesh.vertices = { + { {-1.0f, 1.0f}, {0.0f, 0.0f}, }, + { {-1.0f, -1.0f}, {0.0f, 1.0f}, }, + { {1.0f, -1.0f}, {1.0f, 1.0f}, }, + { {1.0f, 1.0f}, {1.0f, 0.0f}, } + }; + mesh.indices = { + 0, 1, 2, 0, 2, 3 + }; + blitter.descriptor.subpass = 1; + blitter.descriptor.depthTest.test = false; + blitter.descriptor.depthTest.write = false; + + blitter.initialize( this->getName() ); + blitter.initializeGeometry( mesh ); + blitter.material.initializeShaders({ {"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, {"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT} }); + blitter.initializePipeline(); } -*/ - blitter.renderTarget = &renderTarget; - blitter.initializeShaders({ - {"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, - {"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT} - }); - blitter.subpass = 1; - blitter.initialize( device, *this ); - // update layer rendertargets descriptor sets +/* { std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); //{ &ext::vulkan::getRenderMode("Gui") }; - for ( auto layer : layers ) { - RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; - auto& blitter = rtLayer->blitter; - // blitter.subpass = 1; - blitter.initialize( device, *this ); + for ( auto _ : layers ) { + RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _; + auto& blitter = layer->blitter; + blitter.initialize( this->getName() ); } } +*/ } void ext::vulkan::DeferredRenderMode::tick() { ext::vulkan::RenderMode::tick(); - std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); - for ( auto layer : layers ) { - RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; - auto& blitter = rtLayer->blitter; - // update descriptor set - if ( !blitter.initialized ) { - // blitter.subpass = 1; - if ( blitter.renderTarget ) blitter.initialize( *device, *this ); - } - } + if ( ext::vulkan::resized ) { - // destroy if exist - { - renderTarget.initialize( *renderTarget.device ); - } + renderTarget.initialize( *renderTarget.device ); // update blitter descriptor set if ( blitter.initialized ) { - std::vector inputDescriptors; - auto& subpass = renderTarget.passes[blitter.subpass]; - for ( auto& input : subpass.inputs ) { - inputDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( - renderTarget.attachments[input.attachment].view, - input.layout - )); - } - // Set descriptor set - std::vector writeDescriptorSets = { - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(blitter.buffers.at(0).descriptor) - ) - }; - for ( size_t i = 0; i < inputDescriptors.size(); ++i ) { - writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - i + 1, - &inputDescriptors[i] - )); - } - blitter.initializeDescriptorSet( writeDescriptorSets ); - } - // update layer rendertargets descriptor sets - for ( auto layer : layers ) { - RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; - auto& blitter = rtLayer->blitter; - auto& renderTarget = rtLayer->renderTarget; - // update descriptor set - if ( blitter.initialized ) { - renderTarget.initialize( *renderTarget.device ); - VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = blitter.sampler; - std::vector colorDescriptors; - for ( auto& attachment : renderTarget.attachments ) { - if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; - colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( - attachment.view, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - )); - } - - // Set descriptor set - std::vector writeDescriptorSets = { - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(blitter.buffers.at(0).descriptor) - ), - // Binding 1 : Sampler - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_SAMPLER, - 1, - &samplerDescriptor - ), - }; - for ( size_t i = 0; i < colorDescriptors.size(); ++i ) { - writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - i + 2, - &colorDescriptors[i] - )); - } - vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); - } + // blitter.material.textures.clear(); + auto& pipeline = blitter.getPipeline(); + pipeline.update( blitter ); } } +/* + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); + for ( auto _ : layers ) { + RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _; + auto& blitter = layer->blitter; + if ( blitter.initialized ) continue; + blitter.initialize( this->getName() ); + blitter.initializePipeline(); + } +*/ } void ext::vulkan::DeferredRenderMode::destroy() { ext::vulkan::RenderMode::destroy(); @@ -279,22 +222,26 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vectorblitter.initialized ) continue; - if ( rtLayer->blitter.subpass != 0 ) continue; - rtLayer->blitter.createCommandBuffer(commands[i]); + for ( auto _ : layers ) { + RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _; + auto& blitter = layer->blitter; + if ( !blitter.initialized ) continue; + if ( blitter.descriptor.subpass != 0 ) continue; + blitter.record(commands[i]); } } vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); - blitter.createCommandBuffer(commands[i]); + { + blitter.record(commands[i]); + } // render gui layer { - for ( auto layer : layers ) { - RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; - if ( !rtLayer->blitter.initialized ) continue; - if ( rtLayer->blitter.subpass != 1 ) continue; - rtLayer->blitter.createCommandBuffer(commands[i]); + for ( auto _ : layers ) { + RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _; + auto& blitter = layer->blitter; + if ( !blitter.initialized ) continue; + if ( blitter.descriptor.subpass != 1 ) continue; + blitter.record(commands[i]); } } vkCmdEndRenderPass(commands[i]); diff --git a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp index 13fde596..7e70780d 100644 --- a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp @@ -68,17 +68,64 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { } renderTarget.initialize( device ); - blitter.renderTarget = &renderTarget; - blitter.initializeShaders({ - {"./data/shaders/display.rendertarget.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, - {"./data/shaders/display.rendertarget.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT} - }); - // blitter.initialize(); + { + uf::BaseMesh mesh; + mesh.vertices = { + { {-1.0f, 1.0f}, {0.0f, 1.0f}, }, + { {-1.0f, -1.0f}, {0.0f, 0.0f}, }, + { {1.0f, -1.0f}, {1.0f, 0.0f}, }, + { {1.0f, 1.0f}, {1.0f, 1.0f}, } + }; + mesh.indices = { + 0, 1, 2, 2, 3, 0 + }; + /* + mesh.vertices = { + { {-1.0f, 1.0f}, {0.0f, 0.0f}, }, + { {-1.0f, -1.0f}, {0.0f, 1.0f}, }, + { {1.0f, -1.0f}, {1.0f, 1.0f}, }, + + { {-1.0f, 1.0f}, {0.0f, 0.0f}, }, + { {1.0f, -1.0f}, {1.0f, 1.0f}, }, + { {1.0f, 1.0f}, {1.0f, 0.0f}, } + }; + */ + // blitter.descriptor.subpass = 1; + // blitter.descriptor.depthTest.test = false; + // blitter.descriptor.depthTest.write = false; + // blitter.initialize(this->getName()); + + blitter.device = &device; + blitter.material.device = &device; + blitter.initializeGeometry( mesh ); + blitter.material.initializeShaders({ + {"./data/shaders/display.renderTarget.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, + {"./data/shaders/display.renderTarget.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT} + }); + for ( auto& attachment : renderTarget.attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + + Texture2D& texture = blitter.material.textures.emplace_back(); + texture.aliasAttachment(attachment); + } + // blitter.initializePipeline(); + } } void ext::vulkan::RenderTargetRenderMode::tick() { ext::vulkan::RenderMode::tick(); if ( ext::vulkan::resized ) { renderTarget.initialize( *renderTarget.device ); + + blitter.material.textures.clear(); + for ( auto& attachment : renderTarget.attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + + Texture2D& texture = blitter.material.textures.emplace_back(); + texture.aliasAttachment(attachment); + } + + auto& pipeline = blitter.getPipeline(); + pipeline.update( blitter ); } } void ext::vulkan::RenderTargetRenderMode::destroy() { diff --git a/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp b/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp index d116b53d..e0854f08 100644 --- a/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp @@ -16,25 +16,40 @@ namespace { uint8_t DOMINANT_EYE = 0; } -//ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }), blitters({ blitter }) { +// ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }), blitters({ blitter }) { ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }) { } std::string ext::vulkan::StereoscopicDeferredRenderMode::getType() const { return "Deferred (Stereoscopic)"; } +ext::vulkan::RenderTarget& ext::vulkan::StereoscopicDeferredRenderMode::getRenderTarget( size_t i ) { + switch ( i ) { + case 0: return renderTargets.left; + case 1: return renderTargets.right; + default: return renderTarget; + } +} +const ext::vulkan::RenderTarget& ext::vulkan::StereoscopicDeferredRenderMode::getRenderTarget( size_t i ) const { + switch ( i ) { + case 0: return renderTargets.left; + case 1: return renderTargets.right; + default: return renderTarget; + } +} void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { ext::vulkan::RenderMode::initialize( device ); struct EYES { RenderTarget* renderTarget; - DeferredRenderingGraphic* blitter; + Graphic* blitter; }; std::vector eyes = { { &renderTargets.left, &blitters.left }, { &renderTargets.right, &blitters.right }, }; + std::size_t i = 0; for ( auto& eye : eyes ) { auto& renderTarget = *eye.renderTarget; auto& blitter = *eye.blitter; @@ -81,18 +96,32 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { attachments.depth ); } - // Third render pass: write to swapchain - /* - { - renderTarget.addPass( - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - { attachments.swapchain }, - { attachments.output }, - attachments.depth - ); - } - */ renderTarget.initialize( device ); + { + uf::BaseMesh mesh; + mesh.vertices = { + { {-1.0f, 1.0f}, {0.0f, 0.0f}, }, + { {-1.0f, -1.0f}, {0.0f, 1.0f}, }, + { {1.0f, -1.0f}, {1.0f, 1.0f}, }, + { {1.0f, 1.0f}, {1.0f, 0.0f}, } + }; + mesh.indices = { + 0, 1, 2, 0, 2, 3 + }; + blitter.descriptor.subpass = 1; + blitter.descriptor.renderTarget = i++; + blitter.descriptor.depthTest.test = false; + blitter.descriptor.depthTest.write = false; + + blitter.initialize( this->getName() ); + blitter.initializeGeometry( mesh ); + blitter.material.initializeShaders({ + {"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, + {"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT} + }); + blitter.initializePipeline(); + } + /* blitter.renderTarget = &renderTarget; blitter.initializeShaders({ {"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, @@ -101,6 +130,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { blitter.subpass = 1; blitter.initialize( device, *this ); + */ } /* { @@ -114,6 +144,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { } */ // update layer rendertargets descriptor sets +/* { std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); //{ &ext::vulkan::getRenderMode("Gui") }; for ( auto layer : layers ) { @@ -123,9 +154,31 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { blitter.initialize( device, *this ); } } +*/ } void ext::vulkan::StereoscopicDeferredRenderMode::tick() { ext::vulkan::RenderMode::tick(); + if ( ext::vulkan::resized ) { + struct EYES { + RenderTarget* renderTarget; + Graphic* blitter; + }; + std::vector eyes = { + { &renderTargets.left, &blitters.left }, + { &renderTargets.right, &blitters.right }, + }; + for ( auto& eye : eyes ) { + auto& renderTarget = *eye.renderTarget; + auto& blitter = *eye.blitter; + + renderTarget.initialize( *renderTarget.device ); + if ( blitter.initialized ) { + auto& pipeline = blitter.getPipeline(); + pipeline.update( blitter ); + } + } + } +/* std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); for ( auto layer : layers ) { RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; @@ -139,7 +192,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() { if ( ext::vulkan::resized ) { struct EYES { RenderTarget* renderTarget; - DeferredRenderingGraphic* blitter; + Graphic* blitter; }; std::vector eyes = { { &renderTargets.left, &blitters.left }, @@ -224,12 +277,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() { if ( blitter.initialized ) { VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = blitter.sampler; std::vector colorDescriptors; - /* - colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( - renderTarget.attachments[0].view, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - )); - */ for ( auto& attachment : renderTarget.attachments ) { colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( @@ -265,40 +312,17 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() { )); } vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); - /* - VkDescriptorImageInfo renderTargetDescription = ext::vulkan::initializers::descriptorImageInfo( - renderTarget.attachments[0].view, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - blitter.sampler - ); - std::vector writeDescriptorSets = { - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(blitter.buffers.at(0).descriptor) - ), - // Binding 1 : Albedo input attachment - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - &renderTargetDescription - ), - }; - vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); - */ } } } +*/ } void ext::vulkan::StereoscopicDeferredRenderMode::destroy() { ext::vulkan::RenderMode::destroy(); renderTargets.right.destroy(); blitters.left.destroy(); blitters.right.destroy(); - blitter.destroy(); +// blitter.destroy(); } void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const std::vector& graphics ) { // destroy if exists @@ -325,7 +349,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo)); struct EYES { RenderTarget* renderTarget; - DeferredRenderingGraphic* blitter; + Graphic* blitter; }; std::vector eyes = { { &renderTargets.left, &blitters.left }, @@ -396,22 +420,24 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st } // render gui layer { - for ( auto layer : layers ) { - RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; - if ( !rtLayer->blitter.initialized ) continue; - if ( rtLayer->blitter.subpass != 0 ) continue; - rtLayer->blitter.createCommandBuffer(commands[i]); + for ( auto _ : layers ) { + RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _; + auto& blitter = layer->blitter; + if ( !blitter.initialized ) continue; + if ( blitter.descriptor.subpass != 0 ) continue; + blitter.record(commands[i]); } } vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); - blitter.createCommandBuffer(commands[i]); + blitter.record(commands[i]); // render gui layer { - for ( auto layer : layers ) { - RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; - if ( !rtLayer->blitter.initialized ) continue; - if ( rtLayer->blitter.subpass != 1 ) continue; - rtLayer->blitter.createCommandBuffer(commands[i]); + for ( auto _ : layers ) { + RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _; + auto& blitter = layer->blitter; + if ( !blitter.initialized ) continue; + if ( blitter.descriptor.subpass != 1 ) continue; + blitter.record(commands[i]); } } /* diff --git a/engine/src/ext/vulkan/texture.cpp b/engine/src/ext/vulkan/texture.cpp index adf0868a..23e92522 100644 --- a/engine/src/ext/vulkan/texture.cpp +++ b/engine/src/ext/vulkan/texture.cpp @@ -50,6 +50,7 @@ bool ext::vulkan::Texture::generated() const { } void ext::vulkan::Texture::destroy() { if ( !device ) return; + if ( view != VK_NULL_HANDLE ) { vkDestroyImageView(device->logicalDevice, view, nullptr); view = VK_NULL_HANDLE; @@ -546,5 +547,16 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin VK_CHECK_RESULT(vkCreateImageView(device, &viewCreateInfo, nullptr, &view)); // Initialize a descriptor for later use + this->updateDescriptors(); +} +void ext::vulkan::Texture2D::aliasAttachment( const RenderTarget::Attachment& attachment, bool createSampler ) { + image = attachment.image; + view = attachment.view; + imageLayout = attachment.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : attachment.layout; + deviceMemory = attachment.mem; + + // Create sampler + if ( createSampler ) sampler.initialize( ext::vulkan::device, sampler.filter ); + this->updateDescriptors(); } \ No newline at end of file diff --git a/engine/src/utils/camera/camera.cpp b/engine/src/utils/camera/camera.cpp index 0b733edd..98f90e37 100644 --- a/engine/src/utils/camera/camera.cpp +++ b/engine/src/utils/camera/camera.cpp @@ -250,10 +250,10 @@ void uf::Camera::updateView() { transform.orientation = uf::quaternion::identity(); pod::Transform<> flatten = uf::transform::flatten( transform ); - pod::Matrix4t<> translation = uf::matrix::translate( uf::matrix::identity(), -position ); + pod::Matrix4t<> translation = uf::matrix::translate( uf::matrix::identity(), position ); pod::Matrix4t<> rotation = uf::quaternion::matrix( flatten.orientation ); - pod::Matrix4t<> view = rotation * translation; //uf::matrix::inverse( translation * rotation ); + pod::Matrix4t<> view = uf::matrix::inverse( translation * rotation ); transform.orientation = ext::openvr::hmdQuaternion(); this->setView( ext::openvr::hmdViewMatrix(vr::Eye_Left, view ), 0 ); this->setView( ext::openvr::hmdViewMatrix(vr::Eye_Right, view ), 1 ); diff --git a/engine/src/utils/graphic/mesh.cpp b/engine/src/utils/graphic/mesh.cpp index 1f91f71b..9952ad48 100644 --- a/engine/src/utils/graphic/mesh.cpp +++ b/engine/src/utils/graphic/mesh.cpp @@ -1,11 +1,5 @@ #include -/* -uf::Graphic::~Graphic() { - this->destroy(); -} -void uf::Graphic::destroy( bool clear ) { -} -*/ + // Used for terrain std::vector pod::Vertex_3F2F3F32B::descriptor = { { @@ -51,6 +45,16 @@ std::vector pod::Vertex_3F2F::descriptor = { offsetof(pod::Vertex_3F2F, uv) } }; +std::vector pod::Vertex_2F2F::descriptor = { + { + VK_FORMAT_R32G32B32_SFLOAT, + offsetof(pod::Vertex_2F2F, position) + }, + { + VK_FORMAT_R32G32_SFLOAT, + offsetof(pod::Vertex_2F2F, uv) + } +}; // Basic std::vector pod::Vertex_3F::descriptor = { { diff --git a/ext/gui/gui.cpp b/ext/gui/gui.cpp index 8d400828..099e35f7 100644 --- a/ext/gui/gui.cpp +++ b/ext/gui/gui.cpp @@ -1026,6 +1026,21 @@ void ext::Gui::render() { if ( renderMode->getName() == "Gui" ) { auto& blitter = renderMode->blitter; auto& metadata = controller.getComponent(); + + struct UniformDescriptor { + struct { + alignas(16) pod::Matrix4f models[2]; + } matrices; + struct { + alignas(8) pod::Vector2f position = { 0.5f, 0.5f }; + alignas(8) pod::Vector2f radius = { 0.1f, 0.1f }; + alignas(16) pod::Vector4f color = { 1, 1, 1, 1 }; + } cursor; + alignas(4) float alpha; + }; + auto& shader = blitter.material.shaders.front(); + auto& uniforms = shader.uniforms.front().get(); + for ( std::size_t i = 0; i < 2; ++i ) { pod::Transform<> transform; if ( metadata["overlay"]["position"].isArray() ) @@ -1050,37 +1065,37 @@ void ext::Gui::render() { if ( ext::openvr::enabled && (metadata["overlay"]["enabled"].asBool() || ext::vulkan::getRenderMode("Stereoscopic Deferred", true).getType() == "Stereoscopic Deferred" )) { if ( metadata["overlay"]["floating"].asBool() ) { pod::Matrix4f model = uf::transform::model( transform ); - blitter.uniforms.matrices.models[i] = camera.getProjection(i) * ext::openvr::hmdEyePositionMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right ) * model; + uniforms.matrices.models[i] = camera.getProjection(i) * ext::openvr::hmdEyePositionMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right ) * model; } else { auto translation = uf::matrix::translate( uf::matrix::identity(), camera.getTransform().position + controller.getComponent>().position ); auto rotation = uf::quaternion::matrix( controller.getComponent>().orientation * pod::Vector4f{1,1,1,-1} ); pod::Matrix4f model = translation * rotation * uf::transform::model( transform ); - blitter.uniforms.matrices.models[i] = camera.getProjection(i) * camera.getView(i) * model; + uniforms.matrices.models[i] = camera.getProjection(i) * camera.getView(i) * model; } } else { pod::Matrix4t<> model = uf::matrix::translate( uf::matrix::identity(), { 0, 0, 1 } ); - blitter.uniforms.matrices.models[i] = model; + uniforms.matrices.models[i] = model; } - blitter.uniforms.alpha = metadata["overlay"]["alpha"].asFloat(); + uniforms.alpha = metadata["overlay"]["alpha"].asFloat(); - blitter.uniforms.cursor.position.x = (metadata["overlay"]["cursor"]["position"][0].asFloat() + 1.0f) * 0.5f; //(::mouse.position.x + 1.0f) * 0.5f; - blitter.uniforms.cursor.position.y = (metadata["overlay"]["cursor"]["position"][1].asFloat() + 1.0f) * 0.5f; //(::mouse.position.y + 1.0f) * 0.5f; + uniforms.cursor.position.x = (metadata["overlay"]["cursor"]["position"][0].asFloat() + 1.0f) * 0.5f; //(::mouse.position.x + 1.0f) * 0.5f; + uniforms.cursor.position.y = (metadata["overlay"]["cursor"]["position"][1].asFloat() + 1.0f) * 0.5f; //(::mouse.position.y + 1.0f) * 0.5f; pod::Vector3f cursorSize; cursorSize.x = metadata["overlay"]["cursor"]["radius"].asFloat(); cursorSize.y = metadata["overlay"]["cursor"]["radius"].asFloat(); cursorSize = uf::matrix::multiply( uf::matrix::inverse( uf::matrix::scale( uf::matrix::identity() , transform.scale) ), cursorSize ); - blitter.uniforms.cursor.radius.x = cursorSize.x; - blitter.uniforms.cursor.radius.y = cursorSize.y; + uniforms.cursor.radius.x = cursorSize.x; + uniforms.cursor.radius.y = cursorSize.y; - blitter.uniforms.cursor.color.x = metadata["overlay"]["cursor"]["color"][0].asFloat(); - blitter.uniforms.cursor.color.y = metadata["overlay"]["cursor"]["color"][1].asFloat(); - blitter.uniforms.cursor.color.z = metadata["overlay"]["cursor"]["color"][2].asFloat(); - blitter.uniforms.cursor.color.w = metadata["overlay"]["cursor"]["color"][3].asFloat(); + uniforms.cursor.color.x = metadata["overlay"]["cursor"]["color"][0].asFloat(); + uniforms.cursor.color.y = metadata["overlay"]["cursor"]["color"][1].asFloat(); + uniforms.cursor.color.z = metadata["overlay"]["cursor"]["color"][2].asFloat(); + uniforms.cursor.color.w = metadata["overlay"]["cursor"]["color"][3].asFloat(); } - blitter.updateBuffer( (void*) &blitter.uniforms, sizeof(blitter.uniforms), 0 ); + shader.updateBuffer( (void*) &uniforms, sizeof(uniforms), 0 ); } } } diff --git a/ext/main.cpp b/ext/main.cpp index 896b516d..70352f32 100644 --- a/ext/main.cpp +++ b/ext/main.cpp @@ -107,12 +107,13 @@ void EXT_API ext::initialize() { ext::vulkan::DeferredRenderingGraphic::maxLights = ::config["engine"]["scenes"]["max lights"].asUInt(); // ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].asBool(); + ext::openvr::swapEyes = ::config["engine"]["ext"]["vr"]["swap eyes"].asBool(); ext::openvr::driver.manifest = ::config["engine"]["ext"]["vr"]["manifest"].asString(); if ( ext::openvr::enabled ) { ::config["engine"]["render modes"]["stereo deferred"] = true; - ext::vulkan::validation = false; - if ( ::config["engine"]["ext"]["vr"]["invert winding order"].asBool() ) - ext::vulkan::GraphicOld::DEFAULT_WINDING_ORDER = VK_FRONT_FACE_COUNTER_CLOCKWISE; + // ext::vulkan::validation = false; + // if ( ::config["engine"]["ext"]["vr"]["invert winding order"].asBool() ) + // ext::vulkan::GraphicOld::DEFAULT_WINDING_ORDER = VK_FRONT_FACE_COUNTER_CLOCKWISE; } } @@ -124,7 +125,7 @@ void EXT_API ext::initialize() { if ( ::config["engine"]["render modes"]["gui"].asBool() ) { auto* renderMode = new ext::vulkan::RenderTargetRenderMode; ext::vulkan::addRenderMode( renderMode, "Gui" ); - renderMode->blitter.subpass = 1; + renderMode->blitter.descriptor.subpass = 1; } if ( ::config["engine"]["render modes"]["stereo deferred"].asBool() ) ext::vulkan::addRenderMode( new ext::vulkan::StereoscopicDeferredRenderMode, "" ); diff --git a/ext/scenes/test/terrain/marching.cpp b/ext/scenes/test/terrain/marching.cpp index b6d29dc3..db94bcd9 100644 --- a/ext/scenes/test/terrain/marching.cpp +++ b/ext/scenes/test/terrain/marching.cpp @@ -520,13 +520,12 @@ void ext::Marching::render() { auto& root = this->getRootParent(); auto& player = *root.getController(); auto& camera = player.getComponent(); - auto& transform = player.getComponent>(); + auto& transform = this->getComponent>(); auto& model = this->getComponent>(); if ( !graphic.initialized ) return; uf::Serializer& metadata = this->getComponent(); - // auto& uniforms = graphic.uniforms(); auto& uniforms = graphic.material.shaders.front().uniforms.front().get(); - uniforms.matrices.model = uf::transform::model( this->getComponent>() ); + uniforms.matrices.model = uf::transform::model( transform ); for ( std::size_t i = 0; i < 2; ++i ) { uniforms.matrices.view[i] = camera.getView( i ); uniforms.matrices.projection[i] = camera.getProjection( i ); diff --git a/ext/scenes/world/portal/portal.cpp b/ext/scenes/world/portal/portal.cpp index ffdf157d..bcd9e61c 100644 --- a/ext/scenes/world/portal/portal.cpp +++ b/ext/scenes/world/portal/portal.cpp @@ -126,6 +126,7 @@ void ext::Portal::render() { { auto& renderMode = this->getComponent(); auto& blitter = renderMode.blitter; + auto& transform = this->getComponent>(); auto& scene = uf::scene::getCurrentScene(); auto& controller = *scene.getController(); @@ -133,25 +134,40 @@ void ext::Portal::render() { auto& controllerCamera = controller.getComponent(); if ( !blitter.initialized ) return; + struct UniformDescriptor { + struct { + alignas(16) pod::Matrix4f models[2]; + } matrices; + struct { + alignas(8) pod::Vector2f position = { 0.5f, 0.5f }; + alignas(8) pod::Vector2f radius = { 0.1f, 0.1f }; + alignas(16) pod::Vector4f color = { 1, 1, 1, 1 }; + } cursor; + alignas(4) float alpha; + }; + + auto& shader = blitter.material.shaders.front(); + auto& uniforms = shader.uniforms.front().get(); + for ( std::size_t i = 0; i < 2; ++i ) { pod::Matrix4f model = uf::transform::model( transform ); - blitter.uniforms.matrices.models[i] = controllerCamera.getProjection(i) * controllerCamera.getView(i) * model; + uniforms.matrices.models[i] = controllerCamera.getProjection(i) * controllerCamera.getView(i) * model; - blitter.uniforms.alpha = 1.0f; + uniforms.alpha = 1.0f; - blitter.uniforms.cursor.position.x = -1.0f; - blitter.uniforms.cursor.position.y = -1.0f; + uniforms.cursor.position.x = -1.0f; + uniforms.cursor.position.y = -1.0f; - blitter.uniforms.cursor.radius.x = 0.0f; - blitter.uniforms.cursor.radius.y = 0.0f; + uniforms.cursor.radius.x = 0.0f; + uniforms.cursor.radius.y = 0.0f; - blitter.uniforms.cursor.color.x = 0.0f; - blitter.uniforms.cursor.color.y = 0.0f; - blitter.uniforms.cursor.color.z = 0.0f; - blitter.uniforms.cursor.color.w = 0.0f; + uniforms.cursor.color.x = 0.0f; + uniforms.cursor.color.y = 0.0f; + uniforms.cursor.color.z = 0.0f; + uniforms.cursor.color.w = 0.0f; } - blitter.updateBuffer( (void*) &blitter.uniforms, sizeof(blitter.uniforms), 0 ); + shader.updateBuffer( (void*) &uniforms, sizeof(uniforms), 0 ); } } void ext::Portal::destroy() { diff --git a/ext/scenes/world/terrain/region.cpp b/ext/scenes/world/terrain/region.cpp index f3914a7b..aa0e8f72 100644 --- a/ext/scenes/world/terrain/region.cpp +++ b/ext/scenes/world/terrain/region.cpp @@ -304,6 +304,6 @@ void ext::Region::render( ) { } // graphic.updateBuffer( uniforms, 0, false ); - graphic.material.shaders.front().updateBuffer( uniforms, 0, false ); + graphic.material.shaders.front().updateBuffer( uniforms, 0, true ); } } \ No newline at end of file diff --git a/ext/scenes/world/world.cpp b/ext/scenes/world/world.cpp index 818f54a3..d37bed4e 100644 --- a/ext/scenes/world/world.cpp +++ b/ext/scenes/world/world.cpp @@ -301,7 +301,7 @@ void ext::World::render() { /* Update lights */ { uf::Serializer& metadata = this->getComponent(); auto& scene = *this; - std::vector blitters; + std::vector blitters; auto& renderMode = ext::vulkan::getRenderMode("", true); if ( renderMode.getType() == "Deferred (Stereoscopic)" ) { auto* renderModePointer = (ext::vulkan::StereoscopicDeferredRenderMode*) &renderMode; @@ -325,9 +325,29 @@ void ext::World::render() { alignas(16) pod::Vector4f color; } lights; }; + + struct SpecializationConstant { + int32_t maxLights = 32; + } specializationConstants; + for ( size_t _ = 0; _ < blitters.size(); ++_ ) { auto& blitter = *blitters[_]; - uint8_t* buffer = (uint8_t*) (void*) blitter.uniforms; + + uint8_t* buffer; + size_t len; + auto* shader = &blitter.material.shaders.front(); + + for ( auto& _ : blitter.material.shaders ) { + if ( _.uniforms.empty() ) continue; + auto& userdata = _.uniforms.front(); + buffer = (uint8_t*) (void*) userdata; + len = userdata.data().len; + shader = &_; + specializationConstants = _.specializationConstants.get(); + } + + if ( !buffer ) continue; + UniformDescriptor* uniforms = (UniformDescriptor*) buffer; for ( std::size_t i = 0; i < 2; ++i ) { uniforms->matrices.view[i] = camera.getView( i ); @@ -340,7 +360,6 @@ void ext::World::render() { uniforms->ambient.w = metadata["light"]["kexp"].asFloat(); } { - size_t MAX_LIGHTS = blitter.maxLights; std::vector entities; std::function filter = [&]( uf::Entity* entity ) { if ( !entity || entity->getName() != "Light" ) return; @@ -365,12 +384,12 @@ void ext::World::render() { } } UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)]; - for ( size_t i = 0; i < MAX_LIGHTS; ++i ) { + for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) { UniformDescriptor::Light& light = lights[i]; light.position = { 0, 0, 0, 0 }; light.color = { 0, 0, 0, 0 }; } - for ( size_t i = 0; i < MAX_LIGHTS && i < entities.size(); ++i ) { + for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) { UniformDescriptor::Light& light = lights[i]; uf::Entity* entity = entities[i]; @@ -394,7 +413,8 @@ void ext::World::render() { light.color.w = metadata["light"]["radius"].asFloat(); } } - blitter.updateBuffer( (void*) buffer, blitter.uniforms.data().len, 0, false ); + // blitter.updateBuffer( (void*) buffer, blitter.uniforms.data().len, 0, false ); + shader->updateBuffer( (void*) buffer, len, 0, false ); } } }