diff --git a/bin/data/config.json b/bin/data/config.json index 8503f51f..058b5ffc 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -8,7 +8,7 @@ "useLightmaps": false, "max": 32, "shadows": { - "enabled": true, // to-do: fix + "enabled": true, "update": 4, "max": 16, "samples": 2 @@ -67,9 +67,9 @@ "vulkan": { "version": 1.3, "validation": { - "enabled": false, - "messages": false, - "checkpoints": false, + "enabled": true, + "messages": true, + "checkpoints": true, "filters": [ // "0xe5d1743c" // VUID-vkCmdDispatch-None-02699 (problem when using VXGI) (seems to be fixed?) // ,"0x6714bd0c" // VUID-vkCmdDispatch-format-07753 (for some dumb shit) (seems to be fixed?) @@ -169,10 +169,14 @@ ,"VK_KHR_get_memory_requirements2" ,"VK_KHR_bind_memory2" ,"VK_KHR_dedicated_allocation" + ,"VK_KHR_multiview" ] }, "features": [ - "nullDescriptor" + // 1.1 + "multiview" + // + ,"nullDescriptor" ,"fragmentStoresAndAtomics" ,"geometryShader" ,"multiViewport" @@ -192,7 +196,10 @@ ,"bufferDeviceAddress" ], "featureChain": [ - "physicalDevice2" + // 1.1 + "physicalDeviceVulkan11" + // + ,"physicalDevice2" ,"shaderDrawParameters" ,"robustness" ,"shaderClock" @@ -303,7 +310,7 @@ "enabled": false }, "fsr": { - "enabled": true, + "enabled": false, "upscale": true, "interpolation": true, // it works but i don't think it's presenting the frame "sharpness": 0, diff --git a/bin/data/shaders/display/deferred/comp/comp.h b/bin/data/shaders/display/deferred/comp/comp.h index 8d26d024..8b32617b 100644 --- a/bin/data/shaders/display/deferred/comp/comp.h +++ b/bin/data/shaders/display/deferred/comp/comp.h @@ -26,33 +26,33 @@ layout (constant_id = 1) const uint CUBEMAPS = 128; #endif #if !MULTISAMPLING - layout(binding = 0) uniform utexture2D samplerId; + layout(binding = 0) uniform utexture2DArray samplerId; #if BARYCENTRIC #if !BARYCENTRIC_CALCULATE - layout(binding = 1) uniform texture2D samplerBary; + layout(binding = 1) uniform texture2DArray samplerBary; #endif #else - layout(binding = 1) uniform texture2D samplerUv; - layout(binding = 2) uniform texture2D samplerNormal; + layout(binding = 1) uniform texture2DArray samplerUv; + layout(binding = 2) uniform texture2DArray samplerNormal; #endif - layout(binding = 3) uniform texture2D samplerDepth; + layout(binding = 3) uniform texture2DArray samplerDepth; #else - layout(binding = 0) uniform utexture2DMS samplerId; + layout(binding = 0) uniform utexture2DMSArray samplerId; #if BARYCENTRIC #if !BARYCENTRIC_CALCULATE - layout(binding = 1) uniform texture2DMS samplerBary; + layout(binding = 1) uniform texture2DMSArray samplerBary; #endif #else - layout(binding = 1) uniform texture2DMS samplerUv; - layout(binding = 2) uniform texture2DMS samplerNormal; + layout(binding = 1) uniform texture2DMSArray samplerUv; + layout(binding = 2) uniform texture2DMSArray samplerNormal; #endif - layout(binding = 3) uniform texture2DMS samplerDepth; + layout(binding = 3) uniform texture2DMSArray samplerDepth; #endif -layout(binding = 7, rgba16f) uniform writeonly image2D imageColor; -layout(binding = 8, rgba16f) uniform writeonly image2D imageBright; -layout(binding = 9, rg16f) uniform writeonly image2D imageMotion; +layout(binding = 7, rgba16f) uniform writeonly image2DArray imageColor; +layout(binding = 8, rgba16f) uniform writeonly image2DArray imageBright; +layout(binding = 9, rg16f) uniform writeonly image2DArray imageMotion; layout( push_constant ) uniform PushBlock { uint pass; @@ -132,12 +132,12 @@ layout (binding = 20) uniform sampler3D samplerNoise; #endif #if MULTISAMPLING - #define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), msaa.currentID ) + #define IMAGE_LOAD(X) texelFetch( X, ivec3(gl_GlobalInvocationID.xyz), msaa.currentID ) #else - #define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), 0 ) + #define IMAGE_LOAD(X) texelFetch( X, ivec3(gl_GlobalInvocationID.xyz), 0 ) #endif -#define IMAGE_STORE(X, Y) imageStore( X, ivec2(gl_GlobalInvocationID.xy), Y ) +#define IMAGE_STORE(X, Y) imageStore( X, ivec3(gl_GlobalInvocationID.xyz), Y ) bool USE_SKYBOX_ON_DIVERGENCE = false; @@ -158,7 +158,7 @@ void postProcess() { vec2 outFragMotion = surface.motion; if ( ubo.settings.mode.type > 0x0000 ) { - uvec2 renderSize = imageSize(imageColor); + uvec2 renderSize = imageSize(imageColor).xy; vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f; if ( true ) { // if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.barycentric.rgb, 1); @@ -180,10 +180,10 @@ void postProcess() { } void populateSurface() { - const uvec2 renderSize = imageSize(imageColor); - if ( gl_GlobalInvocationID.x >= renderSize.x || gl_GlobalInvocationID.y >= renderSize.y || gl_GlobalInvocationID.z > PushConstant.pass ) return; + const uvec2 renderSize = imageSize(imageColor).xy; + if ( gl_GlobalInvocationID.x >= renderSize.x || gl_GlobalInvocationID.y >= renderSize.y /*|| gl_GlobalInvocationID.z > PushConstant.pass*/ ) return; - surface.pass = PushConstant.pass; + surface.pass = gl_GlobalInvocationID.z; surface.fragment = vec4(0); surface.light = vec4(0); surface.motion = vec2(0); diff --git a/bin/data/shaders/graph/base/vert.h b/bin/data/shaders/graph/base/vert.h index 15ef1442..e9253c33 100644 --- a/bin/data/shaders/graph/base/vert.h +++ b/bin/data/shaders/graph/base/vert.h @@ -1,5 +1,6 @@ layout (constant_id = 0) const uint PASSES = 6; #extension GL_ARB_shader_draw_parameters : enable +#extension GL_EXT_multiview : enable #include "../../common/macros.h" #include "../../common/structs.h" @@ -73,8 +74,8 @@ void main() { const mat4 view = mat4(1); const mat4 projection = mat4(1); #else - const mat4 view = camera.viewport[PushConstant.pass].view; - const mat4 projection = camera.viewport[PushConstant.pass].projection; + const mat4 view = camera.viewport[/*PushConstant.pass*/gl_ViewIndex].view; + const mat4 projection = camera.viewport[/*PushConstant.pass*/gl_ViewIndex].projection; #endif #if SKINNED const mat4 skinned = joints.length() <= 0 || jointID < 0 ? mat4(1.0) : inWeights.x * joints[jointID + int(inJoints.x)] + inWeights.y * joints[jointID + int(inJoints.y)] + inWeights.z * joints[jointID + int(inJoints.z)] + inWeights.w * joints[jointID + int(inJoints.w)]; @@ -93,7 +94,7 @@ void main() { outPOS0 = gl_Position; outPOS1 = gl_Position; - outId = uvec4(triangleID, drawID, instanceID, PushConstant.pass); + outId = uvec4(triangleID, drawID, instanceID, /*PushConstant.pass*/gl_ViewIndex); outPosition = vec3(model * vec4(inPos.xyz, 1.0)); outUv = inUv; diff --git a/bin/data/shaders/graph/voxelize/geom.glsl b/bin/data/shaders/graph/voxelize/geom.glsl index 284268b8..83781ab6 100644 --- a/bin/data/shaders/graph/voxelize/geom.glsl +++ b/bin/data/shaders/graph/voxelize/geom.glsl @@ -1,5 +1,6 @@ #version 450 #pragma shader_stage(geometry) +#extension GL_EXT_multiview : require layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; @@ -56,7 +57,7 @@ void main(){ A = N.z > N[A] ? 2 : A; #endif - const uint CASCADE = inId[0].w; + const uint CASCADE = gl_ViewIndex; // inId[0].w; const float power = cascadePower(CASCADE); vec3 P[3] = { vec3( ubo.voxel * vec4( inPosition[0], 1 ) ) / power, @@ -77,6 +78,7 @@ void main(){ outNormal = inNormal[i]; outTangent = inTangent[i]; outId = inId[i]; + outId.w = gl_ViewIndex; const vec3 P = outPosition; // + D; #if USE_CROSS diff --git a/engine/inc/uf/ext/vulkan/rendertarget.h b/engine/inc/uf/ext/vulkan/rendertarget.h index 39b4f62b..a063e8fc 100644 --- a/engine/inc/uf/ext/vulkan/rendertarget.h +++ b/engine/inc/uf/ext/vulkan/rendertarget.h @@ -23,6 +23,7 @@ namespace ext { VkImage image; VkDeviceMemory mem; VkImageView view; + VkImageView framebufferView; uf::stl::vector views; VmaAllocation allocation; VmaAllocationInfo allocationInfo; diff --git a/engine/inc/uf/ext/vulkan/vk.h b/engine/inc/uf/ext/vulkan/vk.h index 6191b2d2..71dc01dc 100644 --- a/engine/inc/uf/ext/vulkan/vk.h +++ b/engine/inc/uf/ext/vulkan/vk.h @@ -23,6 +23,7 @@ #define VK_DEFAULT_DEFER_BUFFER_DESTROY ext::vulkan::settings::defaultDeferBufferDestroy #define VK_DEFAULT_COMMAND_BUFFER_IMMEDIATE ext::vulkan::settings::defaultCommandBufferImmediate #define VK_UBO_USE_N_BUFFERS 0 +#define VK_USE_MULTIVIEW 1 namespace ext { namespace vulkan { diff --git a/engine/src/engine/ext/light/behavior.cpp b/engine/src/engine/ext/light/behavior.cpp index 6080ff33..9a638ce8 100644 --- a/engine/src/engine/ext/light/behavior.cpp +++ b/engine/src/engine/ext/light/behavior.cpp @@ -78,7 +78,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) { if ( metadataJson["light"]["type"].as() == "point" ) { metadataJson["light"]["fov"] = 90.0f; - renderMode.metadata.subpasses = 6; + renderMode.metadata.views = 6; } float fov = metadataJson["light"]["fov"].as(90) * (3.14159265358f / 180.0f); diff --git a/engine/src/engine/ext/voxelizer/behavior.cpp b/engine/src/engine/ext/voxelizer/behavior.cpp index a83aec0b..146d76f1 100644 --- a/engine/src/engine/ext/voxelizer/behavior.cpp +++ b/engine/src/engine/ext/voxelizer/behavior.cpp @@ -131,7 +131,8 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) { } renderMode.metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::vxgi); renderMode.metadata.samples = 1; - renderMode.metadata.subpasses = metadata.cascades; + // renderMode.metadata.subpasses = metadata.cascades; + renderMode.renderTarget.views = metadata.cascades; renderMode.width = metadata.fragmentSize.x; renderMode.height = metadata.fragmentSize.y; diff --git a/engine/src/ext/vulkan/device.cpp b/engine/src/ext/vulkan/device.cpp index d6820d62..010ce2f9 100644 --- a/engine/src/ext/vulkan/device.cpp +++ b/engine/src/ext/vulkan/device.cpp @@ -378,6 +378,58 @@ namespace { return json; } + void enableRequestedDeviceFeatures11( VkPhysicalDeviceVulkan11Features& features, VkPhysicalDeviceVulkan11Features& enabledFeatures ) { + ext::json::Value json; + + #define CHECK_FEATURE( NAME )\ + if ( feature == #NAME ) {\ + if ( features.NAME == VK_TRUE ) {\ + enabledFeatures.NAME = true;\ + VK_VALIDATION_MESSAGE("Enabled feature: {}", feature);\ + } else VK_VALIDATION_MESSAGE("Failed to enable feature: {}", feature);\ + } + + for ( auto& feature : ext::vulkan::settings::requested::deviceFeatures ) { + CHECK_FEATURE(storageBuffer16BitAccess); + CHECK_FEATURE(uniformAndStorageBuffer16BitAccess); + CHECK_FEATURE(storagePushConstant16); + CHECK_FEATURE(storageInputOutput16); + CHECK_FEATURE(multiview); + CHECK_FEATURE(multiviewGeometryShader); + CHECK_FEATURE(multiviewTessellationShader); + CHECK_FEATURE(variablePointersStorageBuffer); + CHECK_FEATURE(variablePointers); + CHECK_FEATURE(protectedMemory); + CHECK_FEATURE(samplerYcbcrConversion); + CHECK_FEATURE(shaderDrawParameters); + } + #undef CHECK_FEATURE + } + + ext::json::Value retrieveDeviceFeatures11( ext::vulkan::Device& device, VkPhysicalDeviceVulkan11Features& features, VkPhysicalDeviceVulkan11Features& enabledFeatures ) { + ext::json::Value json; + + #define CHECK_FEATURE( NAME )\ + json[#NAME]["supported"] = features.NAME;\ + json[#NAME]["enabled"] = enabledFeatures.NAME; + + CHECK_FEATURE(storageBuffer16BitAccess); + CHECK_FEATURE(uniformAndStorageBuffer16BitAccess); + CHECK_FEATURE(storagePushConstant16); + CHECK_FEATURE(storageInputOutput16); + CHECK_FEATURE(multiview); + CHECK_FEATURE(multiviewGeometryShader); + CHECK_FEATURE(multiviewTessellationShader); + CHECK_FEATURE(variablePointersStorageBuffer); + CHECK_FEATURE(variablePointers); + CHECK_FEATURE(protectedMemory); + CHECK_FEATURE(samplerYcbcrConversion); + CHECK_FEATURE(shaderDrawParameters); + #undef CHECK_FEATURE + + return json; + } + void enableRequestedDeviceFeatures12( VkPhysicalDeviceVulkan12Features& features, VkPhysicalDeviceVulkan12Features& enabledFeatures ) { ext::json::Value json; @@ -1185,6 +1237,7 @@ void ext::vulkan::Device::initialize() { std::queue chain = {}; VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{}; + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{}; VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{}; VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures{}; VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures{}; @@ -1197,12 +1250,16 @@ void ext::vulkan::Device::initialize() { VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR fragmentShaderBarycentricFeatures{}; VkPhysicalDeviceSubgroupSizeControlFeatures subgroupSizeControlFeatures{}; + VkPhysicalDeviceFeatures2 enabledDeviceFeatures2{}; + VkPhysicalDeviceVulkan11Features enabledPhysicalDeviceVulkan11Features{}; VkPhysicalDeviceVulkan12Features enabledPhysicalDeviceVulkan12Features{}; - VkPhysicalDeviceFeatures2 enabledDeviceFeatures2{}; { + { + enabledDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + enabledPhysicalDeviceVulkan11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; enabledPhysicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; - enabledDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - enabledDeviceFeatures2.pNext = &enabledPhysicalDeviceVulkan12Features; + enabledPhysicalDeviceVulkan11Features.pNext = &enabledPhysicalDeviceVulkan12Features; + enabledDeviceFeatures2.pNext = &enabledPhysicalDeviceVulkan11Features; vkGetPhysicalDeviceFeatures2(device.physicalDevice, &enabledDeviceFeatures2); } @@ -1213,6 +1270,20 @@ void ext::vulkan::Device::initialize() { chain.push( &physicalDeviceFeatures2 ); VK_VALIDATION_MESSAGE("Enabled feature chain: {}", "physicalDeviceFeatures2" ); } + if ( ext::vulkan::settings::requested::featureChain["physicalDeviceVulkan11"].as(false) ) { + physicalDeviceVulkan11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + enableRequestedDeviceFeatures11( enabledPhysicalDeviceVulkan11Features, physicalDeviceVulkan11Features ); + chain.push( &physicalDeviceVulkan11Features ); + VK_VALIDATION_MESSAGE("Enabled feature chain: {}", "physicalDeviceVulkan11Features" ); + } else { + // Only add the standalone extension struct if we ARE NOT using the Vulkan 1.1 core struct! + if ( ext::vulkan::settings::requested::featureChain["shaderDrawParameters"].as(false) ) { + shaderDrawParametersFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; + shaderDrawParametersFeatures.shaderDrawParameters = VK_TRUE; + chain.push( &shaderDrawParametersFeatures ); + VK_VALIDATION_MESSAGE("Enabled feature chain: {}", "shaderDrawParametersFeatures" ); + } + } if ( ext::vulkan::settings::requested::featureChain["physicalDeviceVulkan12"].as(false) ) { physicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; enableRequestedDeviceFeatures12( enabledPhysicalDeviceVulkan12Features, physicalDeviceVulkan12Features ); @@ -1239,12 +1310,6 @@ void ext::vulkan::Device::initialize() { } // - if ( ext::vulkan::settings::requested::featureChain["shaderDrawParameters"].as(false) ) { - shaderDrawParametersFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; - shaderDrawParametersFeatures.shaderDrawParameters = VK_TRUE; - chain.push( &shaderDrawParametersFeatures ); - VK_VALIDATION_MESSAGE("Enabled feature chain: {}", "shaderDrawParametersFeatures" ); - } if ( ext::vulkan::settings::requested::featureChain["robustness"].as(false) ) { robustnessFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; robustnessFeatures.nullDescriptor = VK_TRUE; diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index 1209ef03..8319d34e 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -205,46 +205,42 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { metadata.attachments["output"] = attachments.color; // First pass: fill the G-Buffer - for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { + renderTarget.addPass( + /*.*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + #if BARYCENTRIC + #if !BARYCENTRIC_CALCULATE + /*.colors =*/ { attachments.id, attachments.bary }, + #else + /*.colors =*/ { attachments.id }, + #endif + #else + /*.colors =*/ { attachments.id, attachments.uv, attachments.normal }, + #endif + /*.inputs =*/ {}, + /*.resolve =*/{}, + /*.depth = */ attachments.depth, + /*.layer = */0, + /*.autoBuildPipeline =*/ true + ); + if ( DEFERRED_MODE == "fragment" ) { renderTarget.addPass( - /*.*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + /*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + /*.colors =*/ { attachments.color, attachments.scratch, attachments.motion }, #if BARYCENTRIC #if !BARYCENTRIC_CALCULATE - /*.colors =*/ { attachments.id, attachments.bary }, + /*.inputs =*/ { attachments.id, attachments.depth, attachments.bary }, #else - /*.colors =*/ { attachments.id }, + /*.inputs =*/ { attachments.id, attachments.depth }, #endif #else - /*.colors =*/ { attachments.id, attachments.uv, attachments.normal }, + /*.inputs =*/ { attachments.id, attachments.depth, attachments.uv, attachments.normal }, #endif - /*.inputs =*/ {}, /*.resolve =*/{}, - /*.depth = */ attachments.depth, - /*.layer = */eye, - /*.autoBuildPipeline =*/ true + /*.depth = */attachments.depth, + /*.layer = */0, + /*.autoBuildPipeline =*/ false ); } - if ( DEFERRED_MODE == "fragment" ) { - for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { - renderTarget.addPass( - /*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - /*.colors =*/ { attachments.color, attachments.scratch, attachments.motion }, - #if BARYCENTRIC - #if !BARYCENTRIC_CALCULATE - /*.inputs =*/ { attachments.id, attachments.depth, attachments.bary }, - #else - /*.inputs =*/ { attachments.id, attachments.depth }, - #endif - #else - /*.inputs =*/ { attachments.id, attachments.depth, attachments.uv, attachments.normal }, - #endif - /*.resolve =*/{}, - /*.depth = */attachments.depth, - /*.layer = */eye, - /*.autoBuildPipeline =*/ false - ); - } - } // metadata.outputs.emplace_back(metadata.attachments["output"]); renderTarget.initialize( device ); @@ -818,7 +814,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetScissor(commandBuffer, 0, 1, &scissor); // render to geometry buffers - for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { + { size_t currentPass = 0; size_t currentDraw = 0; for ( auto graphic : graphics ) { @@ -826,15 +822,14 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto if ( graphic->descriptor.renderMode != this->getName() ) continue; ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, ::fmt::format("graphic[{}]", currentDraw) ); - graphic->record( commandBuffer, descriptor, eye, currentDraw++, frame ); - } - if ( eye + 1 < metadata.eyes ) { - device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "nextSubpass" ); - vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); ++currentSubpass; + graphic->record( commandBuffer, descriptor, 0, currentDraw++, frame ); } } // skip deferred pass if RT is enabled, we still process geometry for a depth buffer - if ( DEFERRED_MODE == "fragment" ) for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { + if ( DEFERRED_MODE == "fragment" ) { + device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "nextSubpass" ); + vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); ++currentSubpass; + size_t currentPass = 0; size_t currentDraw = 0; { @@ -844,11 +839,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto descriptor.subpass = currentSubpass; descriptor.bind.point = VK_PIPELINE_BIND_POINT_GRAPHICS; device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "deferred" ); - blitter.record(commandBuffer, descriptor, eye, currentDraw++, frame); - } - if ( eye + 1 < metadata.eyes ) { - device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "nextSubpass" ); - vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); ++currentSubpass; + blitter.record(commandBuffer, descriptor, 0, currentDraw++, frame); } } device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "renderPass[end]" ); diff --git a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp index 44fc5d86..66cc533e 100644 --- a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp @@ -18,15 +18,6 @@ const uf::stl::string ext::vulkan::RenderTargetRenderMode::getType() const { ext::vulkan::GraphicDescriptor ext::vulkan::RenderTargetRenderMode::bindGraphicDescriptor( const ext::vulkan::GraphicDescriptor& reference, size_t pass ) { ext::vulkan::GraphicDescriptor descriptor = ext::vulkan::RenderMode::bindGraphicDescriptor(reference, pass); -/* - descriptor.parse(metadata.json["descriptor"]); - // invalidate - if ( metadata.target != "" && descriptor.renderMode != this->getName() && descriptor.renderMode != metadata.target ) { - descriptor.invalidated = true; - } else { - descriptor.renderMode = this->getName(); - } -*/ if ( 0 <= pass && pass < metadata.subpasses && metadata.type == uf::renderer::settings::pipelines::names::vxgi ) { descriptor.cullMode = VK_CULL_MODE_NONE; @@ -56,7 +47,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { } if ( metadata.type == "depth" || metadata.type == uf::renderer::settings::pipelines::names::vxgi ) { - renderTarget.views = metadata.subpasses; struct { size_t depth; } attachments = {}; @@ -82,152 +72,33 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { ); } } else if ( metadata.type == settings::pipelines::names::rt ) { - #if 1 - struct { - size_t depth, color, bright, motion, scratch, output; - } attachments = {}; - - bool blend = true; - attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */ext::vulkan::settings::formats::depth, - /*.layout = */VK_IMAGE_LAYOUT_GENERAL, - /*.usage = */VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - /*.blend = */false, - /*.samples = */1, - }); - attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format =*/ ext::vulkan::settings::pipelines::hdr ? enums::Format::HDR : enums::Format::SDR, - /*.layout = */ VK_IMAGE_LAYOUT_GENERAL, - /*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - /*.blend =*/ blend, - /*.samples =*/ 1, - }); - attachments.bright = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format =*/ ext::vulkan::settings::pipelines::hdr ? enums::Format::HDR : enums::Format::SDR, - /*.layout = */ VK_IMAGE_LAYOUT_GENERAL, - /*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - /*.blend =*/ blend, - /*.samples =*/ 1, - }); - attachments.scratch = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format =*/ ext::vulkan::settings::pipelines::hdr ? enums::Format::HDR : enums::Format::SDR, - /*.layout = */ VK_IMAGE_LAYOUT_GENERAL, - /*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - /*.blend =*/ blend, - /*.samples =*/ 1, - }); - attachments.motion = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - // /*.format = */VK_FORMAT_R32G32B32A32_SFLOAT, - /*.format = */VK_FORMAT_R16G16_SFLOAT, - /*.layout = */ VK_IMAGE_LAYOUT_GENERAL, - /*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - /*.blend = */false, - /*.samples = */1, - }); - - renderTarget.addPass( - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - {}, - {}, - {}, - attachments.depth, - 0, - true - ); - - metadata.attachments["depth"] = attachments.depth; - metadata.attachments["color"] = attachments.color; - metadata.attachments["bright"] = attachments.bright; - metadata.attachments["motion"] = attachments.motion; - metadata.attachments["scratch"] = attachments.scratch; - - metadata.attachments["output"] = attachments.color; - #endif + UF_EXCEPTION("unimplemented"); } else if ( metadata.type == "full" ) { - #if 0 + UF_EXCEPTION("unimplemented"); + } else { struct { - size_t id, position, normal, depth, color; + size_t color, depth; } attachments = {}; - // input g-buffers - attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */VK_FORMAT_R32G32_UINT, + attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{ + /*.format = */VK_FORMAT_R8G8B8A8_UNORM, /*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, /*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - /*.blend = */false, - /*.samples = */msaa, - }); - attachments.position = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */VK_FORMAT_R16G16B16A16_SFLOAT, - /*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - /*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - /*.blend = */false, - /*.samples = */msaa, - }); - attachments.normal = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */VK_FORMAT_R16G16B16A16_SFLOAT, - /*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - /*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - /*.blend = */false, + /*.blend = */true, /*.samples = */msaa, }); attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */ext::vulkan::settings::formats::depth, - /*.layout = */VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - /*.usage = */VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - /*.blend = */false, - /*.samples = */msaa, - }); - // output buffers - attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format =*/ ext::vulkan::settings::pipelines::hdr ? enums::Format::HDR : enums::Format::SDR, - /*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - /*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - /*.blend =*/ blend, - /*.samples =*/ 1, + /*.format = */ ext::vulkan::settings::formats::depth, + /*.layout = */ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + /*.usage = */ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + /*.blend = */ false, + /*.samples = */ 1, }); - metadata.attachments["id"] = attachments.id; - metadata.attachments["position"] = attachments.position; - metadata.attachments["normal"] = attachments.normal; - - metadata.attachments["depth"] = attachments.depth; metadata.attachments["color"] = attachments.color; - metadata.attachments["output"] = attachments.color; + metadata.attachments["depth"] = attachments.depth; - // First pass: fill the G-Buffer - for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { - renderTarget.addPass( - /*.*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - /*.colors =*/ { attachments.id, attachments.uv, attachments.normal }, - /*.inputs =*/ {}, - /*.resolve =*/{}, - /*.depth = */ attachments.depth, - /*.layer = */eye, - /*.autoBuildPipeline =*/ true - ); - } - #endif - } else { for ( size_t currentPass = 0; currentPass < metadata.subpasses; ++currentPass ) { - struct { - size_t color, depth; - } attachments = {}; - - attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */VK_FORMAT_R8G8B8A8_UNORM, - /*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - /*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - /*.blend = */true, - /*.samples = */msaa, - }); - attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{ - /*.format = */ ext::vulkan::settings::formats::depth, - /*.layout = */ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - /*.usage = */ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - /*.blend = */ false, - /*.samples = */ 1, - }); renderTarget.addPass( VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, { attachments.color }, @@ -237,9 +108,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { 0, true ); - - metadata.attachments["color"] = attachments.color; - metadata.attachments["depth"] = attachments.depth; } } @@ -413,39 +281,28 @@ void ext::vulkan::RenderTargetRenderMode::destroy() { } void ext::vulkan::RenderTargetRenderMode::render() { -// if ( this->executed ) return; if ( this->commands.container().empty() ) return; - //lockMutex( this->mostRecentCommandPoolId ); auto& commands = getCommands( this->mostRecentCommandPoolId ); VK_COMMAND_BUFFER_CALLBACK( EXECUTE_BEGIN, VkCommandBuffer{}, 0, {} ); - // Submit commands - // Use a fence to ensure that command buffer has finished executing before using it again - /* - VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[states::currentBuffer], VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT )); - VK_CHECK_RESULT(vkResetFences( *device, 1, &fences[states::currentBuffer] )); - */ - VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = NULL; // Pointer to the list of pipeline stages that the semaphore waits will occur at - submitInfo.pWaitSemaphores = NULL; // Semaphore(s) to wait upon before the submitted command buffer starts executing - submitInfo.waitSemaphoreCount = 0; // One wait semaphore - submitInfo.pSignalSemaphores = NULL; // Semaphore(s) to be signaled when command buffers have completed - submitInfo.signalSemaphoreCount = 0; // One signal semaphore - submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission) + submitInfo.pWaitDstStageMask = NULL; + submitInfo.pWaitSemaphores = NULL; + submitInfo.waitSemaphoreCount = 0; + submitInfo.pSignalSemaphores = NULL; + submitInfo.signalSemaphoreCount = 0; + submitInfo.pCommandBuffers = &commands[states::currentBuffer]; submitInfo.commandBufferCount = 1; -// VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer])); VkQueue queue = device->getQueue( QueueEnum::GRAPHICS ); VkResult res = vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE/*fences[states::currentBuffer]*/); VK_CHECK_QUEUE_CHECKPOINT( queue, res ); VK_COMMAND_BUFFER_CALLBACK( EXECUTE_END, VkCommandBuffer{}, 0, {} ); this->executed = true; - //unlockMutex( this->mostRecentCommandPoolId ); } void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer commandBuffer, uint8_t state ) { ext::vulkan::RenderMode::pipelineBarrier( commandBuffer, state ); @@ -463,17 +320,15 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v auto& sceneMetadataJson = scene.getComponent(); uf::stl::vector clearValues; - for ( size_t j = 0; j < renderTarget.views; ++j ) { - for ( auto& attachment : renderTarget.attachments ) { - auto& clearValue = clearValues.emplace_back(); - if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) { - clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; - } else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) { - if ( uf::matrix::reverseInfiniteProjection ) { - clearValue.depthStencil = { 0.0f, 0 }; - } else { - clearValue.depthStencil = { 1.0f, 0 }; - } + for ( auto& attachment : renderTarget.attachments ) { + auto& clearValue = clearValues.emplace_back(); + if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) { + clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; + } else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) { + if ( uf::matrix::reverseInfiniteProjection ) { + clearValue.depthStencil = { 0.0f, 0 }; + } else { + clearValue.depthStencil = { 1.0f, 0 }; } } } @@ -514,29 +369,6 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v size_t subpasses = renderTarget.passes.size(); size_t currentPass = 0; - // - // this->pipelineBarrier( commands[frame], 1 ); - - // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - - // VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL - // VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL - - #if 0 - for ( auto& attachment : renderTarget.attachments ) { - // transition attachments to general attachments for imageStore - VkImageSubresourceRange subresourceRange; - subresourceRange.baseMipLevel = 0; - subresourceRange.baseArrayLayer = 0; - subresourceRange.levelCount = attachment.descriptor.mips; - subresourceRange.layerCount = renderTarget.views; - subresourceRange.aspectMask = attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; - device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "setImageLayout" ); - uf::renderer::Texture::setImageLayout( commandBuffer, attachment.image, VK_IMAGE_LAYOUT_UNDEFINED, attachment.descriptor.layout, subresourceRange ); - } - #endif - // pre-renderpass commands VK_COMMAND_BUFFER_CALLBACK( CALLBACK_BEGIN, commandBuffer, frame, { device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[begin]" ); @@ -605,8 +437,6 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v VK_COMMAND_BUFFER_CALLBACK( CALLBACK_END, commandBuffer, frame, { device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[end]" ); } ); - - // this->pipelineBarrier( commands[frame], 1 ); } device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "end" ); VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); diff --git a/engine/src/ext/vulkan/rendertarget.cpp b/engine/src/ext/vulkan/rendertarget.cpp index 4ce1743a..70da89d7 100644 --- a/engine/src/ext/vulkan/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendertarget.cpp @@ -85,9 +85,8 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; subresourceRange.baseArrayLayer = 0; - subresourceRange.layerCount = 1; subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.layerCount = 1; + subresourceRange.layerCount = this->views; auto commandBuffer = device->fetchCommandBuffer(uf::renderer::QueueEnum::GRAPHICS); for ( size_t i = 0; i < ext::vulkan::swapchain.buffers; ++i ) { @@ -167,6 +166,12 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->view)); VK_REGISTER_HANDLE( attachment->view ); + if ( imageView.subresourceRange.levelCount > 1 ) { + imageView.subresourceRange.levelCount = 1; + VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->framebufferView)); + VK_REGISTER_HANDLE( attachment->framebufferView ); + } + size_t viewIndex = 0; for ( size_t layer = 0; layer < this->views; ++layer ) { imageView.viewType = VK_IMAGE_VIEW_TYPE_2D; @@ -237,21 +242,19 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) { if ( !renderPass ) { uf::stl::vector attachments; attachments.reserve( this->attachments.size() ); - for ( size_t i = 0; i < this->views; ++i ) { - for ( auto& attachment : this->attachments ) { - VkAttachmentDescription description; - description.format = attachment.descriptor.format; - description.samples = ext::vulkan::sampleCount( attachment.descriptor.samples ); - description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - description.storeOp = attachment.descriptor.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; // isSwapchain ? VK_IMAGE_LAYOUT_UNDEFINED : attachment.descriptor.layout; // VK_IMAGE_LAYOUT_UNDEFINED; - description.finalLayout = ext::vulkan::Texture::remapRenderpassLayout( attachment.descriptor.layout ); - description.flags = 0; + for ( auto& attachment : this->attachments ) { + VkAttachmentDescription description; + description.format = attachment.descriptor.format; + description.samples = ext::vulkan::sampleCount( attachment.descriptor.samples ); + description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + description.storeOp = attachment.descriptor.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE; + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; // isSwapchain ? VK_IMAGE_LAYOUT_UNDEFINED : attachment.descriptor.layout; // VK_IMAGE_LAYOUT_UNDEFINED; + description.finalLayout = ext::vulkan::Texture::remapRenderpassLayout( attachment.descriptor.layout ); + description.flags = 0; - attachments.emplace_back(description); - } + attachments.emplace_back(description); } // ensure that the subpasses are already described @@ -259,12 +262,14 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) { assert( passes.size() > 0 ); // expand attachment indices + /* for ( auto& pass : passes ) { for ( auto& input : pass.inputs ) input.attachment += pass.layer * this->attachments.size(); for ( auto& color : pass.colors ) color.attachment += pass.layer * this->attachments.size(); for ( auto& resolve : pass.resolves ) resolve.attachment += pass.layer * this->attachments.size(); pass.depth.attachment += pass.layer * this->attachments.size(); } + */ uf::stl::vector descriptions; uf::stl::vector dependencies; @@ -380,6 +385,26 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) { renderPassInfo.dependencyCount = static_cast(dependencies.size()); renderPassInfo.pDependencies = &dependencies[0]; + uint32_t viewMask = (1 << this->views) - 1; + + uf::stl::vector viewMasks(descriptions.size(), viewMask); + uf::stl::vector correlationMasks = { viewMask }; + + VkRenderPassMultiviewCreateInfo multiviewInfo = {}; + multiviewInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO; + + if ( this->views > 1 ) { + multiviewInfo.pNext = nullptr; + multiviewInfo.subpassCount = static_cast(viewMasks.size()); + multiviewInfo.pViewMasks = viewMasks.data(); + multiviewInfo.dependencyCount = 0; + multiviewInfo.pViewOffsets = nullptr; + multiviewInfo.correlationMaskCount = 1; + multiviewInfo.pCorrelationMasks = correlationMasks.data(); + + renderPassInfo.pNext = &multiviewInfo; + } + VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass)); VK_REGISTER_HANDLE( renderPass ); } @@ -394,13 +419,13 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) { for ( size_t frame = 0; frame < framebuffers.size(); ++frame ) { uf::stl::vector attachmentViews; - for ( auto view = 0; view < this->views; ++view ) { - for ( auto& attachment : this->attachments ) { - if ( attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) { - attachmentViews.emplace_back(attachment.views[frame]); - } else { - attachmentViews.emplace_back(attachment.views[view * attachment.descriptor.mips]); - } + for ( auto& attachment : this->attachments ) { + if ( attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) { + attachmentViews.emplace_back(attachment.views[frame]); + } else if ( attachment.framebufferView != VK_NULL_HANDLE ) { + attachmentViews.emplace_back(attachment.framebufferView); + } else { + attachmentViews.emplace_back(attachment.view); } } @@ -434,6 +459,11 @@ void ext::vulkan::RenderTarget::destroy() { for ( auto& attachment : attachments ) { if ( attachment.descriptor.aliased ) continue; + if ( attachment.framebufferView ) { + vkDestroyImageView(*device, attachment.framebufferView, nullptr); + VK_UNREGISTER_HANDLE( attachment.framebufferView ); + + } if ( attachment.view ) { if ( attachment.view != attachment.views.front() ) { vkDestroyImageView(*device, attachment.view, nullptr); diff --git a/engine/src/ext/vulkan/vulkan.cpp b/engine/src/ext/vulkan/vulkan.cpp index ecde6c7b..d25fe0f4 100644 --- a/engine/src/ext/vulkan/vulkan.cpp +++ b/engine/src/ext/vulkan/vulkan.cpp @@ -495,7 +495,7 @@ void ext::vulkan::initialize( bool soft ) { void ext::vulkan::tick() { // ext::vulkan::mutex.lock(); if ( ext::vulkan::states::resized ) { - // synchronize(0b11); + synchronize(0b11); ext::vulkan::states::rebuild = true; ::skip = true; }