mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
rsx: Add option to toggle MSAA
This commit is contained in:
parent
ea8409dcfd
commit
bca5f94b3f
11 changed files with 99 additions and 29 deletions
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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"};
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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"}},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue