mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- centralize how image transitions are done in the vulkan backend
This commit is contained in:
parent
99f58855ad
commit
9ab19d057d
12 changed files with 385 additions and 420 deletions
|
@ -918,6 +918,7 @@ set (VULKAN_SOURCES
|
|||
rendering/vulkan/shaders/vk_shader.cpp
|
||||
rendering/vulkan/textures/vk_samplers.cpp
|
||||
rendering/vulkan/textures/vk_hwtexture.cpp
|
||||
rendering/vulkan/textures/vk_imagetransition.cpp
|
||||
rendering/vulkan/thirdparty/volk/volk.c
|
||||
rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "vulkan/system/vk_buffers.h"
|
||||
#include "vulkan/system/vk_swapchain.h"
|
||||
#include "vulkan/renderer/vk_renderstate.h"
|
||||
#include "vulkan/textures/vk_imagetransition.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess_cvars.h"
|
||||
|
@ -30,11 +31,11 @@ void VkPostprocess::SetActiveRenderTarget()
|
|||
auto fb = GetVulkanFrameBuffer();
|
||||
auto buffers = fb->GetBuffers();
|
||||
|
||||
VkPPImageTransition imageTransition;
|
||||
imageTransition.addImage(buffers->PipelineImage[mCurrentPipelineImage].get(), &buffers->PipelineLayout[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
fb->GetRenderState()->SetRenderTarget(buffers->PipelineView[mCurrentPipelineImage].get(), nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
fb->GetRenderState()->SetRenderTarget(buffers->PipelineImage[mCurrentPipelineImage].View.get(), nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
}
|
||||
|
||||
void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
|
@ -70,14 +71,14 @@ void VkPostprocess::BlitSceneToPostprocess()
|
|||
|
||||
mCurrentPipelineImage = 0;
|
||||
|
||||
VkPPImageTransition imageTransition0;
|
||||
imageTransition0.addImage(buffers->SceneColor.get(), &buffers->SceneColorLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false);
|
||||
imageTransition0.addImage(buffers->PipelineImage[mCurrentPipelineImage].get(), &buffers->PipelineLayout[mCurrentPipelineImage], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
imageTransition0.execute(fb->GetDrawCommands());
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false);
|
||||
imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
if (buffers->GetSceneSamples() != VK_SAMPLE_COUNT_1_BIT)
|
||||
{
|
||||
auto sceneColor = buffers->SceneColor.get();
|
||||
auto sceneColor = buffers->SceneColor.Image.get();
|
||||
VkImageResolve resolve = {};
|
||||
resolve.srcOffset = { 0, 0, 0 };
|
||||
resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -92,12 +93,12 @@ void VkPostprocess::BlitSceneToPostprocess()
|
|||
resolve.extent = { (uint32_t)sceneColor->width, (uint32_t)sceneColor->height, 1 };
|
||||
cmdbuffer->resolveImage(
|
||||
sceneColor->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
buffers->PipelineImage[mCurrentPipelineImage]->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
buffers->PipelineImage[mCurrentPipelineImage].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &resolve);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto sceneColor = buffers->SceneColor.get();
|
||||
auto sceneColor = buffers->SceneColor.Image.get();
|
||||
VkImageBlit blit = {};
|
||||
blit.srcOffsets[0] = { 0, 0, 0 };
|
||||
blit.srcOffsets[1] = { sceneColor->width, sceneColor->height, 1 };
|
||||
|
@ -113,7 +114,7 @@ void VkPostprocess::BlitSceneToPostprocess()
|
|||
blit.dstSubresource.layerCount = 1;
|
||||
cmdbuffer->blitImage(
|
||||
sceneColor->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
buffers->PipelineImage[mCurrentPipelineImage]->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
buffers->PipelineImage[mCurrentPipelineImage].Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &blit, VK_FILTER_NEAREST);
|
||||
}
|
||||
}
|
||||
|
@ -123,51 +124,48 @@ void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
|
|||
auto fb = GetVulkanFrameBuffer();
|
||||
auto buffers = fb->GetBuffers();
|
||||
|
||||
VkPPImageTransition imageTransition;
|
||||
imageTransition.addImage(buffers->SceneColor.get(), &buffers->SceneColorLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.addImage(buffers->SceneFog.get(), &buffers->SceneFogLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.addImage(buffers->SceneNormal.get(), &buffers->SceneNormalLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.addImage(buffers->SceneDepthStencil.get(), &buffers->SceneDepthStencilLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.addImage(&buffers->SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.addImage(&buffers->SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.addImage(&buffers->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
}
|
||||
|
||||
void VkPostprocess::BlitCurrentToImage(VulkanImage *dstimage, VkImageLayout *dstlayout, VkImageLayout finallayout)
|
||||
void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
fb->GetRenderState()->EndRenderPass();
|
||||
|
||||
auto srcimage = fb->GetBuffers()->PipelineImage[mCurrentPipelineImage].get();
|
||||
auto srclayout = &fb->GetBuffers()->PipelineLayout[mCurrentPipelineImage];
|
||||
auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage];
|
||||
auto cmdbuffer = fb->GetDrawCommands();
|
||||
|
||||
*dstlayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; // needed by VkPPImageTransition.addImage. Actual layout is undefined.
|
||||
|
||||
VkPPImageTransition imageTransition0;
|
||||
imageTransition0.addImage(srcimage, srclayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false);
|
||||
imageTransition0.addImage(dstimage, dstlayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
VkImageTransition imageTransition0;
|
||||
imageTransition0.addImage(srcimage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false);
|
||||
imageTransition0.addImage(dstimage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
imageTransition0.execute(cmdbuffer);
|
||||
|
||||
VkImageBlit blit = {};
|
||||
blit.srcOffsets[0] = { 0, 0, 0 };
|
||||
blit.srcOffsets[1] = { srcimage->width, srcimage->height, 1 };
|
||||
blit.srcOffsets[1] = { srcimage->Image->width, srcimage->Image->height, 1 };
|
||||
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.srcSubresource.mipLevel = 0;
|
||||
blit.srcSubresource.baseArrayLayer = 0;
|
||||
blit.srcSubresource.layerCount = 1;
|
||||
blit.dstOffsets[0] = { 0, 0, 0 };
|
||||
blit.dstOffsets[1] = { dstimage->width, dstimage->height, 1 };
|
||||
blit.dstOffsets[1] = { dstimage->Image->width, dstimage->Image->height, 1 };
|
||||
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.dstSubresource.mipLevel = 0;
|
||||
blit.dstSubresource.baseArrayLayer = 0;
|
||||
blit.dstSubresource.layerCount = 1;
|
||||
cmdbuffer->blitImage(
|
||||
srcimage->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dstimage->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
srcimage->Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dstimage->Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, &blit, VK_FILTER_NEAREST);
|
||||
|
||||
VkPPImageTransition imageTransition1;
|
||||
imageTransition1.addImage(dstimage, dstlayout, finallayout, false);
|
||||
VkImageTransition imageTransition1;
|
||||
imageTransition1.addImage(dstimage, finallayout, false);
|
||||
imageTransition1.execute(cmdbuffer);
|
||||
}
|
||||
|
||||
|
@ -179,7 +177,7 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool
|
|||
hw_postprocess.customShaders.Run(&renderstate, "screen");
|
||||
|
||||
PresentUniforms uniforms;
|
||||
if (!applyGamma /*|| framebuffer->IsHWGammaActive()*/)
|
||||
if (!applyGamma)
|
||||
{
|
||||
uniforms.InvGamma = 1.0f;
|
||||
uniforms.Contrast = 1.0f;
|
||||
|
@ -263,8 +261,8 @@ void VkPostprocess::UpdateShadowMap()
|
|||
auto fb = GetVulkanFrameBuffer();
|
||||
auto buffers = fb->GetBuffers();
|
||||
|
||||
VkPPImageTransition imageTransition;
|
||||
imageTransition.addImage(buffers->Shadowmap.get(), &buffers->ShadowmapLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&buffers->Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
screen->mShadowMap.FinishUpdate();
|
||||
|
@ -345,14 +343,14 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
if (!imgbuilder.isFormatSupported(fb->device))
|
||||
I_FatalError("Vulkan device does not support the image format required by a postprocess texture\n");
|
||||
Image = imgbuilder.create(fb->device);
|
||||
Image->SetDebugName("VkPPTexture");
|
||||
TexImage.Image = imgbuilder.create(fb->device);
|
||||
TexImage.Image->SetDebugName("VkPPTexture");
|
||||
Format = format;
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(Image.get(), format);
|
||||
View = viewbuilder.create(fb->device);
|
||||
View->SetDebugName("VkPPTextureView");
|
||||
viewbuilder.setImage(TexImage.Image.get(), format);
|
||||
TexImage.View = viewbuilder.create(fb->device);
|
||||
TexImage.View->SetDebugName("VkPPTextureView");
|
||||
|
||||
if (texture->Data)
|
||||
{
|
||||
|
@ -363,9 +361,9 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
Staging = stagingbuilder.create(fb->device);
|
||||
Staging->SetDebugName("VkPPTextureStaging");
|
||||
|
||||
PipelineBarrier barrier0;
|
||||
barrier0.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
barrier0.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
VkImageTransition barrier0;
|
||||
barrier0.addImage(&TexImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
barrier0.execute(fb->GetTransferCommands());
|
||||
|
||||
void *data = Staging->Map(0, totalsize);
|
||||
memcpy(data, texture->Data.get(), totalsize);
|
||||
|
@ -377,19 +375,17 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = texture->Width;
|
||||
region.imageExtent.height = texture->Height;
|
||||
fb->GetTransferCommands()->copyBufferToImage(Staging->buffer, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
fb->GetTransferCommands()->copyBufferToImage(Staging->buffer, TexImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
PipelineBarrier barrier1;
|
||||
barrier1.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
barrier1.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
Layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
VkImageTransition barrier1;
|
||||
barrier1.addImage(&TexImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
barrier1.execute(fb->GetTransferCommands());
|
||||
}
|
||||
else
|
||||
{
|
||||
PipelineBarrier barrier;
|
||||
barrier.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
|
||||
barrier.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
Layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkImageTransition barrier;
|
||||
barrier.addImage(&TexImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier.execute(fb->GetTransferCommands());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -542,16 +538,16 @@ VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, c
|
|||
descriptors->SetDebugName("VkPostprocess.descriptors");
|
||||
|
||||
WriteDescriptors write;
|
||||
VkPPImageTransition imageTransition;
|
||||
VkImageTransition imageTransition;
|
||||
|
||||
for (unsigned int index = 0; index < textures.Size(); index++)
|
||||
{
|
||||
const PPTextureInput &input = textures[index];
|
||||
VulkanSampler *sampler = pp->GetSampler(input.Filter, input.Wrap);
|
||||
TextureImage tex = GetTexture(input.Type, input.Texture);
|
||||
VkTextureImage *tex = GetTexture(input.Type, input.Texture);
|
||||
|
||||
write.addCombinedImageSampler(descriptors.get(), index, tex.view, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
imageTransition.addImage(tex.image, tex.layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
write.addCombinedImageSampler(descriptors.get(), index, tex->DepthOnlyView ? tex->DepthOnlyView.get() : tex->View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
imageTransition.addImage(tex, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
}
|
||||
|
||||
if (bindShadowMapBuffers)
|
||||
|
@ -573,21 +569,21 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
TextureImage tex = GetTexture(output.Type, output.Texture);
|
||||
VkTextureImage *tex = GetTexture(output.Type, output.Texture);
|
||||
|
||||
VkImageView view;
|
||||
int w, h;
|
||||
if (tex.view)
|
||||
if (tex)
|
||||
{
|
||||
VkPPImageTransition imageTransition;
|
||||
imageTransition.addImage(tex.image, tex.layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(tex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture);
|
||||
if (stencilTest)
|
||||
imageTransition.addImage(fb->GetBuffers()->SceneDepthStencil.get(), &fb->GetBuffers()->SceneDepthStencilLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
|
||||
imageTransition.addImage(&fb->GetBuffers()->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
view = tex.view->view;
|
||||
w = tex.image->width;
|
||||
h = tex.image->height;
|
||||
view = tex->View->view;
|
||||
w = tex->Image->width;
|
||||
h = tex->Image->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -604,9 +600,8 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
builder.setSize(w, h);
|
||||
builder.addAttachment(view);
|
||||
if (stencilTest)
|
||||
builder.addAttachment(fb->GetBuffers()->SceneDepthStencilView.get());
|
||||
builder.addAttachment(fb->GetBuffers()->SceneDepthStencil.View.get());
|
||||
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
||||
framebuffer->SetDebugName(tex.debugname);
|
||||
}
|
||||
|
||||
framebufferWidth = w;
|
||||
|
@ -614,10 +609,9 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
return framebuffer.get();
|
||||
}
|
||||
|
||||
VkPPRenderState::TextureImage VkPPRenderState::GetTexture(const PPTextureType &type, PPTexture *pptexture)
|
||||
VkTextureImage *VkPPRenderState::GetTexture(const PPTextureType &type, PPTexture *pptexture)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
TextureImage tex = {};
|
||||
|
||||
if (type == PPTextureType::CurrentPipelineTexture || type == PPTextureType::NextPipelineTexture)
|
||||
{
|
||||
|
@ -625,67 +619,42 @@ VkPPRenderState::TextureImage VkPPRenderState::GetTexture(const PPTextureType &t
|
|||
if (type == PPTextureType::NextPipelineTexture)
|
||||
idx = (idx + 1) % VkRenderBuffers::NumPipelineImages;
|
||||
|
||||
tex.image = fb->GetBuffers()->PipelineImage[idx].get();
|
||||
tex.view = fb->GetBuffers()->PipelineView[idx].get();
|
||||
tex.layout = &fb->GetBuffers()->PipelineLayout[idx];
|
||||
tex.debugname = "PipelineTexture";
|
||||
return &fb->GetBuffers()->PipelineImage[idx];
|
||||
}
|
||||
else if (type == PPTextureType::PPTexture)
|
||||
{
|
||||
auto vktex = GetVkTexture(pptexture);
|
||||
tex.image = vktex->Image.get();
|
||||
tex.view = vktex->View.get();
|
||||
tex.layout = &vktex->Layout;
|
||||
tex.debugname = "PPTexture";
|
||||
return &vktex->TexImage;
|
||||
}
|
||||
else if (type == PPTextureType::SceneColor)
|
||||
{
|
||||
tex.image = fb->GetBuffers()->SceneColor.get();
|
||||
tex.view = fb->GetBuffers()->SceneColorView.get();
|
||||
tex.layout = &fb->GetBuffers()->SceneColorLayout;
|
||||
tex.debugname = "SceneColor";
|
||||
return &fb->GetBuffers()->SceneColor;
|
||||
}
|
||||
else if (type == PPTextureType::SceneNormal)
|
||||
{
|
||||
tex.image = fb->GetBuffers()->SceneNormal.get();
|
||||
tex.view = fb->GetBuffers()->SceneNormalView.get();
|
||||
tex.layout = &fb->GetBuffers()->SceneNormalLayout;
|
||||
tex.debugname = "SceneNormal";
|
||||
return &fb->GetBuffers()->SceneNormal;
|
||||
}
|
||||
else if (type == PPTextureType::SceneFog)
|
||||
{
|
||||
tex.image = fb->GetBuffers()->SceneFog.get();
|
||||
tex.view = fb->GetBuffers()->SceneFogView.get();
|
||||
tex.layout = &fb->GetBuffers()->SceneFogLayout;
|
||||
tex.debugname = "SceneFog";
|
||||
return &fb->GetBuffers()->SceneFog;
|
||||
}
|
||||
else if (type == PPTextureType::SceneDepth)
|
||||
{
|
||||
tex.image = fb->GetBuffers()->SceneDepthStencil.get();
|
||||
tex.view = fb->GetBuffers()->SceneDepthView.get();
|
||||
tex.layout = &fb->GetBuffers()->SceneDepthStencilLayout;
|
||||
tex.debugname = "SceneDepth";
|
||||
return &fb->GetBuffers()->SceneDepthStencil;
|
||||
}
|
||||
else if (type == PPTextureType::ShadowMap)
|
||||
{
|
||||
tex.image = fb->GetBuffers()->Shadowmap.get();
|
||||
tex.view = fb->GetBuffers()->ShadowmapView.get();
|
||||
tex.layout = &fb->GetBuffers()->ShadowmapLayout;
|
||||
tex.debugname = "Shadowmap";
|
||||
return &fb->GetBuffers()->Shadowmap;
|
||||
}
|
||||
else if (type == PPTextureType::SwapChain)
|
||||
{
|
||||
tex.image = nullptr;
|
||||
tex.view = nullptr;
|
||||
tex.layout = nullptr;
|
||||
tex.debugname = "SwapChain";
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_FatalError("VkPPRenderState::GetTexture not implemented yet for this texture type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
VkPPShader *VkPPRenderState::GetVkShader(PPShader *shader)
|
||||
|
@ -805,79 +774,3 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey &key)
|
|||
RenderPass = builder.create(GetVulkanFrameBuffer()->device);
|
||||
RenderPass->SetDebugName("VkPPRenderPassSetup.RenderPass");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VkPPImageTransition::addImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout targetLayout, bool undefinedSrcLayout)
|
||||
{
|
||||
if (*layout == targetLayout)
|
||||
return;
|
||||
|
||||
VkAccessFlags srcAccess = 0;
|
||||
VkAccessFlags dstAccess = 0;
|
||||
VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
switch (*layout)
|
||||
{
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_SHADER_READ_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
break;
|
||||
default:
|
||||
I_FatalError("Unimplemented src image layout transition\n");
|
||||
}
|
||||
|
||||
switch (targetLayout)
|
||||
{
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_SHADER_READ_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
break;
|
||||
default:
|
||||
I_FatalError("Unimplemented dst image layout transition\n");
|
||||
}
|
||||
|
||||
barrier.addImage(image, undefinedSrcLayout ? VK_IMAGE_LAYOUT_UNDEFINED : *layout, targetLayout, srcAccess, dstAccess, aspectMask);
|
||||
needbarrier = true;
|
||||
*layout = targetLayout;
|
||||
}
|
||||
|
||||
void VkPPImageTransition::execute(VulkanCommandBuffer *cmdbuffer)
|
||||
{
|
||||
if (needbarrier)
|
||||
barrier.execute(cmdbuffer, srcStageMask, dstStageMask);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
#include "vulkan/system/vk_objects.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
#include "vulkan/textures/vk_imagetransition.h"
|
||||
|
||||
class FString;
|
||||
|
||||
|
@ -34,19 +35,6 @@ public:
|
|||
bool operator!=(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) != 0; }
|
||||
};
|
||||
|
||||
class VkPPImageTransition
|
||||
{
|
||||
public:
|
||||
void addImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout targetLayout, bool undefinedSrcLayout);
|
||||
void execute(VulkanCommandBuffer *cmdbuffer);
|
||||
|
||||
private:
|
||||
PipelineBarrier barrier;
|
||||
VkPipelineStageFlags srcStageMask = 0;
|
||||
VkPipelineStageFlags dstStageMask = 0;
|
||||
bool needbarrier = false;
|
||||
};
|
||||
|
||||
class VkPostprocess
|
||||
{
|
||||
public:
|
||||
|
@ -67,7 +55,7 @@ public:
|
|||
void ImageTransitionScene(bool undefinedSrcLayout);
|
||||
|
||||
void BlitSceneToPostprocess();
|
||||
void BlitCurrentToImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
void BlitCurrentToImage(VkTextureImage *image, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders);
|
||||
|
||||
private:
|
||||
|
@ -101,10 +89,8 @@ class VkPPTexture : public PPTextureBackend
|
|||
public:
|
||||
VkPPTexture(PPTexture *texture);
|
||||
|
||||
std::unique_ptr<VulkanImage> Image;
|
||||
std::unique_ptr<VulkanImageView> View;
|
||||
VkTextureImage TexImage;
|
||||
std::unique_ptr<VulkanBuffer> Staging;
|
||||
VkImageLayout Layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkFormat Format;
|
||||
};
|
||||
|
||||
|
@ -143,12 +129,5 @@ private:
|
|||
VkPPShader *GetVkShader(PPShader *shader);
|
||||
VkPPTexture *GetVkTexture(PPTexture *texture);
|
||||
|
||||
struct TextureImage
|
||||
{
|
||||
VulkanImage *image;
|
||||
VulkanImageView *view;
|
||||
VkImageLayout *layout;
|
||||
const char *debugname;
|
||||
};
|
||||
TextureImage GetTexture(const PPTextureType &type, PPTexture *tex);
|
||||
VkTextureImage *GetTexture(const PPTextureType &type, PPTexture *tex);
|
||||
};
|
||||
|
|
|
@ -71,39 +71,32 @@ void VkRenderBuffers::CreatePipeline(int width, int height)
|
|||
for (int i = 0; i < NumPipelineImages; i++)
|
||||
{
|
||||
PipelineImage[i].reset();
|
||||
PipelineView[i].reset();
|
||||
}
|
||||
|
||||
PipelineBarrier barrier;
|
||||
VkImageTransition barrier;
|
||||
for (int i = 0; i < NumPipelineImages; i++)
|
||||
{
|
||||
ImageBuilder builder;
|
||||
builder.setSize(width, height);
|
||||
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
PipelineImage[i] = builder.create(fb->device);
|
||||
PipelineImage[i]->SetDebugName("VkRenderBuffers.PipelineImage");
|
||||
PipelineImage[i].Image = builder.create(fb->device);
|
||||
PipelineImage[i].Image->SetDebugName("VkRenderBuffers.PipelineImage");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(PipelineImage[i].get(), VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
PipelineView[i] = viewbuilder.create(fb->device);
|
||||
PipelineView[i]->SetDebugName("VkRenderBuffers.PipelineView");
|
||||
viewbuilder.setImage(PipelineImage[i].Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
PipelineImage[i].View = viewbuilder.create(fb->device);
|
||||
PipelineImage[i].View->SetDebugName("VkRenderBuffers.PipelineView");
|
||||
|
||||
barrier.addImage(PipelineImage[i].get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
PipelineLayout[i] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
barrier.addImage(&PipelineImage[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
}
|
||||
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||
barrier.execute(fb->GetDrawCommands());
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits samples)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
SceneColorView.reset();
|
||||
SceneDepthStencilView.reset();
|
||||
SceneDepthView.reset();
|
||||
SceneNormalView.reset();
|
||||
SceneFogView.reset();
|
||||
SceneColor.reset();
|
||||
SceneDepthStencil.reset();
|
||||
SceneNormal.reset();
|
||||
|
@ -114,14 +107,12 @@ void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits s
|
|||
CreateSceneNormal(width, height, samples);
|
||||
CreateSceneFog(width, height, samples);
|
||||
|
||||
PipelineBarrier barrier;
|
||||
barrier.addImage(SceneColor.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
barrier.addImage(SceneDepthStencil.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.addImage(SceneNormal.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
barrier.addImage(SceneFog.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||
|
||||
SceneColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkImageTransition barrier;
|
||||
barrier.addImage(&SceneColor, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier.addImage(&SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true);
|
||||
barrier.addImage(&SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier.addImage(&SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier.execute(fb->GetDrawCommands());
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagBits samples)
|
||||
|
@ -133,13 +124,13 @@ void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagB
|
|||
builder.setSamples(samples);
|
||||
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
||||
SceneColor = builder.create(fb->device);
|
||||
SceneColor->SetDebugName("VkRenderBuffers.SceneColor");
|
||||
SceneColor.Image = builder.create(fb->device);
|
||||
SceneColor.Image->SetDebugName("VkRenderBuffers.SceneColor");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(SceneColor.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
SceneColorView = viewbuilder.create(fb->device);
|
||||
SceneColorView->SetDebugName("VkRenderBuffers.SceneColorView");
|
||||
viewbuilder.setImage(SceneColor.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
SceneColor.View = viewbuilder.create(fb->device);
|
||||
SceneColor.View->SetDebugName("VkRenderBuffers.SceneColorView");
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples)
|
||||
|
@ -160,17 +151,18 @@ void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCou
|
|||
I_FatalError("This device does not support any of the required depth stencil image formats.");
|
||||
}
|
||||
}
|
||||
SceneDepthStencil = builder.create(fb->device);
|
||||
SceneDepthStencil->SetDebugName("VkRenderBuffers.SceneDepthStencil");
|
||||
SceneDepthStencil.Image = builder.create(fb->device);
|
||||
SceneDepthStencil.Image->SetDebugName("VkRenderBuffers.SceneDepthStencil");
|
||||
SceneDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(SceneDepthStencil.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
SceneDepthStencilView = viewbuilder.create(fb->device);
|
||||
SceneDepthStencilView->SetDebugName("VkRenderBuffers.SceneDepthStencilView");
|
||||
viewbuilder.setImage(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
SceneDepthStencil.View = viewbuilder.create(fb->device);
|
||||
SceneDepthStencil.View->SetDebugName("VkRenderBuffers.SceneDepthStencilView");
|
||||
|
||||
viewbuilder.setImage(SceneDepthStencil.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
SceneDepthView = viewbuilder.create(fb->device);
|
||||
SceneDepthView->SetDebugName("VkRenderBuffers.SceneDepthView");
|
||||
viewbuilder.setImage(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
SceneDepthStencil.DepthOnlyView = viewbuilder.create(fb->device);
|
||||
SceneDepthStencil.DepthOnlyView->SetDebugName("VkRenderBuffers.SceneDepthView");
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateSceneFog(int width, int height, VkSampleCountFlagBits samples)
|
||||
|
@ -182,13 +174,13 @@ void VkRenderBuffers::CreateSceneFog(int width, int height, VkSampleCountFlagBit
|
|||
builder.setSamples(samples);
|
||||
builder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
|
||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
SceneFog = builder.create(fb->device);
|
||||
SceneFog->SetDebugName("VkRenderBuffers.SceneFog");
|
||||
SceneFog.Image = builder.create(fb->device);
|
||||
SceneFog.Image->SetDebugName("VkRenderBuffers.SceneFog");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(SceneFog.get(), VK_FORMAT_R8G8B8A8_UNORM);
|
||||
SceneFogView = viewbuilder.create(fb->device);
|
||||
SceneFogView->SetDebugName("VkRenderBuffers.SceneFogView");
|
||||
viewbuilder.setImage(SceneFog.Image.get(), VK_FORMAT_R8G8B8A8_UNORM);
|
||||
SceneFog.View = viewbuilder.create(fb->device);
|
||||
SceneFog.View->SetDebugName("VkRenderBuffers.SceneFogView");
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples)
|
||||
|
@ -200,22 +192,21 @@ void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlag
|
|||
builder.setSamples(samples);
|
||||
builder.setFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32);
|
||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
SceneNormal = builder.create(fb->device);
|
||||
SceneNormal->SetDebugName("VkRenderBuffers.SceneNormal");
|
||||
SceneNormal.Image = builder.create(fb->device);
|
||||
SceneNormal.Image->SetDebugName("VkRenderBuffers.SceneNormal");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(SceneNormal.get(), VK_FORMAT_A2R10G10B10_UNORM_PACK32);
|
||||
SceneNormalView = viewbuilder.create(fb->device);
|
||||
SceneNormalView->SetDebugName("VkRenderBuffers.SceneNormalView");
|
||||
viewbuilder.setImage(SceneNormal.Image.get(), VK_FORMAT_A2R10G10B10_UNORM_PACK32);
|
||||
SceneNormal.View = viewbuilder.create(fb->device);
|
||||
SceneNormal.View->SetDebugName("VkRenderBuffers.SceneNormalView");
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateShadowmap()
|
||||
{
|
||||
if (Shadowmap && Shadowmap->width == gl_shadowmap_quality)
|
||||
if (Shadowmap.Image && Shadowmap.Image->width == gl_shadowmap_quality)
|
||||
return;
|
||||
|
||||
Shadowmap.reset();
|
||||
ShadowmapView.reset();
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
|
@ -223,17 +214,17 @@ void VkRenderBuffers::CreateShadowmap()
|
|||
builder.setSize(gl_shadowmap_quality, 1024);
|
||||
builder.setFormat(VK_FORMAT_R32_SFLOAT);
|
||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
Shadowmap = builder.create(fb->device);
|
||||
Shadowmap->SetDebugName("VkRenderBuffers.Shadowmap");
|
||||
Shadowmap.Image = builder.create(fb->device);
|
||||
Shadowmap.Image->SetDebugName("VkRenderBuffers.Shadowmap");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(Shadowmap.get(), VK_FORMAT_R32_SFLOAT);
|
||||
ShadowmapView = viewbuilder.create(fb->device);
|
||||
ShadowmapView->SetDebugName("VkRenderBuffers.ShadowmapView");
|
||||
viewbuilder.setImage(Shadowmap.Image.get(), VK_FORMAT_R32_SFLOAT);
|
||||
Shadowmap.View = viewbuilder.create(fb->device);
|
||||
Shadowmap.View->SetDebugName("VkRenderBuffers.ShadowmapView");
|
||||
|
||||
PipelineBarrier barrier;
|
||||
barrier.addImage(Shadowmap.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
VkImageTransition barrier;
|
||||
barrier.addImage(&Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true);
|
||||
barrier.execute(fb->GetDrawCommands());
|
||||
|
||||
if (!ShadowmapSampler)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "vulkan/system/vk_objects.h"
|
||||
#include "vulkan/textures/vk_imagetransition.h"
|
||||
|
||||
class VkRenderBuffers
|
||||
{
|
||||
|
@ -17,30 +18,18 @@ public:
|
|||
int GetSceneHeight() const { return mSceneHeight; }
|
||||
VkSampleCountFlagBits GetSceneSamples() const { return mSamples; }
|
||||
|
||||
std::unique_ptr<VulkanImage> SceneColor;
|
||||
std::unique_ptr<VulkanImage> SceneDepthStencil;
|
||||
std::unique_ptr<VulkanImage> SceneNormal;
|
||||
std::unique_ptr<VulkanImage> SceneFog;
|
||||
std::unique_ptr<VulkanImageView> SceneColorView;
|
||||
std::unique_ptr<VulkanImageView> SceneDepthStencilView;
|
||||
std::unique_ptr<VulkanImageView> SceneDepthView;
|
||||
std::unique_ptr<VulkanImageView> SceneNormalView;
|
||||
std::unique_ptr<VulkanImageView> SceneFogView;
|
||||
VkTextureImage SceneColor;
|
||||
VkTextureImage SceneDepthStencil;
|
||||
VkTextureImage SceneNormal;
|
||||
VkTextureImage SceneFog;
|
||||
|
||||
VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
VkImageLayout SceneColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkImageLayout SceneDepthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
VkImageLayout SceneNormalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
VkImageLayout SceneFogLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
static const int NumPipelineImages = 2;
|
||||
std::unique_ptr<VulkanImage> PipelineImage[NumPipelineImages];
|
||||
std::unique_ptr<VulkanImageView> PipelineView[NumPipelineImages];
|
||||
VkImageLayout PipelineLayout[NumPipelineImages] = { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
|
||||
VkTextureImage PipelineImage[NumPipelineImages];
|
||||
|
||||
std::unique_ptr<VulkanImage> Shadowmap;
|
||||
std::unique_ptr<VulkanImageView> ShadowmapView;
|
||||
VkTextureImage Shadowmap;
|
||||
std::unique_ptr<VulkanSampler> ShadowmapSampler;
|
||||
VkImageLayout ShadowmapLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
private:
|
||||
void CreatePipeline(int width, int height);
|
||||
|
|
|
@ -175,7 +175,7 @@ void VkRenderPassManager::UpdateDynamicSet()
|
|||
update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightBufferSSO->mBuffer.get());
|
||||
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatricesUBO->mBuffer.get(), 0, sizeof(MatricesUBO));
|
||||
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamUBO->mBuffer.get(), 0, sizeof(StreamUBO));
|
||||
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->ShadowmapView.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->Shadowmap.View.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.updateSets(fb->device);
|
||||
}
|
||||
|
||||
|
|
|
@ -568,9 +568,9 @@ void VkRenderState::BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuf
|
|||
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
||||
builder.addAttachment(mRenderTarget.View);
|
||||
if (key.DrawBuffers > 1)
|
||||
builder.addAttachment(buffers->SceneFogView.get());
|
||||
builder.addAttachment(buffers->SceneFog.View.get());
|
||||
if (key.DrawBuffers > 2)
|
||||
builder.addAttachment(buffers->SceneNormalView.get());
|
||||
builder.addAttachment(buffers->SceneNormal.View.get());
|
||||
if (key.UsesDepthStencil())
|
||||
builder.addAttachment(mRenderTarget.DepthStencil);
|
||||
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
||||
|
|
|
@ -444,7 +444,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
|||
|
||||
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
||||
{
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->SceneDepthStencilView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
bool useSSAO = (gl_ssao != 0);
|
||||
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
||||
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
||||
|
@ -505,33 +505,32 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
|
||||
int width = mat->TextureWidth();
|
||||
int height = mat->TextureHeight();
|
||||
VulkanImage *image = BaseLayer->GetImage(tex, 0, 0);
|
||||
VulkanImageView *view = BaseLayer->GetImageView(tex, 0, 0);
|
||||
VulkanImageView *depthStencilView = BaseLayer->GetDepthStencilView(tex);
|
||||
VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0);
|
||||
VkTextureImage *depthStencil = BaseLayer->GetDepthStencil(tex);
|
||||
|
||||
mRenderState->EndRenderPass();
|
||||
|
||||
PipelineBarrier barrier0;
|
||||
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(GetDrawCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
VkImageTransition barrier0;
|
||||
barrier0.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier0.execute(GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(view, depthStencilView, image->width, image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
mRenderState->SetRenderTarget(image->View.get(), depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
bounds.width = MIN(mat->GetWidth(), image->width);
|
||||
bounds.height = MIN(mat->GetHeight(), image->height);
|
||||
bounds.width = MIN(mat->GetWidth(), image->Image->width);
|
||||
bounds.height = MIN(mat->GetHeight(), image->Image->height);
|
||||
|
||||
FRenderViewpoint texvp;
|
||||
RenderViewpoint(texvp, Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
|
||||
|
||||
mRenderState->EndRenderPass();
|
||||
|
||||
PipelineBarrier barrier1;
|
||||
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(GetDrawCommands(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
VkImageTransition barrier1;
|
||||
barrier1.addImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
barrier1.execute(GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->SceneDepthStencilView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
|
||||
tex->SetUpdated(true);
|
||||
}
|
||||
|
@ -736,14 +735,15 @@ FTexture *VulkanFrameBuffer::WipeEndScreen()
|
|||
|
||||
void VulkanFrameBuffer::CopyScreenToBuffer(int w, int h, void *data)
|
||||
{
|
||||
VkTextureImage image;
|
||||
|
||||
// Convert from rgba16f to rgba8 using the GPU:
|
||||
ImageBuilder imgbuilder;
|
||||
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
|
||||
imgbuilder.setUsage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
imgbuilder.setSize(w, h);
|
||||
auto image = imgbuilder.create(device);
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
GetPostprocess()->BlitCurrentToImage(image.get(), &layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
image.Image = imgbuilder.create(device);
|
||||
GetPostprocess()->BlitCurrentToImage(&image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
|
||||
// Staging buffer for download
|
||||
BufferBuilder bufbuilder;
|
||||
|
@ -758,7 +758,7 @@ void VulkanFrameBuffer::CopyScreenToBuffer(int w, int h, void *data)
|
|||
region.imageExtent.depth = 1;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
GetDrawCommands()->copyImageToBuffer(image->image, layout, staging->buffer, 1, ®ion);
|
||||
GetDrawCommands()->copyImageToBuffer(image.Image->image, image.Layout, staging->buffer, 1, ®ion);
|
||||
|
||||
// Submit command buffers and wait for device to finish the work
|
||||
WaitForCommands(false);
|
||||
|
|
|
@ -70,10 +70,12 @@ void VkHardwareTexture::Reset()
|
|||
ResetDescriptors();
|
||||
|
||||
auto &deleteList = fb->FrameDeleteList;
|
||||
if (mImage) deleteList.Images.push_back(std::move(mImage));
|
||||
if (mImageView) deleteList.ImageViews.push_back(std::move(mImageView));
|
||||
if (mDepthStencil) deleteList.Images.push_back(std::move(mDepthStencil));
|
||||
if (mDepthStencilView) deleteList.ImageViews.push_back(std::move(mDepthStencilView));
|
||||
if (mImage.Image) deleteList.Images.push_back(std::move(mImage.Image));
|
||||
if (mImage.View) deleteList.ImageViews.push_back(std::move(mImage.View));
|
||||
if (mDepthStencil.Image) deleteList.Images.push_back(std::move(mDepthStencil.Image));
|
||||
if (mDepthStencil.View) deleteList.ImageViews.push_back(std::move(mDepthStencil.View));
|
||||
mImage.reset();
|
||||
mDepthStencil.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,12 +107,12 @@ void VkHardwareTexture::ResetAllDescriptors()
|
|||
void VkHardwareTexture::Precache(FMaterial *mat, int translation, int flags)
|
||||
{
|
||||
int numLayers = mat->GetLayers();
|
||||
GetImageView(mat->tex, translation, flags);
|
||||
GetImage(mat->tex, translation, flags);
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
FTexture *layer;
|
||||
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0);
|
||||
systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,42 +146,31 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
|
|||
|
||||
VulkanSampler *sampler = fb->GetSamplerManager()->Get(clampmode);
|
||||
|
||||
auto baseView = GetImageView(tex, translation, flags);
|
||||
|
||||
WriteDescriptors update;
|
||||
update.addCombinedImageSampler(descriptor.get(), 0, baseView, sampler, mImageLayout);
|
||||
update.addCombinedImageSampler(descriptor.get(), 0, GetImage(tex, translation, flags)->View.get(), sampler, mImage.Layout);
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
FTexture *layer;
|
||||
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout);
|
||||
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0)->View.get(), sampler, systex->mImage.Layout);
|
||||
}
|
||||
update.updateSets(fb->device);
|
||||
mDescriptorSets.emplace_back(clampmode, flags, std::move(descriptor));
|
||||
return mDescriptorSets.back().descriptor.get();
|
||||
}
|
||||
|
||||
VulkanImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags)
|
||||
VkTextureImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags)
|
||||
{
|
||||
if (!mImage)
|
||||
if (!mImage.Image)
|
||||
{
|
||||
CreateImage(tex, translation, flags);
|
||||
}
|
||||
return mImage.get();
|
||||
return &mImage;
|
||||
}
|
||||
|
||||
VulkanImageView *VkHardwareTexture::GetImageView(FTexture *tex, int translation, int flags)
|
||||
VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex)
|
||||
{
|
||||
if (!mImageView)
|
||||
{
|
||||
CreateImage(tex, translation, flags);
|
||||
}
|
||||
return mImageView.get();
|
||||
}
|
||||
|
||||
VulkanImageView *VkHardwareTexture::GetDepthStencilView(FTexture *tex)
|
||||
{
|
||||
if (!mDepthStencilView)
|
||||
if (!mDepthStencil.View)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
|
@ -192,19 +183,20 @@ VulkanImageView *VkHardwareTexture::GetDepthStencilView(FTexture *tex)
|
|||
builder.setSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||
builder.setFormat(format);
|
||||
builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
mDepthStencil = builder.create(fb->device);
|
||||
mDepthStencil->SetDebugName("VkHardwareTexture.DepthStencil");
|
||||
mDepthStencil.Image = builder.create(fb->device);
|
||||
mDepthStencil.Image->SetDebugName("VkHardwareTexture.DepthStencil");
|
||||
mDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(mDepthStencil.get(), format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
mDepthStencilView = viewbuilder.create(fb->device);
|
||||
mDepthStencilView->SetDebugName("VkHardwareTexture.DepthStencilView");
|
||||
viewbuilder.setImage(mDepthStencil.Image.get(), format, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
mDepthStencil.View = viewbuilder.create(fb->device);
|
||||
mDepthStencil.View->SetDebugName("VkHardwareTexture.DepthStencilView");
|
||||
|
||||
PipelineBarrier barrier;
|
||||
barrier.addImage(mDepthStencil.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->GetTransferCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||
VkImageTransition barrier;
|
||||
barrier.addImage(&mDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true);
|
||||
barrier.execute(fb->GetTransferCommands());
|
||||
}
|
||||
return mDepthStencilView.get();
|
||||
return &mDepthStencil;
|
||||
}
|
||||
|
||||
void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||
|
@ -236,19 +228,19 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
|||
imgbuilder.setFormat(format);
|
||||
imgbuilder.setSize(w, h);
|
||||
imgbuilder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
mImage = imgbuilder.create(fb->device);
|
||||
mImage->SetDebugName("VkHardwareTexture.mImage");
|
||||
mImage.Image = imgbuilder.create(fb->device);
|
||||
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(mImage.get(), format);
|
||||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||
viewbuilder.setImage(mImage.Image.get(), format);
|
||||
mImage.View = viewbuilder.create(fb->device);
|
||||
mImage.View->SetDebugName("VkHardwareTexture.mImageView");
|
||||
|
||||
auto cmdbuffer = fb->GetTransferCommands();
|
||||
|
||||
PipelineBarrier imageTransition;
|
||||
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||
imageTransition.execute(cmdbuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true);
|
||||
imageTransition.execute(cmdbuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,19 +264,19 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
|
|||
imgbuilder.setFormat(format);
|
||||
imgbuilder.setSize(w, h, GetMipLevels(w, h));
|
||||
imgbuilder.setUsage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
mImage = imgbuilder.create(fb->device);
|
||||
mImage->SetDebugName("VkHardwareTexture.mImage");
|
||||
mImage.Image = imgbuilder.create(fb->device);
|
||||
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(mImage.get(), format);
|
||||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||
viewbuilder.setImage(mImage.Image.get(), format);
|
||||
mImage.View = viewbuilder.create(fb->device);
|
||||
mImage.View->SetDebugName("VkHardwareTexture.mImageView");
|
||||
|
||||
auto cmdbuffer = fb->GetTransferCommands();
|
||||
|
||||
PipelineBarrier imageTransition0;
|
||||
imageTransition0.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
imageTransition0.execute(cmdbuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
imageTransition.execute(cmdbuffer);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -292,54 +284,11 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
|
|||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = w;
|
||||
region.imageExtent.height = h;
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, mImage->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, mImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
fb->FrameDeleteList.Buffers.push_back(std::move(stagingBuffer));
|
||||
|
||||
GenerateMipmaps(mImage.get(), cmdbuffer);
|
||||
}
|
||||
|
||||
void VkHardwareTexture::GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer *cmdbuffer)
|
||||
{
|
||||
int mipWidth = image->width;
|
||||
int mipHeight = image->height;
|
||||
int i;
|
||||
for (i = 1; mipWidth > 1 || mipHeight > 1; i++)
|
||||
{
|
||||
PipelineBarrier barrier0;
|
||||
barrier0.addImage(image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier0.addImage(image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i);
|
||||
barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
|
||||
int nextWidth = std::max(mipWidth >> 1, 1);
|
||||
int nextHeight = std::max(mipHeight >> 1, 1);
|
||||
|
||||
VkImageBlit blit = {};
|
||||
blit.srcOffsets[0] = { 0, 0, 0 };
|
||||
blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
|
||||
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.srcSubresource.mipLevel = i - 1;
|
||||
blit.srcSubresource.baseArrayLayer = 0;
|
||||
blit.srcSubresource.layerCount = 1;
|
||||
blit.dstOffsets[0] = { 0, 0, 0 };
|
||||
blit.dstOffsets[1] = { nextWidth, nextHeight, 1 };
|
||||
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.dstSubresource.mipLevel = i;
|
||||
blit.dstSubresource.baseArrayLayer = 0;
|
||||
blit.dstSubresource.layerCount = 1;
|
||||
cmdbuffer->blitImage(image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR);
|
||||
|
||||
PipelineBarrier barrier1;
|
||||
barrier1.addImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier1.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
mipWidth = nextWidth;
|
||||
mipHeight = nextHeight;
|
||||
}
|
||||
|
||||
PipelineBarrier barrier2;
|
||||
barrier2.addImage(image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier2.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
mImage.GenerateMipmaps(cmdbuffer);
|
||||
}
|
||||
|
||||
int VkHardwareTexture::GetMipLevels(int w, int h)
|
||||
|
@ -356,12 +305,12 @@ int VkHardwareTexture::GetMipLevels(int w, int h)
|
|||
|
||||
void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
|
||||
{
|
||||
if (mImage && (mImage->width != w || mImage->height != h || mTexelsize != texelsize))
|
||||
if (mImage.Image && (mImage.Image->width != w || mImage.Image->height != h || mTexelsize != texelsize))
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (!mImage)
|
||||
if (!mImage.Image)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
|
@ -376,21 +325,20 @@ void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
|
|||
imgbuilder.setMemoryType(
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
mImage = imgbuilder.create(fb->device, &allocatedBytes);
|
||||
mImage->SetDebugName("VkHardwareTexture.mImage");
|
||||
mImageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
mImage.Image = imgbuilder.create(fb->device, &allocatedBytes);
|
||||
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
|
||||
mTexelsize = texelsize;
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(mImage.get(), format);
|
||||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||
viewbuilder.setImage(mImage.Image.get(), format);
|
||||
mImage.View = viewbuilder.create(fb->device);
|
||||
mImage.View->SetDebugName("VkHardwareTexture.mImageView");
|
||||
|
||||
auto cmdbuffer = fb->GetTransferCommands();
|
||||
|
||||
PipelineBarrier imageTransition;
|
||||
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, mImageLayout, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||
imageTransition.execute(cmdbuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
VkImageTransition imageTransition;
|
||||
imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_GENERAL, true);
|
||||
imageTransition.execute(cmdbuffer);
|
||||
|
||||
bufferpitch = int(allocatedBytes / h / texelsize);
|
||||
}
|
||||
|
@ -398,12 +346,12 @@ void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
|
|||
|
||||
uint8_t *VkHardwareTexture::MapBuffer()
|
||||
{
|
||||
return (uint8_t*)mImage->Map(0, mImage->width * mImage->height * mTexelsize);
|
||||
return (uint8_t*)mImage.Image->Map(0, mImage.Image->width * mImage.Image->height * mTexelsize);
|
||||
}
|
||||
|
||||
unsigned int VkHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name)
|
||||
{
|
||||
mImage->Unmap();
|
||||
mImage.Image->Unmap();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -417,15 +365,14 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
|
|||
imgbuilder.setFormat(format);
|
||||
imgbuilder.setSize(w, h);
|
||||
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
|
||||
mImage = imgbuilder.create(fb->device);
|
||||
mImage->SetDebugName(name);
|
||||
mImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
mImage.Image = imgbuilder.create(fb->device);
|
||||
mImage.Image->SetDebugName(name);
|
||||
mTexelsize = 4;
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(mImage.get(), format);
|
||||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName(name);
|
||||
viewbuilder.setImage(mImage.Image.get(), format);
|
||||
mImage.View = viewbuilder.create(fb->device);
|
||||
mImage.View->SetDebugName(name);
|
||||
|
||||
fb->GetPostprocess()->BlitCurrentToImage(mImage.get(), &mImageLayout);
|
||||
fb->GetPostprocess()->BlitCurrentToImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "tarray.h"
|
||||
#include "hwrenderer/textures/hw_ihwtexture.h"
|
||||
#include "volk/volk.h"
|
||||
#include "vk_imagetransition.h"
|
||||
|
||||
struct FMaterialState;
|
||||
class VulkanDescriptorSet;
|
||||
|
@ -40,9 +41,8 @@ public:
|
|||
|
||||
void DeleteDescriptors() override { ResetDescriptors(); }
|
||||
|
||||
VulkanImage *GetImage(FTexture *tex, int translation, int flags);
|
||||
VulkanImageView *GetImageView(FTexture *tex, int translation, int flags);
|
||||
VulkanImageView *GetDepthStencilView(FTexture *tex);
|
||||
VkTextureImage *GetImage(FTexture *tex, int translation, int flags);
|
||||
VkTextureImage *GetDepthStencil(FTexture *tex);
|
||||
|
||||
static void ResetAllDescriptors();
|
||||
|
||||
|
@ -50,7 +50,6 @@ private:
|
|||
void CreateImage(FTexture *tex, int translation, int flags);
|
||||
|
||||
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels);
|
||||
void GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer *cmdbuffer);
|
||||
static int GetMipLevels(int w, int h);
|
||||
|
||||
void ResetDescriptors();
|
||||
|
@ -74,11 +73,8 @@ private:
|
|||
};
|
||||
|
||||
std::vector<DescriptorEntry> mDescriptorSets;
|
||||
std::unique_ptr<VulkanImage> mImage;
|
||||
std::unique_ptr<VulkanImageView> mImageView;
|
||||
VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
VkTextureImage mImage;
|
||||
int mTexelsize = 4;
|
||||
|
||||
std::unique_ptr<VulkanImage> mDepthStencil;
|
||||
std::unique_ptr<VulkanImageView> mDepthStencilView;
|
||||
VkTextureImage mDepthStencil;
|
||||
};
|
||||
|
|
130
src/rendering/vulkan/textures/vk_imagetransition.cpp
Normal file
130
src/rendering/vulkan/textures/vk_imagetransition.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
|
||||
#include "vk_imagetransition.h"
|
||||
|
||||
void VkImageTransition::addImage(VkTextureImage *image, VkImageLayout targetLayout, bool undefinedSrcLayout)
|
||||
{
|
||||
if (image->Layout == targetLayout)
|
||||
return;
|
||||
|
||||
VkAccessFlags srcAccess = 0;
|
||||
VkAccessFlags dstAccess = 0;
|
||||
VkImageAspectFlags aspectMask = image->AspectMask;
|
||||
|
||||
switch (image->Layout)
|
||||
{
|
||||
case VK_IMAGE_LAYOUT_UNDEFINED:
|
||||
srcAccess = 0;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_SHADER_READ_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
break;
|
||||
default:
|
||||
I_FatalError("Unimplemented src image layout transition\n");
|
||||
}
|
||||
|
||||
switch (targetLayout)
|
||||
{
|
||||
case VK_IMAGE_LAYOUT_GENERAL:
|
||||
dstAccess = 0;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_SHADER_READ_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
dstAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
break;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
srcStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
break;
|
||||
default:
|
||||
I_FatalError("Unimplemented dst image layout transition\n");
|
||||
}
|
||||
|
||||
barrier.addImage(image->Image.get(), undefinedSrcLayout ? VK_IMAGE_LAYOUT_UNDEFINED : image->Layout, targetLayout, srcAccess, dstAccess, aspectMask);
|
||||
needbarrier = true;
|
||||
image->Layout = targetLayout;
|
||||
}
|
||||
|
||||
void VkImageTransition::execute(VulkanCommandBuffer *cmdbuffer)
|
||||
{
|
||||
if (needbarrier)
|
||||
barrier.execute(cmdbuffer, srcStageMask, dstStageMask);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VkTextureImage::GenerateMipmaps(VulkanCommandBuffer *cmdbuffer)
|
||||
{
|
||||
int mipWidth = Image->width;
|
||||
int mipHeight = Image->height;
|
||||
int i;
|
||||
for (i = 1; mipWidth > 1 || mipHeight > 1; i++)
|
||||
{
|
||||
PipelineBarrier barrier0;
|
||||
barrier0.addImage(Image.get(), Layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier0.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i);
|
||||
barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
Layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
||||
int nextWidth = std::max(mipWidth >> 1, 1);
|
||||
int nextHeight = std::max(mipHeight >> 1, 1);
|
||||
|
||||
VkImageBlit blit = {};
|
||||
blit.srcOffsets[0] = { 0, 0, 0 };
|
||||
blit.srcOffsets[1] = { mipWidth, mipHeight, 1 };
|
||||
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.srcSubresource.mipLevel = i - 1;
|
||||
blit.srcSubresource.baseArrayLayer = 0;
|
||||
blit.srcSubresource.layerCount = 1;
|
||||
blit.dstOffsets[0] = { 0, 0, 0 };
|
||||
blit.dstOffsets[1] = { nextWidth, nextHeight, 1 };
|
||||
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.dstSubresource.mipLevel = i;
|
||||
blit.dstSubresource.baseArrayLayer = 0;
|
||||
blit.dstSubresource.layerCount = 1;
|
||||
cmdbuffer->blitImage(Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR);
|
||||
|
||||
PipelineBarrier barrier1;
|
||||
barrier1.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier1.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
mipWidth = nextWidth;
|
||||
mipHeight = nextHeight;
|
||||
}
|
||||
|
||||
PipelineBarrier barrier2;
|
||||
barrier2.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier2.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
Layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
39
src/rendering/vulkan/textures/vk_imagetransition.h
Normal file
39
src/rendering/vulkan/textures/vk_imagetransition.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "vulkan/system/vk_objects.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
|
||||
class VkTextureImage
|
||||
{
|
||||
public:
|
||||
void reset()
|
||||
{
|
||||
AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
Layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
DepthOnlyView.reset();
|
||||
View.reset();
|
||||
Image.reset();
|
||||
}
|
||||
|
||||
void GenerateMipmaps(VulkanCommandBuffer *cmdbuffer);
|
||||
|
||||
std::unique_ptr<VulkanImage> Image;
|
||||
std::unique_ptr<VulkanImageView> View;
|
||||
std::unique_ptr<VulkanImageView> DepthOnlyView;
|
||||
VkImageLayout Layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkImageAspectFlags AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
};
|
||||
|
||||
class VkImageTransition
|
||||
{
|
||||
public:
|
||||
void addImage(VkTextureImage *image, VkImageLayout targetLayout, bool undefinedSrcLayout);
|
||||
void execute(VulkanCommandBuffer *cmdbuffer);
|
||||
|
||||
private:
|
||||
PipelineBarrier barrier;
|
||||
VkPipelineStageFlags srcStageMask = 0;
|
||||
VkPipelineStageFlags dstStageMask = 0;
|
||||
bool needbarrier = false;
|
||||
};
|
Loading…
Reference in a new issue