mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-26 07:50:06 +00:00
rasterizer_cache: Create Surface MSAA handles upon ScaleUp
This commit is contained in:
parent
aebd108328
commit
44cb5a4ad2
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user