nvnflinger/gpu: implement blending
This commit is contained in:
parent
06fd7f2012
commit
962c82540c
37 changed files with 383 additions and 141 deletions
|
|
@ -362,10 +362,10 @@ vk::PipelineLayout CreateWrappedPipelineLayout(const Device& device,
|
|||
});
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders,
|
||||
bool enable_blending) {
|
||||
static vk::Pipeline CreateWrappedPipelineImpl(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders,
|
||||
VkPipelineColorBlendAttachmentState blending) {
|
||||
const std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages{{
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
|
|
@ -443,30 +443,6 @@ vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderp
|
|||
.alphaToOneEnable = VK_FALSE,
|
||||
};
|
||||
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_disabled{
|
||||
.blendEnable = VK_FALSE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_enabled{
|
||||
.blendEnable = VK_TRUE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
const VkPipelineColorBlendStateCreateInfo color_blend_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
|
|
@ -474,8 +450,7 @@ vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderp
|
|||
.logicOpEnable = VK_FALSE,
|
||||
.logicOp = VK_LOGIC_OP_COPY,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments =
|
||||
enable_blending ? &color_blend_attachment_enabled : &color_blend_attachment_disabled,
|
||||
.pAttachments = &blending,
|
||||
.blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
|
||||
};
|
||||
|
||||
|
|
@ -515,6 +490,63 @@ vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderp
|
|||
});
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders) {
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_disabled{
|
||||
.blendEnable = VK_FALSE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
return CreateWrappedPipelineImpl(device, renderpass, layout, shaders,
|
||||
color_blend_attachment_disabled);
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedPremultipliedBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders) {
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_premultiplied{
|
||||
.blendEnable = VK_TRUE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
return CreateWrappedPipelineImpl(device, renderpass, layout, shaders,
|
||||
color_blend_attachment_premultiplied);
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedCoverageBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders) {
|
||||
constexpr VkPipelineColorBlendAttachmentState color_blend_attachment_coverage{
|
||||
.blendEnable = VK_TRUE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
};
|
||||
|
||||
return CreateWrappedPipelineImpl(device, renderpass, layout, shaders,
|
||||
color_blend_attachment_coverage);
|
||||
}
|
||||
|
||||
VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector<VkDescriptorImageInfo>& images,
|
||||
VkSampler sampler, VkImageView view,
|
||||
VkDescriptorSet set, u32 binding) {
|
||||
|
|
|
|||
|
|
@ -42,8 +42,13 @@ vk::PipelineLayout CreateWrappedPipelineLayout(const Device& device,
|
|||
vk::DescriptorSetLayout& layout);
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders,
|
||||
bool enable_blending = false);
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders);
|
||||
vk::Pipeline CreateWrappedPremultipliedBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders);
|
||||
vk::Pipeline CreateWrappedCoverageBlendingPipeline(
|
||||
const Device& device, vk::RenderPass& renderpass, vk::PipelineLayout& layout,
|
||||
std::tuple<vk::ShaderModule&, vk::ShaderModule&> shaders);
|
||||
VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector<VkDescriptorImageInfo>& images,
|
||||
VkSampler sampler, VkImageView view,
|
||||
VkDescriptorSet set, u32 binding);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ WindowAdaptPass::WindowAdaptPass(const Device& device_, VkFormat frame_format,
|
|||
CreatePipelineLayout();
|
||||
CreateVertexShader();
|
||||
CreateRenderPass(frame_format);
|
||||
CreatePipeline();
|
||||
CreatePipelines();
|
||||
}
|
||||
|
||||
WindowAdaptPass::~WindowAdaptPass() = default;
|
||||
|
|
@ -34,7 +34,6 @@ void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, s
|
|||
|
||||
const VkFramebuffer host_framebuffer{*dst->framebuffer};
|
||||
const VkRenderPass renderpass{*render_pass};
|
||||
const VkPipeline graphics_pipeline{*pipeline};
|
||||
const VkPipelineLayout graphics_pipeline_layout{*pipeline_layout};
|
||||
const VkExtent2D render_area{
|
||||
.width = dst->width,
|
||||
|
|
@ -44,9 +43,23 @@ void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, s
|
|||
const size_t layer_count = configs.size();
|
||||
std::vector<PresentPushConstants> push_constants(layer_count);
|
||||
std::vector<VkDescriptorSet> descriptor_sets(layer_count);
|
||||
std::vector<VkPipeline> graphics_pipelines(layer_count);
|
||||
|
||||
auto layer_it = layers.begin();
|
||||
for (size_t i = 0; i < layer_count; i++) {
|
||||
switch (configs[i].blending) {
|
||||
case Tegra::BlendMode::Opaque:
|
||||
default:
|
||||
graphics_pipelines[i] = *opaque_pipeline;
|
||||
break;
|
||||
case Tegra::BlendMode::Premultiplied:
|
||||
graphics_pipelines[i] = *premultiplied_pipeline;
|
||||
break;
|
||||
case Tegra::BlendMode::Coverage:
|
||||
graphics_pipelines[i] = *coverage_pipeline;
|
||||
break;
|
||||
}
|
||||
|
||||
layer_it->ConfigureDraw(&push_constants[i], &descriptor_sets[i], rasterizer, *sampler,
|
||||
image_index, configs[i], layout);
|
||||
layer_it++;
|
||||
|
|
@ -77,8 +90,8 @@ void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, s
|
|||
BeginRenderPass(cmdbuf, renderpass, host_framebuffer, render_area);
|
||||
cmdbuf.ClearAttachments({clear_attachment}, {clear_rect});
|
||||
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline);
|
||||
for (size_t i = 0; i < layer_count; i++) {
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipelines[i]);
|
||||
cmdbuf.PushConstants(graphics_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
push_constants[i]);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_layout, 0,
|
||||
|
|
@ -129,9 +142,13 @@ void WindowAdaptPass::CreateRenderPass(VkFormat frame_format) {
|
|||
render_pass = CreateWrappedRenderPass(device, frame_format, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
}
|
||||
|
||||
void WindowAdaptPass::CreatePipeline() {
|
||||
pipeline = CreateWrappedPipeline(device, render_pass, pipeline_layout,
|
||||
std::tie(vertex_shader, fragment_shader), false);
|
||||
void WindowAdaptPass::CreatePipelines() {
|
||||
opaque_pipeline = CreateWrappedPipeline(device, render_pass, pipeline_layout,
|
||||
std::tie(vertex_shader, fragment_shader));
|
||||
premultiplied_pipeline = CreateWrappedPremultipliedBlendingPipeline(
|
||||
device, render_pass, pipeline_layout, std::tie(vertex_shader, fragment_shader));
|
||||
coverage_pipeline = CreateWrappedCoverageBlendingPipeline(
|
||||
device, render_pass, pipeline_layout, std::tie(vertex_shader, fragment_shader));
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ private:
|
|||
void CreatePipelineLayout();
|
||||
void CreateVertexShader();
|
||||
void CreateRenderPass(VkFormat frame_format);
|
||||
void CreatePipeline();
|
||||
void CreatePipelines();
|
||||
|
||||
private:
|
||||
const Device& device;
|
||||
|
|
@ -52,7 +52,9 @@ private:
|
|||
vk::ShaderModule vertex_shader;
|
||||
vk::ShaderModule fragment_shader;
|
||||
vk::RenderPass render_pass;
|
||||
vk::Pipeline pipeline;
|
||||
vk::Pipeline opaque_pipeline;
|
||||
vk::Pipeline premultiplied_pipeline;
|
||||
vk::Pipeline coverage_pipeline;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
|||
|
|
@ -101,8 +101,10 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
|
|||
surface),
|
||||
blit_swapchain(device_memory, device, memory_allocator, present_manager, scheduler),
|
||||
blit_screenshot(device_memory, device, memory_allocator, present_manager, scheduler),
|
||||
blit_application_layer(device_memory, device, memory_allocator, present_manager, scheduler),
|
||||
rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker,
|
||||
scheduler) {
|
||||
scheduler),
|
||||
application_frame() {
|
||||
if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) {
|
||||
turbo_mode.emplace(instance, dld);
|
||||
scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); });
|
||||
|
|
|
|||
|
|
@ -80,8 +80,11 @@ private:
|
|||
PresentManager present_manager;
|
||||
BlitScreen blit_swapchain;
|
||||
BlitScreen blit_screenshot;
|
||||
BlitScreen blit_application_layer;
|
||||
RasterizerVulkan rasterizer;
|
||||
std::optional<TurboMode> turbo_mode;
|
||||
|
||||
Frame application_frame;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
|||
Reference in a new issue