rsx: Add option to toggle MSAA

This commit is contained in:
kd-11 2019-06-06 13:25:32 +03:00 committed by kd-11
parent ea8409dcfd
commit bca5f94b3f
11 changed files with 99 additions and 29 deletions

View file

@ -16,6 +16,12 @@ namespace rsx
require_unresolve = 4
};
enum surface_sample_layout : u32
{
null = 0,
ps3 = 1
};
template <typename surface_type>
struct surface_overlap_info_t
{
@ -137,6 +143,7 @@ namespace rsx
u8 samples_y = 1;
std::unique_ptr<typename std::remove_pointer<image_storage_type>::type> resolve_surface;
surface_sample_layout sample_layout = surface_sample_layout::null;
flags32_t memory_usage_flags = surface_usage_flags::unknown;
flags32_t state_flags = surface_state_flags::ready;
@ -444,7 +451,7 @@ namespace rsx
// HACK!! This should be cleared through memory barriers only
state_flags = rsx::surface_state_flags::ready;
if (spp > 1)
if (spp > 1 && sample_layout != surface_sample_layout::null)
{
msaa_flags = resolve_flags;
}
@ -518,5 +525,15 @@ namespace rsx
y1 *= samples_y;
y2 *= samples_y;
}
template<typename T>
void transform_blit_coordinates(rsx::surface_access access_type, area_base<T>& region)
{
if (spp == 1 || sample_layout == rsx::surface_sample_layout::ps3)
return;
verify(HERE), access_type != rsx::surface_access::write;
transform_samples_to_pixels(region);
}
};
}

View file

@ -2889,18 +2889,16 @@ namespace rsx
}
}
if (src_is_render_target &&
dynamic_cast<decltype(src_subres.surface)>(vram_texture) != nullptr)
if (src_is_render_target)
{
// The resource is of surface type; possibly disabled AA emulation
src_subres.surface->transform_samples_to_pixels(src_area);
src_subres.surface->transform_blit_coordinates(rsx::surface_access::transfer, src_area);
}
if (dst_is_render_target &&
dynamic_cast<decltype(dst_subres.surface)>(dest_texture) != nullptr)
if (dst_is_render_target)
{
// The resource is of surface type; possibly disabled AA emulation
dst_subres.surface->transform_samples_to_pixels(dst_area);
dst_subres.surface->transform_blit_coordinates(rsx::surface_access::transfer, dst_area);
}
typeless_info.analyse();

View file

