mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
vulkan: improve render pass performance
Before this patch some common patterns would lead to very suboptimal
render passes.
Consider the following code:
```lua
local canvas = love.graphics.newCanvas(...)
function love.draw()
love.graphics.setCanvas(canvas)
love.graphics.clear(...)
love.graphics.draw(...)
love.graphics.setCanvas()
love.graphics.draw(canvas)
end
```
This would lead to the following rendering:
1) render pass on main window with loadOp=load, followed by an immediate
call to vkCmdClearAttachments
2) render pass on canvas with loadOp=load, followed by an immediate call
to vkCmdClearAttachments
3) render pass on main window with loadOp=load
This patch changes the behaviour to the more performant
(and equivalent) version:
1) render pass on canvas with loadOp=clear
2) render pass on main window with loadOp=clear
This is especially helpful on mobile devices, where creating render
passes is an expensive operation.
This commit is contained in:
@@ -110,66 +110,10 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d
|
||||
|
||||
flushBatchedDraws();
|
||||
|
||||
if (!renderPassState.active)
|
||||
startRenderPass();
|
||||
|
||||
VkClearAttachment attachment{};
|
||||
|
||||
if (color.hasValue)
|
||||
{
|
||||
Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a);
|
||||
gammaCorrectColor(cf);
|
||||
|
||||
attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
attachment.clearValue.color.float32[0] = static_cast<float>(cf.r);
|
||||
attachment.clearValue.color.float32[1] = static_cast<float>(cf.g);
|
||||
attachment.clearValue.color.float32[2] = static_cast<float>(cf.b);
|
||||
attachment.clearValue.color.float32[3] = static_cast<float>(cf.a);
|
||||
}
|
||||
|
||||
VkClearAttachment depthStencilAttachment{};
|
||||
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
depthStencilAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.stencil = static_cast<uint32_t>(stencil.value);
|
||||
}
|
||||
if (depth.hasValue)
|
||||
{
|
||||
depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.depth = static_cast<float>(depth.value);
|
||||
}
|
||||
|
||||
std::array<VkClearAttachment, 2> attachments = {
|
||||
attachment,
|
||||
depthStencilAttachment
|
||||
};
|
||||
|
||||
VkClearRect rect{};
|
||||
rect.layerCount = 1;
|
||||
rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
|
||||
rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
|
||||
|
||||
vkCmdClearAttachments(
|
||||
commandBuffers[currentFrame],
|
||||
static_cast<uint32_t>(attachments.size()), attachments.data(),
|
||||
1, &rect);
|
||||
}
|
||||
|
||||
void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
|
||||
{
|
||||
if (colors.empty() && !stencil.hasValue && !depth.hasValue)
|
||||
return;
|
||||
|
||||
flushBatchedDraws();
|
||||
|
||||
if (!renderPassState.active)
|
||||
startRenderPass();
|
||||
|
||||
std::vector<VkClearAttachment> attachments;
|
||||
for (const auto &color : colors)
|
||||
if (renderPassState.active)
|
||||
{
|
||||
VkClearAttachment attachment{};
|
||||
|
||||
if (color.hasValue)
|
||||
{
|
||||
Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a);
|
||||
@@ -181,33 +125,154 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
|
||||
attachment.clearValue.color.float32[2] = static_cast<float>(cf.b);
|
||||
attachment.clearValue.color.float32[3] = static_cast<float>(cf.a);
|
||||
}
|
||||
attachments.push_back(attachment);
|
||||
|
||||
VkClearAttachment depthStencilAttachment{};
|
||||
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
depthStencilAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.stencil = static_cast<uint32_t>(stencil.value);
|
||||
}
|
||||
if (depth.hasValue)
|
||||
{
|
||||
depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.depth = static_cast<float>(depth.value);
|
||||
}
|
||||
|
||||
std::array<VkClearAttachment, 2> attachments = {
|
||||
attachment,
|
||||
depthStencilAttachment
|
||||
};
|
||||
|
||||
VkClearRect rect{};
|
||||
rect.layerCount = 1;
|
||||
rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
|
||||
rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
|
||||
|
||||
vkCmdClearAttachments(
|
||||
commandBuffers[currentFrame],
|
||||
static_cast<uint32_t>(attachments.size()), attachments.data(),
|
||||
1, &rect);
|
||||
}
|
||||
|
||||
VkClearAttachment depthStencilAttachment{};
|
||||
|
||||
if (stencil.hasValue)
|
||||
else
|
||||
{
|
||||
depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.stencil = static_cast<uint32_t>(stencil.value);
|
||||
renderPassState.useConfigurations = true;
|
||||
|
||||
if (color.hasValue)
|
||||
{
|
||||
renderPassState.renderPassConfiguration.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
renderPassState.clearColors[0].color.float32[0] = static_cast<float>(color.value.r);
|
||||
renderPassState.clearColors[0].color.float32[1] = static_cast<float>(color.value.g);
|
||||
renderPassState.clearColors[0].color.float32[2] = static_cast<float>(color.value.b);
|
||||
renderPassState.clearColors[0].color.float32[3] = static_cast<float>(color.value.a);
|
||||
}
|
||||
|
||||
if (depth.hasValue)
|
||||
{
|
||||
renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.depthLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
renderPassState.clearColors[1].depthStencil.depth = static_cast<float>(depth.value);
|
||||
}
|
||||
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
renderPassState.clearColors[1].depthStencil.stencil = static_cast<uint32_t>(stencil.value);
|
||||
}
|
||||
|
||||
if (renderPassState.isWindow)
|
||||
{
|
||||
renderPassState.windowClearRequested = true;
|
||||
renderPassState.mainWindowClearColorValue = color;
|
||||
renderPassState.mainWindowClearDepthValue = depth;
|
||||
renderPassState.mainWindowClearStencilValue = stencil;
|
||||
}
|
||||
else
|
||||
startRenderPass();
|
||||
}
|
||||
if (depth.hasValue)
|
||||
}
|
||||
|
||||
void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
|
||||
{
|
||||
if (colors.empty() && !stencil.hasValue && !depth.hasValue)
|
||||
return;
|
||||
|
||||
flushBatchedDraws();
|
||||
|
||||
if (renderPassState.active)
|
||||
{
|
||||
depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.depth = static_cast<float>(depth.value);
|
||||
std::vector<VkClearAttachment> attachments;
|
||||
for (const auto &color : colors)
|
||||
{
|
||||
VkClearAttachment attachment{};
|
||||
if (color.hasValue)
|
||||
{
|
||||
Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a);
|
||||
gammaCorrectColor(cf);
|
||||
|
||||
attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
attachment.clearValue.color.float32[0] = static_cast<float>(cf.r);
|
||||
attachment.clearValue.color.float32[1] = static_cast<float>(cf.g);
|
||||
attachment.clearValue.color.float32[2] = static_cast<float>(cf.b);
|
||||
attachment.clearValue.color.float32[3] = static_cast<float>(cf.a);
|
||||
}
|
||||
attachments.push_back(attachment);
|
||||
}
|
||||
|
||||
VkClearAttachment depthStencilAttachment{};
|
||||
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.stencil = static_cast<uint32_t>(stencil.value);
|
||||
}
|
||||
if (depth.hasValue)
|
||||
{
|
||||
depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
depthStencilAttachment.clearValue.depthStencil.depth = static_cast<float>(depth.value);
|
||||
}
|
||||
|
||||
attachments.push_back(depthStencilAttachment);
|
||||
|
||||
VkClearRect rect{};
|
||||
rect.layerCount = 1;
|
||||
rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
|
||||
rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
|
||||
|
||||
vkCmdClearAttachments(
|
||||
commandBuffers[currentFrame],
|
||||
static_cast<uint32_t>(attachments.size()), attachments.data(),
|
||||
1, &rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderPassState.useConfigurations = true;
|
||||
|
||||
attachments.push_back(depthStencilAttachment);
|
||||
for (size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
if (colors[i].hasValue)
|
||||
{
|
||||
renderPassState.renderPassConfiguration.colorAttachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
renderPassState.clearColors[i].color.float32[0] = colors[i].value.r;
|
||||
renderPassState.clearColors[i].color.float32[1] = colors[i].value.g;
|
||||
renderPassState.clearColors[i].color.float32[2] = colors[i].value.b;
|
||||
renderPassState.clearColors[i].color.float32[3] = colors[i].value.a;
|
||||
}
|
||||
}
|
||||
|
||||
VkClearRect rect{};
|
||||
rect.layerCount = 1;
|
||||
rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
|
||||
rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
|
||||
if (depth.hasValue)
|
||||
{
|
||||
renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.depthLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
renderPassState.clearColors[colors.size()].depthStencil.depth = depth.value;
|
||||
}
|
||||
|
||||
vkCmdClearAttachments(
|
||||
commandBuffers[currentFrame],
|
||||
static_cast<uint32_t>(attachments.size()), attachments.data(),
|
||||
1, &rect);
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
renderPassState.clearColors[colors.size()].depthStencil.stencil = stencil.value;
|
||||
}
|
||||
|
||||
startRenderPass();
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::discard(const std::vector<bool> &colorbuffers, bool depthstencil)
|
||||
@@ -215,40 +280,19 @@ void Graphics::discard(const std::vector<bool> &colorbuffers, bool depthstencil)
|
||||
if (renderPassState.active)
|
||||
endRenderPass();
|
||||
|
||||
if (renderPassState.useConfigurations)
|
||||
{
|
||||
auto & renderPassConfiguration = renderPassState.renderPassConfiguration;
|
||||
renderPassState.useConfigurations = true;
|
||||
auto & renderPassConfiguration = renderPassState.renderPassConfiguration;
|
||||
|
||||
for (size_t i = 0; i < colorbuffers.size(); i++)
|
||||
renderPassConfiguration.colorAttachments[i].discard = colorbuffers[i];
|
||||
renderPassConfiguration.staticData.depthAttachment.discard = depthstencil;
|
||||
for (size_t i = 0; i < colorbuffers.size(); i++)
|
||||
{
|
||||
if (colorbuffers[i])
|
||||
renderPassConfiguration.colorAttachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
}
|
||||
else
|
||||
|
||||
if (depthstencil)
|
||||
{
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
renderPassConfiguration.colorAttachments.push_back({ swapChainImageFormat, colorbuffers[0], msaaSamples });
|
||||
renderPassConfiguration.staticData.depthAttachment = { findDepthFormat(), depthstencil, msaaSamples };
|
||||
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
||||
renderPassConfiguration.staticData.resolve = false;
|
||||
else
|
||||
renderPassConfiguration.staticData.resolve = true;
|
||||
|
||||
FramebufferConfiguration framebufferConfiguration{};
|
||||
framebufferConfiguration.staticData.depthView = depthImageView;
|
||||
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
||||
{
|
||||
framebufferConfiguration.colorViews.push_back(swapChainImageViews.at(imageIndex));
|
||||
framebufferConfiguration.staticData.resolveView = VK_NULL_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
framebufferConfiguration.colorViews.push_back(colorImageView);
|
||||
framebufferConfiguration.staticData.resolveView = swapChainImageViews.at(imageIndex);
|
||||
}
|
||||
|
||||
renderPassState.useConfigurations = true;
|
||||
renderPassState.renderPassConfiguration = renderPassConfiguration;
|
||||
renderPassState.framebufferConfiguration = framebufferConfiguration;
|
||||
renderPassConfiguration.staticData.depthStencilAttachment.depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
renderPassConfiguration.staticData.depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
}
|
||||
|
||||
startRenderPass();
|
||||
@@ -422,6 +466,9 @@ void Graphics::present(void *screenshotCallbackdata)
|
||||
if (isRenderTargetActive())
|
||||
throw love::Exception("present cannot be called while a render target is active.");
|
||||
|
||||
if (!renderPassState.active && renderPassState.windowClearRequested)
|
||||
startRenderPass();
|
||||
|
||||
deprecations.draw(this);
|
||||
|
||||
submitGpuCommands(true, screenshotCallbackdata);
|
||||
@@ -1938,8 +1985,8 @@ void Graphics::createScreenshotCallbackBuffers()
|
||||
void Graphics::createDefaultRenderPass()
|
||||
{
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
renderPassConfiguration.colorAttachments.push_back({ swapChainImageFormat, false, msaaSamples });
|
||||
renderPassConfiguration.staticData.depthAttachment = { findDepthFormat(), false, msaaSamples };
|
||||
renderPassConfiguration.colorAttachments.push_back({ swapChainImageFormat, VK_ATTACHMENT_LOAD_OP_LOAD, msaaSamples });
|
||||
renderPassConfiguration.staticData.depthStencilAttachment = { findDepthFormat(), VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD, msaaSamples };
|
||||
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
||||
renderPassConfiguration.staticData.resolve = false;
|
||||
else
|
||||
@@ -2050,10 +2097,7 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
|
||||
VkAttachmentDescription colorDescription{};
|
||||
colorDescription.format = colorAttachment.format;
|
||||
colorDescription.samples = colorAttachment.msaaSamples;
|
||||
if (colorAttachment.discard)
|
||||
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
else
|
||||
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
colorDescription.loadOp = colorAttachment.loadOp;
|
||||
colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
@@ -2066,24 +2110,18 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
|
||||
subPass.pColorAttachments = colorAttachmentRefs.data();
|
||||
|
||||
VkAttachmentReference depthStencilAttachmentRef{};
|
||||
if (configuration.staticData.depthAttachment.format != VK_FORMAT_UNDEFINED)
|
||||
if (configuration.staticData.depthStencilAttachment.format != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
depthStencilAttachmentRef.attachment = attachment++;
|
||||
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
subPass.pDepthStencilAttachment = &depthStencilAttachmentRef;
|
||||
|
||||
VkAttachmentDescription depthStencilAttachment{};
|
||||
depthStencilAttachment.format = configuration.staticData.depthAttachment.format;
|
||||
depthStencilAttachment.samples = configuration.staticData.depthAttachment.msaaSamples;
|
||||
if (configuration.staticData.depthAttachment.discard)
|
||||
depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
else
|
||||
depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depthStencilAttachment.format = configuration.staticData.depthStencilAttachment.format;
|
||||
depthStencilAttachment.samples = configuration.staticData.depthStencilAttachment.msaaSamples;
|
||||
depthStencilAttachment.loadOp = configuration.staticData.depthStencilAttachment.depthLoadOp;
|
||||
depthStencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
if (configuration.staticData.depthAttachment.discard)
|
||||
depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
else
|
||||
depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depthStencilAttachment.stencilLoadOp = configuration.staticData.depthStencilAttachment.stencilLoadOp;
|
||||
depthStencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
depthStencilAttachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depthStencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
@@ -2285,13 +2323,18 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
|
||||
|
||||
void Graphics::setDefaultRenderPass()
|
||||
{
|
||||
uint32_t numClearValues = 2;
|
||||
renderPassState.clearColors.resize(numClearValues);
|
||||
|
||||
renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassState.beginInfo.renderPass = defaultRenderPass;
|
||||
renderPassState.beginInfo.framebuffer = defaultFramebuffers[imageIndex];
|
||||
renderPassState.beginInfo.renderArea.offset = { 0, 0 };
|
||||
renderPassState.beginInfo.renderArea.extent = swapChainExtent;
|
||||
renderPassState.beginInfo.clearValueCount = 0;
|
||||
renderPassState.beginInfo.clearValueCount = numClearValues;
|
||||
renderPassState.beginInfo.pClearValues = renderPassState.clearColors.data();
|
||||
|
||||
renderPassState.isWindow = true;
|
||||
renderPassState.useConfigurations = false;
|
||||
renderPassState.pipeline = VK_NULL_HANDLE;
|
||||
renderPassState.width = static_cast<float>(swapChainExtent.width);
|
||||
@@ -2299,6 +2342,36 @@ void Graphics::setDefaultRenderPass()
|
||||
renderPassState.msaa = msaaSamples;
|
||||
renderPassState.numColorAttachments = 1;
|
||||
renderPassState.transitionImages.clear();
|
||||
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
renderPassConfiguration.colorAttachments.push_back({ swapChainImageFormat, VK_ATTACHMENT_LOAD_OP_LOAD, msaaSamples });
|
||||
renderPassConfiguration.staticData.depthStencilAttachment = { findDepthFormat(), VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD, msaaSamples };
|
||||
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
||||
renderPassConfiguration.staticData.resolve = false;
|
||||
else
|
||||
renderPassConfiguration.staticData.resolve = true;
|
||||
|
||||
FramebufferConfiguration framebufferConfiguration{};
|
||||
framebufferConfiguration.staticData.depthView = depthImageView;
|
||||
framebufferConfiguration.staticData.width = swapChainExtent.width;
|
||||
framebufferConfiguration.staticData.height = swapChainExtent.height;
|
||||
|
||||
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
|
||||
{
|
||||
framebufferConfiguration.colorViews.push_back(swapChainImageViews.at(imageIndex));
|
||||
framebufferConfiguration.staticData.resolveView = VK_NULL_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
framebufferConfiguration.colorViews.push_back(colorImageView);
|
||||
framebufferConfiguration.staticData.resolveView = swapChainImageViews.at(imageIndex);
|
||||
}
|
||||
|
||||
renderPassState.renderPassConfiguration = renderPassConfiguration;
|
||||
renderPassState.framebufferConfiguration = framebufferConfiguration;
|
||||
|
||||
if (renderPassState.windowClearRequested)
|
||||
clear(renderPassState.mainWindowClearColorValue, renderPassState.mainWindowClearStencilValue, renderPassState.mainWindowClearDepthValue);
|
||||
}
|
||||
|
||||
void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
|
||||
@@ -2310,12 +2383,13 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
|
||||
for (const auto &color : rts.colors)
|
||||
renderPassConfiguration.colorAttachments.push_back({
|
||||
Vulkan::getTextureFormat(color.texture->getPixelFormat(), isPixelFormatSRGB(color.texture->getPixelFormat())).internalFormat,
|
||||
false,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
dynamic_cast<Texture*>(color.texture)->getMsaaSamples() });
|
||||
if (rts.depthStencil.texture != nullptr)
|
||||
renderPassConfiguration.staticData.depthAttachment = {
|
||||
renderPassConfiguration.staticData.depthStencilAttachment = {
|
||||
Vulkan::getTextureFormat(rts.depthStencil.texture->getPixelFormat(), false).internalFormat,
|
||||
false,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
dynamic_cast<Texture*>(rts.depthStencil.texture)->getMsaaSamples() };
|
||||
|
||||
FramebufferConfiguration configuration{};
|
||||
@@ -2333,14 +2407,19 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
|
||||
configuration.staticData.width = static_cast<uint32_t>(pixelw);
|
||||
configuration.staticData.height = static_cast<uint32_t>(pixelh);
|
||||
|
||||
uint32_t numClearValues = rts.colors.size() + 1;
|
||||
renderPassState.clearColors.resize(numClearValues);
|
||||
|
||||
renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassState.beginInfo.renderPass = VK_NULL_HANDLE;
|
||||
renderPassState.beginInfo.framebuffer = VK_NULL_HANDLE;
|
||||
renderPassState.beginInfo.renderArea.offset = {0, 0};
|
||||
renderPassState.beginInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw);
|
||||
renderPassState.beginInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh);
|
||||
renderPassState.beginInfo.clearValueCount = 0;
|
||||
renderPassState.beginInfo.clearValueCount = numClearValues;
|
||||
renderPassState.beginInfo.pClearValues = renderPassState.clearColors.data();
|
||||
|
||||
renderPassState.isWindow = false;
|
||||
renderPassState.useConfigurations = true;
|
||||
renderPassState.renderPassConfiguration = renderPassConfiguration;
|
||||
renderPassState.framebufferConfiguration = configuration;
|
||||
@@ -2356,6 +2435,9 @@ void Graphics::startRenderPass()
|
||||
{
|
||||
renderPassState.active = true;
|
||||
|
||||
if (renderPassState.isWindow && renderPassState.windowClearRequested)
|
||||
renderPassState.windowClearRequested = false;
|
||||
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
|
||||
@@ -46,27 +46,43 @@ namespace graphics
|
||||
namespace vulkan
|
||||
{
|
||||
|
||||
struct RenderPassAttachment
|
||||
struct ColorAttachment
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
bool discard = true;
|
||||
VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
bool operator==(const RenderPassAttachment &attachment) const
|
||||
bool operator==(const ColorAttachment&attachment) const
|
||||
{
|
||||
return format == attachment.format &&
|
||||
discard == attachment.discard &&
|
||||
loadOp == attachment.loadOp &&
|
||||
msaaSamples == attachment.msaaSamples;
|
||||
}
|
||||
};
|
||||
|
||||
struct DepthStencilAttachment
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkAttachmentLoadOp depthLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
bool operator==(const DepthStencilAttachment &attachment) const
|
||||
{
|
||||
return format == attachment.format &&
|
||||
depthLoadOp == attachment.depthLoadOp &&
|
||||
stencilLoadOp == attachment.stencilLoadOp &&
|
||||
msaaSamples == attachment.msaaSamples;
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderPassConfiguration
|
||||
{
|
||||
std::vector<RenderPassAttachment> colorAttachments;
|
||||
std::vector<ColorAttachment> colorAttachments;
|
||||
|
||||
struct StaticRenderPassConfiguration
|
||||
{
|
||||
RenderPassAttachment depthAttachment;
|
||||
DepthStencilAttachment depthStencilAttachment;
|
||||
bool resolve = false;
|
||||
} staticData;
|
||||
|
||||
@@ -216,6 +232,7 @@ struct RenderpassState
|
||||
{
|
||||
bool active = false;
|
||||
VkRenderPassBeginInfo beginInfo{};
|
||||
bool isWindow = false;
|
||||
bool useConfigurations = false;
|
||||
RenderPassConfiguration renderPassConfiguration{};
|
||||
FramebufferConfiguration framebufferConfiguration{};
|
||||
@@ -225,6 +242,12 @@ struct RenderpassState
|
||||
float width = 0.0f;
|
||||
float height = 0.0f;
|
||||
VkSampleCountFlagBits msaa = VK_SAMPLE_COUNT_1_BIT;
|
||||
std::vector<VkClearValue> clearColors;
|
||||
|
||||
bool windowClearRequested = false;
|
||||
OptionalColorD mainWindowClearColorValue;
|
||||
OptionalDouble mainWindowClearDepthValue;
|
||||
OptionalInt mainWindowClearStencilValue;
|
||||
};
|
||||
|
||||
struct ScreenshotReadbackBuffer
|
||||
|
||||
Reference in New Issue
Block a user