Validation layer wants layout specified during linking (is it right? nobody knows! the vulkan spec is unreadable in this part, thanks khronos!)

Fix light probe pass using depth stencil format selection before it was set
This commit is contained in:
Magnus Norddahl 2025-04-20 18:15:38 +02:00
commit 26b10dbdda
12 changed files with 108 additions and 71 deletions

View file

@ -1196,9 +1196,15 @@ std::unique_ptr<VulkanPipeline> GraphicsPipelineBuilder::Create(VulkanDevice* de
if (!libraries.empty())
{
auto subpass = pipelineInfo.subpass;
auto layout = pipelineInfo.layout;
auto renderpass = pipelineInfo.renderPass;
auto flags = pipelineInfo.flags;
pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
pipelineInfo.flags = flags;
pipelineInfo.subpass = subpass;
pipelineInfo.layout = layout;
pipelineInfo.renderPass = renderpass;
libraryCreate.libraryCount = (uint32_t)libraries.size();
libraryCreate.pLibraries = libraries.data();
}

View file

@ -101,7 +101,7 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
if (key.StencilTest == WhichDepthStencil::Scene)
{
builder.AddDepthStencilAttachment(
fb->GetBuffers()->SceneDepthStencilFormat, key.Samples,
fb->DepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
@ -109,7 +109,7 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
if (key.StencilTest == WhichDepthStencil::Pipeline)
{
builder.AddDepthStencilAttachment(
fb->GetBuffers()->PipelineDepthStencilFormat, key.Samples,
fb->DepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);

View file

@ -422,7 +422,7 @@ VkRenderPassSetup::VkRenderPassSetup(VulkanRenderDevice* fb, const VkRenderPassK
std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearTargets)
{
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, PassKey.NormalFormat };
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, fb->NormalFormat };
RenderPassBuilder builder;
@ -441,7 +441,7 @@ std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearT
if (PassKey.DepthStencil)
{
builder.AddDepthStencilAttachment(
PassKey.DepthStencilFormat, (VkSampleCountFlagBits)PassKey.Samples,
fb->DepthStencilFormat, (VkSampleCountFlagBits)PassKey.Samples,
(clearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
(clearTargets & CT_Stencil) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
@ -774,6 +774,8 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::LinkPipeline(const VkPipeline
GraphicsPipelineBuilder builder;
builder.Cache(fb->GetRenderPassManager()->GetCache());
builder.Layout(fb->GetRenderPassManager()->GetPipelineLayout(key.ShaderKey.Layout.UseLevelMesh, program->Uniforms.sz));
builder.RenderPass(GetRenderPass(0));
builder.AddLibrary(GetVertexInputLibrary(key.ShaderKey.VertexFormat, key.DrawType, key.ShaderKey.Layout.UseLevelMesh, program->Uniforms.sz));
builder.AddLibrary(GetVertexShaderLibrary(key, isUberShader));
builder.AddLibrary(GetFragmentShaderLibrary(key, isUberShader));

View file

@ -68,8 +68,6 @@ public:
int Samples = 0;
int DrawBuffers = 0;
VkFormat DrawBufferFormat = VK_FORMAT_UNDEFINED;
VkFormat NormalFormat = VK_FORMAT_UNDEFINED;
VkFormat DepthStencilFormat = VK_FORMAT_UNDEFINED;
bool operator<(const VkRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkRenderPassKey)) < 0; }
bool operator==(const VkRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkRenderPassKey)) == 0; }

View file

@ -79,7 +79,7 @@ VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex)
{
if (!mDepthStencil.View)
{
VkFormat format = fb->GetBuffers()->SceneDepthStencilFormat;
VkFormat format = fb->DepthStencilFormat;
int w = tex->GetWidth();
int h = tex->GetHeight();

View file

@ -141,31 +141,22 @@ VulkanFramebuffer* VkRenderBuffers::GetZMinMaxFramebuffer(int index)
void VkRenderBuffers::CreatePipelineDepthStencil(int width, int height)
{
ImageBuilder builder;
builder.Size(width, height);
builder.Format(PipelineDepthStencilFormat);
builder.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.IsFormatSupported(fb->GetDevice()))
{
PipelineDepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
builder.Format(PipelineDepthStencilFormat);
if (!builder.IsFormatSupported(fb->GetDevice()))
{
I_FatalError("This device does not support any of the required depth stencil image formats.");
}
}
builder.DebugName("VkRenderBuffers.PipelineDepthStencil");
PipelineDepthStencil.Image = ImageBuilder()
.Size(width, height)
.Format(fb->DepthStencilFormat)
.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkRenderBuffers.PipelineDepthStencil")
.Create(fb->GetDevice());
PipelineDepthStencil.Image = builder.Create(fb->GetDevice());
PipelineDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
PipelineDepthStencil.View = ImageViewBuilder()
.Image(PipelineDepthStencil.Image.get(), PipelineDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
.Image(PipelineDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
.DebugName("VkRenderBuffers.PipelineDepthStencilView")
.Create(fb->GetDevice());
PipelineDepthStencil.DepthOnlyView = ImageViewBuilder()
.Image(PipelineDepthStencil.Image.get(), PipelineDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT)
.Image(PipelineDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT)
.DebugName("VkRenderBuffers.PipelineDepthView")
.Create(fb->GetDevice());
}
@ -239,32 +230,23 @@ void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagB
void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples)
{
ImageBuilder builder;
builder.Size(width, height);
builder.Samples(samples);
builder.Format(SceneDepthStencilFormat);
builder.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.IsFormatSupported(fb->GetDevice()))
{
SceneDepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
builder.Format(SceneDepthStencilFormat);
if (!builder.IsFormatSupported(fb->GetDevice()))
{
I_FatalError("This device does not support any of the required depth stencil image formats.");
}
}
builder.DebugName("VkRenderBuffers.SceneDepthStencil");
SceneDepthStencil.Image = ImageBuilder()
.Size(width, height)
.Samples(samples)
.Format(fb->DepthStencilFormat)
.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkRenderBuffers.SceneDepthStencil")
.Create(fb->GetDevice());
SceneDepthStencil.Image = builder.Create(fb->GetDevice());
SceneDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
SceneDepthStencil.View = ImageViewBuilder()
.Image(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
.Image(SceneDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
.DebugName("VkRenderBuffers.SceneDepthStencilView")
.Create(fb->GetDevice());
SceneDepthStencil.DepthOnlyView = ImageViewBuilder()
.Image(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT)
.Image(SceneDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT)
.DebugName("VkRenderBuffers.SceneDepthView")
.Create(fb->GetDevice());
}
@ -341,22 +323,16 @@ void VkRenderBuffers::CreateSceneLightTiles(int width, int height)
void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples)
{
ImageBuilder builder;
builder.Size(width, height);
builder.Samples(samples);
builder.Format(SceneNormalFormat);
builder.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
if (!builder.IsFormatSupported(fb->GetDevice(), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
{
SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM;
builder.Format(SceneNormalFormat);
}
builder.DebugName("VkRenderBuffers.SceneNormal");
SceneNormal.Image = builder.Create(fb->GetDevice());
SceneNormal.Image = ImageBuilder()
.Size(width, height)
.Samples(samples)
.Format(fb->NormalFormat)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.DebugName("VkRenderBuffers.SceneNormal")
.Create(fb->GetDevice());
SceneNormal.View = ImageViewBuilder()
.Image(SceneNormal.Image.get(), SceneNormalFormat)
.Image(SceneNormal.Image.get(), fb->NormalFormat)
.DebugName("VkRenderBuffers.SceneNormalView")
.Create(fb->GetDevice());
}

View file

@ -40,10 +40,6 @@ public:
VkTextureImage SceneZMinMax[6];
std::unique_ptr<VulkanBuffer> SceneLightTiles;
VkFormat PipelineDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
VkFormat SceneNormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
static const int NumPipelineImages = 2;
VkTextureImage PipelineDepthStencil;
VkTextureImage PipelineImage[NumPipelineImages];

View file

@ -114,7 +114,7 @@ void VkLightprober::CreateEnvironmentMap()
.DebugName("VkLightprober.environmentMap.cubeview")
.Create(fb->GetDevice());
VkFormat format = fb->GetBuffers()->SceneDepthStencilFormat;
VkFormat format = fb->DepthStencilFormat;
environmentMap.zbuffer = ImageBuilder()
.Size(environmentMap.textureSize, environmentMap.textureSize)

View file

@ -199,15 +199,50 @@ VulkanRenderDevice::~VulkanRenderDevice()
if (mDescriptorSetManager)
mDescriptorSetManager->Deinit();
mCommands->DeleteFrameObjects();
if (mCommands)
mCommands->DeleteFrameObjects();
if (mTextureManager)
mTextureManager->Deinit();
if (mBufferManager)
mBufferManager->Deinit();
if (mShaderManager)
mShaderManager->Deinit();
if (mCommands)
mCommands->DeleteFrameObjects();
}
mCommands->DeleteFrameObjects();
bool VulkanRenderDevice::SupportsRenderTargetFormat(VkFormat format)
{
if (ImageBuilder()
.Size(1024, 1024)
.Format(format)
.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.IsFormatSupported(GetDevice()))
return true;
return ImageBuilder()
.Size(1024, 1024)
.Format(format)
.Samples(VK_SAMPLE_COUNT_4_BIT)
.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.IsFormatSupported(GetDevice());
}
bool VulkanRenderDevice::SupportsNormalGBufferFormat(VkFormat format)
{
if (ImageBuilder()
.Size(1024, 1024)
.Format(format)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.IsFormatSupported(GetDevice()))
return true;
return ImageBuilder()
.Size(1024, 1024)
.Format(format)
.Samples(VK_SAMPLE_COUNT_4_BIT)
.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.IsFormatSupported(GetDevice());
}
void VulkanRenderDevice::InitializeState()
@ -231,6 +266,32 @@ void VulkanRenderDevice::InitializeState()
uniformblockalignment = (unsigned int)mDevice->PhysicalDevice.Properties.Properties.limits.minUniformBufferOffsetAlignment;
maxuniformblock = std::min(mDevice->PhysicalDevice.Properties.Properties.limits.maxUniformBufferRange, (uint32_t)1024 * 1024);
if (SupportsRenderTargetFormat(VK_FORMAT_D24_UNORM_S8_UINT))
{
DepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
}
else if (SupportsRenderTargetFormat(VK_FORMAT_D32_SFLOAT_S8_UINT))
{
DepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
}
else
{
I_FatalError("This device does not support any of the required depth stencil image formats.");
}
if (SupportsNormalGBufferFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32))
{
NormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
}
else if (SupportsNormalGBufferFormat(VK_FORMAT_R8G8B8A8_UNORM))
{
NormalFormat = VK_FORMAT_R8G8B8A8_UNORM;
}
else
{
I_FatalError("This device does not support any of the required normal buffer image formats.");
}
NullMesh.reset(new LevelMesh());
levelMesh = NullMesh.get();

View file

@ -104,6 +104,9 @@ public:
bool IsSurfaceAvailable() { return HasSurface; }
VkFormat DepthStencilFormat = VK_FORMAT_UNDEFINED;
VkFormat NormalFormat = VK_FORMAT_UNDEFINED;
private:
void RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc) override;
void RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc, TArrayView<uint16_t>& irradianceMap, TArrayView<uint16_t>& prefilterMap) override;
@ -111,6 +114,9 @@ private:
void PrintStartupLog();
void CopyScreenToBuffer(int w, int h, uint8_t *data) override;
bool SupportsRenderTargetFormat(VkFormat format);
bool SupportsNormalGBufferFormat(VkFormat format);
bool HasSurface = false;
std::shared_ptr<VulkanDevice> mDevice;

View file

@ -826,8 +826,6 @@ void VkRenderState::SetRenderTarget(VkTextureImage *image, VulkanImageView *dept
mRenderTarget.Height = height;
mRenderTarget.Format = format;
mRenderTarget.Samples = samples;
mRenderTarget.NormalFormat = buffers->SceneNormalFormat;
mRenderTarget.DepthStencilFormat = buffers->SceneDepthStencilFormat;
}
void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
@ -837,8 +835,6 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
key.Samples = mRenderTarget.Samples;
key.DrawBuffers = mRenderTarget.DrawBuffers;
key.DepthStencil = !!mRenderTarget.DepthStencil;
key.NormalFormat = mRenderTarget.NormalFormat;
key.DepthStencilFormat = mRenderTarget.DepthStencilFormat;
mPassSetup = fb->GetRenderPassManager()->GetRenderPass(key);
@ -895,8 +891,6 @@ void VkRenderState::RaytraceScene(const FVector3& cameraPos, const VSMatrix& vie
key.Samples = mRenderTarget.Samples;
key.DrawBuffers = mRenderTarget.DrawBuffers;
key.DepthStencil = !!mRenderTarget.DepthStencil;
key.NormalFormat = mRenderTarget.NormalFormat;
key.DepthStencilFormat = mRenderTarget.DepthStencilFormat;
fb->GetLevelMesh()->RaytraceScene(key, mCommandBuffer, cameraPos, viewToWorld, fovy, aspect);
}

View file

@ -152,8 +152,6 @@ protected:
VkFormat Format = VK_FORMAT_R16G16B16A16_SFLOAT;
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
int DrawBuffers = 1;
VkFormat NormalFormat = VK_FORMAT_UNDEFINED;
VkFormat DepthStencilFormat = VK_FORMAT_UNDEFINED;
} mRenderTarget;
TArray<uint32_t> mQueryResultsBuffer;