@ -658,9 +658,9 @@ namespace rsx
auto alpha_ref = rsx::method_registers.alpha_ref() / 255.f;
auto rop_control = rsx::method_registers.alpha_test_enabled()? 1u : 0u;
if (0 &&
rsx::method_registers.msaa_alpha_to_coverage_enabled() &&
rsx::method_registers.surface_antialias() != rsx::surface_antialiasing::center_1_sample)
if (rsx::method_registers.msaa_alpha_to_coverage_enabled() &&
rsx::method_registers.surface_antialias() != rsx::surface_antialiasing::center_1_sample &&
g_cfg.video.antialiasing_level == msaa_level::none)
{
// Alpha values generate a coverage mask for order independent blending
// Requires hardware AA to work properly (or just fragment sample stage in fragment shaders)

View file

@ -22,7 +22,7 @@ namespace vk
vk::viewable_image* get_surface(rsx::surface_access access_type) override
{
if (spp == 1 || access_type == rsx::surface_access::write)
if (samples() == 1 || access_type == rsx::surface_access::write)
{
return this;
}
@ -277,7 +277,7 @@ namespace vk
};
const bool read_access = (access != rsx::surface_access::write);
if (spp > 1 && read_access)
if (samples() > 1 && read_access)
{
get_resolve_target();
}
@ -352,10 +352,13 @@ namespace vk
auto src_area = old_contents.src_rect();
auto dst_area = old_contents.dst_rect();
if (g_cfg.video.antialiasing_level != msaa_level::none)
{
src_texture->transform_pixels_to_samples(src_area);
this->transform_pixels_to_samples(dst_area);
}
vk::image *target_image = (spp > 1) ? get_resolve_target() : this;
vk::image *target_image = (samples() > 1) ? get_resolve_target() : this;
if (dst_area.x1 == 0 && dst_area.y1 == 0 &&
unsigned(dst_area.x2) == target_image->width() && unsigned(dst_area.y2) == target_image->height())
{
@ -386,7 +389,7 @@ namespace vk
on_write_copy();
if (!read_access && spp > 1)
if (!read_access && samples() > 1)
{
// Write barrier, must initialize
unresolve(cmd);
@ -421,11 +424,23 @@ namespace rsx
vk::render_device &device, vk::command_buffer& cmd)
{
const auto fmt = vk::get_compatible_surface_format(format);
const auto spp = get_format_sample_count(antialias);
VkFormat requested_format = fmt.first;
VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (antialias == rsx::surface_antialiasing::center_1_sample)
u8 samples;
surface_sample_layout sample_layout;
if (g_cfg.video.antialiasing_level == msaa_level::_auto)
{
samples = get_format_sample_count(antialias);
sample_layout = surface_sample_layout::ps3;
}
else
{
samples = 1;
sample_layout = surface_sample_layout::null;
}
VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (LIKELY(samples == 1))
{
usage_flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
}
@ -440,7 +455,7 @@ namespace rsx
VK_IMAGE_TYPE_2D,
requested_format,
static_cast<uint32_t>(rsx::apply_resolution_scale((u16)width, true)), static_cast<uint32_t>(rsx::apply_resolution_scale((u16)height, true)), 1, 1, 1,
static_cast<VkSampleCountFlagBits>(spp),
static_cast<VkSampleCountFlagBits>(samples),
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
usage_flags,
@ -450,6 +465,7 @@ namespace rsx
rtt->set_format(format);
rtt->set_aa_mode(antialias);
rtt->sample_layout = sample_layout;
rtt->memory_usage_flags = rsx::surface_usage_flags::attachment;
rtt->state_flags = rsx::surface_state_flags::erase_bkgnd;
rtt->native_component_map = fmt.second;
@ -471,10 +487,22 @@ namespace rsx
vk::render_device &device, vk::command_buffer& cmd)
{
const VkFormat requested_format = vk::get_compatible_depth_surface_format(device.get_formats_support(), format);
const auto spp = get_format_sample_count(antialias);
VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
if (antialias == rsx::surface_antialiasing::center_1_sample)
u8 samples;
surface_sample_layout sample_layout;
if (g_cfg.video.antialiasing_level == msaa_level::_auto)
{
samples = get_format_sample_count(antialias);
sample_layout = surface_sample_layout::ps3;
}
else
{
samples = 1;
sample_layout = surface_sample_layout::null;
}
if (LIKELY(samples == 1))
{
usage_flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
@ -485,7 +513,7 @@ namespace rsx
VK_IMAGE_TYPE_2D,
requested_format,
static_cast<uint32_t>(rsx::apply_resolution_scale((u16)width, true)), static_cast<uint32_t>(rsx::apply_resolution_scale((u16)height, true)), 1, 1, 1,
static_cast<VkSampleCountFlagBits>(spp),
static_cast<VkSampleCountFlagBits>(samples),
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
usage_flags,
@ -495,6 +523,7 @@ namespace rsx
ds->set_format(format);
ds->set_aa_mode(antialias);
ds->sample_layout = sample_layout;
ds->memory_usage_flags= rsx::surface_usage_flags::attachment;
ds->state_flags = rsx::surface_state_flags::erase_bkgnd;
ds->native_component_map = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R };
@ -540,6 +569,7 @@ namespace rsx
sink->memory_usage_flags = rsx::surface_usage_flags::storage;
sink->state_flags = rsx::surface_state_flags::erase_bkgnd;
sink->native_component_map = ref->native_component_map;
sink->sample_layout = ref->sample_layout;
sink->native_pitch = u16(prev.width * ref->get_bpp() * ref->samples_x);
sink->surface_width = prev.width;
sink->surface_height = prev.height;

View file

@ -171,6 +171,21 @@ void fmt_class_string<video_aspect>::format(std::string& out, u64 arg)
});
}
template <>
void fmt_class_string<msaa_level>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](msaa_level value)
{
switch (value)
{
case msaa_level::none: return "Disabled";
case msaa_level::_auto: return "Auto";
}
return unknown;
});
}
template <>
void fmt_class_string<keyboard_handler>::format(std::string& out, u64 arg)
{

View file

@ -148,6 +148,12 @@ enum class frame_limit_type
_auto,
};
enum class msaa_level
{
none,
_auto
};
enum class detail_level
{
minimal,
@ -430,6 +436,7 @@ struct cfg_root : cfg::node
cfg::_enum<video_resolution> resolution{this, "Resolution", video_resolution::_720};
cfg::_enum<video_aspect> aspect_ratio{this, "Aspect ratio", video_aspect::_16_9};
cfg::_enum<frame_limit_type> frame_limit{this, "Frame limit", frame_limit_type::none};
cfg::_enum<msaa_level> antialiasing_level{this, "MSAA", msaa_level::none};
cfg::_bool write_color_buffers{this, "Write Color Buffers"};
cfg::_bool write_depth_buffer{this, "Write Depth Buffer"};

View file

@ -107,6 +107,7 @@
"graphicsAdapterBox_Linux": "On multi GPU systems select which GPU to use in RPCS3 when using Vulkan.\nThis is not needed when using OpenGL.",
"aspectBox": "Leave this on 16:9 unless you have a 4:3 monitor.\nAuto also works well, especially if you use a resolution that is not 720p.",
"frameLimitBox": "Off is the best option as it performs faster.\nUsing the frame limiter will add extra overhead and slow down the game.\nHowever, some games will crash if the frame rate is too high.\nIf that happens, set value to anything other than Off.",
"antiAliasing": "Emulate PS3 multisampling layout.\nCan fix some otherwise difficult to solve graphics glitches.\nLow to moderate performance hit depending on your GPU hardware.",
"anisotropicFilterOverride": "Higher values increase sharpness of textures on sloped surfaces at the cost of GPU resources.\nModern GPUs can handle this setting just fine even at 16x.\nKeep this on Automatic if you want to use the original setting used by a real PS3."
},
"sliders": {

View file

@ -53,6 +53,7 @@ public:
Resolution,
AspectRatio,
FrameLimit,
MSAA,
LogShaderPrograms,
WriteDepthBuffer,
WriteColorBuffers,
@ -262,6 +263,7 @@ private:
{ Resolution, { "Video", "Resolution"}},
{ AspectRatio, { "Video", "Aspect ratio"}},
{ FrameLimit, { "Video", "Frame limit"}},
{ MSAA, { "Video", "MSAA"}},
{ LogShaderPrograms, { "Video", "Log shader programs"}},
{ WriteDepthBuffer, { "Video", "Write Depth Buffer"}},
{ WriteColorBuffers, { "Video", "Write Color Buffers"}},

View file

@ -525,6 +525,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> guiSettings, std:
xemu_settings->EnhanceComboBox(ui->frameLimitBox, emu_settings::FrameLimit);
SubscribeTooltip(ui->frameLimitBox, json_gpu_cbo["frameLimitBox"].toString());
xemu_settings->EnhanceComboBox(ui->antiAliasing, emu_settings::MSAA);
SubscribeTooltip(ui->antiAliasing, json_gpu_cbo["antiAliasing"].toString());
xemu_settings->EnhanceComboBox(ui->anisotropicFilterOverride, emu_settings::AnisotropicFilterOverride, true);
SubscribeTooltip(ui->anisotropicFilterOverride, json_gpu_cbo["anisotropicFilterOverride"].toString());
// only allow values 0,2,4,8,16

View file

@ -468,9 +468,6 @@
</item>
<item>
<widget class="QGroupBox" name="gb_antiAliasing">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Anti-Aliasing</string>
</property>