rasterizer_cache: Create Surface MSAA handles upon ScaleUp

This commit is contained in:
Wunkolo 2023-11-20 10:20:01 -08:00
parent aebd108328
commit 44cb5a4ad2
5 changed files with 71 additions and 46 deletions

View file

@ -431,8 +431,10 @@ void RasterizerCache<T>::CopySurface(Surface& src_surface, Surface& dst_surface,
const u32 src_scale = src_surface.res_scale; const u32 src_scale = src_surface.res_scale;
const u32 dst_scale = dst_surface.res_scale; const u32 dst_scale = dst_surface.res_scale;
if (src_scale > dst_scale) { const u32 src_sample_count = src_surface.sample_count;
dst_surface.ScaleUp(src_scale); const u32 dst_sample_count = dst_surface.sample_count;
if ((src_scale > dst_scale) || (src_sample_count > dst_sample_count)) {
dst_surface.ScaleUp(src_scale, src_sample_count);
} }
const auto src_rect = src_surface.GetScaledSubRect(subrect_params); const auto src_rect = src_surface.GetScaledSubRect(subrect_params);
@ -1171,8 +1173,9 @@ bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfacePar
return false; return false;
} }
const u32 res_scale = src_surface.res_scale; const u32 res_scale = src_surface.res_scale;
if (res_scale > surface.res_scale) { const u8 sample_count = src_surface.sample_count;
surface.ScaleUp(res_scale); if ((res_scale > surface.res_scale) || (sample_count > surface.sample_count)) {
surface.ScaleUp(res_scale, sample_count);
} }
const PAddr addr = boost::icl::lower(interval); const PAddr addr = boost::icl::lower(interval);
const SurfaceParams copy_params = surface.FromInterval(copy_interval); const SurfaceParams copy_params = surface.FromInterval(copy_interval);
@ -1349,8 +1352,8 @@ SurfaceId RasterizerCache<T>::CreateSurface(const SurfaceParams& params) {
return surface_id; return surface_id;
}(); }();
Surface& surface = slot_surfaces[surface_id]; Surface& surface = slot_surfaces[surface_id];
if (params.res_scale > surface.res_scale) { if ((params.res_scale > surface.res_scale) || (params.sample_count > surface.sample_count)) {
surface.ScaleUp(params.res_scale); surface.ScaleUp(params.res_scale, params.sample_count);
} }
surface.MarkInvalid(surface.GetInterval()); surface.MarkInvalid(surface.GetInterval());
return surface_id; return surface_id;

View file

@ -550,23 +550,33 @@ void Surface::Attach(GLenum target, u32 level, u32 layer, bool scaled) {
} }
} }
void Surface::ScaleUp(u32 new_scale) { void Surface::ScaleUp(u32 new_scale, u8 new_sample_count) {
if (res_scale == new_scale || new_scale == 1) { if (res_scale == new_scale) {
return;
}
if (sample_count == new_sample_count) {
return; return;
} }
res_scale = new_scale; res_scale = new_scale;
textures[1] = MakeHandle(GL_TEXTURE_2D, GetScaledWidth(), GetScaledHeight(), levels, tuple,
DebugName(true));
for (u32 level = 0; level < levels; level++) { if (res_scale > 1) {
const VideoCore::TextureBlit blit = {
.src_level = level, textures[1] = MakeHandle(GL_TEXTURE_2D, GetScaledWidth(), GetScaledHeight(), levels, tuple,
.dst_level = level, DebugName(true));
.src_rect = GetRect(level), for (u32 level = 0; level < levels; level++) {
.dst_rect = GetScaledRect(level), const VideoCore::TextureBlit blit = {
}; .src_level = level,
BlitScale(blit, true); .dst_level = level,
.src_rect = GetRect(level),
.dst_rect = GetScaledRect(level),
};
BlitScale(blit, true);
}
}
if (new_sample_count > 1) {
// Todo(wunk): OpenGL MSAA
} }
} }

View file

@ -126,8 +126,8 @@ public:
/// Attaches a handle of surface to the specified framebuffer target /// Attaches a handle of surface to the specified framebuffer target
void Attach(GLenum target, u32 level, u32 layer, bool scaled = true); void Attach(GLenum target, u32 level, u32 layer, bool scaled = true);
/// Scales up the surface to match the new resolution scale. /// Scales up the surface to match the new resolution scale and sample-count.
void ScaleUp(u32 new_scale); void ScaleUp(u32 new_scale, u8 new_sample_count);
/// Returns the bpp of the internal surface format /// Returns the bpp of the internal surface format
u32 GetInternalBytesPerPixel() const; u32 GetInternalBytesPerPixel() const;

