VK_KHR_multiview support (but it broke VXGI)

This commit is contained in:
ecker 2026-05-11 20:56:16 -05:00
parent 2e018962ee
commit 2475605941
13 changed files with 235 additions and 306 deletions

View File

@ -8,7 +8,7 @@
"useLightmaps": false, "useLightmaps": false,
"max": 32, "max": 32,
"shadows": { "shadows": {
"enabled": true, // to-do: fix "enabled": true,
"update": 4, "update": 4,
"max": 16, "max": 16,
"samples": 2 "samples": 2
@ -67,9 +67,9 @@
"vulkan": { "vulkan": {
"version": 1.3, "version": 1.3,
"validation": { "validation": {
"enabled": false, "enabled": true,
"messages": false, "messages": true,
"checkpoints": false, "checkpoints": true,
"filters": [ "filters": [
// "0xe5d1743c" // VUID-vkCmdDispatch-None-02699 (problem when using VXGI) (seems to be fixed?) // "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?) // ,"0x6714bd0c" // VUID-vkCmdDispatch-format-07753 (for some dumb shit) (seems to be fixed?)
@ -169,10 +169,14 @@
,"VK_KHR_get_memory_requirements2" ,"VK_KHR_get_memory_requirements2"
,"VK_KHR_bind_memory2" ,"VK_KHR_bind_memory2"
,"VK_KHR_dedicated_allocation" ,"VK_KHR_dedicated_allocation"
,"VK_KHR_multiview"
] ]
}, },
"features": [ "features": [
"nullDescriptor" // 1.1
"multiview"
//
,"nullDescriptor"
,"fragmentStoresAndAtomics" ,"fragmentStoresAndAtomics"
,"geometryShader" ,"geometryShader"
,"multiViewport" ,"multiViewport"
@ -192,7 +196,10 @@
,"bufferDeviceAddress" ,"bufferDeviceAddress"
], ],
"featureChain": [ "featureChain": [
"physicalDevice2" // 1.1
"physicalDeviceVulkan11"
//
,"physicalDevice2"
,"shaderDrawParameters" ,"shaderDrawParameters"
,"robustness" ,"robustness"
,"shaderClock" ,"shaderClock"
@ -303,7 +310,7 @@
"enabled": false "enabled": false
}, },
"fsr": { "fsr": {
"enabled": true, "enabled": false,
"upscale": true, "upscale": true,
"interpolation": true, // it works but i don't think it's presenting the frame "interpolation": true, // it works but i don't think it's presenting the frame
"sharpness": 0, "sharpness": 0,

View File

@ -26,33 +26,33 @@ layout (constant_id = 1) const uint CUBEMAPS = 128;
#endif #endif
#if !MULTISAMPLING #if !MULTISAMPLING
layout(binding = 0) uniform utexture2D samplerId; layout(binding = 0) uniform utexture2DArray samplerId;
#if BARYCENTRIC #if BARYCENTRIC
#if !BARYCENTRIC_CALCULATE #if !BARYCENTRIC_CALCULATE
layout(binding = 1) uniform texture2D samplerBary; layout(binding = 1) uniform texture2DArray samplerBary;
#endif #endif
#else #else
layout(binding = 1) uniform texture2D samplerUv; layout(binding = 1) uniform texture2DArray samplerUv;
layout(binding = 2) uniform texture2D samplerNormal; layout(binding = 2) uniform texture2DArray samplerNormal;
#endif #endif
layout(binding = 3) uniform texture2D samplerDepth; layout(binding = 3) uniform texture2DArray samplerDepth;
#else #else
layout(binding = 0) uniform utexture2DMS samplerId; layout(binding = 0) uniform utexture2DMSArray samplerId;
#if BARYCENTRIC #if BARYCENTRIC
#if !BARYCENTRIC_CALCULATE #if !BARYCENTRIC_CALCULATE
layout(binding = 1) uniform texture2DMS samplerBary; layout(binding = 1) uniform texture2DMSArray samplerBary;
#endif #endif
#else #else
layout(binding = 1) uniform texture2DMS samplerUv; layout(binding = 1) uniform texture2DMSArray samplerUv;
layout(binding = 2) uniform texture2DMS samplerNormal; layout(binding = 2) uniform texture2DMSArray samplerNormal;
#endif #endif
layout(binding = 3) uniform texture2DMS samplerDepth; layout(binding = 3) uniform texture2DMSArray samplerDepth;
#endif #endif
layout(binding = 7, rgba16f) uniform writeonly image2D imageColor; layout(binding = 7, rgba16f) uniform writeonly image2DArray imageColor;
layout(binding = 8, rgba16f) uniform writeonly image2D imageBright; layout(binding = 8, rgba16f) uniform writeonly image2DArray imageBright;
layout(binding = 9, rg16f) uniform writeonly image2D imageMotion; layout(binding = 9, rg16f) uniform writeonly image2DArray imageMotion;
layout( push_constant ) uniform PushBlock { layout( push_constant ) uniform PushBlock {
uint pass; uint pass;
@ -132,12 +132,12 @@ layout (binding = 20) uniform sampler3D samplerNoise;
#endif #endif
#if MULTISAMPLING #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 #else
#define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), 0 ) #define IMAGE_LOAD(X) texelFetch( X, ivec3(gl_GlobalInvocationID.xyz), 0 )
#endif #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; bool USE_SKYBOX_ON_DIVERGENCE = false;
@ -158,7 +158,7 @@ void postProcess() {
vec2 outFragMotion = surface.motion; vec2 outFragMotion = surface.motion;
if ( ubo.settings.mode.type > 0x0000 ) { 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; vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
if ( true ) { if ( true ) {
// if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.barycentric.rgb, 1); // if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.barycentric.rgb, 1);
@ -180,10 +180,10 @@ void postProcess() {
} }
void populateSurface() { void populateSurface() {
const uvec2 renderSize = imageSize(imageColor); const uvec2 renderSize = imageSize(imageColor).xy;
if ( gl_GlobalInvocationID.x >= renderSize.x || gl_GlobalInvocationID.y >= renderSize.y || gl_GlobalInvocationID.z > PushConstant.pass ) return; 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.fragment = vec4(0);
surface.light = vec4(0); surface.light = vec4(0);
surface.motion = vec2(0); surface.motion = vec2(0);

View File

@ -1,5 +1,6 @@
layout (constant_id = 0) const uint PASSES = 6; layout (constant_id = 0) const uint PASSES = 6;
#extension GL_ARB_shader_draw_parameters : enable #extension GL_ARB_shader_draw_parameters : enable
#extension GL_EXT_multiview : enable
#include "../../common/macros.h" #include "../../common/macros.h"
#include "../../common/structs.h" #include "../../common/structs.h"
@ -73,8 +74,8 @@ void main() {
const mat4 view = mat4(1); const mat4 view = mat4(1);
const mat4 projection = mat4(1); const mat4 projection = mat4(1);
#else #else
const mat4 view = camera.viewport[PushConstant.pass].view; const mat4 view = camera.viewport[/*PushConstant.pass*/gl_ViewIndex].view;
const mat4 projection = camera.viewport[PushConstant.pass].projection; const mat4 projection = camera.viewport[/*PushConstant.pass*/gl_ViewIndex].projection;
#endif #endif
#if SKINNED #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)]; 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; outPOS0 = gl_Position;
outPOS1 = 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)); outPosition = vec3(model * vec4(inPos.xyz, 1.0));
outUv = inUv; outUv = inUv;

View File

@ -1,5 +1,6 @@
#version 450 #version 450
#pragma shader_stage(geometry) #pragma shader_stage(geometry)
#extension GL_EXT_multiview : require
layout(triangles) in; layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out; layout(triangle_strip, max_vertices = 3) out;
@ -56,7 +57,7 @@ void main(){
A = N.z > N[A] ? 2 : A; A = N.z > N[A] ? 2 : A;
#endif #endif
const uint CASCADE = inId[0].w; const uint CASCADE = gl_ViewIndex; // inId[0].w;
const float power = cascadePower(CASCADE); const float power = cascadePower(CASCADE);
vec3 P[3] = { vec3 P[3] = {
vec3( ubo.voxel * vec4( inPosition[0], 1 ) ) / power, vec3( ubo.voxel * vec4( inPosition[0], 1 ) ) / power,
@ -77,6 +78,7 @@ void main(){
outNormal = inNormal[i]; outNormal = inNormal[i];
outTangent = inTangent[i]; outTangent = inTangent[i];
outId = inId[i]; outId = inId[i];
outId.w = gl_ViewIndex;
const vec3 P = outPosition; // + D; const vec3 P = outPosition; // + D;
#if USE_CROSS #if USE_CROSS

View File

@ -23,6 +23,7 @@ namespace ext {
VkImage image; VkImage image;
VkDeviceMemory mem; VkDeviceMemory mem;
VkImageView view; VkImageView view;
VkImageView framebufferView;
uf::stl::vector<VkImageView> views; uf::stl::vector<VkImageView> views;
VmaAllocation allocation; VmaAllocation allocation;
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocationInfo;

View File

@ -23,6 +23,7 @@
#define VK_DEFAULT_DEFER_BUFFER_DESTROY ext::vulkan::settings::defaultDeferBufferDestroy #define VK_DEFAULT_DEFER_BUFFER_DESTROY ext::vulkan::settings::defaultDeferBufferDestroy
#define VK_DEFAULT_COMMAND_BUFFER_IMMEDIATE ext::vulkan::settings::defaultCommandBufferImmediate #define VK_DEFAULT_COMMAND_BUFFER_IMMEDIATE ext::vulkan::settings::defaultCommandBufferImmediate
#define VK_UBO_USE_N_BUFFERS 0 #define VK_UBO_USE_N_BUFFERS 0
#define VK_USE_MULTIVIEW 1
namespace ext { namespace ext {
namespace vulkan { namespace vulkan {

View File

@ -78,7 +78,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
if ( metadataJson["light"]["type"].as<uf::stl::string>() == "point" ) { if ( metadataJson["light"]["type"].as<uf::stl::string>() == "point" ) {
metadataJson["light"]["fov"] = 90.0f; metadataJson["light"]["fov"] = 90.0f;
renderMode.metadata.subpasses = 6; renderMode.metadata.views = 6;
} }
float fov = metadataJson["light"]["fov"].as<float>(90) * (3.14159265358f / 180.0f); float fov = metadataJson["light"]["fov"].as<float>(90) * (3.14159265358f / 180.0f);

View File

@ -131,7 +131,8 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
} }
renderMode.metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::vxgi); renderMode.metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::vxgi);
renderMode.metadata.samples = 1; 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.width = metadata.fragmentSize.x;
renderMode.height = metadata.fragmentSize.y; renderMode.height = metadata.fragmentSize.y;

View File

@ -378,6 +378,58 @@ namespace {
return json; 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 ) { void enableRequestedDeviceFeatures12( VkPhysicalDeviceVulkan12Features& features, VkPhysicalDeviceVulkan12Features& enabledFeatures ) {
ext::json::Value json; ext::json::Value json;
@ -1185,6 +1237,7 @@ void ext::vulkan::Device::initialize() {
std::queue<void*> chain = {}; std::queue<void*> chain = {};
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{}; VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{};
VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{};
VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{}; VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{};
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures{}; VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures{};
VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures{}; VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures{};
@ -1197,12 +1250,16 @@ void ext::vulkan::Device::initialize() {
VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR fragmentShaderBarycentricFeatures{}; VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR fragmentShaderBarycentricFeatures{};
VkPhysicalDeviceSubgroupSizeControlFeatures subgroupSizeControlFeatures{}; VkPhysicalDeviceSubgroupSizeControlFeatures subgroupSizeControlFeatures{};
VkPhysicalDeviceFeatures2 enabledDeviceFeatures2{};
VkPhysicalDeviceVulkan11Features enabledPhysicalDeviceVulkan11Features{};
VkPhysicalDeviceVulkan12Features enabledPhysicalDeviceVulkan12Features{}; 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; enabledPhysicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
enabledDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; enabledPhysicalDeviceVulkan11Features.pNext = &enabledPhysicalDeviceVulkan12Features;
enabledDeviceFeatures2.pNext = &enabledPhysicalDeviceVulkan12Features; enabledDeviceFeatures2.pNext = &enabledPhysicalDeviceVulkan11Features;
vkGetPhysicalDeviceFeatures2(device.physicalDevice, &enabledDeviceFeatures2); vkGetPhysicalDeviceFeatures2(device.physicalDevice, &enabledDeviceFeatures2);
} }
@ -1213,6 +1270,20 @@ void ext::vulkan::Device::initialize() {
chain.push( &physicalDeviceFeatures2 ); chain.push( &physicalDeviceFeatures2 );
VK_VALIDATION_MESSAGE("Enabled feature chain: {}", "physicalDeviceFeatures2" ); VK_VALIDATION_MESSAGE("Enabled feature chain: {}", "physicalDeviceFeatures2" );
} }
if ( ext::vulkan::settings::requested::featureChain["physicalDeviceVulkan11"].as<bool>(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<bool>(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<bool>(false) ) { if ( ext::vulkan::settings::requested::featureChain["physicalDeviceVulkan12"].as<bool>(false) ) {
physicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; physicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
enableRequestedDeviceFeatures12( enabledPhysicalDeviceVulkan12Features, physicalDeviceVulkan12Features ); enableRequestedDeviceFeatures12( enabledPhysicalDeviceVulkan12Features, physicalDeviceVulkan12Features );
@ -1239,12 +1310,6 @@ void ext::vulkan::Device::initialize() {
} }
// //
if ( ext::vulkan::settings::requested::featureChain["shaderDrawParameters"].as<bool>(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<bool>(false) ) { if ( ext::vulkan::settings::requested::featureChain["robustness"].as<bool>(false) ) {
robustnessFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; robustnessFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
robustnessFeatures.nullDescriptor = VK_TRUE; robustnessFeatures.nullDescriptor = VK_TRUE;

View File

@ -205,46 +205,42 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
metadata.attachments["output"] = attachments.color; metadata.attachments["output"] = attachments.color;
// First pass: fill the G-Buffer // 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( 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
#if !BARYCENTRIC_CALCULATE #if !BARYCENTRIC_CALCULATE
/*.colors =*/ { attachments.id, attachments.bary }, /*.inputs =*/ { attachments.id, attachments.depth, attachments.bary },
#else #else
/*.colors =*/ { attachments.id }, /*.inputs =*/ { attachments.id, attachments.depth },
#endif #endif
#else #else
/*.colors =*/ { attachments.id, attachments.uv, attachments.normal }, /*.inputs =*/ { attachments.id, attachments.depth, attachments.uv, attachments.normal },
#endif #endif
/*.inputs =*/ {},
/*.resolve =*/{}, /*.resolve =*/{},
/*.depth = */ attachments.depth, /*.depth = */attachments.depth,
/*.layer = */eye, /*.layer = */0,
/*.autoBuildPipeline =*/ true /*.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"]); // metadata.outputs.emplace_back(metadata.attachments["output"]);
renderTarget.initialize( device ); renderTarget.initialize( device );
@ -818,7 +814,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
// render to geometry buffers // render to geometry buffers
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { {
size_t currentPass = 0; size_t currentPass = 0;
size_t currentDraw = 0; size_t currentDraw = 0;
for ( auto graphic : graphics ) { for ( auto graphic : graphics ) {
@ -826,15 +822,14 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
if ( graphic->descriptor.renderMode != this->getName() ) continue; if ( graphic->descriptor.renderMode != this->getName() ) continue;
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass); ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass);
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, ::fmt::format("graphic[{}]", currentDraw) ); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, ::fmt::format("graphic[{}]", currentDraw) );
graphic->record( commandBuffer, descriptor, eye, currentDraw++, frame ); graphic->record( commandBuffer, descriptor, 0, currentDraw++, frame );
}
if ( eye + 1 < metadata.eyes ) {
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "nextSubpass" );
vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); ++currentSubpass;
} }
} }
// skip deferred pass if RT is enabled, we still process geometry for a depth buffer // 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 currentPass = 0;
size_t currentDraw = 0; size_t currentDraw = 0;
{ {
@ -844,11 +839,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
descriptor.subpass = currentSubpass; descriptor.subpass = currentSubpass;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_GRAPHICS; descriptor.bind.point = VK_PIPELINE_BIND_POINT_GRAPHICS;
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "deferred" ); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "deferred" );
blitter.record(commandBuffer, descriptor, eye, currentDraw++, frame); blitter.record(commandBuffer, descriptor, 0, currentDraw++, frame);
}
if ( eye + 1 < metadata.eyes ) {
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "nextSubpass" );
vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); ++currentSubpass;
} }
} }
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "renderPass[end]" ); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "renderPass[end]" );

View File

@ -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 ext::vulkan::RenderTargetRenderMode::bindGraphicDescriptor( const ext::vulkan::GraphicDescriptor& reference, size_t pass ) {
ext::vulkan::GraphicDescriptor descriptor = ext::vulkan::RenderMode::bindGraphicDescriptor(reference, 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 ) { if ( 0 <= pass && pass < metadata.subpasses && metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
descriptor.cullMode = VK_CULL_MODE_NONE; 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 ) { if ( metadata.type == "depth" || metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
renderTarget.views = metadata.subpasses;
struct { struct {
size_t depth; size_t depth;
} attachments = {}; } attachments = {};
@ -82,152 +72,33 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
); );
} }
} else if ( metadata.type == settings::pipelines::names::rt ) { } else if ( metadata.type == settings::pipelines::names::rt ) {
#if 1 UF_EXCEPTION("unimplemented");
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
} else if ( metadata.type == "full" ) { } else if ( metadata.type == "full" ) {
#if 0 UF_EXCEPTION("unimplemented");
} else {
struct { struct {
size_t id, position, normal, depth, color; size_t color, depth;
} attachments = {}; } attachments = {};
// input g-buffers attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{
attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{ /*.format = */VK_FORMAT_R8G8B8A8_UNORM,
/*.format = */VK_FORMAT_R32G32_UINT,
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, /*.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, /*.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.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,
/*.samples = */msaa, /*.samples = */msaa,
}); });
attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{ attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */ext::vulkan::settings::formats::depth, /*.format = */ ext::vulkan::settings::formats::depth,
/*.layout = */VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, /*.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, /*.usage = */ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
/*.blend = */false, /*.blend = */ false,
/*.samples = */msaa, /*.samples = */ 1,
});
// 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,
}); });
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["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 ) { 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( renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.color }, { attachments.color },
@ -237,9 +108,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
0, 0,
true 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() { void ext::vulkan::RenderTargetRenderMode::render() {
// if ( this->executed ) return;
if ( this->commands.container().empty() ) return; if ( this->commands.container().empty() ) return;
//lockMutex( this->mostRecentCommandPoolId );
auto& commands = getCommands( this->mostRecentCommandPoolId ); auto& commands = getCommands( this->mostRecentCommandPoolId );
VK_COMMAND_BUFFER_CALLBACK( EXECUTE_BEGIN, VkCommandBuffer{}, 0, {} ); 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 = {}; VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 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.pWaitDstStageMask = NULL;
submitInfo.pWaitSemaphores = NULL; // Semaphore(s) to wait upon before the submitted command buffer starts executing submitInfo.pWaitSemaphores = NULL;
submitInfo.waitSemaphoreCount = 0; // One wait semaphore submitInfo.waitSemaphoreCount = 0;
submitInfo.pSignalSemaphores = NULL; // Semaphore(s) to be signaled when command buffers have completed submitInfo.pSignalSemaphores = NULL;
submitInfo.signalSemaphoreCount = 0; // One signal semaphore submitInfo.signalSemaphoreCount = 0;
submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission) submitInfo.pCommandBuffers = &commands[states::currentBuffer];
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
// VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
VkQueue queue = device->getQueue( QueueEnum::GRAPHICS ); VkQueue queue = device->getQueue( QueueEnum::GRAPHICS );
VkResult res = vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE/*fences[states::currentBuffer]*/); VkResult res = vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE/*fences[states::currentBuffer]*/);
VK_CHECK_QUEUE_CHECKPOINT( queue, res ); VK_CHECK_QUEUE_CHECKPOINT( queue, res );
VK_COMMAND_BUFFER_CALLBACK( EXECUTE_END, VkCommandBuffer{}, 0, {} ); VK_COMMAND_BUFFER_CALLBACK( EXECUTE_END, VkCommandBuffer{}, 0, {} );
this->executed = true; this->executed = true;
//unlockMutex( this->mostRecentCommandPoolId );
} }
void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer commandBuffer, uint8_t state ) { void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer commandBuffer, uint8_t state ) {
ext::vulkan::RenderMode::pipelineBarrier( commandBuffer, 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::Serializer>(); auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
uf::stl::vector<VkClearValue> clearValues; uf::stl::vector<VkClearValue> clearValues;
for ( size_t j = 0; j < renderTarget.views; ++j ) { for ( auto& attachment : renderTarget.attachments ) {
for ( auto& attachment : renderTarget.attachments ) { auto& clearValue = clearValues.emplace_back();
auto& clearValue = clearValues.emplace_back(); if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) { clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } };
clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; } else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
} else if ( attachment.descriptor.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) { if ( uf::matrix::reverseInfiniteProjection ) {
if ( uf::matrix::reverseInfiniteProjection ) { clearValue.depthStencil = { 0.0f, 0 };
clearValue.depthStencil = { 0.0f, 0 }; } else {
} else { clearValue.depthStencil = { 1.0f, 0 };
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 subpasses = renderTarget.passes.size();
size_t currentPass = 0; 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 // pre-renderpass commands
VK_COMMAND_BUFFER_CALLBACK( CALLBACK_BEGIN, commandBuffer, frame, { VK_COMMAND_BUFFER_CALLBACK( CALLBACK_BEGIN, commandBuffer, frame, {
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[begin]" ); 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, { VK_COMMAND_BUFFER_CALLBACK( CALLBACK_END, commandBuffer, frame, {
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[end]" ); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::GENERIC, "callback[end]" );
} ); } );
// this->pipelineBarrier( commands[frame], 1 );
} }
device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "end" ); device->UF_CHECKPOINT_MARK( commandBuffer, pod::Checkpoint::END, "end" );
VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer));

View File

@ -85,9 +85,8 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
subresourceRange.baseMipLevel = 0; subresourceRange.baseMipLevel = 0;
subresourceRange.levelCount = 1; subresourceRange.levelCount = 1;
subresourceRange.baseArrayLayer = 0; subresourceRange.baseArrayLayer = 0;
subresourceRange.layerCount = 1;
subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 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); auto commandBuffer = device->fetchCommandBuffer(uf::renderer::QueueEnum::GRAPHICS);
for ( size_t i = 0; i < ext::vulkan::swapchain.buffers; ++i ) { 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_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->view));
VK_REGISTER_HANDLE( 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; size_t viewIndex = 0;
for ( size_t layer = 0; layer < this->views; ++layer ) { for ( size_t layer = 0; layer < this->views; ++layer ) {
imageView.viewType = VK_IMAGE_VIEW_TYPE_2D; imageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
@ -237,21 +242,19 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
if ( !renderPass ) { if ( !renderPass ) {
uf::stl::vector<VkAttachmentDescription> attachments; attachments.reserve( this->attachments.size() ); uf::stl::vector<VkAttachmentDescription> attachments; attachments.reserve( this->attachments.size() );
for ( size_t i = 0; i < this->views; ++i ) { for ( auto& attachment : this->attachments ) {
for ( auto& attachment : this->attachments ) { VkAttachmentDescription description;
VkAttachmentDescription description; description.format = attachment.descriptor.format;
description.format = attachment.descriptor.format; description.samples = ext::vulkan::sampleCount( attachment.descriptor.samples );
description.samples = ext::vulkan::sampleCount( attachment.descriptor.samples ); description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
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.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.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; description.stencilStoreOp = VK_ATTACHMENT_STORE_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.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.finalLayout = ext::vulkan::Texture::remapRenderpassLayout( attachment.descriptor.layout ); description.flags = 0;
description.flags = 0;
attachments.emplace_back(description); attachments.emplace_back(description);
}
} }
// ensure that the subpasses are already described // ensure that the subpasses are already described
@ -259,12 +262,14 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
assert( passes.size() > 0 ); assert( passes.size() > 0 );
// expand attachment indices // expand attachment indices
/*
for ( auto& pass : passes ) { for ( auto& pass : passes ) {
for ( auto& input : pass.inputs ) input.attachment += pass.layer * this->attachments.size(); 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& color : pass.colors ) color.attachment += pass.layer * this->attachments.size();
for ( auto& resolve : pass.resolves ) resolve.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(); pass.depth.attachment += pass.layer * this->attachments.size();
} }
*/
uf::stl::vector<VkSubpassDescription> descriptions; uf::stl::vector<VkSubpassDescription> descriptions;
uf::stl::vector<VkSubpassDependency> dependencies; uf::stl::vector<VkSubpassDependency> dependencies;
@ -380,6 +385,26 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size()); renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
renderPassInfo.pDependencies = &dependencies[0]; renderPassInfo.pDependencies = &dependencies[0];
uint32_t viewMask = (1 << this->views) - 1;
uf::stl::vector<uint32_t> viewMasks(descriptions.size(), viewMask);
uf::stl::vector<uint32_t> 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<uint32_t>(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_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass));
VK_REGISTER_HANDLE( 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 ) { for ( size_t frame = 0; frame < framebuffers.size(); ++frame ) {
uf::stl::vector<VkImageView> attachmentViews; uf::stl::vector<VkImageView> attachmentViews;
for ( auto view = 0; view < this->views; ++view ) { for ( auto& attachment : this->attachments ) {
for ( auto& attachment : this->attachments ) { if ( attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) {
if ( attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) { attachmentViews.emplace_back(attachment.views[frame]);
attachmentViews.emplace_back(attachment.views[frame]); } else if ( attachment.framebufferView != VK_NULL_HANDLE ) {
} else { attachmentViews.emplace_back(attachment.framebufferView);
attachmentViews.emplace_back(attachment.views[view * attachment.descriptor.mips]); } else {
} attachmentViews.emplace_back(attachment.view);
} }
} }
@ -434,6 +459,11 @@ void ext::vulkan::RenderTarget::destroy() {
for ( auto& attachment : attachments ) { for ( auto& attachment : attachments ) {
if ( attachment.descriptor.aliased ) continue; if ( attachment.descriptor.aliased ) continue;
if ( attachment.framebufferView ) {
vkDestroyImageView(*device, attachment.framebufferView, nullptr);
VK_UNREGISTER_HANDLE( attachment.framebufferView );
}
if ( attachment.view ) { if ( attachment.view ) {
if ( attachment.view != attachment.views.front() ) { if ( attachment.view != attachment.views.front() ) {
vkDestroyImageView(*device, attachment.view, nullptr); vkDestroyImageView(*device, attachment.view, nullptr);

View File

@ -495,7 +495,7 @@ void ext::vulkan::initialize( bool soft ) {
void ext::vulkan::tick() { void ext::vulkan::tick() {
// ext::vulkan::mutex.lock(); // ext::vulkan::mutex.lock();
if ( ext::vulkan::states::resized ) { if ( ext::vulkan::states::resized ) {
// synchronize(0b11); synchronize(0b11);
ext::vulkan::states::rebuild = true; ext::vulkan::states::rebuild = true;
::skip = true; ::skip = true;
} }