mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-06 14:09:58 +00:00
Remove some dependencies to framebuffer and renderpass
This commit is contained in:
@@ -31,7 +31,6 @@ FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_c
|
||||
, m_extent{extent}
|
||||
{
|
||||
CreateImages(device);
|
||||
CreateRenderPasses(device);
|
||||
CreateSampler(device);
|
||||
CreateShaders(device);
|
||||
CreateDescriptorPool(device);
|
||||
@@ -51,14 +50,6 @@ void FSR::CreateImages(const Device& device) {
|
||||
}
|
||||
}
|
||||
|
||||
void FSR::CreateRenderPasses(const Device& device) {
|
||||
m_renderpass = CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
for (auto& images : m_dynamic_images) {
|
||||
images.framebuffers[Easu] = CreateWrappedFramebuffer(device, m_renderpass, images.image_views[Easu], m_extent);
|
||||
images.framebuffers[Rcas] = CreateWrappedFramebuffer(device, m_renderpass, images.image_views[Rcas], m_extent);
|
||||
}
|
||||
}
|
||||
|
||||
void FSR::CreateSampler(const Device& device) {
|
||||
m_sampler = CreateBilinearSampler(device);
|
||||
}
|
||||
@@ -112,9 +103,11 @@ void FSR::CreatePipelineLayouts(const Device& device) {
|
||||
}
|
||||
|
||||
void FSR::CreatePipelines(const Device& device) {
|
||||
m_easu_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout,
|
||||
m_easu_pipeline = CreateWrappedPipeline(device, VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
m_pipeline_layout,
|
||||
std::tie(m_vert_shader, m_easu_shader));
|
||||
m_rcas_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout,
|
||||
m_rcas_pipeline = CreateWrappedPipeline(device, VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
m_pipeline_layout,
|
||||
std::tie(m_vert_shader, m_rcas_shader));
|
||||
}
|
||||
|
||||
@@ -129,19 +122,6 @@ void FSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, siz
|
||||
device.GetLogical().UpdateDescriptorSets(updates, {});
|
||||
}
|
||||
|
||||
void FSR::UploadImages(const Device& device, Scheduler& scheduler) {
|
||||
if (!m_images_ready) {
|
||||
m_images_ready = true;
|
||||
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
|
||||
for (auto& image : m_dynamic_images) {
|
||||
ClearColorImage(cmdbuf, *image.images[Easu]);
|
||||
ClearColorImage(cmdbuf, *image.images[Rcas]);
|
||||
}
|
||||
});
|
||||
scheduler.Finish();
|
||||
}
|
||||
}
|
||||
|
||||
VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage source_image,
|
||||
VkImageView source_image_view, VkExtent2D input_image_extent,
|
||||
const Common::Rectangle<f32>& crop_rect) {
|
||||
@@ -151,12 +131,11 @@ VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_i
|
||||
VkImage rcas_image = *images.images[Rcas];
|
||||
VkDescriptorSet easu_descriptor_set = images.descriptor_sets[Easu];
|
||||
VkDescriptorSet rcas_descriptor_set = images.descriptor_sets[Rcas];
|
||||
VkFramebuffer easu_framebuffer = *images.framebuffers[Easu];
|
||||
VkFramebuffer rcas_framebuffer = *images.framebuffers[Rcas];
|
||||
VkImageView easu_view = *images.image_views[Easu];
|
||||
VkImageView rcas_view = *images.image_views[Rcas];
|
||||
VkPipeline easu_pipeline = *m_easu_pipeline;
|
||||
VkPipeline rcas_pipeline = *m_rcas_pipeline;
|
||||
VkPipelineLayout pipeline_layout = *m_pipeline_layout;
|
||||
VkRenderPass renderpass = *m_renderpass;
|
||||
VkExtent2D extent = m_extent;
|
||||
|
||||
const f32 input_image_width = static_cast<f32>(input_image_extent.width);
|
||||
@@ -179,30 +158,31 @@ VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_i
|
||||
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
|
||||
FsrRcasCon(rcas_con.data(), sharpening);
|
||||
|
||||
UploadImages(device, scheduler);
|
||||
UpdateDescriptorSets(device, source_image_view, image_index);
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([=](vk::CommandBuffer cmdbuf) {
|
||||
TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, easu_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, renderpass, easu_framebuffer, extent);
|
||||
TransitionImageLayout(cmdbuf, easu_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, easu_view, extent, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, easu_pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0,
|
||||
easu_descriptor_set, {});
|
||||
cmdbuf.PushConstants(pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, easu_con);
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
|
||||
TransitionImageLayout(cmdbuf, easu_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, rcas_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, renderpass, rcas_framebuffer, extent);
|
||||
TransitionImageLayout(cmdbuf, rcas_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, rcas_view, extent, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, rcas_pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0,
|
||||
rcas_descriptor_set, {});
|
||||
cmdbuf.PushConstants(pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, rcas_con);
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
|
||||
TransitionImageLayout(cmdbuf, rcas_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
});
|
||||
|
||||
@@ -24,7 +24,6 @@ public:
|
||||
|
||||
private:
|
||||
void CreateImages(const Device& device);
|
||||
void CreateRenderPasses(const Device& device);
|
||||
void CreateSampler(const Device& device);
|
||||
void CreateShaders(const Device& device);
|
||||
void CreateDescriptorPool(const Device& device);
|
||||
@@ -33,7 +32,6 @@ private:
|
||||
void CreatePipelineLayouts(const Device& device);
|
||||
void CreatePipelines(const Device& device);
|
||||
|
||||
void UploadImages(const Device& device, Scheduler& scheduler);
|
||||
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
|
||||
|
||||
MemoryAllocator& m_memory_allocator;
|
||||
@@ -54,17 +52,14 @@ private:
|
||||
vk::ShaderModule m_rcas_shader;
|
||||
vk::Pipeline m_easu_pipeline;
|
||||
vk::Pipeline m_rcas_pipeline;
|
||||
vk::RenderPass m_renderpass;
|
||||
vk::Sampler m_sampler;
|
||||
|
||||
struct Images {
|
||||
vk::DescriptorSets descriptor_sets;
|
||||
std::array<vk::Image, MaxFsrStage> images;
|
||||
std::array<vk::ImageView, MaxFsrStage> image_views;
|
||||
std::array<vk::Framebuffer, MaxFsrStage> framebuffers;
|
||||
};
|
||||
std::vector<Images> m_dynamic_images;
|
||||
bool m_images_ready{};
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -21,7 +21,6 @@ FXAA::FXAA(const Device& device, MemoryAllocator& allocator, size_t image_count,
|
||||
, m_image_count(u32(image_count))
|
||||
{
|
||||
CreateImages(device, allocator);
|
||||
CreateRenderPasses(device);
|
||||
CreateSampler(device);
|
||||
CreateShaders(device);
|
||||
CreateDescriptorPool(device);
|
||||
@@ -41,15 +40,6 @@ void FXAA::CreateImages(const Device& device, MemoryAllocator& allocator) {
|
||||
}
|
||||
}
|
||||
|
||||
void FXAA::CreateRenderPasses(const Device& device) {
|
||||
m_renderpass = CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
|
||||
for (auto& image : m_dynamic_images) {
|
||||
image.framebuffer =
|
||||
CreateWrappedFramebuffer(device, m_renderpass, image.image_view, m_extent);
|
||||
}
|
||||
}
|
||||
|
||||
void FXAA::CreateSampler(const Device& device) {
|
||||
m_sampler = CreateWrappedSampler(device);
|
||||
}
|
||||
@@ -83,7 +73,7 @@ void FXAA::CreatePipelineLayouts(const Device& device) {
|
||||
}
|
||||
|
||||
void FXAA::CreatePipelines(const Device& device) {
|
||||
m_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout,
|
||||
m_pipeline = CreateWrappedPipeline(device, VK_FORMAT_R16G16B16A16_SFLOAT, m_pipeline_layout,
|
||||
std::tie(m_vertex_shader, m_fragment_shader));
|
||||
}
|
||||
|
||||
@@ -99,44 +89,28 @@ void FXAA::UpdateDescriptorSets(const Device& device, VkImageView image_view, si
|
||||
device.GetLogical().UpdateDescriptorSets(updates, {});
|
||||
}
|
||||
|
||||
void FXAA::UploadImages(const Device& device, Scheduler& scheduler) {
|
||||
if (m_images_ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
|
||||
for (auto& image : m_dynamic_images) {
|
||||
ClearColorImage(cmdbuf, *image.image);
|
||||
}
|
||||
});
|
||||
scheduler.Finish();
|
||||
|
||||
m_images_ready = true;
|
||||
}
|
||||
|
||||
void FXAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage* inout_image, VkImageView* inout_image_view) {
|
||||
const Image& image{m_dynamic_images[image_index]};
|
||||
const VkImage input_image{*inout_image};
|
||||
const VkImage output_image{*image.image};
|
||||
const VkImageView output_view{*image.image_view};
|
||||
const VkDescriptorSet descriptor_set{image.descriptor_sets[0]};
|
||||
const VkFramebuffer framebuffer{*image.framebuffer};
|
||||
const VkRenderPass renderpass{*m_renderpass};
|
||||
const VkPipeline pipeline{*m_pipeline};
|
||||
const VkPipelineLayout layout{*m_pipeline_layout};
|
||||
const VkExtent2D extent{m_extent};
|
||||
|
||||
UploadImages(device, scheduler);
|
||||
UpdateDescriptorSets(device, *inout_image_view, image_index);
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([=](vk::CommandBuffer cmdbuf) {
|
||||
TransitionImageLayout(cmdbuf, input_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, renderpass, framebuffer, extent);
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, output_view, extent, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, {});
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
});
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
|
||||
private:
|
||||
void CreateImages(const Device& device, MemoryAllocator& allocator);
|
||||
void CreateRenderPasses(const Device& device);
|
||||
void CreateSampler(const Device& device);
|
||||
void CreateShaders(const Device& device);
|
||||
void CreateDescriptorPool(const Device& device);
|
||||
@@ -34,11 +33,9 @@ private:
|
||||
void CreatePipelineLayouts(const Device& device);
|
||||
void CreatePipelines(const Device& device);
|
||||
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
|
||||
void UploadImages(const Device& device, Scheduler& scheduler);
|
||||
|
||||
struct Image {
|
||||
vk::DescriptorSets descriptor_sets{};
|
||||
vk::Framebuffer framebuffer{};
|
||||
vk::Image image{};
|
||||
vk::ImageView image_view{};
|
||||
};
|
||||
@@ -51,9 +48,7 @@ private:
|
||||
vk::DescriptorSetLayout m_descriptor_set_layout{};
|
||||
vk::PipelineLayout m_pipeline_layout{};
|
||||
vk::Pipeline m_pipeline{};
|
||||
vk::RenderPass m_renderpass{};
|
||||
vk::Sampler m_sampler{};
|
||||
bool m_images_ready{};
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -126,68 +126,7 @@ VkPrimitiveTopology ToTopology(reshadefx::primitive_topology topology) {
|
||||
}
|
||||
}
|
||||
|
||||
vk::RenderPass CreateFxRenderPass(const Device& device, VkFormat format, bool clear) {
|
||||
VkAttachmentLoadOp load_op = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
VkImageLayout initial_layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
if (clear) {
|
||||
load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
const VkAttachmentDescription2 attachment{
|
||||
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.format = format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = load_op,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = initial_layout,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
static constexpr VkAttachmentReference2 reference{
|
||||
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
|
||||
.pNext = nullptr,
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.aspectMask = 0,
|
||||
};
|
||||
|
||||
const VkSubpassDescription2 subpass{
|
||||
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.viewMask = 0,
|
||||
.inputAttachmentCount = 0,
|
||||
.pInputAttachments = nullptr,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &reference,
|
||||
.pResolveAttachments = nullptr,
|
||||
.pDepthStencilAttachment = nullptr,
|
||||
.preserveAttachmentCount = 0,
|
||||
.pPreserveAttachments = nullptr,
|
||||
};
|
||||
|
||||
return device.GetLogical().CreateRenderPass2(VkRenderPassCreateInfo2{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &attachment,
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subpass,
|
||||
.dependencyCount = 0,
|
||||
.pDependencies = nullptr,
|
||||
.correlatedViewMaskCount = 0,
|
||||
.pCorrelatedViewMasks = nullptr,
|
||||
});
|
||||
}
|
||||
|
||||
vk::Pipeline CreateFxPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
vk::Pipeline CreateFxPipeline(const Device& device, VkFormat format,
|
||||
vk::PipelineLayout& layout, VkShaderModule vertex_shader,
|
||||
VkShaderModule fragment_shader,
|
||||
const reshadefx::pass& pass) {
|
||||
@@ -308,9 +247,10 @@ vk::Pipeline CreateFxPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
.pDynamicStates = dynamic_states.data(),
|
||||
};
|
||||
|
||||
const VkPipelineRenderingCreateInfo rendering_ci = ColorRenderingInfo(format);
|
||||
return device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.pNext = &rendering_ci,
|
||||
.flags = 0,
|
||||
.stageCount = static_cast<u32>(stages.size()),
|
||||
.pStages = stages.data(),
|
||||
@@ -324,7 +264,7 @@ vk::Pipeline CreateFxPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
.pColorBlendState = &color_blend,
|
||||
.pDynamicState = &dynamic_state,
|
||||
.layout = *layout,
|
||||
.renderPass = *renderpass,
|
||||
.renderPass = VK_NULL_HANDLE,
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = nullptr,
|
||||
.basePipelineIndex = 0,
|
||||
@@ -540,7 +480,9 @@ bool PostProcessChain::BuildEffects(const Device& device, MemoryAllocator& alloc
|
||||
for (const auto& pass : technique->passes) {
|
||||
Pass out;
|
||||
out.num_vertices = pass.num_vertices;
|
||||
out.clear = pass.clear_render_targets != 0;
|
||||
if (pass.clear_render_targets != 0) {
|
||||
out.load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
}
|
||||
out.target_texture = NO_TEXTURE;
|
||||
out.extent = m_extent;
|
||||
|
||||
@@ -606,23 +548,9 @@ bool PostProcessChain::BuildEffects(const Device& device, MemoryAllocator& alloc
|
||||
continue;
|
||||
}
|
||||
|
||||
out.renderpass = CreateFxRenderPass(device, target_format, out.clear);
|
||||
out.pipeline = CreateFxPipeline(device, out.renderpass, out.pipeline_layout,
|
||||
out.pipeline = CreateFxPipeline(device, target_format, out.pipeline_layout,
|
||||
*vertex_shader->second, *fragment_shader->second, pass);
|
||||
|
||||
if (out.writes_backbuffer) {
|
||||
for (u32 image = 0; image < m_image_count; ++image) {
|
||||
for (size_t slot = 0; slot < 2; ++slot) {
|
||||
out.framebuffers.push_back(CreateWrappedFramebuffer(
|
||||
device, out.renderpass, m_frames[image].views[slot], out.extent));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.framebuffers.push_back(
|
||||
CreateWrappedFramebuffer(device, out.renderpass,
|
||||
effect.textures[out.target_texture].view, out.extent));
|
||||
}
|
||||
|
||||
effect.passes.push_back(std::move(out));
|
||||
}
|
||||
|
||||
@@ -859,19 +787,20 @@ void PostProcessChain::Draw(const Device& device, Scheduler& scheduler, size_t i
|
||||
|
||||
UpdateDescriptors(device, effect, pass, image_index, current_view);
|
||||
|
||||
VkFramebuffer framebuffer{};
|
||||
VkImage target_image{};
|
||||
VkImageView target_view{};
|
||||
if (pass.writes_backbuffer) {
|
||||
const u32 target_slot = (slot + 1) % 2;
|
||||
framebuffer = *pass.framebuffers[image_index * 2 + target_slot];
|
||||
target_image = *frame.images[target_slot];
|
||||
target_view = *frame.views[target_slot];
|
||||
} else {
|
||||
framebuffer = *pass.framebuffers[0];
|
||||
target_image = *effect.textures[pass.target_texture].image;
|
||||
const Texture& texture = effect.textures[pass.target_texture];
|
||||
target_image = *texture.image;
|
||||
target_view = *texture.view;
|
||||
}
|
||||
|
||||
const VkImage source_image = current_image;
|
||||
const VkRenderPass renderpass = *pass.renderpass;
|
||||
const VkAttachmentLoadOp load_op = pass.load_op;
|
||||
const VkPipeline pipeline = *pass.pipeline;
|
||||
const VkPipelineLayout layout = *pass.pipeline_layout;
|
||||
const VkDescriptorSet uniform_set = effect.uniform_sets[image_index];
|
||||
@@ -883,12 +812,12 @@ void PostProcessChain::Draw(const Device& device, Scheduler& scheduler, size_t i
|
||||
scheduler.Record([=](vk::CommandBuffer cmdbuf) {
|
||||
TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, target_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, renderpass, framebuffer, extent);
|
||||
BeginRendering(cmdbuf, target_view, extent, load_op);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0,
|
||||
std::array{uniform_set, sampler_set}, {});
|
||||
cmdbuf.Draw(vertices, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
TransitionImageLayout(cmdbuf, target_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
});
|
||||
|
||||
|
||||
@@ -77,17 +77,15 @@ private:
|
||||
};
|
||||
|
||||
struct Pass {
|
||||
vk::RenderPass renderpass{};
|
||||
vk::Pipeline pipeline{};
|
||||
vk::DescriptorSetLayout sampler_layout{};
|
||||
vk::PipelineLayout pipeline_layout{};
|
||||
vk::DescriptorSets sampler_sets{};
|
||||
std::vector<SamplerBinding> sampler_bindings{};
|
||||
std::vector<vk::Framebuffer> framebuffers{};
|
||||
size_t target_texture{};
|
||||
VkExtent2D extent{};
|
||||
u32 num_vertices{3};
|
||||
bool clear{};
|
||||
VkAttachmentLoadOp load_op{VK_ATTACHMENT_LOAD_OP_LOAD};
|
||||
bool writes_backbuffer{};
|
||||
};
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image
|
||||
images.image_view = CreateWrappedImageView(device, images.image, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
}
|
||||
|
||||
m_renderpass = CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
for (auto& images : m_dynamic_images)
|
||||
images.framebuffer = CreateWrappedFramebuffer(device, m_renderpass, images.image_view, m_extent);
|
||||
|
||||
m_sampler = CreateBilinearSampler(device);
|
||||
m_vert_shader = BuildShader(device, SGSR1_SHADER_VERT_SPV);
|
||||
m_stage_shader = m_edge_dir
|
||||
@@ -66,7 +62,9 @@ SGSR::SGSR(const Device& device, MemoryAllocator& memory_allocator, size_t image
|
||||
.pPushConstantRanges = &range,
|
||||
};
|
||||
m_pipeline_layout = device.GetLogical().CreatePipelineLayout(ci);
|
||||
m_stage_pipeline = CreateWrappedPipeline(device, m_renderpass, m_pipeline_layout, std::tie(m_vert_shader, m_stage_shader));
|
||||
m_stage_pipeline = CreateWrappedPipeline(device, VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
m_pipeline_layout,
|
||||
std::tie(m_vert_shader, m_stage_shader));
|
||||
}
|
||||
|
||||
void SGSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index) {
|
||||
@@ -78,26 +76,14 @@ void SGSR::UpdateDescriptorSets(const Device& device, VkImageView image_view, si
|
||||
device.GetLogical().UpdateDescriptorSets(updates, {});
|
||||
}
|
||||
|
||||
void SGSR::UploadImages(const Device& device, Scheduler& scheduler) {
|
||||
if (!m_images_ready) {
|
||||
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
|
||||
for (auto& image : m_dynamic_images)
|
||||
ClearColorImage(cmdbuf, *image.image);
|
||||
});
|
||||
scheduler.Finish();
|
||||
m_images_ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
VkImageView SGSR::Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage source_image, VkImageView source_image_view, VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect) {
|
||||
Images& images = m_dynamic_images[image_index];
|
||||
auto const output_image = *images.image;
|
||||
auto const output_view = *images.image_view;
|
||||
auto const descriptor_set = images.descriptor_sets[0];
|
||||
auto const framebuffer = *images.framebuffer;
|
||||
auto const pipeline = *m_stage_pipeline;
|
||||
|
||||
VkPipelineLayout layout = *m_pipeline_layout;
|
||||
VkRenderPass renderpass = *m_renderpass;
|
||||
VkExtent2D extent = m_extent;
|
||||
|
||||
const f32 input_image_width = f32(input_image_extent.width);
|
||||
@@ -125,19 +111,19 @@ VkImageView SGSR::Draw(const Device& device, Scheduler& scheduler, size_t image_
|
||||
viewport_con[7] = std::bit_cast<u32>((std::min)(crop_rect.top, crop_rect.bottom));
|
||||
viewport_con[8] = std::bit_cast<u32>(edge_sharpness);
|
||||
|
||||
UploadImages(device, scheduler);
|
||||
UpdateDescriptorSets(device, source_image_view, image_index);
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([=](vk::CommandBuffer cmdbuf) {
|
||||
TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, renderpass, framebuffer, extent);
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, output_view, extent, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, {});
|
||||
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, viewport_con);
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
});
|
||||
return *images.image_view;
|
||||
|
||||
@@ -19,7 +19,6 @@ public:
|
||||
VkImageView Draw(const Device& device, Scheduler& scheduler, size_t image_index, VkImage source_image, VkImageView source_image_view, VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect);
|
||||
private:
|
||||
void Initialize(const Device& device);
|
||||
void UploadImages(const Device& device, Scheduler& scheduler);
|
||||
void UpdateDescriptorSets(const Device& device, VkImageView image_view, size_t image_index);
|
||||
|
||||
MemoryAllocator& m_memory_allocator;
|
||||
@@ -32,17 +31,14 @@ private:
|
||||
vk::ShaderModule m_vert_shader;
|
||||
vk::ShaderModule m_stage_shader;
|
||||
vk::Pipeline m_stage_pipeline;
|
||||
vk::RenderPass m_renderpass;
|
||||
vk::Sampler m_sampler;
|
||||
|
||||
struct Images {
|
||||
vk::DescriptorSets descriptor_sets;
|
||||
vk::Image image;
|
||||
vk::ImageView image_view;
|
||||
vk::Framebuffer framebuffer;
|
||||
};
|
||||
std::vector<Images> m_dynamic_images;
|
||||
bool m_images_ready{};
|
||||
bool m_edge_dir{};
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ SMAA::SMAA(const Device& device, MemoryAllocator& allocator, size_t image_count,
|
||||
, m_image_count(u32(image_count))
|
||||
{
|
||||
CreateImages(device);
|
||||
CreateRenderPasses(device);
|
||||
CreateSampler(device);
|
||||
CreateShaders(device);
|
||||
CreateDescriptorPool(device);
|
||||
@@ -74,26 +73,6 @@ void SMAA::CreateImages(const Device& device) {
|
||||
}
|
||||
}
|
||||
|
||||
void SMAA::CreateRenderPasses(const Device& device) {
|
||||
m_renderpasses[EdgeDetection] = CreateWrappedRenderPass(device, VK_FORMAT_R16G16_SFLOAT);
|
||||
m_renderpasses[BlendingWeightCalculation] =
|
||||
CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
m_renderpasses[NeighborhoodBlending] =
|
||||
CreateWrappedRenderPass(device, VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
|
||||
for (auto& images : m_dynamic_images) {
|
||||
images.framebuffers[EdgeDetection] = CreateWrappedFramebuffer(
|
||||
device, m_renderpasses[EdgeDetection], images.image_views[Edges], m_extent);
|
||||
|
||||
images.framebuffers[BlendingWeightCalculation] =
|
||||
CreateWrappedFramebuffer(device, m_renderpasses[BlendingWeightCalculation],
|
||||
images.image_views[Blend], m_extent);
|
||||
|
||||
images.framebuffers[NeighborhoodBlending] = CreateWrappedFramebuffer(
|
||||
device, m_renderpasses[NeighborhoodBlending], images.image_views[Output], m_extent);
|
||||
}
|
||||
}
|
||||
|
||||
void SMAA::CreateSampler(const Device& device) {
|
||||
m_sampler = CreateWrappedSampler(device);
|
||||
}
|
||||
@@ -155,9 +134,14 @@ void SMAA::CreatePipelineLayouts(const Device& device) {
|
||||
}
|
||||
|
||||
void SMAA::CreatePipelines(const Device& device) {
|
||||
static constexpr std::array<VkFormat, MaxSMAAStage> formats{
|
||||
VK_FORMAT_R16G16_SFLOAT,
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
};
|
||||
for (size_t i = 0; i < MaxSMAAStage; i++) {
|
||||
m_pipelines[i] =
|
||||
CreateWrappedPipeline(device, m_renderpasses[i], m_pipeline_layouts[i],
|
||||
CreateWrappedPipeline(device, formats[i], m_pipeline_layouts[i],
|
||||
std::tie(m_vertex_shaders[i], m_fragment_shaders[i]));
|
||||
}
|
||||
}
|
||||
@@ -202,15 +186,6 @@ void SMAA::UploadImages(const Device& device, Scheduler& scheduler) {
|
||||
UploadImage(device, m_allocator, scheduler, m_static_images[Search], search_extent,
|
||||
VK_FORMAT_R8_UNORM, ARRAY_TO_SPAN(searchTexBytes));
|
||||
|
||||
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
|
||||
for (auto& images : m_dynamic_images) {
|
||||
for (size_t i = 0; i < MaxDynamicImage; i++) {
|
||||
ClearColorImage(cmdbuf, *images.images[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
scheduler.Finish();
|
||||
|
||||
m_images_ready = true;
|
||||
}
|
||||
|
||||
@@ -228,10 +203,9 @@ void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index,
|
||||
VkDescriptorSet neighborhood_blending_descriptor_set =
|
||||
images.descriptor_sets[NeighborhoodBlending];
|
||||
|
||||
VkFramebuffer edge_detection_framebuffer = *images.framebuffers[EdgeDetection];
|
||||
VkFramebuffer blending_weight_calculation_framebuffer =
|
||||
*images.framebuffers[BlendingWeightCalculation];
|
||||
VkFramebuffer neighborhood_blending_framebuffer = *images.framebuffers[NeighborhoodBlending];
|
||||
VkImageView edges_view = *images.image_views[Edges];
|
||||
VkImageView blend_view = *images.image_views[Blend];
|
||||
VkImageView output_view = *images.image_views[Output];
|
||||
|
||||
UploadImages(device, scheduler);
|
||||
UpdateDescriptorSets(device, *inout_image_view, image_index);
|
||||
@@ -239,38 +213,38 @@ void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index,
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([=, this](vk::CommandBuffer cmdbuf) {
|
||||
TransitionImageLayout(cmdbuf, input_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, *m_renderpasses[EdgeDetection], edge_detection_framebuffer,
|
||||
m_extent);
|
||||
TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, edges_view, m_extent, VK_ATTACHMENT_LOAD_OP_CLEAR);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelines[EdgeDetection]);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
*m_pipeline_layouts[EdgeDetection], 0,
|
||||
edge_detection_descriptor_set, {});
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
|
||||
TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, blend_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, *m_renderpasses[BlendingWeightCalculation],
|
||||
blending_weight_calculation_framebuffer, m_extent);
|
||||
TransitionImageLayout(cmdbuf, blend_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, blend_view, m_extent, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
*m_pipelines[BlendingWeightCalculation]);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
*m_pipeline_layouts[BlendingWeightCalculation], 0,
|
||||
blending_weight_calculation_descriptor_set, {});
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
|
||||
TransitionImageLayout(cmdbuf, blend_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
BeginRenderPass(cmdbuf, *m_renderpasses[NeighborhoodBlending],
|
||||
neighborhood_blending_framebuffer, m_extent);
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, output_view, m_extent, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelines[NeighborhoodBlending]);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
*m_pipeline_layouts[NeighborhoodBlending], 0,
|
||||
neighborhood_blending_descriptor_set, {});
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL);
|
||||
});
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ private:
|
||||
};
|
||||
|
||||
void CreateImages(const Device& device);
|
||||
void CreateRenderPasses(const Device& device);
|
||||
void CreateSampler(const Device& device);
|
||||
void CreateShaders(const Device& device);
|
||||
void CreateDescriptorPool(const Device& device);
|
||||
@@ -68,7 +67,6 @@ private:
|
||||
std::array<vk::ShaderModule, MaxSMAAStage> m_vertex_shaders{};
|
||||
std::array<vk::ShaderModule, MaxSMAAStage> m_fragment_shaders{};
|
||||
std::array<vk::Pipeline, MaxSMAAStage> m_pipelines{};
|
||||
std::array<vk::RenderPass, MaxSMAAStage> m_renderpasses{};
|
||||
|
||||
std::array<vk::Image, MaxStaticImage> m_static_images{};
|
||||
std::array<vk::ImageView, MaxStaticImage> m_static_image_views{};
|
||||
@@ -77,7 +75,6 @@ private:
|
||||
vk::DescriptorSets descriptor_sets{};
|
||||
std::array<vk::Image, MaxDynamicImage> images{};
|
||||
std::array<vk::ImageView, MaxDynamicImage> image_views{};
|
||||
std::array<vk::Framebuffer, MaxSMAAStage> framebuffers{};
|
||||
};
|
||||
std::vector<Images> m_dynamic_images{};
|
||||
bool m_images_ready{};
|
||||
|
||||
@@ -198,100 +198,6 @@ vk::ImageView CreateWrappedImageView(const Device& device, vk::Image& image, VkF
|
||||
});
|
||||
}
|
||||
|
||||
vk::RenderPass CreateWrappedRenderPass(const Device& device, VkFormat format,
|
||||
VkImageLayout initial_layout) {
|
||||
const VkAttachmentDescription2 attachment{
|
||||
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
|
||||
.pNext = nullptr,
|
||||
.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,
|
||||
.format = format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = initial_layout == VK_IMAGE_LAYOUT_UNDEFINED ? VK_ATTACHMENT_LOAD_OP_DONT_CARE
|
||||
: VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.initialLayout = initial_layout,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
static constexpr VkAttachmentReference2 color_attachment_ref{
|
||||
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
|
||||
.pNext = nullptr,
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.aspectMask = 0,
|
||||
};
|
||||
|
||||
const VkSubpassDescription2 subpass_description{
|
||||
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.viewMask = 0,
|
||||
.inputAttachmentCount = 0,
|
||||
.pInputAttachments = nullptr,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &color_attachment_ref,
|
||||
.pResolveAttachments = nullptr,
|
||||
.pDepthStencilAttachment = nullptr,
|
||||
.preserveAttachmentCount = 0,
|
||||
.pPreserveAttachments = nullptr,
|
||||
};
|
||||
|
||||
static constexpr VkMemoryBarrier2 dependency_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
|
||||
.pNext = nullptr,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.dstAccessMask =
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
};
|
||||
|
||||
static constexpr VkSubpassDependency2 dependency{
|
||||
.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
|
||||
.pNext = &dependency_barrier,
|
||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
||||
.dstSubpass = 0,
|
||||
.srcStageMask = 0,
|
||||
.dstStageMask = 0,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = 0,
|
||||
.dependencyFlags = 0,
|
||||
.viewOffset = 0,
|
||||
};
|
||||
|
||||
return device.GetLogical().CreateRenderPass2(VkRenderPassCreateInfo2{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &attachment,
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subpass_description,
|
||||
.dependencyCount = 1,
|
||||
.pDependencies = &dependency,
|
||||
.correlatedViewMaskCount = 0,
|
||||
.pCorrelatedViewMasks = nullptr,
|
||||
});
|
||||
}
|
||||
|
||||
vk::Framebuffer CreateWrappedFramebuffer(const Device& device, vk::RenderPass& render_pass,
|
||||
vk::ImageView& dest_image, VkExtent2D extent) {
|
||||
return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.renderPass = *render_pass,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = dest_image.address(),
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.layers = 1,
|
||||
});
|
||||
}
|
||||
|
||||
vk::Sampler CreateWrappedSampler(const Device& device, VkFilter filter) {
|
||||
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
@@ -422,8 +328,20 @@ vk::PipelineLayout CreateWrappedPipelineLayout(const Device& device,
|
||||
});
|
||||
}
|
||||
|
||||
VkPipelineRenderingCreateInfo ColorRenderingInfo(const VkFormat& format) {
|
||||
return {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.viewMask = 0,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachmentFormats = &format,
|
||||
.depthAttachmentFormat = VK_FORMAT_UNDEFINED,
|
||||
.stencilAttachmentFormat = VK_FORMAT_UNDEFINED,
|
||||
};
|
||||
}
|
||||
|
||||
static vk::Pipeline CreateWrappedPipelineImpl(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
const Device& device, VkFormat format, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders,
|
||||
VkPipelineColorBlendAttachmentState blending) {
|
||||
const std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages{{
|
||||
@@ -527,9 +445,10 @@ static vk::Pipeline CreateWrappedPipelineImpl(
|
||||
.pDynamicStates = dynamic_states.data(),
|
||||
};
|
||||
|
||||
const VkPipelineRenderingCreateInfo rendering_ci = ColorRenderingInfo(format);
|
||||
return device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.pNext = &rendering_ci,
|
||||
.flags = 0,
|
||||
.stageCount = static_cast<u32>(shader_stages.size()),
|
||||
.pStages = shader_stages.data(),
|
||||
@@ -543,14 +462,14 @@ static vk::Pipeline CreateWrappedPipelineImpl(
|
||||
.pColorBlendState = &color_blend_ci,
|
||||
.pDynamicState = &dynamic_state_ci,
|
||||
.layout = *layout,
|
||||
.renderPass = *renderpass,
|
||||
.renderPass = VK_NULL_HANDLE,
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = 0,
|
||||
.basePipelineIndex = 0,
|
||||
});
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, VkFormat format,
|
||||
vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders) {
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_disabled{
|
||||
@@ -565,12 +484,12 @@ vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderp
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
return CreateWrappedPipelineImpl(device, renderpass, layout, shaders,
|
||||
return CreateWrappedPipelineImpl(device, format, layout, shaders,
|
||||
color_blend_attachment_disabled);
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedPremultipliedBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
const Device& device, VkFormat format, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders) {
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_premultiplied{
|
||||
.blendEnable = VK_TRUE,
|
||||
@@ -584,12 +503,12 @@ vk::Pipeline CreateWrappedPremultipliedBlendingPipeline(
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
return CreateWrappedPipelineImpl(device, renderpass, layout, shaders,
|
||||
return CreateWrappedPipelineImpl(device, format, layout, shaders,
|
||||
color_blend_attachment_premultiplied);
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedCoverageBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
const Device& device, VkFormat format, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders) {
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_coverage{
|
||||
.blendEnable = VK_TRUE,
|
||||
@@ -603,7 +522,7 @@ vk::Pipeline CreateWrappedCoverageBlendingPipeline(
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
return CreateWrappedPipelineImpl(device, renderpass, layout, shaders,
|
||||
return CreateWrappedPipelineImpl(device, format, layout, shaders,
|
||||
color_blend_attachment_coverage);
|
||||
}
|
||||
|
||||
@@ -725,21 +644,35 @@ void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) {
|
||||
cmdbuf.ClearColorImage(image, VK_IMAGE_LAYOUT_GENERAL, {}, subresources);
|
||||
}
|
||||
|
||||
void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer,
|
||||
VkExtent2D extent) {
|
||||
const VkRenderPassBeginInfo renderpass_bi{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
void BeginRendering(vk::CommandBuffer& cmdbuf, VkImageView view, VkExtent2D extent,
|
||||
VkAttachmentLoadOp load_op, const VkClearValue& clear_value) {
|
||||
const VkRenderingAttachmentInfo attachment{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.pNext = nullptr,
|
||||
.renderPass = render_pass,
|
||||
.framebuffer = framebuffer,
|
||||
.imageView = view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = VK_RESOLVE_MODE_NONE,
|
||||
.resolveImageView = VK_NULL_HANDLE,
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.loadOp = load_op,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.clearValue = clear_value,
|
||||
};
|
||||
cmdbuf.BeginRendering(VkRenderingInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.renderArea{
|
||||
.offset{},
|
||||
.extent = extent,
|
||||
},
|
||||
.clearValueCount = 0,
|
||||
.pClearValues = nullptr,
|
||||
};
|
||||
cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
|
||||
.layerCount = 1,
|
||||
.viewMask = 0,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &attachment,
|
||||
.pDepthAttachment = nullptr,
|
||||
.pStencilAttachment = nullptr,
|
||||
});
|
||||
|
||||
const VkViewport viewport{
|
||||
.x = 0.0f,
|
||||
|
||||
@@ -27,10 +27,6 @@ void DownloadColorImage(vk::CommandBuffer& cmdbuf, VkImage image, VkBuffer buffe
|
||||
void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image);
|
||||
|
||||
vk::ImageView CreateWrappedImageView(const Device& device, vk::Image& image, VkFormat format);
|
||||
vk::RenderPass CreateWrappedRenderPass(const Device& device, VkFormat format,
|
||||
VkImageLayout initial_layout = VK_IMAGE_LAYOUT_GENERAL);
|
||||
vk::Framebuffer CreateWrappedFramebuffer(const Device& device, vk::RenderPass& render_pass,
|
||||
vk::ImageView& dest_image, VkExtent2D extent);
|
||||
vk::Sampler CreateWrappedSampler(const Device& device, VkFilter filter = VK_FILTER_LINEAR);
|
||||
vk::ShaderModule CreateWrappedShaderModule(const Device& device, std::span<const u32> code);
|
||||
vk::DescriptorPool CreateWrappedDescriptorPool(const Device& device, size_t max_descriptors,
|
||||
@@ -47,16 +43,17 @@ vk::DescriptorSets CreateWrappedDescriptorSets(vk::DescriptorPool& pool,
|
||||
vk::Span<VkDescriptorSetLayout> layouts);
|
||||
vk::PipelineLayout CreateWrappedPipelineLayout(const Device& device,
|
||||
vk::DescriptorSetLayout& layout);
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
[[nodiscard]] VkPipelineRenderingCreateInfo ColorRenderingInfo(const VkFormat& format);
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, VkFormat format,
|
||||
vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders);
|
||||
vk::Pipeline CreateWrappedComputePipeline(const Device& device, vk::PipelineLayout& layout,
|
||||
VkShaderModule shader);
|
||||
vk::Pipeline CreateWrappedPremultipliedBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
const Device& device, VkFormat format, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders);
|
||||
vk::Pipeline CreateWrappedCoverageBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
const Device& device, VkFormat format, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders);
|
||||
VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector<VkDescriptorImageInfo>& images,
|
||||
VkSampler sampler, VkImageView view,
|
||||
@@ -65,7 +62,7 @@ vk::Sampler CreateBilinearSampler(const Device& device);
|
||||
vk::Sampler CreateNearestNeighborSampler(const Device& device);
|
||||
vk::Sampler CreateCubicSampler(const Device& device, VkCubicFilterWeightsQCOM qcom_weights);
|
||||
|
||||
void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer,
|
||||
VkExtent2D extent);
|
||||
void BeginRendering(vk::CommandBuffer& cmdbuf, VkImageView view, VkExtent2D extent,
|
||||
VkAttachmentLoadOp load_op, const VkClearValue& clear_value = {});
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -25,8 +25,7 @@ WindowAdaptPass::WindowAdaptPass(const Device& device, VkFormat frame_format, vk
|
||||
CreateDescriptorSetLayout(device);
|
||||
CreatePipelineLayout(device);
|
||||
CreateVertexShader(device);
|
||||
CreateRenderPass(device, frame_format);
|
||||
CreatePipelines(device);
|
||||
CreatePipelines(device, frame_format);
|
||||
}
|
||||
|
||||
WindowAdaptPass::~WindowAdaptPass() = default;
|
||||
@@ -36,8 +35,8 @@ void WindowAdaptPass::Draw(const Device& device, RasterizerVulkan& rasterizer, S
|
||||
std::span<const Tegra::FramebufferConfig> configs,
|
||||
const Layout::FramebufferLayout& layout, Frame* dst) {
|
||||
|
||||
const VkFramebuffer host_framebuffer{*dst->framebuffer};
|
||||
const VkRenderPass renderpass{*render_pass};
|
||||
const VkImage host_image{*dst->image};
|
||||
const VkImageView host_view{*dst->image_view};
|
||||
const VkPipelineLayout graphics_pipeline_layout{*pipeline_layout};
|
||||
const VkExtent2D render_area{
|
||||
.width = dst->width,
|
||||
@@ -73,26 +72,13 @@ void WindowAdaptPass::Draw(const Device& device, RasterizerVulkan& rasterizer, S
|
||||
const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f;
|
||||
const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f;
|
||||
const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f;
|
||||
const VkClearAttachment clear_attachment{
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.colorAttachment = 0,
|
||||
.clearValue =
|
||||
{
|
||||
.color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}},
|
||||
},
|
||||
};
|
||||
const VkClearRect clear_rect{
|
||||
.rect =
|
||||
{
|
||||
.offset = {0, 0},
|
||||
.extent = render_area,
|
||||
},
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
const VkClearValue clear_value{
|
||||
.color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}},
|
||||
};
|
||||
|
||||
BeginRenderPass(cmdbuf, renderpass, host_framebuffer, render_area);
|
||||
cmdbuf.ClearAttachments({clear_attachment}, {clear_rect});
|
||||
TransitionImageLayout(cmdbuf, host_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
BeginRendering(cmdbuf, host_view, render_area, VK_ATTACHMENT_LOAD_OP_CLEAR, clear_value);
|
||||
|
||||
for (size_t i = 0; i < layer_count; i++) {
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipelines[i]);
|
||||
@@ -103,7 +89,7 @@ void WindowAdaptPass::Draw(const Device& device, RasterizerVulkan& rasterizer, S
|
||||
cmdbuf.Draw(4, 1, 0, 0);
|
||||
}
|
||||
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.EndRendering();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -111,10 +97,6 @@ VkDescriptorSetLayout WindowAdaptPass::GetDescriptorSetLayout() {
|
||||
return *descriptor_set_layout;
|
||||
}
|
||||
|
||||
VkRenderPass WindowAdaptPass::GetRenderPass() {
|
||||
return *render_pass;
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreateDescriptorSetLayout(const Device& device) {
|
||||
descriptor_set_layout =
|
||||
CreateWrappedDescriptorSetLayout(device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER});
|
||||
@@ -142,17 +124,13 @@ void WindowAdaptPass::CreateVertexShader(const Device& device) {
|
||||
vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV);
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreateRenderPass(const Device& device, VkFormat frame_format) {
|
||||
render_pass = CreateWrappedRenderPass(device, frame_format, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreatePipelines(const Device& device) {
|
||||
opaque_pipeline = CreateWrappedPipeline(device, render_pass, pipeline_layout,
|
||||
void WindowAdaptPass::CreatePipelines(const Device& device, VkFormat frame_format) {
|
||||
opaque_pipeline = CreateWrappedPipeline(device, frame_format, pipeline_layout,
|
||||
std::tie(vertex_shader, fragment_shader));
|
||||
premultiplied_pipeline = CreateWrappedPremultipliedBlendingPipeline(
|
||||
device, render_pass, pipeline_layout, std::tie(vertex_shader, fragment_shader));
|
||||
device, frame_format, pipeline_layout, std::tie(vertex_shader, fragment_shader));
|
||||
coverage_pipeline = CreateWrappedCoverageBlendingPipeline(
|
||||
device, render_pass, pipeline_layout, std::tie(vertex_shader, fragment_shader));
|
||||
device, frame_format, pipeline_layout, std::tie(vertex_shader, fragment_shader));
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -38,21 +38,18 @@ public:
|
||||
const Layout::FramebufferLayout& layout, Frame* dst);
|
||||
|
||||
VkDescriptorSetLayout GetDescriptorSetLayout();
|
||||
VkRenderPass GetRenderPass();
|
||||
|
||||
private:
|
||||
void CreateDescriptorSetLayout(const Device& device);
|
||||
void CreatePipelineLayout(const Device& device);
|
||||
void CreateVertexShader(const Device& device);
|
||||
void CreateRenderPass(const Device& device, VkFormat frame_format);
|
||||
void CreatePipelines(const Device& device);
|
||||
void CreatePipelines(const Device& device, VkFormat frame_format);
|
||||
|
||||
vk::DescriptorSetLayout descriptor_set_layout;
|
||||
vk::PipelineLayout pipeline_layout;
|
||||
vk::Sampler sampler;
|
||||
vk::ShaderModule vertex_shader;
|
||||
vk::ShaderModule fragment_shader;
|
||||
vk::RenderPass render_pass;
|
||||
vk::Pipeline opaque_pipeline;
|
||||
vk::Pipeline premultiplied_pipeline;
|
||||
vk::Pipeline coverage_pipeline;
|
||||
|
||||
@@ -275,7 +275,6 @@ vk::Buffer RendererVulkan::RenderToBuffer(std::span<const Tegra::FramebufferConf
|
||||
f.image =
|
||||
CreateWrappedImage(memory_allocator, VkExtent2D{layout.width, layout.height}, format);
|
||||
f.image_view = CreateWrappedImageView(device, f.image, format);
|
||||
f.framebuffer = blit_capture.CreateFramebuffer(device, layout, *f.image_view, format);
|
||||
return f;
|
||||
}();
|
||||
|
||||
@@ -353,8 +352,6 @@ void RendererVulkan::RenderAppletCaptureLayer(
|
||||
if (!applet_frame.image) {
|
||||
applet_frame.image = CreateWrappedImage(memory_allocator, CaptureImageSize, CaptureFormat);
|
||||
applet_frame.image_view = CreateWrappedImageView(device, applet_frame.image, CaptureFormat);
|
||||
applet_frame.framebuffer = blit_applet.CreateFramebuffer(device,
|
||||
VideoCore::Capture::Layout, *applet_frame.image_view, CaptureFormat);
|
||||
}
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
|
||||
@@ -98,8 +98,7 @@ void BlitScreen::PrepareFrame(const Device& device, Frame* frame,
|
||||
return;
|
||||
}
|
||||
|
||||
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
|
||||
window_adapt->GetRenderPass(), true);
|
||||
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format, true);
|
||||
}
|
||||
|
||||
void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer, Frame* frame,
|
||||
@@ -133,13 +132,13 @@ void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer,
|
||||
|
||||
if (presentation_recreate_required) {
|
||||
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
|
||||
window_adapt->GetRenderPass(), storage_required);
|
||||
storage_required);
|
||||
}
|
||||
|
||||
image_index = 0;
|
||||
} else if (present_manager.NeedsStorage(frame, storage_required)) {
|
||||
present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format,
|
||||
window_adapt->GetRenderPass(), true);
|
||||
true);
|
||||
}
|
||||
|
||||
const VkExtent2D window_size{
|
||||
@@ -162,39 +161,4 @@ void BlitScreen::DrawToFrame(const Device& device, RasterizerVulkan& rasterizer,
|
||||
}
|
||||
}
|
||||
|
||||
vk::Framebuffer BlitScreen::CreateFramebuffer(const Device& device, const Layout::FramebufferLayout& layout,
|
||||
VkImageView image_view,
|
||||
VkFormat current_view_format) {
|
||||
bool format_updated = swapchain_view_format != current_view_format;
|
||||
swapchain_view_format = current_view_format;
|
||||
|
||||
if (!window_adapt || scaling_filter != filters.get_scaling_filter() || format_updated) {
|
||||
WaitIdle(device);
|
||||
SetWindowAdaptPass(device);
|
||||
image_index = 0;
|
||||
}
|
||||
|
||||
const VkExtent2D extent{
|
||||
.width = layout.width,
|
||||
.height = layout.height,
|
||||
};
|
||||
|
||||
return CreateFramebuffer(device, image_view, extent, window_adapt->GetRenderPass());
|
||||
}
|
||||
|
||||
vk::Framebuffer BlitScreen::CreateFramebuffer(const Device& device, const VkImageView& image_view, VkExtent2D extent,
|
||||
VkRenderPass render_pass) {
|
||||
return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.renderPass = render_pass,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &image_view,
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.layers = 1,
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -62,15 +62,9 @@ public:
|
||||
|
||||
void PrepareFrame(const Device& device, Frame* frame, const Layout::FramebufferLayout& layout);
|
||||
|
||||
[[nodiscard]] vk::Framebuffer CreateFramebuffer(const Device& device, const Layout::FramebufferLayout& layout,
|
||||
VkImageView image_view,
|
||||
VkFormat current_view_format);
|
||||
|
||||
private:
|
||||
void WaitIdle(const Device& device);
|
||||
void SetWindowAdaptPass(const Device& device);
|
||||
vk::Framebuffer CreateFramebuffer(const Device& device, const VkImageView& image_view, VkExtent2D extent,
|
||||
VkRenderPass render_pass);
|
||||
|
||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||
MemoryAllocator& memory_allocator;
|
||||
|
||||
@@ -209,7 +209,7 @@ bool PresentManager::NeedsStorage(const Frame* frame, bool required) const {
|
||||
}
|
||||
|
||||
void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format,
|
||||
VkRenderPass rd, bool storage) {
|
||||
bool storage) {
|
||||
auto& dld = device.GetLogical();
|
||||
|
||||
frame->width = width;
|
||||
@@ -295,19 +295,6 @@ void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const VkImageView image_view{*frame->image_view};
|
||||
frame->framebuffer = dld.CreateFramebuffer({
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.renderPass = rd,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &image_view,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.layers = 1,
|
||||
});
|
||||
}
|
||||
|
||||
void PresentManager::WaitPresent() {
|
||||
|
||||
@@ -33,7 +33,6 @@ struct Frame {
|
||||
vk::Image image;
|
||||
vk::ImageView image_view;
|
||||
vk::ImageView storage_view;
|
||||
vk::Framebuffer framebuffer;
|
||||
vk::CommandBuffer cmdbuf;
|
||||
vk::Semaphore render_ready;
|
||||
vk::Fence present_done;
|
||||
@@ -59,7 +58,7 @@ public:
|
||||
|
||||
/// Recreates the present frame to match the provided parameters
|
||||
void RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format,
|
||||
VkRenderPass rd, bool storage);
|
||||
bool storage);
|
||||
|
||||
[[nodiscard]] bool NeedsStorage(const Frame* frame, bool required) const;
|
||||
|
||||
|
||||
@@ -1423,8 +1423,7 @@ void Device::RemoveUnsuitableExtensions() {
|
||||
|
||||
extensions.synchronization2 = features.synchronization2.synchronization2;
|
||||
extensions.dynamic_rendering = features.dynamic_rendering.dynamicRendering;
|
||||
if (!extensions.synchronization2 || !extensions.dynamic_rendering ||
|
||||
!IsKhrCreateRenderPass2Supported()) {
|
||||
if (!extensions.synchronization2 || !extensions.dynamic_rendering) {
|
||||
throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,11 +637,6 @@ FN_MAX_LIMIT_LIST
|
||||
return extensions.shader_stencil_export;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_KHR_create_renderpass2.
|
||||
bool IsKhrCreateRenderPass2Supported() const {
|
||||
return extensions.create_renderpass2 || instance_version >= VK_API_VERSION_1_2;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_KHR_depth_stencil_resolve.
|
||||
bool IsKhrDepthStencilResolveSupported() const {
|
||||
return extensions.depth_stencil_resolve || instance_version >= VK_API_VERSION_1_2;
|
||||
|
||||
@@ -88,7 +88,6 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
X(vkBeginCommandBuffer);
|
||||
X(vkCmdBeginConditionalRenderingEXT);
|
||||
X(vkCmdBeginQuery);
|
||||
X(vkCmdBeginRenderPass);
|
||||
X(vkCmdBeginRendering);
|
||||
X(vkCmdBeginTransformFeedbackEXT);
|
||||
X(vkCmdBindDescriptorSets);
|
||||
@@ -116,7 +115,6 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
X(vkCmdDrawIndirectByteCountEXT);
|
||||
X(vkCmdEndConditionalRenderingEXT);
|
||||
X(vkCmdEndQuery);
|
||||
X(vkCmdEndRenderPass);
|
||||
X(vkCmdEndRendering);
|
||||
X(vkCmdEndTransformFeedbackEXT);
|
||||
X(vkCmdFillBuffer);
|
||||
@@ -169,13 +167,11 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
X(vkCreateDescriptorSetLayout);
|
||||
X(vkCreateDescriptorUpdateTemplate);
|
||||
X(vkCreateFence);
|
||||
X(vkCreateFramebuffer);
|
||||
X(vkCreateGraphicsPipelines);
|
||||
X(vkCreateImageView);
|
||||
X(vkCreatePipelineCache);
|
||||
X(vkCreatePipelineLayout);
|
||||
X(vkCreateQueryPool);
|
||||
X(vkCreateRenderPass2);
|
||||
X(vkCreateSampler);
|
||||
X(vkCreateSemaphore);
|
||||
X(vkCreateShaderModule);
|
||||
@@ -187,14 +183,12 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
X(vkDestroyDescriptorSetLayout);
|
||||
X(vkDestroyDescriptorUpdateTemplate);
|
||||
X(vkDestroyFence);
|
||||
X(vkDestroyFramebuffer);
|
||||
X(vkDestroyImage);
|
||||
X(vkDestroyImageView);
|
||||
X(vkDestroyPipeline);
|
||||
X(vkDestroyPipelineCache);
|
||||
X(vkDestroyPipelineLayout);
|
||||
X(vkDestroyQueryPool);
|
||||
X(vkDestroyRenderPass);
|
||||
X(vkDestroySampler);
|
||||
X(vkDestroySemaphore);
|
||||
X(vkDestroyShaderModule);
|
||||
@@ -265,10 +259,6 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
if (!dld.vkCmdEndRendering) {
|
||||
Proc(dld.vkCmdEndRendering, dld, "vkCmdEndRenderingKHR", device);
|
||||
}
|
||||
|
||||
if (!dld.vkCreateRenderPass2) {
|
||||
Proc(dld.vkCreateRenderPass2, dld, "vkCreateRenderPass2KHR", device);
|
||||
}
|
||||
#undef X
|
||||
}
|
||||
|
||||
@@ -363,10 +353,6 @@ void Destroy(VkDevice device, VkFence handle, const DeviceDispatch& dld) noexcep
|
||||
dld.vkDestroyFence(device, handle, nullptr);
|
||||
}
|
||||
|
||||
void Destroy(VkDevice device, VkFramebuffer handle, const DeviceDispatch& dld) noexcept {
|
||||
dld.vkDestroyFramebuffer(device, handle, nullptr);
|
||||
}
|
||||
|
||||
void Destroy(VkDevice device, VkImage handle, const DeviceDispatch& dld) noexcept {
|
||||
dld.vkDestroyImage(device, handle, nullptr);
|
||||
}
|
||||
@@ -391,10 +377,6 @@ void Destroy(VkDevice device, VkQueryPool handle, const DeviceDispatch& dld) noe
|
||||
dld.vkDestroyQueryPool(device, handle, nullptr);
|
||||
}
|
||||
|
||||
void Destroy(VkDevice device, VkRenderPass handle, const DeviceDispatch& dld) noexcept {
|
||||
dld.vkDestroyRenderPass(device, handle, nullptr);
|
||||
}
|
||||
|
||||
void Destroy(VkDevice device, VkSampler handle, const DeviceDispatch& dld) noexcept {
|
||||
dld.vkDestroySampler(device, handle, nullptr);
|
||||
}
|
||||
@@ -529,10 +511,6 @@ void Fence::SetObjectNameEXT(const char* name) const {
|
||||
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_FENCE, name);
|
||||
}
|
||||
|
||||
void Framebuffer::SetObjectNameEXT(const char* name) const {
|
||||
SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_FRAMEBUFFER, name);
|
||||
}
|
||||
|
||||
DescriptorSets DescriptorPool::Allocate(const VkDescriptorSetAllocateInfo& ai) const {
|
||||
const std::size_t num = ai.descriptorSetCount;
|
||||
std::unique_ptr sets = std::make_unique<VkDescriptorSet[]>(num);
|
||||
@@ -662,12 +640,6 @@ DescriptorPool Device::CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci
|
||||
return DescriptorPool(object, handle, *dld);
|
||||
}
|
||||
|
||||
RenderPass Device::CreateRenderPass2(const VkRenderPassCreateInfo2& ci) const {
|
||||
VkRenderPass object;
|
||||
Check(dld->vkCreateRenderPass2(handle, &ci, nullptr, &object));
|
||||
return RenderPass(object, handle, *dld);
|
||||
}
|
||||
|
||||
DescriptorSetLayout Device::CreateDescriptorSetLayout(
|
||||
const VkDescriptorSetLayoutCreateInfo& ci) const {
|
||||
VkDescriptorSetLayout object;
|
||||
@@ -712,12 +684,6 @@ Sampler Device::CreateSampler(const VkSamplerCreateInfo& ci) const {
|
||||
return Sampler(object, handle, *dld);
|
||||
}
|
||||
|
||||
Framebuffer Device::CreateFramebuffer(const VkFramebufferCreateInfo& ci) const {
|
||||
VkFramebuffer object;
|
||||
Check(dld->vkCreateFramebuffer(handle, &ci, nullptr, &object));
|
||||
return Framebuffer(object, handle, *dld);
|
||||
}
|
||||
|
||||
CommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo& ci) const {
|
||||
VkCommandPool object;
|
||||
Check(dld->vkCreateCommandPool(handle, &ci, nullptr, &object));
|
||||
|
||||
@@ -237,7 +237,6 @@ struct DeviceDispatch : InstanceDispatch {
|
||||
PFN_vkBeginCommandBuffer vkBeginCommandBuffer{};
|
||||
PFN_vkCmdBeginConditionalRenderingEXT vkCmdBeginConditionalRenderingEXT{};
|
||||
PFN_vkCmdBeginQuery vkCmdBeginQuery{};
|
||||
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass{};
|
||||
PFN_vkCmdBeginRendering vkCmdBeginRendering{};
|
||||
PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT{};
|
||||
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets{};
|
||||
@@ -266,7 +265,6 @@ struct DeviceDispatch : InstanceDispatch {
|
||||
PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT{};
|
||||
PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT{};
|
||||
PFN_vkCmdEndQuery vkCmdEndQuery{};
|
||||
PFN_vkCmdEndRenderPass vkCmdEndRenderPass{};
|
||||
PFN_vkCmdEndRendering vkCmdEndRendering{};
|
||||
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
|
||||
PFN_vkCmdFillBuffer vkCmdFillBuffer{};
|
||||
@@ -318,13 +316,11 @@ struct DeviceDispatch : InstanceDispatch {
|
||||
PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout{};
|
||||
PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate{};
|
||||
PFN_vkCreateFence vkCreateFence{};
|
||||
PFN_vkCreateFramebuffer vkCreateFramebuffer{};
|
||||
PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines{};
|
||||
PFN_vkCreateImageView vkCreateImageView{};
|
||||
PFN_vkCreatePipelineCache vkCreatePipelineCache{};
|
||||
PFN_vkCreatePipelineLayout vkCreatePipelineLayout{};
|
||||
PFN_vkCreateQueryPool vkCreateQueryPool{};
|
||||
PFN_vkCreateRenderPass2 vkCreateRenderPass2{};
|
||||
PFN_vkCreateSampler vkCreateSampler{};
|
||||
PFN_vkCreateSemaphore vkCreateSemaphore{};
|
||||
PFN_vkCreateShaderModule vkCreateShaderModule{};
|
||||
@@ -336,14 +332,12 @@ struct DeviceDispatch : InstanceDispatch {
|
||||
PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout{};
|
||||
PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate{};
|
||||
PFN_vkDestroyFence vkDestroyFence{};
|
||||
PFN_vkDestroyFramebuffer vkDestroyFramebuffer{};
|
||||
PFN_vkDestroyImage vkDestroyImage{};
|
||||
PFN_vkDestroyImageView vkDestroyImageView{};
|
||||
PFN_vkDestroyPipeline vkDestroyPipeline{};
|
||||
PFN_vkDestroyPipelineCache vkDestroyPipelineCache{};
|
||||
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout{};
|
||||
PFN_vkDestroyQueryPool vkDestroyQueryPool{};
|
||||
PFN_vkDestroyRenderPass vkDestroyRenderPass{};
|
||||
PFN_vkDestroySampler vkDestroySampler{};
|
||||
PFN_vkDestroySemaphore vkDestroySemaphore{};
|
||||
PFN_vkDestroyShaderModule vkDestroyShaderModule{};
|
||||
@@ -396,14 +390,12 @@ void Destroy(VkDevice, VkDescriptorPool, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkDescriptorUpdateTemplate, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkFramebuffer, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkImage, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkImageView, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkPipeline, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkPipelineCache, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkPipelineLayout, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkQueryPool, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkRenderPass, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkSampler, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkSwapchainKHR, const DeviceDispatch&) noexcept;
|
||||
void Destroy(VkDevice, VkSemaphore, const DeviceDispatch&) noexcept;
|
||||
@@ -651,7 +643,6 @@ using DescriptorUpdateTemplate = Handle<VkDescriptorUpdateTemplate, VkDevice, De
|
||||
using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>;
|
||||
using PipelineLayout = Handle<VkPipelineLayout, VkDevice, DeviceDispatch>;
|
||||
using QueryPool = Handle<VkQueryPool, VkDevice, DeviceDispatch>;
|
||||
using RenderPass = Handle<VkRenderPass, VkDevice, DeviceDispatch>;
|
||||
using Sampler = Handle<VkSampler, VkDevice, DeviceDispatch>;
|
||||
using SurfaceKHR = Handle<VkSurfaceKHR, VkInstance, InstanceDispatch>;
|
||||
|
||||
@@ -905,14 +896,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class Framebuffer : public Handle<VkFramebuffer, VkDevice, DeviceDispatch> {
|
||||
using Handle<VkFramebuffer, VkDevice, DeviceDispatch>::Handle;
|
||||
|
||||
public:
|
||||
/// Set object name.
|
||||
void SetObjectNameEXT(const char* name) const;
|
||||
};
|
||||
|
||||
class DescriptorPool : public Handle<VkDescriptorPool, VkDevice, DeviceDispatch> {
|
||||
using Handle<VkDescriptorPool, VkDevice, DeviceDispatch>::Handle;
|
||||
|
||||
@@ -1025,8 +1008,6 @@ public:
|
||||
|
||||
[[nodiscard]] DescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci) const;
|
||||
|
||||
[[nodiscard]] RenderPass CreateRenderPass2(const VkRenderPassCreateInfo2& ci) const;
|
||||
|
||||
[[nodiscard]] DescriptorSetLayout CreateDescriptorSetLayout(
|
||||
const VkDescriptorSetLayoutCreateInfo& ci) const;
|
||||
|
||||
@@ -1042,8 +1023,6 @@ public:
|
||||
|
||||
[[nodiscard]] Sampler CreateSampler(const VkSamplerCreateInfo& ci) const;
|
||||
|
||||
[[nodiscard]] Framebuffer CreateFramebuffer(const VkFramebufferCreateInfo& ci) const;
|
||||
|
||||
[[nodiscard]] CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const;
|
||||
|
||||
[[nodiscard]] DescriptorUpdateTemplate CreateDescriptorUpdateTemplate(
|
||||
@@ -1187,15 +1166,6 @@ public:
|
||||
Check(dld->vkEndCommandBuffer(handle));
|
||||
}
|
||||
|
||||
void BeginRenderPass(const VkRenderPassBeginInfo& renderpass_bi,
|
||||
VkSubpassContents contents) const noexcept {
|
||||
dld->vkCmdBeginRenderPass(handle, &renderpass_bi, contents);
|
||||
}
|
||||
|
||||
void EndRenderPass() const noexcept {
|
||||
dld->vkCmdEndRenderPass(handle);
|
||||
}
|
||||
|
||||
void BeginRendering(const VkRenderingInfo& rendering_info) const noexcept {
|
||||
dld->vkCmdBeginRendering(handle, &rendering_info);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user