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 dst_scale = dst_surface.res_scale;
if (src_scale > dst_scale) {
dst_surface.ScaleUp(src_scale);
const u32 src_sample_count = src_surface.sample_count;
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);
@ -1171,8 +1173,9 @@ bool RasterizerCache<T>::ValidateByReinterpretation(Surface& surface, SurfacePar
return false;
}
const u32 res_scale = src_surface.res_scale;
if (res_scale > surface.res_scale) {
surface.ScaleUp(res_scale);
const u8 sample_count = src_surface.sample_count;
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 SurfaceParams copy_params = surface.FromInterval(copy_interval);
@ -1349,8 +1352,8 @@ SurfaceId RasterizerCache<T>::CreateSurface(const SurfaceParams& params) {
return surface_id;
}();
Surface& surface = slot_surfaces[surface_id];
if (params.res_scale > surface.res_scale) {
surface.ScaleUp(params.res_scale);
if ((params.res_scale > surface.res_scale) || (params.sample_count > surface.sample_count)) {
surface.ScaleUp(params.res_scale, params.sample_count);
}
surface.MarkInvalid(surface.GetInterval());
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) {
if (res_scale == new_scale || new_scale == 1) {
void Surface::ScaleUp(u32 new_scale, u8 new_sample_count) {
if (res_scale == new_scale) {
return;
}
if (sample_count == new_sample_count) {
return;
}
res_scale = new_scale;
textures[1] = MakeHandle(GL_TEXTURE_2D, GetScaledWidth(), GetScaledHeight(), levels, tuple,
DebugName(true));
for (u32 level = 0; level < levels; level++) {
const VideoCore::TextureBlit blit = {
.src_level = level,
.dst_level = level,
.src_rect = GetRect(level),
.dst_rect = GetScaledRect(level),
};
BlitScale(blit, true);
if (res_scale > 1) {
textures[1] = MakeHandle(GL_TEXTURE_2D, GetScaledWidth(), GetScaledHeight(), levels, tuple,
DebugName(true));
for (u32 level = 0; level < levels; level++) {
const VideoCore::TextureBlit blit = {
.src_level = level,
.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
void Attach(GLenum target, u32 level, u32 layer, bool scaled = true);
/// Scales up the surface to match the new resolution scale.
void ScaleUp(u32 new_scale);
/// Scales up the surface to match the new resolution scale and sample-count.
void ScaleUp(u32 new_scale, u8 new_sample_count);
/// Returns the bpp of the internal surface format
u32 GetInternalBytesPerPixel() const;

View file

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

View file

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