mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-26 00:56:45 +00:00
[vulkan] Initial dynamic rendering implementation
This commit is contained in:
@@ -545,6 +545,10 @@ void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view)
|
|||||||
|
|
||||||
void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) {
|
void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) {
|
||||||
const VkRenderPass render_pass = framebuffer->RenderPass();
|
const VkRenderPass render_pass = framebuffer->RenderPass();
|
||||||
|
if (!render_pass) {
|
||||||
|
framebuffer->BeginRendering(cmdbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const VkFramebuffer framebuffer_handle = framebuffer->Handle();
|
const VkFramebuffer framebuffer_handle = framebuffer->Handle();
|
||||||
const VkExtent2D render_area = framebuffer->RenderArea();
|
const VkExtent2D render_area = framebuffer->RenderArea();
|
||||||
const VkRenderPassBeginInfo renderpass_bi{
|
const VkRenderPassBeginInfo renderpass_bi{
|
||||||
@@ -561,6 +565,31 @@ void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer)
|
|||||||
};
|
};
|
||||||
cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
|
cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EndRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) {
|
||||||
|
if (framebuffer->RenderPass()) {
|
||||||
|
cmdbuf.EndRenderPass();
|
||||||
|
} else {
|
||||||
|
cmdbuf.EndRendering();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] VkPipelineRenderingCreateInfo MakePipelineRenderingCreateInfo(
|
||||||
|
const Framebuffer* framebuffer) {
|
||||||
|
return VkPipelineRenderingCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.viewMask = 0,
|
||||||
|
.colorAttachmentCount = framebuffer->NumColorAttachments(),
|
||||||
|
.pColorAttachmentFormats = framebuffer->ColorAttachmentFormats().data(),
|
||||||
|
.depthAttachmentFormat = framebuffer->HasAspectDepthBit()
|
||||||
|
? framebuffer->DepthAttachmentFormat()
|
||||||
|
: VK_FORMAT_UNDEFINED,
|
||||||
|
.stencilAttachmentFormat = framebuffer->HasAspectStencilBit()
|
||||||
|
? framebuffer->DepthAttachmentFormat()
|
||||||
|
: VK_FORMAT_UNDEFINED,
|
||||||
|
};
|
||||||
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
|
BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
|
||||||
@@ -623,10 +652,12 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageV
|
|||||||
const BlitImagePipelineKey key{
|
const BlitImagePipelineKey key{
|
||||||
.renderpass = dst_framebuffer->RenderPass(),
|
.renderpass = dst_framebuffer->RenderPass(),
|
||||||
.operation = operation,
|
.operation = operation,
|
||||||
|
.color_formats = dst_framebuffer->ColorAttachmentFormats(),
|
||||||
|
.depth_format = dst_framebuffer->DepthAttachmentFormat(),
|
||||||
};
|
};
|
||||||
const VkPipelineLayout layout = *one_texture_pipeline_layout;
|
const VkPipelineLayout layout = *one_texture_pipeline_layout;
|
||||||
const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler;
|
const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler;
|
||||||
const VkPipeline pipeline = FindOrEmplaceColorPipeline(key);
|
const VkPipeline pipeline = FindOrEmplaceColorPipeline(key, dst_framebuffer);
|
||||||
const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
|
const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
|
||||||
|
|
||||||
RecordShaderReadBarrier(scheduler, src_image_view);
|
RecordShaderReadBarrier(scheduler, src_image_view);
|
||||||
@@ -651,9 +682,11 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
|
|||||||
const BlitImagePipelineKey key{
|
const BlitImagePipelineKey key{
|
||||||
.renderpass = dst_framebuffer->RenderPass(),
|
.renderpass = dst_framebuffer->RenderPass(),
|
||||||
.operation = Tegra::Engines::Fermi2D::Operation::SrcCopy,
|
.operation = Tegra::Engines::Fermi2D::Operation::SrcCopy,
|
||||||
|
.color_formats = dst_framebuffer->ColorAttachmentFormats(),
|
||||||
|
.depth_format = dst_framebuffer->DepthAttachmentFormat(),
|
||||||
};
|
};
|
||||||
const VkPipelineLayout layout = *one_texture_pipeline_layout;
|
const VkPipelineLayout layout = *one_texture_pipeline_layout;
|
||||||
const VkPipeline pipeline = FindOrEmplaceColorPipeline(key);
|
const VkPipeline pipeline = FindOrEmplaceColorPipeline(key, dst_framebuffer);
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
scheduler.Record([this, dst_framebuffer, src_image_view, src_image, src_sampler, dst_region,
|
scheduler.Record([this, dst_framebuffer, src_image_view, src_image, src_sampler, dst_region,
|
||||||
src_region, src_size, pipeline, layout](vk::CommandBuffer cmdbuf) {
|
src_region, src_size, pipeline, layout](vk::CommandBuffer cmdbuf) {
|
||||||
@@ -666,7 +699,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
|
|||||||
nullptr);
|
nullptr);
|
||||||
BindBlitState(cmdbuf, layout, dst_region, src_region, src_size);
|
BindBlitState(cmdbuf, layout, dst_region, src_region, src_size);
|
||||||
cmdbuf.Draw(3, 1, 0, 0);
|
cmdbuf.Draw(3, 1, 0, 0);
|
||||||
cmdbuf.EndRenderPass();
|
EndRenderPass(cmdbuf, dst_framebuffer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,10 +780,12 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
|
|||||||
const BlitImagePipelineKey key{
|
const BlitImagePipelineKey key{
|
||||||
.renderpass = dst_framebuffer->RenderPass(),
|
.renderpass = dst_framebuffer->RenderPass(),
|
||||||
.operation = operation,
|
.operation = operation,
|
||||||
|
.color_formats = dst_framebuffer->ColorAttachmentFormats(),
|
||||||
|
.depth_format = dst_framebuffer->DepthAttachmentFormat(),
|
||||||
};
|
};
|
||||||
const VkPipelineLayout layout = *two_textures_pipeline_layout;
|
const VkPipelineLayout layout = *two_textures_pipeline_layout;
|
||||||
const VkSampler sampler = *nearest_sampler;
|
const VkSampler sampler = *nearest_sampler;
|
||||||
const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key);
|
const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key, dst_framebuffer);
|
||||||
const VkImageView src_depth_view = src_image_view.DepthView();
|
const VkImageView src_depth_view = src_image_view.DepthView();
|
||||||
const VkImageView src_stencil_view = src_image_view.StencilView();
|
const VkImageView src_stencil_view = src_image_view.StencilView();
|
||||||
|
|
||||||
@@ -772,25 +807,25 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
|
|||||||
|
|
||||||
void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
|
||||||
const ImageView& src_image_view) {
|
const ImageView& src_image_view) {
|
||||||
ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass());
|
ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer);
|
||||||
Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view);
|
Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
|
||||||
const ImageView& src_image_view) {
|
const ImageView& src_image_view) {
|
||||||
ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass());
|
ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer);
|
||||||
Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
|
Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer,
|
||||||
const ImageView& src_image_view) {
|
const ImageView& src_image_view) {
|
||||||
ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass());
|
ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer);
|
||||||
Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view);
|
Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
|
||||||
const ImageView& src_image_view) {
|
const ImageView& src_image_view) {
|
||||||
ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass());
|
ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer);
|
||||||
Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view);
|
Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,35 +836,35 @@ void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
|
|||||||
LOG_WARNING(Render_Vulkan, "ConvertABGR8ToD24S8 requires shader_stencil_export, skipping");
|
LOG_WARNING(Render_Vulkan, "ConvertABGR8ToD24S8 requires shader_stencil_export, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
|
ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer,
|
||||||
convert_abgr8_to_d24s8_frag);
|
convert_abgr8_to_d24s8_frag);
|
||||||
Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
|
Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer,
|
||||||
const ImageView& src_image_view) {
|
const ImageView& src_image_view) {
|
||||||
ConvertPipelineDepthTargetEx(convert_abgr8_to_d32f_pipeline, dst_framebuffer->RenderPass(),
|
ConvertPipelineDepthTargetEx(convert_abgr8_to_d32f_pipeline, dst_framebuffer,
|
||||||
convert_abgr8_to_d32f_frag);
|
convert_abgr8_to_d32f_frag);
|
||||||
Convert(*convert_abgr8_to_d32f_pipeline, dst_framebuffer, src_image_view);
|
Convert(*convert_abgr8_to_d32f_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer,
|
||||||
ImageView& src_image_view) {
|
ImageView& src_image_view) {
|
||||||
ConvertPipelineColorTargetEx(convert_d32f_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
|
ConvertPipelineColorTargetEx(convert_d32f_to_abgr8_pipeline, dst_framebuffer,
|
||||||
convert_d32f_to_abgr8_frag);
|
convert_d32f_to_abgr8_frag);
|
||||||
ConvertDepthStencil(*convert_d32f_to_abgr8_pipeline, dst_framebuffer, src_image_view);
|
ConvertDepthStencil(*convert_d32f_to_abgr8_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
|
||||||
ImageView& src_image_view) {
|
ImageView& src_image_view) {
|
||||||
ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
|
ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer,
|
||||||
convert_d24s8_to_abgr8_frag);
|
convert_d24s8_to_abgr8_frag);
|
||||||
ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view);
|
ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer,
|
void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer,
|
||||||
ImageView& src_image_view) {
|
ImageView& src_image_view) {
|
||||||
ConvertPipelineColorTargetEx(convert_s8d24_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
|
ConvertPipelineColorTargetEx(convert_s8d24_to_abgr8_pipeline, dst_framebuffer,
|
||||||
convert_s8d24_to_abgr8_frag);
|
convert_s8d24_to_abgr8_frag);
|
||||||
ConvertDepthStencil(*convert_s8d24_to_abgr8_pipeline, dst_framebuffer, src_image_view);
|
ConvertDepthStencil(*convert_s8d24_to_abgr8_pipeline, dst_framebuffer, src_image_view);
|
||||||
}
|
}
|
||||||
@@ -840,8 +875,10 @@ void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_ma
|
|||||||
const BlitImagePipelineKey key{
|
const BlitImagePipelineKey key{
|
||||||
.renderpass = dst_framebuffer->RenderPass(),
|
.renderpass = dst_framebuffer->RenderPass(),
|
||||||
.operation = Tegra::Engines::Fermi2D::Operation::BlendPremult,
|
.operation = Tegra::Engines::Fermi2D::Operation::BlendPremult,
|
||||||
|
.color_formats = dst_framebuffer->ColorAttachmentFormats(),
|
||||||
|
.depth_format = dst_framebuffer->DepthAttachmentFormat(),
|
||||||
};
|
};
|
||||||
const VkPipeline pipeline = FindOrEmplaceClearColorPipeline(key);
|
const VkPipeline pipeline = FindOrEmplaceClearColorPipeline(key, dst_framebuffer);
|
||||||
const VkPipelineLayout layout = *clear_color_pipeline_layout;
|
const VkPipelineLayout layout = *clear_color_pipeline_layout;
|
||||||
scheduler.RequestRenderpass(dst_framebuffer);
|
scheduler.RequestRenderpass(dst_framebuffer);
|
||||||
scheduler.Record(
|
scheduler.Record(
|
||||||
@@ -867,8 +904,10 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool
|
|||||||
.stencil_mask = stencil_mask,
|
.stencil_mask = stencil_mask,
|
||||||
.stencil_compare_mask = stencil_compare_mask,
|
.stencil_compare_mask = stencil_compare_mask,
|
||||||
.stencil_ref = stencil_ref,
|
.stencil_ref = stencil_ref,
|
||||||
|
.color_formats = dst_framebuffer->ColorAttachmentFormats(),
|
||||||
|
.depth_format = dst_framebuffer->DepthAttachmentFormat(),
|
||||||
};
|
};
|
||||||
const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key);
|
const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key, dst_framebuffer);
|
||||||
const VkPipelineLayout layout = *clear_color_pipeline_layout;
|
const VkPipelineLayout layout = *clear_color_pipeline_layout;
|
||||||
scheduler.RequestRenderpass(dst_framebuffer);
|
scheduler.RequestRenderpass(dst_framebuffer);
|
||||||
scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) {
|
||||||
@@ -1140,12 +1179,14 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer
|
|||||||
scheduler.InvalidateState();
|
scheduler.InvalidateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key) {
|
VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key,
|
||||||
|
const Framebuffer* framebuffer) {
|
||||||
const auto it = std::ranges::find(blit_color_keys, key);
|
const auto it = std::ranges::find(blit_color_keys, key);
|
||||||
if (it != blit_color_keys.end()) {
|
if (it != blit_color_keys.end()) {
|
||||||
return *blit_color_pipelines[std::distance(blit_color_keys.begin(), it)];
|
return *blit_color_pipelines[std::distance(blit_color_keys.begin(), it)];
|
||||||
}
|
}
|
||||||
blit_color_keys.push_back(key);
|
blit_color_keys.push_back(key);
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
|
||||||
|
|
||||||
const std::array stages = MakeStages(*full_screen_vert, *blit_color_to_color_frag);
|
const std::array stages = MakeStages(*full_screen_vert, *blit_color_to_color_frag);
|
||||||
const VkPipelineColorBlendAttachmentState blend_attachment{
|
const VkPipelineColorBlendAttachmentState blend_attachment{
|
||||||
@@ -1173,7 +1214,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe
|
|||||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||||
blit_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
blit_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = key.renderpass ? nullptr : &rendering_ci,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.stageCount = static_cast<u32>(stages.size()),
|
.stageCount = static_cast<u32>(stages.size()),
|
||||||
.pStages = stages.data(),
|
.pStages = stages.data(),
|
||||||
@@ -1195,17 +1236,19 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe
|
|||||||
return *blit_color_pipelines.back();
|
return *blit_color_pipelines.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key) {
|
VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key,
|
||||||
|
const Framebuffer* framebuffer) {
|
||||||
const auto it = std::ranges::find(blit_depth_stencil_keys, key);
|
const auto it = std::ranges::find(blit_depth_stencil_keys, key);
|
||||||
if (it != blit_depth_stencil_keys.end()) {
|
if (it != blit_depth_stencil_keys.end()) {
|
||||||
return *blit_depth_stencil_pipelines[std::distance(blit_depth_stencil_keys.begin(), it)];
|
return *blit_depth_stencil_pipelines[std::distance(blit_depth_stencil_keys.begin(), it)];
|
||||||
}
|
}
|
||||||
blit_depth_stencil_keys.push_back(key);
|
blit_depth_stencil_keys.push_back(key);
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
|
||||||
const std::array stages = MakeStages(*full_screen_vert, *blit_depth_stencil_frag);
|
const std::array stages = MakeStages(*full_screen_vert, *blit_depth_stencil_frag);
|
||||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||||
blit_depth_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
blit_depth_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = key.renderpass ? nullptr : &rendering_ci,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.stageCount = static_cast<u32>(stages.size()),
|
.stageCount = static_cast<u32>(stages.size()),
|
||||||
.pStages = stages.data(),
|
.pStages = stages.data(),
|
||||||
@@ -1227,12 +1270,14 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
|
|||||||
return *blit_depth_stencil_pipelines.back();
|
return *blit_depth_stencil_pipelines.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipelineKey& key) {
|
VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipelineKey& key,
|
||||||
|
const Framebuffer* framebuffer) {
|
||||||
const auto it = std::ranges::find(clear_color_keys, key);
|
const auto it = std::ranges::find(clear_color_keys, key);
|
||||||
if (it != clear_color_keys.end()) {
|
if (it != clear_color_keys.end()) {
|
||||||
return *clear_color_pipelines[std::distance(clear_color_keys.begin(), it)];
|
return *clear_color_pipelines[std::distance(clear_color_keys.begin(), it)];
|
||||||
}
|
}
|
||||||
clear_color_keys.push_back(key);
|
clear_color_keys.push_back(key);
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
|
||||||
const std::array stages = MakeStages(*clear_color_vert, *clear_color_frag);
|
const std::array stages = MakeStages(*clear_color_vert, *clear_color_frag);
|
||||||
const VkPipelineColorBlendAttachmentState color_blend_attachment_state{
|
const VkPipelineColorBlendAttachmentState color_blend_attachment_state{
|
||||||
.blendEnable = VK_TRUE,
|
.blendEnable = VK_TRUE,
|
||||||
@@ -1258,7 +1303,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
|
|||||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||||
clear_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
clear_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = key.renderpass ? nullptr : &rendering_ci,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.stageCount = static_cast<u32>(stages.size()),
|
.stageCount = static_cast<u32>(stages.size()),
|
||||||
.pStages = stages.data(),
|
.pStages = stages.data(),
|
||||||
@@ -1281,12 +1326,13 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
||||||
const BlitDepthStencilPipelineKey& key) {
|
const BlitDepthStencilPipelineKey& key, const Framebuffer* framebuffer) {
|
||||||
const auto it = std::ranges::find(clear_stencil_keys, key);
|
const auto it = std::ranges::find(clear_stencil_keys, key);
|
||||||
if (it != clear_stencil_keys.end()) {
|
if (it != clear_stencil_keys.end()) {
|
||||||
return *clear_stencil_pipelines[std::distance(clear_stencil_keys.begin(), it)];
|
return *clear_stencil_pipelines[std::distance(clear_stencil_keys.begin(), it)];
|
||||||
}
|
}
|
||||||
clear_stencil_keys.push_back(key);
|
clear_stencil_keys.push_back(key);
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
|
||||||
const std::array stages = MakeStages(*clear_color_vert, *clear_stencil_frag);
|
const std::array stages = MakeStages(*clear_color_vert, *clear_stencil_frag);
|
||||||
const auto stencil = VkStencilOpState{
|
const auto stencil = VkStencilOpState{
|
||||||
.failOp = VK_STENCIL_OP_KEEP,
|
.failOp = VK_STENCIL_OP_KEEP,
|
||||||
@@ -1314,7 +1360,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
|||||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||||
clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = key.renderpass ? nullptr : &rendering_ci,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.stageCount = static_cast<u32>(stages.size()),
|
.stageCount = static_cast<u32>(stages.size()),
|
||||||
.pStages = stages.data(),
|
.pStages = stages.data(),
|
||||||
@@ -1462,25 +1508,29 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipeline
|
|||||||
return *msaa_copy_pipelines.back();
|
return *msaa_copy_pipelines.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
|
void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline,
|
||||||
ConvertPipeline(pipeline, renderpass, false);
|
const Framebuffer* framebuffer) {
|
||||||
|
ConvertPipeline(pipeline, framebuffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
|
void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline,
|
||||||
ConvertPipeline(pipeline, renderpass, true);
|
const Framebuffer* framebuffer) {
|
||||||
|
ConvertPipeline(pipeline, framebuffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
|
||||||
vk::ShaderModule& module, bool single_texture,
|
vk::ShaderModule& module, bool single_texture,
|
||||||
bool is_target_depth) {
|
bool is_target_depth) {
|
||||||
if (pipeline) {
|
if (pipeline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const VkRenderPass renderpass = framebuffer->RenderPass();
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
|
||||||
const std::array stages = MakeStages(*full_screen_vert, *module);
|
const std::array stages = MakeStages(*full_screen_vert, *module);
|
||||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||||
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
|
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = renderpass ? nullptr : &rendering_ci,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.stageCount = static_cast<u32>(stages.size()),
|
.stageCount = static_cast<u32>(stages.size()),
|
||||||
.pStages = stages.data(),
|
.pStages = stages.data(),
|
||||||
@@ -1502,28 +1552,32 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline,
|
||||||
|
const Framebuffer* framebuffer,
|
||||||
vk::ShaderModule& module) {
|
vk::ShaderModule& module) {
|
||||||
ConvertPipelineEx(pipeline, renderpass, module, false, false);
|
ConvertPipelineEx(pipeline, framebuffer, module, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline,
|
||||||
|
const Framebuffer* framebuffer,
|
||||||
vk::ShaderModule& module) {
|
vk::ShaderModule& module) {
|
||||||
ConvertPipelineEx(pipeline, renderpass, module, true, true);
|
ConvertPipelineEx(pipeline, framebuffer, module, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
|
||||||
bool is_target_depth) {
|
bool is_target_depth) {
|
||||||
if (pipeline) {
|
if (pipeline) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const VkRenderPass renderpass = framebuffer->RenderPass();
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
|
||||||
VkShaderModule frag_shader =
|
VkShaderModule frag_shader =
|
||||||
is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag;
|
is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag;
|
||||||
const std::array stages = MakeStages(*full_screen_vert, frag_shader);
|
const std::array stages = MakeStages(*full_screen_vert, frag_shader);
|
||||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||||
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
|
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = renderpass ? nullptr : &rendering_ci,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.stageCount = static_cast<u32>(stages.size()),
|
.stageCount = static_cast<u32>(stages.size()),
|
||||||
.pStages = stages.data(),
|
.pStages = stages.data(),
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ struct BlitImagePipelineKey {
|
|||||||
|
|
||||||
VkRenderPass renderpass;
|
VkRenderPass renderpass;
|
||||||
Tegra::Engines::Fermi2D::Operation operation;
|
Tegra::Engines::Fermi2D::Operation operation;
|
||||||
|
std::array<VkFormat, VideoCommon::NUM_RT> color_formats;
|
||||||
|
VkFormat depth_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlitDepthStencilPipelineKey {
|
struct BlitDepthStencilPipelineKey {
|
||||||
@@ -43,6 +45,8 @@ struct BlitDepthStencilPipelineKey {
|
|||||||
u8 stencil_mask;
|
u8 stencil_mask;
|
||||||
u32 stencil_compare_mask;
|
u32 stencil_compare_mask;
|
||||||
u32 stencil_ref;
|
u32 stencil_ref;
|
||||||
|
std::array<VkFormat, VideoCommon::NUM_RT> color_formats;
|
||||||
|
VkFormat depth_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MSAACopyPipelineKey {
|
struct MSAACopyPipelineKey {
|
||||||
@@ -123,31 +127,35 @@ private:
|
|||||||
void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
|
void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
|
||||||
ImageView& src_image_view);
|
ImageView& src_image_view);
|
||||||
|
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key);
|
[[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key,
|
||||||
|
const Framebuffer* framebuffer);
|
||||||
|
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key);
|
[[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key,
|
||||||
|
const Framebuffer* framebuffer);
|
||||||
|
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceClearColorPipeline(const BlitImagePipelineKey& key);
|
[[nodiscard]] VkPipeline FindOrEmplaceClearColorPipeline(const BlitImagePipelineKey& key,
|
||||||
|
const Framebuffer* framebuffer);
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceClearStencilPipeline(
|
[[nodiscard]] VkPipeline FindOrEmplaceClearStencilPipeline(
|
||||||
const BlitDepthStencilPipelineKey& key);
|
const BlitDepthStencilPipelineKey& key, const Framebuffer* framebuffer);
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceMSAACopyPipeline(const MSAACopyPipelineKey& key);
|
[[nodiscard]] VkPipeline FindOrEmplaceMSAACopyPipeline(const MSAACopyPipelineKey& key);
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPipelineKey& key);
|
[[nodiscard]] VkPipeline FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPipelineKey& key);
|
||||||
[[nodiscard]] VkPipeline FindOrEmplaceResolveDepthStencilPipeline(VkRenderPass renderpass,
|
[[nodiscard]] VkPipeline FindOrEmplaceResolveDepthStencilPipeline(VkRenderPass renderpass,
|
||||||
bool resolve_stencil);
|
bool resolve_stencil);
|
||||||
|
|
||||||
void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth);
|
void ConvertPipeline(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
|
||||||
|
bool is_target_depth);
|
||||||
|
|
||||||
void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass);
|
void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, const Framebuffer* framebuffer);
|
||||||
|
|
||||||
void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass);
|
void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, const Framebuffer* framebuffer);
|
||||||
|
|
||||||
void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void ConvertPipelineEx(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
|
||||||
vk::ShaderModule& module, bool single_texture, bool is_target_depth);
|
vk::ShaderModule& module, bool single_texture, bool is_target_depth);
|
||||||
|
|
||||||
void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
|
||||||
vk::ShaderModule& module);
|
vk::ShaderModule& module);
|
||||||
|
|
||||||
void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
|
void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
|
||||||
vk::ShaderModule& module);
|
vk::ShaderModule& module);
|
||||||
|
|
||||||
const Device& device;
|
const Device& device;
|
||||||
|
|||||||
@@ -290,7 +290,10 @@ GraphicsPipeline::GraphicsPipeline(
|
|||||||
descriptor_update_template =
|
descriptor_update_template =
|
||||||
builder.CreateTemplate(set_layout, *pipeline_layout, uses_push_descriptor);
|
builder.CreateTemplate(set_layout, *pipeline_layout, uses_push_descriptor);
|
||||||
|
|
||||||
const VkRenderPass render_pass{render_pass_cache.Get(MakeRenderPassKey(key.state, device))};
|
VkRenderPass render_pass{};
|
||||||
|
if (!device.IsKhrDynamicRenderingSupported()) {
|
||||||
|
render_pass = render_pass_cache.Get(MakeRenderPassKey(key.state, device));
|
||||||
|
}
|
||||||
Validate();
|
Validate();
|
||||||
try {
|
try {
|
||||||
MakePipeline(render_pass);
|
MakePipeline(render_pass);
|
||||||
@@ -996,9 +999,47 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||||||
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
|
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RenderPassKey renderpass_key{MakeRenderPassKey(key.state, device)};
|
||||||
|
std::array<VkFormat, Maxwell::NumRenderTargets> color_attachment_formats{};
|
||||||
|
for (size_t index = 0; index < renderpass_key.color_formats.size(); ++index) {
|
||||||
|
const PixelFormat pixel_format{renderpass_key.color_formats[index]};
|
||||||
|
if (pixel_format == PixelFormat::Invalid) {
|
||||||
|
color_attachment_formats[index] = VK_FORMAT_UNDEFINED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
color_attachment_formats[index] =
|
||||||
|
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, pixel_format).format;
|
||||||
|
}
|
||||||
|
VkFormat depth_attachment_format{VK_FORMAT_UNDEFINED};
|
||||||
|
VkFormat stencil_attachment_format{VK_FORMAT_UNDEFINED};
|
||||||
|
if (renderpass_key.depth_format != PixelFormat::Invalid) {
|
||||||
|
const VkFormat format{
|
||||||
|
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true,
|
||||||
|
renderpass_key.depth_format)
|
||||||
|
.format};
|
||||||
|
const auto surface_type{VideoCore::Surface::GetFormatType(renderpass_key.depth_format)};
|
||||||
|
if (surface_type == VideoCore::Surface::SurfaceType::Depth ||
|
||||||
|
surface_type == VideoCore::Surface::SurfaceType::DepthStencil) {
|
||||||
|
depth_attachment_format = format;
|
||||||
|
}
|
||||||
|
if (surface_type == VideoCore::Surface::SurfaceType::Stencil ||
|
||||||
|
surface_type == VideoCore::Surface::SurfaceType::DepthStencil) {
|
||||||
|
stencil_attachment_format = format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const VkPipelineRenderingCreateInfo rendering_ci{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.viewMask = 0,
|
||||||
|
.colorAttachmentCount = static_cast<u32>(NumAttachments(key.state)),
|
||||||
|
.pColorAttachmentFormats = color_attachment_formats.data(),
|
||||||
|
.depthAttachmentFormat = depth_attachment_format,
|
||||||
|
.stencilAttachmentFormat = stencil_attachment_format,
|
||||||
|
};
|
||||||
|
|
||||||
pipeline = device.GetLogical().CreateGraphicsPipeline({
|
pipeline = device.GetLogical().CreateGraphicsPipeline({
|
||||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = device.IsKhrDynamicRenderingSupported() ? &rendering_ci : nullptr,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
.stageCount = static_cast<u32>(shader_stages.size()),
|
.stageCount = static_cast<u32>(shader_stages.size()),
|
||||||
.pStages = shader_stages.data(),
|
.pStages = shader_stages.data(),
|
||||||
|
|||||||
@@ -423,6 +423,7 @@ void RasterizerVulkan::Clear(u32 layer_count) {
|
|||||||
const bool can_defer_clear = ENABLE_DEFERRED_CLEAR && !regs.clear_control.use_scissor &&
|
const bool can_defer_clear = ENABLE_DEFERRED_CLEAR && !regs.clear_control.use_scissor &&
|
||||||
regs.clear_surface.layer == 0 &&
|
regs.clear_surface.layer == 0 &&
|
||||||
!scheduler.IsRenderPassActive() &&
|
!scheduler.IsRenderPassActive() &&
|
||||||
|
!device.IsKhrDynamicRenderingSupported() &&
|
||||||
(!use_color || color_full_channels) && ds_deferrable;
|
(!use_color || color_full_channels) && ds_deferrable;
|
||||||
if (!can_defer_clear) {
|
if (!can_defer_clear) {
|
||||||
scheduler.RequestRenderpass(framebuffer);
|
scheduler.RequestRenderpass(framebuffer);
|
||||||
|
|||||||
@@ -95,11 +95,40 @@ void Scheduler::DispatchWork() {
|
|||||||
|
|
||||||
void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass renderpass,
|
void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass renderpass,
|
||||||
const VkClearValue* clear_values, u32 clear_value_count) {
|
const VkClearValue* clear_values, u32 clear_value_count) {
|
||||||
const VkFramebuffer framebuffer_handle = framebuffer->Handle();
|
|
||||||
const VkExtent2D render_area = framebuffer->RenderArea();
|
const VkExtent2D render_area = framebuffer->RenderArea();
|
||||||
|
if (device.IsKhrDynamicRenderingSupported()) {
|
||||||
|
std::array<VkImageView, 9> attachment_views{};
|
||||||
|
const auto& color_views = framebuffer->ColorAttachments();
|
||||||
|
for (size_t index = 0; index < color_views.size(); ++index) {
|
||||||
|
attachment_views[index] = color_views[index];
|
||||||
|
}
|
||||||
|
attachment_views[8] = framebuffer->DepthAttachment();
|
||||||
|
state.renderpass = VkRenderPass{};
|
||||||
|
state.framebuffer = VkFramebuffer{};
|
||||||
|
state.attachment_views = attachment_views;
|
||||||
|
state.render_area = render_area;
|
||||||
|
state.rendering = true;
|
||||||
|
|
||||||
|
if (GPU::Logging::IsActive() && Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
||||||
|
const std::string render_pass_info =
|
||||||
|
fmt::format("renderArea={}x{}, numImages={}", render_area.width, render_area.height,
|
||||||
|
framebuffer->NumImages());
|
||||||
|
GPU::Logging::GPULogger::GetInstance().LogRenderPassBegin(render_pass_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Record([framebuffer](vk::CommandBuffer cmdbuf) {
|
||||||
|
framebuffer->BeginRendering(cmdbuf);
|
||||||
|
});
|
||||||
|
num_renderpass_images = framebuffer->NumImages();
|
||||||
|
renderpass_images = framebuffer->Images();
|
||||||
|
renderpass_image_ranges = framebuffer->ImageRanges();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const VkFramebuffer framebuffer_handle = framebuffer->Handle();
|
||||||
state.renderpass = renderpass;
|
state.renderpass = renderpass;
|
||||||
state.framebuffer = framebuffer_handle;
|
state.framebuffer = framebuffer_handle;
|
||||||
state.render_area = render_area;
|
state.render_area = render_area;
|
||||||
|
state.rendering = true;
|
||||||
|
|
||||||
if (GPU::Logging::IsActive() && Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
if (GPU::Logging::IsActive() && Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
||||||
const std::string render_pass_info =
|
const std::string render_pass_info =
|
||||||
@@ -195,9 +224,25 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
|
|||||||
RealizeDeferredClear();
|
RealizeDeferredClear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const VkExtent2D render_area = framebuffer->RenderArea();
|
||||||
|
if (device.IsKhrDynamicRenderingSupported()) {
|
||||||
|
std::array<VkImageView, 9> attachment_views{};
|
||||||
|
const auto& color_views = framebuffer->ColorAttachments();
|
||||||
|
for (size_t index = 0; index < color_views.size(); ++index) {
|
||||||
|
attachment_views[index] = color_views[index];
|
||||||
|
}
|
||||||
|
attachment_views[8] = framebuffer->DepthAttachment();
|
||||||
|
if (state.rendering && attachment_views == state.attachment_views &&
|
||||||
|
render_area.width == state.render_area.width &&
|
||||||
|
render_area.height == state.render_area.height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EndRenderPass();
|
||||||
|
BeginRenderPassImpl(framebuffer, VkRenderPass{}, nullptr, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const VkRenderPass renderpass = framebuffer->RenderPass();
|
const VkRenderPass renderpass = framebuffer->RenderPass();
|
||||||
const VkFramebuffer framebuffer_handle = framebuffer->Handle();
|
const VkFramebuffer framebuffer_handle = framebuffer->Handle();
|
||||||
const VkExtent2D render_area = framebuffer->RenderArea();
|
|
||||||
if (renderpass == state.renderpass && framebuffer_handle == state.framebuffer &&
|
if (renderpass == state.renderpass && framebuffer_handle == state.framebuffer &&
|
||||||
render_area.width == state.render_area.width &&
|
render_area.width == state.render_area.width &&
|
||||||
render_area.height == state.render_area.height) {
|
render_area.height == state.render_area.height) {
|
||||||
@@ -380,7 +425,7 @@ void Scheduler::EndPendingOperations() {
|
|||||||
void Scheduler::EndRenderPass()
|
void Scheduler::EndRenderPass()
|
||||||
{
|
{
|
||||||
RealizeDeferredClear();
|
RealizeDeferredClear();
|
||||||
if (!state.renderpass) {
|
if (!state.rendering) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +443,8 @@ void Scheduler::EndRenderPass()
|
|||||||
Record([num_images = num_renderpass_images,
|
Record([num_images = num_renderpass_images,
|
||||||
images = renderpass_images,
|
images = renderpass_images,
|
||||||
ranges = renderpass_image_ranges,
|
ranges = renderpass_image_ranges,
|
||||||
has_transform_feedback = device.IsExtTransformFeedbackSupported()](
|
has_transform_feedback = device.IsExtTransformFeedbackSupported(),
|
||||||
|
dynamic_rendering = device.IsKhrDynamicRenderingSupported()](
|
||||||
vk::CommandBuffer cmdbuf) {
|
vk::CommandBuffer cmdbuf) {
|
||||||
std::array<VkImageMemoryBarrier, 9> barriers;
|
std::array<VkImageMemoryBarrier, 9> barriers;
|
||||||
for (size_t i = 0; i < num_images; ++i) {
|
for (size_t i = 0; i < num_images; ++i) {
|
||||||
@@ -435,7 +481,11 @@ void Scheduler::EndRenderPass()
|
|||||||
.subresourceRange = range,
|
.subresourceRange = range,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
cmdbuf.EndRenderPass();
|
if (dynamic_rendering) {
|
||||||
|
cmdbuf.EndRendering();
|
||||||
|
} else {
|
||||||
|
cmdbuf.EndRenderPass();
|
||||||
|
}
|
||||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
|
||||||
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
|
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
|
||||||
@@ -453,6 +503,9 @@ void Scheduler::EndRenderPass()
|
|||||||
});
|
});
|
||||||
|
|
||||||
state.renderpass = VkRenderPass{};
|
state.renderpass = VkRenderPass{};
|
||||||
|
state.framebuffer = VkFramebuffer{};
|
||||||
|
state.attachment_views = {};
|
||||||
|
state.rendering = false;
|
||||||
num_renderpass_images = 0;
|
num_renderpass_images = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
|
|
||||||
/// Returns true when a render pass is currently active in the scheduler state.
|
/// Returns true when a render pass is currently active in the scheduler state.
|
||||||
bool IsRenderPassActive() const {
|
bool IsRenderPassActive() const {
|
||||||
return state.renderpass != VK_NULL_HANDLE;
|
return state.rendering;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the pipeline to the current execution context.
|
/// Update the pipeline to the current execution context.
|
||||||
@@ -250,8 +250,10 @@ private:
|
|||||||
struct State {
|
struct State {
|
||||||
VkRenderPass renderpass{};
|
VkRenderPass renderpass{};
|
||||||
VkFramebuffer framebuffer{};
|
VkFramebuffer framebuffer{};
|
||||||
|
std::array<VkImageView, 9> attachment_views{};
|
||||||
VkExtent2D render_area = {0, 0};
|
VkExtent2D render_area = {0, 0};
|
||||||
GraphicsPipeline* graphics_pipeline = nullptr;
|
GraphicsPipeline* graphics_pipeline = nullptr;
|
||||||
|
bool rendering = false;
|
||||||
bool is_rescaling = false;
|
bool is_rescaling = false;
|
||||||
bool rescaling_defined = false;
|
bool rescaling_defined = false;
|
||||||
bool needs_state_enable_refresh = false;
|
bool needs_state_enable_refresh = false;
|
||||||
|
|||||||
@@ -1353,7 +1353,7 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
|
void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
|
||||||
if (!dst->RenderPass()) {
|
if (!dst->RenderPass() && !device.IsKhrDynamicRenderingSupported()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2683,7 +2683,7 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
|
|||||||
.height = key.size.height,
|
.height = key.size.height,
|
||||||
}} {
|
}} {
|
||||||
CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled);
|
CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled);
|
||||||
if (runtime.device.HasDebuggingToolAttached()) {
|
if (runtime.device.HasDebuggingToolAttached() && framebuffer) {
|
||||||
framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str());
|
framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2726,6 +2726,12 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
image_ranges[num_images] = MakeSubresourceRange(color_buffer);
|
image_ranges[num_images] = MakeSubresourceRange(color_buffer);
|
||||||
rt_map[index] = num_images;
|
rt_map[index] = num_images;
|
||||||
samples = color_buffer->Samples();
|
samples = color_buffer->Samples();
|
||||||
|
color_attachments[index] = color_buffer->RenderTarget();
|
||||||
|
color_attachment_formats[index] =
|
||||||
|
MaxwellToVK::SurfaceFormat(runtime.device, FormatType::Optimal, true,
|
||||||
|
color_buffer->format)
|
||||||
|
.format;
|
||||||
|
num_color_attachments = static_cast<u32>(index + 1);
|
||||||
++num_images;
|
++num_images;
|
||||||
}
|
}
|
||||||
const size_t num_colors = attachments.size();
|
const size_t num_colors = attachments.size();
|
||||||
@@ -2741,6 +2747,11 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
const VkImageSubresourceRange subresource_range = MakeSubresourceRange(depth_buffer);
|
const VkImageSubresourceRange subresource_range = MakeSubresourceRange(depth_buffer);
|
||||||
image_ranges[num_images] = subresource_range;
|
image_ranges[num_images] = subresource_range;
|
||||||
samples = depth_buffer->Samples();
|
samples = depth_buffer->Samples();
|
||||||
|
depth_attachment = depth_buffer->RenderTarget();
|
||||||
|
depth_attachment_format =
|
||||||
|
MaxwellToVK::SurfaceFormat(runtime.device, FormatType::Optimal, true,
|
||||||
|
depth_buffer->format)
|
||||||
|
.format;
|
||||||
++num_images;
|
++num_images;
|
||||||
has_depth = (subresource_range.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0;
|
has_depth = (subresource_range.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0;
|
||||||
has_stencil = (subresource_range.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;
|
has_stencil = (subresource_range.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0;
|
||||||
@@ -2755,7 +2766,6 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
discard_msaa_color =
|
discard_msaa_color =
|
||||||
ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_COLOR_DISCARD && do_resolve_color;
|
ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_COLOR_DISCARD && do_resolve_color;
|
||||||
|
|
||||||
renderpass = runtime.render_pass_cache.Get(renderpass_key);
|
|
||||||
render_pass_key = renderpass_key;
|
render_pass_key = renderpass_key;
|
||||||
render_pass_cache = &runtime.render_pass_cache;
|
render_pass_cache = &runtime.render_pass_cache;
|
||||||
render_area.width = (std::min)(render_area.width, width);
|
render_area.width = (std::min)(render_area.width, width);
|
||||||
@@ -2819,6 +2829,11 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
num_color_buffers = static_cast<u32>(num_colors);
|
num_color_buffers = static_cast<u32>(num_colors);
|
||||||
|
layer_count = static_cast<u32>((std::max)(num_layers, 1));
|
||||||
|
if (runtime.device.IsKhrDynamicRenderingSupported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
renderpass = runtime.render_pass_cache.Get(renderpass_key);
|
||||||
framebuffer = runtime.device.GetLogical().CreateFramebuffer({
|
framebuffer = runtime.device.GetLogical().CreateFramebuffer({
|
||||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
@@ -2828,7 +2843,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
.pAttachments = attachments.data(),
|
.pAttachments = attachments.data(),
|
||||||
.width = render_area.width,
|
.width = render_area.width,
|
||||||
.height = render_area.height,
|
.height = render_area.height,
|
||||||
.layers = static_cast<u32>((std::max)(num_layers, 1)),
|
.layers = layer_count,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2844,6 +2859,53 @@ VkRenderPass Framebuffer::RenderPassVariant(u32 color_clear_mask, bool depth_ste
|
|||||||
return render_pass_cache->Get(key);
|
return render_pass_cache->Get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Framebuffer::BeginRendering(vk::CommandBuffer cmdbuf) const {
|
||||||
|
std::array<VkRenderingAttachmentInfo, NUM_RT> color_attachment_infos{};
|
||||||
|
for (size_t index = 0; index < num_color_attachments; ++index) {
|
||||||
|
color_attachment_infos[index] = VkRenderingAttachmentInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.imageView = color_attachments[index],
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
.resolveMode = VK_RESOLVE_MODE_NONE,
|
||||||
|
.resolveImageView = VK_NULL_HANDLE,
|
||||||
|
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
|
.clearValue = {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const VkRenderingAttachmentInfo depth_attachment_info{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.imageView = depth_attachment,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
.resolveMode = VK_RESOLVE_MODE_NONE,
|
||||||
|
.resolveImageView = VK_NULL_HANDLE,
|
||||||
|
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
|
.clearValue = {},
|
||||||
|
};
|
||||||
|
const VkRenderingInfo rendering_info{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.flags = 0,
|
||||||
|
.renderArea =
|
||||||
|
{
|
||||||
|
.offset = {.x = 0, .y = 0},
|
||||||
|
.extent = render_area,
|
||||||
|
},
|
||||||
|
.layerCount = layer_count,
|
||||||
|
.viewMask = 0,
|
||||||
|
.colorAttachmentCount = num_color_attachments,
|
||||||
|
.pColorAttachments = color_attachment_infos.data(),
|
||||||
|
.pDepthAttachment = has_depth ? &depth_attachment_info : nullptr,
|
||||||
|
.pStencilAttachment = has_stencil ? &depth_attachment_info : nullptr,
|
||||||
|
};
|
||||||
|
cmdbuf.BeginRendering(rendering_info);
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCacheRuntime::AccelerateImageUpload(
|
void TextureCacheRuntime::AccelerateImageUpload(
|
||||||
Image& image, const StagingBufferRef& map,
|
Image& image, const StagingBufferRef& map,
|
||||||
std::span<const VideoCommon::SwizzleParameters> swizzles,
|
std::span<const VideoCommon::SwizzleParameters> swizzles,
|
||||||
|
|||||||
@@ -178,6 +178,8 @@ public:
|
|||||||
std::span<ImageView*, NUM_RT> color_buffers, ImageView* depth_buffer,
|
std::span<ImageView*, NUM_RT> color_buffers, ImageView* depth_buffer,
|
||||||
bool is_rescaled = false);
|
bool is_rescaled = false);
|
||||||
|
|
||||||
|
void BeginRendering(vk::CommandBuffer cmdbuf) const;
|
||||||
|
|
||||||
[[nodiscard]] VkFramebuffer Handle() const noexcept {
|
[[nodiscard]] VkFramebuffer Handle() const noexcept {
|
||||||
return *framebuffer;
|
return *framebuffer;
|
||||||
}
|
}
|
||||||
@@ -193,6 +195,30 @@ public:
|
|||||||
[[nodiscard]] VkRenderPass RenderPassVariant(u32 color_clear_mask, bool depth_stencil_clear,
|
[[nodiscard]] VkRenderPass RenderPassVariant(u32 color_clear_mask, bool depth_stencil_clear,
|
||||||
u32 color_discard_mask) const;
|
u32 color_discard_mask) const;
|
||||||
|
|
||||||
|
[[nodiscard]] u32 NumColorAttachments() const noexcept {
|
||||||
|
return num_color_attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const std::array<VkImageView, NUM_RT>& ColorAttachments() const noexcept {
|
||||||
|
return color_attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const std::array<VkFormat, NUM_RT>& ColorAttachmentFormats() const noexcept {
|
||||||
|
return color_attachment_formats;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] VkImageView DepthAttachment() const noexcept {
|
||||||
|
return depth_attachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] VkFormat DepthAttachmentFormat() const noexcept {
|
||||||
|
return depth_attachment_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 NumLayers() const noexcept {
|
||||||
|
return layer_count;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] VkExtent2D RenderArea() const noexcept {
|
[[nodiscard]] VkExtent2D RenderArea() const noexcept {
|
||||||
return render_area;
|
return render_area;
|
||||||
}
|
}
|
||||||
@@ -255,6 +281,12 @@ private:
|
|||||||
std::array<VkImage, 9> images{};
|
std::array<VkImage, 9> images{};
|
||||||
std::array<VkImageSubresourceRange, 9> image_ranges{};
|
std::array<VkImageSubresourceRange, 9> image_ranges{};
|
||||||
std::array<size_t, NUM_RT> rt_map{};
|
std::array<size_t, NUM_RT> rt_map{};
|
||||||
|
std::array<VkImageView, NUM_RT> color_attachments{};
|
||||||
|
std::array<VkFormat, NUM_RT> color_attachment_formats{};
|
||||||
|
VkImageView depth_attachment{};
|
||||||
|
VkFormat depth_attachment_format = VK_FORMAT_UNDEFINED;
|
||||||
|
u32 num_color_attachments = 0;
|
||||||
|
u32 layer_count = 1;
|
||||||
bool has_depth{};
|
bool has_depth{};
|
||||||
bool has_stencil{};
|
bool has_stencil{};
|
||||||
bool is_rescaled{};
|
bool is_rescaled{};
|
||||||
|
|||||||
@@ -1373,6 +1373,11 @@ void Device::RemoveUnsuitableExtensions() {
|
|||||||
extensions.maintenance3 = loaded_extensions.contains(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
|
extensions.maintenance3 = loaded_extensions.contains(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
|
||||||
RemoveExtensionIfUnsuitable(extensions.maintenance3, VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
|
RemoveExtensionIfUnsuitable(extensions.maintenance3, VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
|
||||||
|
|
||||||
|
// VK_KHR_dynamic_rendering
|
||||||
|
extensions.dynamic_rendering = features.dynamic_rendering.dynamicRendering;
|
||||||
|
RemoveExtensionFeatureIfUnsuitable(extensions.dynamic_rendering, features.dynamic_rendering,
|
||||||
|
VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
||||||
|
|
||||||
// VK_KHR_maintenance4
|
// VK_KHR_maintenance4
|
||||||
extensions.maintenance4 = features.maintenance4.maintenance4;
|
extensions.maintenance4 = features.maintenance4.maintenance4;
|
||||||
RemoveExtensionFeatureIfUnsuitable(extensions.maintenance4, features.maintenance4,
|
RemoveExtensionFeatureIfUnsuitable(extensions.maintenance4, features.maintenance4,
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
|||||||
FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \
|
FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \
|
||||||
shader_demote_to_helper_invocation) \
|
shader_demote_to_helper_invocation) \
|
||||||
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \
|
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \
|
||||||
|
FEATURE(KHR, DynamicRendering, DYNAMIC_RENDERING, dynamic_rendering) \
|
||||||
FEATURE(KHR, Maintenance4, MAINTENANCE_4, maintenance4) \
|
FEATURE(KHR, Maintenance4, MAINTENANCE_4, maintenance4) \
|
||||||
FEATURE(KHR, Synchronization2, SYNCHRONIZATION_2, synchronization2)
|
FEATURE(KHR, Synchronization2, SYNCHRONIZATION_2, synchronization2)
|
||||||
|
|
||||||
@@ -941,6 +942,11 @@ FN_MAX_LIMIT_LIST
|
|||||||
return extensions.maintenance3;
|
return extensions.maintenance3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the device supports VK_KHR_dynamic_rendering.
|
||||||
|
bool IsKhrDynamicRenderingSupported() const {
|
||||||
|
return extensions.dynamic_rendering;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the device supports VK_KHR_maintenance4.
|
/// Returns true if the device supports VK_KHR_maintenance4.
|
||||||
bool IsKhrMaintenance4Supported() const {
|
bool IsKhrMaintenance4Supported() const {
|
||||||
return extensions.maintenance4;
|
return extensions.maintenance4;
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
|||||||
X(vkCmdBeginConditionalRenderingEXT);
|
X(vkCmdBeginConditionalRenderingEXT);
|
||||||
X(vkCmdBeginQuery);
|
X(vkCmdBeginQuery);
|
||||||
X(vkCmdBeginRenderPass);
|
X(vkCmdBeginRenderPass);
|
||||||
|
X(vkCmdBeginRendering);
|
||||||
X(vkCmdBeginTransformFeedbackEXT);
|
X(vkCmdBeginTransformFeedbackEXT);
|
||||||
X(vkCmdBeginDebugUtilsLabelEXT);
|
X(vkCmdBeginDebugUtilsLabelEXT);
|
||||||
X(vkCmdBindDescriptorSets);
|
X(vkCmdBindDescriptorSets);
|
||||||
@@ -119,6 +120,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
|||||||
X(vkCmdEndConditionalRenderingEXT);
|
X(vkCmdEndConditionalRenderingEXT);
|
||||||
X(vkCmdEndQuery);
|
X(vkCmdEndQuery);
|
||||||
X(vkCmdEndRenderPass);
|
X(vkCmdEndRenderPass);
|
||||||
|
X(vkCmdEndRendering);
|
||||||
X(vkCmdEndTransformFeedbackEXT);
|
X(vkCmdEndTransformFeedbackEXT);
|
||||||
X(vkCmdEndDebugUtilsLabelEXT);
|
X(vkCmdEndDebugUtilsLabelEXT);
|
||||||
X(vkCmdFillBuffer);
|
X(vkCmdFillBuffer);
|
||||||
@@ -257,6 +259,12 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
|||||||
Proc(dld.vkCmdDrawIndexedIndirectCount, dld, "vkCmdDrawIndexedIndirectCountKHR", device);
|
Proc(dld.vkCmdDrawIndexedIndirectCount, dld, "vkCmdDrawIndexedIndirectCountKHR", device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support for dynamic rendering is optional until Vulkan 1.3
|
||||||
|
if (!dld.vkCmdBeginRendering) {
|
||||||
|
Proc(dld.vkCmdBeginRendering, dld, "vkCmdBeginRenderingKHR", device);
|
||||||
|
Proc(dld.vkCmdEndRendering, dld, "vkCmdEndRenderingKHR", device);
|
||||||
|
}
|
||||||
|
|
||||||
// Synchronization2 is core in Vulkan 1.3, otherwise requires VK_KHR_synchronization2
|
// Synchronization2 is core in Vulkan 1.3, otherwise requires VK_KHR_synchronization2
|
||||||
if (!dld.vkCmdPipelineBarrier2) {
|
if (!dld.vkCmdPipelineBarrier2) {
|
||||||
Proc(dld.vkCmdPipelineBarrier2, dld, "vkCmdPipelineBarrier2KHR", device);
|
Proc(dld.vkCmdPipelineBarrier2, dld, "vkCmdPipelineBarrier2KHR", device);
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ struct DeviceDispatch : InstanceDispatch {
|
|||||||
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT{};
|
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT{};
|
||||||
PFN_vkCmdBeginQuery vkCmdBeginQuery{};
|
PFN_vkCmdBeginQuery vkCmdBeginQuery{};
|
||||||
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass{};
|
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass{};
|
||||||
|
PFN_vkCmdBeginRendering vkCmdBeginRendering{};
|
||||||
PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT{};
|
PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT{};
|
||||||
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets{};
|
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets{};
|
||||||
PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer{};
|
PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer{};
|
||||||
@@ -236,6 +237,7 @@ struct DeviceDispatch : InstanceDispatch {
|
|||||||
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{};
|
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{};
|
||||||
PFN_vkCmdEndQuery vkCmdEndQuery{};
|
PFN_vkCmdEndQuery vkCmdEndQuery{};
|
||||||
PFN_vkCmdEndRenderPass vkCmdEndRenderPass{};
|
PFN_vkCmdEndRenderPass vkCmdEndRenderPass{};
|
||||||
|
PFN_vkCmdEndRendering vkCmdEndRendering{};
|
||||||
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
|
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
|
||||||
PFN_vkCmdFillBuffer vkCmdFillBuffer{};
|
PFN_vkCmdFillBuffer vkCmdFillBuffer{};
|
||||||
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{};
|
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{};
|
||||||
@@ -1186,6 +1188,14 @@ public:
|
|||||||
dld->vkCmdEndRenderPass(handle);
|
dld->vkCmdEndRenderPass(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BeginRendering(const VkRenderingInfo& rendering_info) const noexcept {
|
||||||
|
dld->vkCmdBeginRendering(handle, &rendering_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndRendering() const noexcept {
|
||||||
|
dld->vkCmdEndRendering(handle);
|
||||||
|
}
|
||||||
|
|
||||||
void BeginQuery(VkQueryPool query_pool, u32 query, VkQueryControlFlags flags) const noexcept {
|
void BeginQuery(VkQueryPool query_pool, u32 query, VkQueryControlFlags flags) const noexcept {
|
||||||
dld->vkCmdBeginQuery(handle, query_pool, query, flags);
|
dld->vkCmdBeginQuery(handle, query_pool, query, flags);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user