View file

@ -1084,12 +1084,16 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download,
}); });
} }
void Surface::ScaleUp(u32 new_scale) { void Surface::ScaleUp(u32 new_scale, u8 new_sample_count) {
if (res_scale == new_scale || new_scale == 1) { if (res_scale == new_scale) {
return;
}
if (sample_count == new_sample_count) {
return; return;
} }
res_scale = new_scale; res_scale = new_scale;
sample_count = new_sample_count;
const bool is_mutable = pixel_format == VideoCore::PixelFormat::RGBA8; const bool is_mutable = pixel_format == VideoCore::PixelFormat::RGBA8;
@ -1101,27 +1105,35 @@ void Surface::ScaleUp(u32 new_scale) {
flags |= vk::ImageCreateFlagBits::eMutableFormat; flags |= vk::ImageCreateFlagBits::eMutableFormat;
} }
handles[1] = MakeHandle(instance, GetScaledWidth(), GetScaledHeight(), levels, texture_type, if (res_scale > 1) {
traits.native, vk::SampleCountFlagBits::e1, traits.usage, flags, handles[1] = MakeHandle(instance, GetScaledWidth(), GetScaledHeight(), levels, texture_type,
traits.aspect, false, DebugName(true)); traits.native, vk::SampleCountFlagBits::e1, traits.usage, flags,
traits.aspect, false, DebugName(true));
runtime->renderpass_cache.EndRendering(); runtime->renderpass_cache.EndRendering();
scheduler->Record( scheduler->Record(
[raw_images = std::array{Image()}, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { [raw_images = std::array{Image()}, aspect = traits.aspect](vk::CommandBuffer cmdbuf) {
const auto barriers = MakeInitBarriers(aspect, raw_images); const auto barriers = MakeInitBarriers(aspect, raw_images);
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlagBits::eByRegion, {}, {}, barriers); vk::DependencyFlagBits::eByRegion, {}, {}, barriers);
}); });
LOG_INFO(HW_GPU, "Surface scale up!"); LOG_INFO(HW_GPU, "Surface scale up!");
for (u32 level = 0; level < levels; level++) { for (u32 level = 0; level < levels; level++) {
const VideoCore::TextureBlit blit = { const VideoCore::TextureBlit blit = {
.src_level = level, .src_level = level,
.dst_level = level, .dst_level = level,
.src_rect = GetRect(level), .src_rect = GetRect(level),
.dst_rect = GetScaledRect(level), .dst_rect = GetScaledRect(level),
}; };
BlitScale(blit, true); BlitScale(blit, true);
}
}
if (sample_count > 1) {
handles[3] = MakeHandle(instance, GetScaledWidth(), GetScaledHeight(), levels, texture_type,
traits.native, vk::SampleCountFlagBits(sample_count), traits.usage,
flags, traits.aspect, false, DebugName(true, false, sample_count));
} }
} }
@ -1487,8 +1499,8 @@ void Surface::BlitScale(const VideoCore::TextureBlit& blit, bool up_scale) {
Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferParams& params, Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferParams& params,
Surface* color, Surface* depth) Surface* color, Surface* depth)
: VideoCore::FramebufferParams{params}, res_scale{color ? color->res_scale : VideoCore::FramebufferParams{params},
: (depth ? depth->res_scale : 1u)}, res_scale{color ? color->res_scale : (depth ? depth->res_scale : 1u)},
sample_count{params.sample_count} { sample_count{params.sample_count} {
auto& renderpass_cache = runtime.GetRenderpassCache(); auto& renderpass_cache = runtime.GetRenderpassCache();
if (shadow_rendering && !color) { if (shadow_rendering && !color) {

View file

@ -156,8 +156,8 @@ public:
void Download(const VideoCore::BufferTextureCopy& download, void Download(const VideoCore::BufferTextureCopy& download,
const VideoCore::StagingData& staging); const VideoCore::StagingData& staging);
/// Scales up the surface to match the new resolution scale. /// Scales up the surface to match the new resolution scale and sample-count.
void ScaleUp(u32 new_scale); void ScaleUp(u32 new_scale, u8 new_sample_count);
/// Returns the bpp of the internal surface format /// Returns the bpp of the internal surface format
u32 GetInternalBytesPerPixel() const; u32 GetInternalBytesPerPixel() const;