rasterizer: Add multi-sampled framebuffers

Vulkan implementation only
This commit is contained in:
Wunkolo 2023-11-10 17:48:51 -08:00
parent 89ffff3426
commit 82e9f4ca03
4 changed files with 27 additions and 9 deletions

View file

@ -27,7 +27,8 @@ struct FramebufferParams {
u32 color_level;
u32 depth_level;
bool shadow_rendering;
INSERT_PADDING_BYTES(3);
u8 sample_count;
INSERT_PADDING_BYTES(2);
bool operator==(const FramebufferParams& params) const noexcept {
return std::memcmp(this, &params, sizeof(FramebufferParams)) == 0;

View file

@ -748,6 +748,7 @@ FramebufferHelper<T> RasterizerCache<T>::GetFramebufferSurfaces(bool using_color
.color_level = color_level,
.depth_level = depth_level,
.shadow_rendering = regs.framebuffer.IsShadowRendering(),
.sample_count = sample_count,
};
auto [it, new_framebuffer] = framebuffers.try_emplace(fb_params);

View file

@ -1458,8 +1458,9 @@ void Surface::BlitScale(const VideoCore::TextureBlit& blit, bool up_scale) {
Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferParams& params,
Surface* color, Surface* depth)
: VideoCore::FramebufferParams{params}, res_scale{color ? color->res_scale
: (depth ? depth->res_scale : 1u)} {
: VideoCore::FramebufferParams{params},
res_scale{color ? color->res_scale : (depth ? depth->res_scale : 1u)},
sample_count{params.sample_count} {
auto& renderpass_cache = runtime.GetRenderpassCache();
if (shadow_rendering && !color) {
return;
@ -1474,12 +1475,12 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa
if (!shadow_rendering) {
formats[index] = surface->pixel_format;
}
images[index] = surface->Image();
aspects[index] = surface->Aspect();
images[index] = surface->Image();
image_views[index] = shadow_rendering ? surface->StorageView() : surface->FramebufferView();
};
boost::container::static_vector<vk::ImageView, 2> attachments;
boost::container::static_vector<vk::ImageView, 4> attachments;
if (color) {
prepare(0, color);
@ -1491,6 +1492,16 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa
attachments.emplace_back(image_views[1]);
}
if (sample_count > 1) {
if (color) {
attachments.emplace_back(color->ImageView(3));
}
if (depth) {
attachments.emplace_back(depth->ImageView(3));
}
}
const vk::Device device = runtime.GetInstance().GetDevice();
if (shadow_rendering) {
render_pass =
@ -1498,7 +1509,7 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa
framebuffer = MakeFramebuffer(device, render_pass, color->GetScaledWidth(),
color->GetScaledHeight(), {});
} else {
render_pass = renderpass_cache.GetRenderpass(formats[0], formats[1], false);
render_pass = renderpass_cache.GetRenderpass(formats[0], formats[1], false, sample_count);
framebuffer = MakeFramebuffer(device, render_pass, width, height, attachments);
}
}

View file

@ -215,7 +215,7 @@ public:
return framebuffer.get();
}
[[nodiscard]] std::array<vk::Image, 2> Images() const noexcept {
[[nodiscard]] std::array<vk::Image, 4> Images() const noexcept {
return images;
}
@ -227,6 +227,10 @@ public:
return render_pass;
}
u8 Samples() const noexcept {
return sample_count;
}
u32 Scale() const noexcept {
return res_scale;
}
@ -240,8 +244,8 @@ public:
}
private:
std::array<vk::Image, 2> images{};
std::array<vk::ImageView, 2> image_views{};
std::array<vk::Image, 4> images{};
std::array<vk::ImageView, 4> image_views{};
vk::UniqueFramebuffer framebuffer;
vk::RenderPass render_pass;
std::array<vk::ImageAspectFlags, 2> aspects{};
@ -250,6 +254,7 @@ private:
u32 width{};
u32 height{};
u32 res_scale{1};
u8 sample_count{1};
};
class Sampler {