mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 06:53:40 +00:00
- rendering to texture requires a separate depth/stencil image as the image used by the main view may be using multisampling
This commit is contained in:
parent
32109a75a7
commit
e1ae8bbc59
8 changed files with 50 additions and 10 deletions
|
@ -34,7 +34,7 @@ void VkPostprocess::SetActiveRenderTarget()
|
||||||
imageTransition.addImage(buffers->PipelineImage[mCurrentPipelineImage].get(), &buffers->PipelineLayout[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
imageTransition.addImage(buffers->PipelineImage[mCurrentPipelineImage].get(), &buffers->PipelineLayout[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
||||||
imageTransition.execute(fb->GetDrawCommands());
|
imageTransition.execute(fb->GetDrawCommands());
|
||||||
|
|
||||||
fb->GetRenderState()->SetRenderTarget(buffers->PipelineView[mCurrentPipelineImage].get(), buffers->GetWidth(), buffers->GetHeight(), VK_SAMPLE_COUNT_1_BIT);
|
fb->GetRenderState()->SetRenderTarget(buffers->PipelineView[mCurrentPipelineImage].get(), buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
|
void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||||
|
|
|
@ -55,6 +55,7 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
|
||||||
if (width != mWidth || height != mHeight || mSamples != samples)
|
if (width != mWidth || height != mHeight || mSamples != samples)
|
||||||
CreateScene(width, height, samples);
|
CreateScene(width, height, samples);
|
||||||
|
|
||||||
|
CreateCamTexDepthStencil();
|
||||||
CreateShadowmap();
|
CreateShadowmap();
|
||||||
|
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
|
@ -142,6 +143,31 @@ void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagB
|
||||||
SceneColorView->SetDebugName("VkRenderBuffers.SceneColorView");
|
SceneColorView->SetDebugName("VkRenderBuffers.SceneColorView");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VkRenderBuffers::CreateCamTexDepthStencil()
|
||||||
|
{
|
||||||
|
if (CamtexDepthStencil)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
|
ImageBuilder builder;
|
||||||
|
builder.setSize(1024, 1024);
|
||||||
|
builder.setSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||||
|
builder.setFormat(SceneDepthStencilFormat);
|
||||||
|
builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
|
CamtexDepthStencil = builder.create(fb->device);
|
||||||
|
CamtexDepthStencil->SetDebugName("VkRenderBuffers.CamtexDepthStencil");
|
||||||
|
|
||||||
|
ImageViewBuilder viewbuilder;
|
||||||
|
viewbuilder.setImage(CamtexDepthStencil.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
CamtexDepthStencilView = viewbuilder.create(fb->device);
|
||||||
|
CamtexDepthStencilView->SetDebugName("VkRenderBuffers.CamtexDepthStencilView");
|
||||||
|
|
||||||
|
PipelineBarrier barrier;
|
||||||
|
barrier.addImage(CamtexDepthStencil.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples)
|
void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples)
|
||||||
{
|
{
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
|
@ -32,6 +32,9 @@ public:
|
||||||
VkImageLayout SceneNormalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
VkImageLayout SceneNormalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
VkImageLayout SceneFogLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
VkImageLayout SceneFogLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
std::unique_ptr<VulkanImage> CamtexDepthStencil;
|
||||||
|
std::unique_ptr<VulkanImageView> CamtexDepthStencilView;
|
||||||
|
|
||||||
static const int NumPipelineImages = 2;
|
static const int NumPipelineImages = 2;
|
||||||
std::unique_ptr<VulkanImage> PipelineImage[NumPipelineImages];
|
std::unique_ptr<VulkanImage> PipelineImage[NumPipelineImages];
|
||||||
std::unique_ptr<VulkanImageView> PipelineView[NumPipelineImages];
|
std::unique_ptr<VulkanImageView> PipelineView[NumPipelineImages];
|
||||||
|
@ -50,6 +53,7 @@ private:
|
||||||
void CreateSceneFog(int width, int height, VkSampleCountFlagBits samples);
|
void CreateSceneFog(int width, int height, VkSampleCountFlagBits samples);
|
||||||
void CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples);
|
void CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples);
|
||||||
void CreateShadowmap();
|
void CreateShadowmap();
|
||||||
|
void CreateCamTexDepthStencil();
|
||||||
VkSampleCountFlagBits GetBestSampleCount();
|
VkSampleCountFlagBits GetBestSampleCount();
|
||||||
|
|
||||||
int mWidth = 0;
|
int mWidth = 0;
|
||||||
|
|
|
@ -208,17 +208,23 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
||||||
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32 };
|
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32 };
|
||||||
|
|
||||||
RenderPassBuilder builder;
|
RenderPassBuilder builder;
|
||||||
for (int i = 0; i < key.DrawBuffers; i++)
|
|
||||||
|
builder.addAttachment(
|
||||||
|
key.DrawBufferFormat, (VkSampleCountFlagBits)key.Samples,
|
||||||
|
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
|
for (int i = 1; i < key.DrawBuffers; i++)
|
||||||
{
|
{
|
||||||
builder.addAttachment(
|
builder.addAttachment(
|
||||||
drawBufferFormats[i], i == 0 ? (VkSampleCountFlagBits)key.Samples : buffers->GetSceneSamples(),
|
drawBufferFormats[i], buffers->GetSceneSamples(),
|
||||||
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
if (key.UsesDepthStencil())
|
if (key.UsesDepthStencil())
|
||||||
{
|
{
|
||||||
builder.addDepthStencilAttachment(
|
builder.addDepthStencilAttachment(
|
||||||
buffers->SceneDepthStencilFormat, buffers->GetSceneSamples(),
|
buffers->SceneDepthStencilFormat, key.DrawBufferFormat == VK_FORMAT_R8G8B8A8_UNORM ? VK_SAMPLE_COUNT_1_BIT : buffers->GetSceneSamples(),
|
||||||
(key.ClearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(key.ClearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
(key.ClearTargets & CT_Stencil) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(key.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);
|
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
int ClearTargets;
|
int ClearTargets;
|
||||||
int DrawBuffers;
|
int DrawBuffers;
|
||||||
int NumTextureLayers;
|
int NumTextureLayers;
|
||||||
|
VkFormat DrawBufferFormat;
|
||||||
|
|
||||||
bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }
|
bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
passKey.StencilPassOp = mStencilOp;
|
passKey.StencilPassOp = mStencilOp;
|
||||||
passKey.ColorMask = mColorMask;
|
passKey.ColorMask = mColorMask;
|
||||||
passKey.CullMode = mCullMode;
|
passKey.CullMode = mCullMode;
|
||||||
|
passKey.DrawBufferFormat = mRenderTarget.Format;
|
||||||
passKey.Samples = mRenderTarget.Samples;
|
passKey.Samples = mRenderTarget.Samples;
|
||||||
passKey.DrawBuffers = mRenderTarget.DrawBuffers;
|
passKey.DrawBuffers = mRenderTarget.DrawBuffers;
|
||||||
passKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->GetLayers() : 0;
|
passKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->GetLayers() : 0;
|
||||||
|
@ -535,13 +536,14 @@ void VkRenderState::EnableDrawBuffers(int count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkRenderState::SetRenderTarget(VulkanImageView *view, int width, int height, VkSampleCountFlagBits samples)
|
void VkRenderState::SetRenderTarget(VulkanImageView *view, int width, int height, VkFormat format, VkSampleCountFlagBits samples)
|
||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
mRenderTarget.View = view;
|
mRenderTarget.View = view;
|
||||||
mRenderTarget.Width = width;
|
mRenderTarget.Width = width;
|
||||||
mRenderTarget.Height = height;
|
mRenderTarget.Height = height;
|
||||||
|
mRenderTarget.Format = format;
|
||||||
mRenderTarget.Samples = samples;
|
mRenderTarget.Samples = samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +566,7 @@ void VkRenderState::BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuf
|
||||||
if (key.DrawBuffers > 2)
|
if (key.DrawBuffers > 2)
|
||||||
builder.addAttachment(buffers->SceneNormalView.get());
|
builder.addAttachment(buffers->SceneNormalView.get());
|
||||||
if (key.UsesDepthStencil())
|
if (key.UsesDepthStencil())
|
||||||
builder.addAttachment(buffers->SceneDepthStencilView.get());
|
builder.addAttachment(mRenderTarget.Format == VK_FORMAT_R8G8B8A8_UNORM ? buffers->CamtexDepthStencilView.get() : buffers->SceneDepthStencilView.get());
|
||||||
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
void EnableDrawBuffers(int count) override;
|
void EnableDrawBuffers(int count) override;
|
||||||
|
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
void SetRenderTarget(VulkanImageView *view, int width, int height, VkSampleCountFlagBits samples);
|
void SetRenderTarget(VulkanImageView *view, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||||
void Bind(int bindingpoint, uint32_t offset);
|
void Bind(int bindingpoint, uint32_t offset);
|
||||||
void EndRenderPass();
|
void EndRenderPass();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
|
@ -114,6 +114,7 @@ protected:
|
||||||
VulkanImageView *View = nullptr;
|
VulkanImageView *View = nullptr;
|
||||||
int Width = 0;
|
int Width = 0;
|
||||||
int Height = 0;
|
int Height = 0;
|
||||||
|
VkFormat Format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
|
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
int DrawBuffers = 1;
|
int DrawBuffers = 1;
|
||||||
} mRenderTarget;
|
} mRenderTarget;
|
||||||
|
|
|
@ -442,7 +442,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
||||||
|
|
||||||
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
||||||
{
|
{
|
||||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), GetBuffers()->GetSceneSamples());
|
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||||
bool useSSAO = (gl_ssao != 0);
|
bool useSSAO = (gl_ssao != 0);
|
||||||
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
||||||
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
||||||
|
@ -513,7 +513,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
||||||
barrier0.addImage(image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
barrier0.addImage(image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||||
barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||||
|
|
||||||
mRenderState->SetRenderTarget(view, image->width, image->height, VK_SAMPLE_COUNT_1_BIT);
|
mRenderState->SetRenderTarget(view, image->width, image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||||
|
|
||||||
IntRect bounds;
|
IntRect bounds;
|
||||||
bounds.left = bounds.top = 0;
|
bounds.left = bounds.top = 0;
|
||||||
|
@ -529,7 +529,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
||||||
barrier1.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
barrier1.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||||
barrier1.execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
barrier1.execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), GetBuffers()->GetSceneSamples());
|
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||||
|
|
||||||
tex->SetUpdated(true);
|
tex->SetUpdated(true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue