mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 19:21:55 +01:00
Implement a helper shader for partial clears
These are not natively supported by Vulkan, so use a helper shader and colorWriteMask for the same behaviour.
This commit is contained in:
parent
ac0e225114
commit
13a96c5aba
@ -137,6 +137,10 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
view->range.layerCount != 1 || view->range.baseArrayLayer != 0 || clearSurface.rtArrayIndex != 0;
|
view->range.layerCount != 1 || view->range.baseArrayLayer != 0 || clearSurface.rtArrayIndex != 0;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
// Always use surfaceClip for render area since it's more likely to match the renderArea of draws and avoid an RP break
|
||||||
|
const auto &surfaceClip{clearEngineRegisters.surfaceClip};
|
||||||
|
vk::Rect2D renderArea{{surfaceClip.horizontal.x, surfaceClip.vertical.y}, {surfaceClip.horizontal.width, surfaceClip.vertical.height}};
|
||||||
|
|
||||||
auto clearRects{util::MakeFilledArray<vk::ClearRect, 2>(vk::ClearRect{.rect = scissor, .baseArrayLayer = clearSurface.rtArrayIndex, .layerCount = 1})};
|
auto clearRects{util::MakeFilledArray<vk::ClearRect, 2>(vk::ClearRect{.rect = scissor, .baseArrayLayer = clearSurface.rtArrayIndex, .layerCount = 1})};
|
||||||
boost::container::small_vector<vk::ClearAttachment, 2> clearAttachments;
|
boost::container::small_vector<vk::ClearAttachment, 2> clearAttachments;
|
||||||
|
|
||||||
@ -147,14 +151,23 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
if (auto view{activeState.GetColorRenderTargetForClear(ctx, clearSurface.mrtSelect)}) {
|
if (auto view{activeState.GetColorRenderTargetForClear(ctx, clearSurface.mrtSelect)}) {
|
||||||
ctx.executor.AttachTexture(&*view);
|
ctx.executor.AttachTexture(&*view);
|
||||||
|
|
||||||
if (!(clearSurface.rEnable && clearSurface.gEnable && clearSurface.bEnable && clearSurface.aEnable))
|
bool partialClear{!(clearSurface.rEnable && clearSurface.gEnable && clearSurface.bEnable && clearSurface.aEnable)};
|
||||||
Logger::Warn("Partial clears are unimplemented! Performing full clear instead");
|
if (!(view->range.aspectMask & vk::ImageAspectFlagBits::eColor))
|
||||||
|
|
||||||
if (!(view->range.aspectMask & vk::ImageAspectFlagBits::eColor)) {
|
|
||||||
Logger::Warn("Colour RT used in clear lacks colour aspect"); // TODO: Drop this check after texman rework
|
Logger::Warn("Colour RT used in clear lacks colour aspect"); // TODO: Drop this check after texman rework
|
||||||
}
|
|
||||||
|
|
||||||
if (needsAttachmentClearCmd(view)) {
|
|
||||||
|
if (partialClear) {
|
||||||
|
ctx.gpu.helperShaders.clearHelperShader.Clear(ctx.gpu, view->range.aspectMask,
|
||||||
|
(clearSurface.rEnable ? vk::ColorComponentFlagBits::eR : vk::ColorComponentFlags{}) |
|
||||||
|
(clearSurface.gEnable ? vk::ColorComponentFlagBits::eG : vk::ColorComponentFlags{}) |
|
||||||
|
(clearSurface.bEnable ? vk::ColorComponentFlagBits::eB : vk::ColorComponentFlags{}) |
|
||||||
|
(clearSurface.aEnable ? vk::ColorComponentFlagBits::eA : vk::ColorComponentFlags{}),
|
||||||
|
{clearEngineRegisters.colorClearValue}, &*view, [=](auto &&executionCallback) {
|
||||||
|
auto dst{view.get()};
|
||||||
|
ctx.executor.AddSubpass(std::move(executionCallback), renderArea, {}, {}, span<TextureView *>{dst}, nullptr);
|
||||||
|
});
|
||||||
|
ctx.executor.NotifyPipelineChange();
|
||||||
|
} else if (needsAttachmentClearCmd(view)) {
|
||||||
clearAttachments.push_back({.aspectMask = view->range.aspectMask, .clearValue = {clearEngineRegisters.colorClearValue}});
|
clearAttachments.push_back({.aspectMask = view->range.aspectMask, .clearValue = {clearEngineRegisters.colorClearValue}});
|
||||||
colorView = view;
|
colorView = view;
|
||||||
} else {
|
} else {
|
||||||
@ -190,10 +203,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
if (clearAttachments.empty())
|
if (clearAttachments.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Always use surfaceClip for render area since it's more likely to match the renderArea of draws and avoid an RP break
|
|
||||||
const auto &surfaceClip{clearEngineRegisters.surfaceClip};
|
|
||||||
vk::Rect2D renderArea{{surfaceClip.horizontal.x, surfaceClip.vertical.y}, {surfaceClip.horizontal.width, surfaceClip.vertical.height}};
|
|
||||||
|
|
||||||
std::array<TextureView *, 1> colorAttachments{colorView ? &*colorView : nullptr};
|
std::array<TextureView *, 1> colorAttachments{colorView ? &*colorView : nullptr};
|
||||||
ctx.executor.AddSubpass([clearAttachments, clearRects](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32) {
|
ctx.executor.AddSubpass([clearAttachments, clearRects](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32) {
|
||||||
commandBuffer.clearAttachments(clearAttachments, span(clearRects).first(clearAttachments.size()));
|
commandBuffer.clearAttachments(clearAttachments, span(clearRects).first(clearAttachments.size()));
|
||||||
|
@ -23,7 +23,7 @@ namespace skyline::gpu {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleColourRTShader::SimpleColourRTShader(GPU &gpu, std::shared_ptr<vfs::Backing> vertexShader, std::shared_ptr<vfs::Backing> fragmentShader)
|
SimpleSingleRtShader::SimpleSingleRtShader(GPU &gpu, std::shared_ptr<vfs::Backing> vertexShader, std::shared_ptr<vfs::Backing> fragmentShader)
|
||||||
: vertexShaderModule{CreateShaderModule(gpu, *vertexShader)},
|
: vertexShaderModule{CreateShaderModule(gpu, *vertexShader)},
|
||||||
fragmentShaderModule{CreateShaderModule(gpu, *fragmentShader)},
|
fragmentShaderModule{CreateShaderModule(gpu, *fragmentShader)},
|
||||||
shaderStages{{
|
shaderStages{{
|
||||||
@ -39,8 +39,10 @@ namespace skyline::gpu {
|
|||||||
}}
|
}}
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
cache::GraphicsPipelineCache::CompiledPipeline SimpleColourRTShader::GetPipeline(GPU &gpu,
|
cache::GraphicsPipelineCache::CompiledPipeline SimpleSingleRtShader::GetPipeline(GPU &gpu,
|
||||||
TextureView *colorAttachment,
|
TextureView *colorAttachment, TextureView *depthStencilAttachment,
|
||||||
|
bool depthWrite, bool stencilWrite, u32 stencilValue,
|
||||||
|
vk::ColorComponentFlags colorWriteMask,
|
||||||
span<const vk::DescriptorSetLayoutBinding> layoutBindings, span<const vk::PushConstantRange> pushConstantRanges) {
|
span<const vk::DescriptorSetLayoutBinding> layoutBindings, span<const vk::PushConstantRange> pushConstantRanges) {
|
||||||
constexpr static vk::PipelineInputAssemblyStateCreateInfo inputAssemblyState{
|
constexpr static vk::PipelineInputAssemblyStateCreateInfo inputAssemblyState{
|
||||||
.topology = vk::PrimitiveTopology::eTriangleList,
|
.topology = vk::PrimitiveTopology::eTriangleList,
|
||||||
@ -73,19 +75,31 @@ namespace skyline::gpu {
|
|||||||
.alphaToOneEnable = false
|
.alphaToOneEnable = false
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static vk::PipelineDepthStencilStateCreateInfo depthStencilState{
|
vk::PipelineDepthStencilStateCreateInfo depthStencilState{
|
||||||
.depthTestEnable = false,
|
.depthTestEnable = depthWrite,
|
||||||
.depthWriteEnable = false,
|
.depthWriteEnable = depthWrite,
|
||||||
|
.depthCompareOp = vk::CompareOp::eAlways,
|
||||||
.depthBoundsTestEnable = false,
|
.depthBoundsTestEnable = false,
|
||||||
.stencilTestEnable = false,
|
.stencilTestEnable = stencilWrite,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static vk::PipelineColorBlendAttachmentState attachmentState{
|
if (stencilWrite) {
|
||||||
|
depthStencilState.front = depthStencilState.back = {
|
||||||
|
.depthFailOp = vk::StencilOp::eReplace,
|
||||||
|
.passOp = vk::StencilOp::eReplace,
|
||||||
|
.compareOp = vk::CompareOp::eAlways,
|
||||||
|
.compareMask = 0xFF,
|
||||||
|
.writeMask = 0xFF,
|
||||||
|
.reference = stencilValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PipelineColorBlendAttachmentState attachmentState{
|
||||||
.blendEnable = false,
|
.blendEnable = false,
|
||||||
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA
|
.colorWriteMask = colorWriteMask
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static vk::PipelineColorBlendStateCreateInfo blendState{
|
vk::PipelineColorBlendStateCreateInfo blendState{
|
||||||
.logicOpEnable = false,
|
.logicOpEnable = false,
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
.pAttachments = &attachmentState
|
.pAttachments = &attachmentState
|
||||||
@ -100,11 +114,11 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
vertexState.unlink<vk::PipelineVertexInputDivisorStateCreateInfoEXT>();
|
vertexState.unlink<vk::PipelineVertexInputDivisorStateCreateInfoEXT>();
|
||||||
|
|
||||||
auto colourAttachmentDimensions{colorAttachment->texture->dimensions};
|
auto attachmentDimensions{colorAttachment ? colorAttachment->texture->dimensions : depthStencilAttachment->texture->dimensions};
|
||||||
|
|
||||||
vk::Viewport viewport{
|
vk::Viewport viewport{
|
||||||
.height = static_cast<float>(colourAttachmentDimensions.height),
|
.height = static_cast<float>(attachmentDimensions.height),
|
||||||
.width = static_cast<float>(colourAttachmentDimensions.width),
|
.width = static_cast<float>(attachmentDimensions.width),
|
||||||
.x = 0.0f,
|
.x = 0.0f,
|
||||||
.y = 0.0f,
|
.y = 0.0f,
|
||||||
.minDepth = 0.0f,
|
.minDepth = 0.0f,
|
||||||
@ -112,7 +126,7 @@ namespace skyline::gpu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vk::Rect2D scissor{
|
vk::Rect2D scissor{
|
||||||
.extent = colourAttachmentDimensions
|
.extent = attachmentDimensions
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::PipelineViewportStateCreateInfo viewportState{
|
vk::PipelineViewportStateCreateInfo viewportState{
|
||||||
@ -134,7 +148,7 @@ namespace skyline::gpu {
|
|||||||
.colorBlendState = blendState,
|
.colorBlendState = blendState,
|
||||||
.dynamicState = {},
|
.dynamicState = {},
|
||||||
.colorAttachments = span<TextureView *>{colorAttachment},
|
.colorAttachments = span<TextureView *>{colorAttachment},
|
||||||
.depthStencilAttachment = nullptr,
|
.depthStencilAttachment = depthStencilAttachment,
|
||||||
}, layoutBindings, pushConstantRanges, true);
|
}, layoutBindings, pushConstantRanges, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +156,12 @@ namespace skyline::gpu {
|
|||||||
struct Vec2 {
|
struct Vec2 {
|
||||||
float x, y;
|
float x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Vec4 {
|
||||||
|
float x, y, z, w;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Bool = u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace blit {
|
namespace blit {
|
||||||
@ -177,7 +197,7 @@ namespace skyline::gpu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BlitHelperShader::BlitHelperShader(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem)
|
BlitHelperShader::BlitHelperShader(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem)
|
||||||
: SimpleColourRTShader{gpu, shaderFileSystem->OpenFile("shaders/blit.vert.spv"), shaderFileSystem->OpenFile("shaders/blit.frag.spv")},
|
: SimpleSingleRtShader{gpu, shaderFileSystem->OpenFile("shaders/blit.vert.spv"), shaderFileSystem->OpenFile("shaders/blit.frag.spv")},
|
||||||
bilinearSampler{gpu.vkDevice.createSampler(
|
bilinearSampler{gpu.vkDevice.createSampler(
|
||||||
vk::SamplerCreateInfo{
|
vk::SamplerCreateInfo{
|
||||||
.addressModeU = vk::SamplerAddressMode::eRepeat,
|
.addressModeU = vk::SamplerAddressMode::eRepeat,
|
||||||
@ -231,7 +251,10 @@ namespace skyline::gpu {
|
|||||||
.dstSrcScaleFactor = {dstSrcScaleFactorX * (srcRect.width / srcImageDimensions.width), dstSrcScaleFactorY * (srcRect.height / srcImageDimensions.height)},
|
.dstSrcScaleFactor = {dstSrcScaleFactorX * (srcRect.width / srcImageDimensions.width), dstSrcScaleFactorY * (srcRect.height / srcImageDimensions.height)},
|
||||||
.srcHeightRecip = 1.0f / srcImageDimensions.height
|
.srcHeightRecip = 1.0f / srcImageDimensions.height
|
||||||
},
|
},
|
||||||
GetPipeline(gpu, dstImageView, {blit::SamplerLayoutBinding}, blit::PushConstantRanges))
|
GetPipeline(gpu, dstImageView,
|
||||||
|
nullptr, false, false, 0,
|
||||||
|
vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
||||||
|
{blit::SamplerLayoutBinding}, blit::PushConstantRanges))
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::DescriptorImageInfo imageInfo{
|
vk::DescriptorImageInfo imageInfo{
|
||||||
@ -263,7 +286,63 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace clear {
|
||||||
|
struct FragmentPushConstantLayout {
|
||||||
|
glsl::Vec4 color;
|
||||||
|
glsl::Bool clearDepth;
|
||||||
|
float depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr static std::array<vk::PushConstantRange, 1> PushConstantRanges{
|
||||||
|
vk::PushConstantRange{
|
||||||
|
.stageFlags = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
.size = sizeof(FragmentPushConstantLayout),
|
||||||
|
.offset = 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearHelperShader::ClearHelperShader(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem)
|
||||||
|
: SimpleSingleRtShader{gpu, shaderFileSystem->OpenFile("shaders/clear.vert.spv"), shaderFileSystem->OpenFile("shaders/clear.frag.spv")} {}
|
||||||
|
|
||||||
|
void ClearHelperShader::Clear(GPU &gpu, vk::ImageAspectFlags mask, vk::ColorComponentFlags components, vk::ClearValue value, TextureView *dstImageView,
|
||||||
|
std::function<void(std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)> &&)> &&recordCb) {
|
||||||
|
struct DrawState {
|
||||||
|
clear::FragmentPushConstantLayout fragmentPushConstants;
|
||||||
|
cache::GraphicsPipelineCache::CompiledPipeline pipeline;
|
||||||
|
|
||||||
|
DrawState(GPU &gpu,
|
||||||
|
clear::FragmentPushConstantLayout fragmentPushConstants,
|
||||||
|
cache::GraphicsPipelineCache::CompiledPipeline pipeline)
|
||||||
|
: fragmentPushConstants{fragmentPushConstants},
|
||||||
|
pipeline{pipeline} {}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool writeColor{mask & vk::ImageAspectFlagBits::eColor};
|
||||||
|
bool writeDepth{mask & vk::ImageAspectFlagBits::eDepth};
|
||||||
|
bool writeStencil{mask & vk::ImageAspectFlagBits::eStencil};
|
||||||
|
|
||||||
|
auto drawState{std::make_shared<DrawState>(
|
||||||
|
gpu,
|
||||||
|
clear::FragmentPushConstantLayout{
|
||||||
|
.color = {value.color.float32[0], value.color.float32[1], value.color.float32[2], value.color.float32[3]},
|
||||||
|
.clearDepth = (mask & vk::ImageAspectFlagBits::eDepth) != vk::ImageAspectFlags{},
|
||||||
|
.depth = value.depthStencil.depth
|
||||||
|
},
|
||||||
|
GetPipeline(gpu, writeColor ? dstImageView : nullptr, (writeDepth || writeStencil) ? dstImageView : nullptr, writeDepth, writeStencil, value.depthStencil.stencil, components, {}, clear::PushConstantRanges))
|
||||||
|
};
|
||||||
|
|
||||||
|
recordCb([drawState = std::move(drawState)](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu, vk::RenderPass, u32) {
|
||||||
|
cycle->AttachObject(drawState);
|
||||||
|
commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, drawState->pipeline.pipeline);
|
||||||
|
commandBuffer.pushConstants(drawState->pipeline.pipelineLayout, vk::ShaderStageFlagBits::eFragment, 0,
|
||||||
|
vk::ArrayProxy<const clear::FragmentPushConstantLayout>{drawState->fragmentPushConstants});
|
||||||
|
commandBuffer.draw(6, 1, 0, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
HelperShaders::HelperShaders(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem)
|
HelperShaders::HelperShaders(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem)
|
||||||
: blitHelperShader(gpu, std::move(shaderFileSystem)) {}
|
: blitHelperShader(gpu, shaderFileSystem),
|
||||||
|
clearHelperShader(gpu, shaderFileSystem) {}
|
||||||
|
|
||||||
}
|
}
|
@ -16,29 +16,31 @@ namespace skyline::gpu {
|
|||||||
class GPU;
|
class GPU;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A base class that can be inherited by helper shaders that render to a single color rendertarget to simplify pipeline creation
|
* @brief A base class that can be inherited by helper shaders that render to a single color/depth rendertarget to simplify pipeline creation
|
||||||
*/
|
*/
|
||||||
class SimpleColourRTShader {
|
class SimpleSingleRtShader {
|
||||||
protected:
|
protected:
|
||||||
vk::raii::ShaderModule vertexShaderModule;
|
vk::raii::ShaderModule vertexShaderModule;
|
||||||
vk::raii::ShaderModule fragmentShaderModule;
|
vk::raii::ShaderModule fragmentShaderModule;
|
||||||
|
|
||||||
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages; //!< Shader stages for the vertex and fragment shader modules
|
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages; //!< Shader stages for the vertex and fragment shader modules
|
||||||
|
|
||||||
SimpleColourRTShader(GPU &gpu, std::shared_ptr<vfs::Backing> vertexShader, std::shared_ptr<vfs::Backing> fragmentShader);
|
SimpleSingleRtShader(GPU &gpu, std::shared_ptr<vfs::Backing> vertexShader, std::shared_ptr<vfs::Backing> fragmentShader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a potentially cached pipeline built according to the supplied input state
|
* @brief Returns a potentially cached pipeline built according to the supplied input state
|
||||||
*/
|
*/
|
||||||
cache::GraphicsPipelineCache::CompiledPipeline GetPipeline(GPU &gpu,
|
cache::GraphicsPipelineCache::CompiledPipeline GetPipeline(GPU &gpu,
|
||||||
TextureView *colorAttachment,
|
TextureView *colorAttachment, TextureView *depthStenilAttachment,
|
||||||
|
bool depthWrite, bool stencilWrite, u32 stencilValue,
|
||||||
|
vk::ColorComponentFlags colorWriteMask,
|
||||||
span<const vk::DescriptorSetLayoutBinding> layoutBindings, span<const vk::PushConstantRange> pushConstantRanges);
|
span<const vk::DescriptorSetLayoutBinding> layoutBindings, span<const vk::PushConstantRange> pushConstantRanges);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Simple helper shader for blitting a texture to a rendertarget with subpixel-precision
|
* @brief Simple helper shader for blitting a texture to a rendertarget with subpixel-precision
|
||||||
*/
|
*/
|
||||||
class BlitHelperShader : SimpleColourRTShader {
|
class BlitHelperShader : SimpleSingleRtShader {
|
||||||
private:
|
private:
|
||||||
vk::raii::Sampler bilinearSampler;
|
vk::raii::Sampler bilinearSampler;
|
||||||
vk::raii::Sampler nearestSampler;
|
vk::raii::Sampler nearestSampler;
|
||||||
@ -73,11 +75,30 @@ namespace skyline::gpu {
|
|||||||
std::function<void(std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)> &&)> &&recordCb);
|
std::function<void(std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)> &&)> &&recordCb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simple helper shader for clearing a texture to a given color
|
||||||
|
*/
|
||||||
|
class ClearHelperShader : SimpleSingleRtShader {
|
||||||
|
public:
|
||||||
|
ClearHelperShader(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Records a sequenced GPU clear operation using a shader
|
||||||
|
* @param mask Mask of which aspects to clear
|
||||||
|
* @param components Mask of which components to clear
|
||||||
|
* @param value The value to clear to
|
||||||
|
* @param recordCb Callback used to record the blit commands for sequenced execution on the GPU
|
||||||
|
*/
|
||||||
|
void Clear(GPU &gpu, vk::ImageAspectFlags mask, vk::ColorComponentFlags components, vk::ClearValue value, TextureView *dstImageView,
|
||||||
|
std::function<void(std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)> &&)> &&recordCb);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Holds all helper shaders to avoid redundantly recreating them on each usage
|
* @brief Holds all helper shaders to avoid redundantly recreating them on each usage
|
||||||
*/
|
*/
|
||||||
struct HelperShaders {
|
struct HelperShaders {
|
||||||
BlitHelperShader blitHelperShader;
|
BlitHelperShader blitHelperShader;
|
||||||
|
ClearHelperShader clearHelperShader;
|
||||||
|
|
||||||
HelperShaders(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem);
|
HelperShaders(GPU &gpu, std::shared_ptr<vfs::FileSystem> shaderFileSystem);
|
||||||
};
|
};
|
||||||
|
17
app/src/main/shaders/clear.frag
Normal file
17
app/src/main/shaders/clear.frag
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 colour;
|
||||||
|
|
||||||
|
layout (push_constant) uniform constants {
|
||||||
|
vec4 colour;
|
||||||
|
bool clearDepth;
|
||||||
|
float depth;
|
||||||
|
} PC;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
if (PC.clearDepth)
|
||||||
|
gl_FragDepth = PC.depth;
|
||||||
|
else
|
||||||
|
colour = PC.colour;
|
||||||
|
}
|
14
app/src/main/shaders/clear.vert
Normal file
14
app/src/main/shaders/clear.vert
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const vec2 lut[6] = vec2[6](
|
||||||
|
vec2(-1, -1),
|
||||||
|
vec2(-1, 1),
|
||||||
|
vec2(1, 1),
|
||||||
|
vec2(1, 1),
|
||||||
|
vec2(1, -1),
|
||||||
|
vec2(-1, -1)
|
||||||
|
);
|
||||||
|
|
||||||
|
gl_Position = vec4(lut[gl_VertexIndex], 0, 1);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user