2020-12-05 13:08:24 +01:00
|
|
|
#pragma once
|
2016-01-19 18:43:16 +01:00
|
|
|
#include "../Common/surface_store.h"
|
2016-09-18 07:19:26 +02:00
|
|
|
#include "GLHelpers.h"
|
2017-09-26 15:24:43 +02:00
|
|
|
#include "../rsx_utils.h"
|
2016-01-19 18:43:16 +01:00
|
|
|
|
|
|
|
|
struct color_swizzle
|
|
|
|
|
{
|
|
|
|
|
gl::texture::channel a = gl::texture::channel::a;
|
|
|
|
|
gl::texture::channel r = gl::texture::channel::r;
|
|
|
|
|
gl::texture::channel g = gl::texture::channel::g;
|
|
|
|
|
gl::texture::channel b = gl::texture::channel::b;
|
|
|
|
|
|
|
|
|
|
color_swizzle() = default;
|
|
|
|
|
color_swizzle(gl::texture::channel a, gl::texture::channel r, gl::texture::channel g, gl::texture::channel b)
|
|
|
|
|
: a(a), r(r), g(g), b(b)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct color_format
|
|
|
|
|
{
|
|
|
|
|
gl::texture::type type;
|
|
|
|
|
gl::texture::format format;
|
2019-08-13 15:29:30 +02:00
|
|
|
gl::texture::internal_format internal_format;
|
2016-01-19 18:43:16 +01:00
|
|
|
bool swap_bytes;
|
|
|
|
|
color_swizzle swizzle;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct depth_format
|
|
|
|
|
{
|
|
|
|
|
gl::texture::type type;
|
|
|
|
|
gl::texture::format format;
|
|
|
|
|
gl::texture::internal_format internal_format;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
namespace rsx
|
|
|
|
|
{
|
|
|
|
|
namespace internals
|
|
|
|
|
{
|
|
|
|
|
color_format surface_color_format_to_gl(rsx::surface_color_format color_format);
|
2020-08-15 13:07:18 +02:00
|
|
|
depth_format surface_depth_format_to_gl(rsx::surface_depth_format2 depth_format);
|
2016-01-19 18:43:16 +01:00
|
|
|
u8 get_pixel_size(rsx::surface_depth_format format);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-16 19:29:56 +01:00
|
|
|
namespace gl
|
|
|
|
|
{
|
2018-07-17 18:42:51 +02:00
|
|
|
class render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor<texture*>
|
2017-02-16 19:29:56 +01:00
|
|
|
{
|
2020-01-26 11:28:28 +01:00
|
|
|
void clear_memory(gl::command_context& cmd);
|
|
|
|
|
void load_memory(gl::command_context& cmd);
|
2021-05-11 23:44:40 +02:00
|
|
|
void initialize_memory(gl::command_context& cmd, rsx::surface_access access);
|
2020-01-26 11:28:28 +01:00
|
|
|
|
2017-02-16 19:29:56 +01:00
|
|
|
public:
|
2020-09-05 17:27:24 +02:00
|
|
|
render_target(GLuint width, GLuint height, GLenum sized_format, rsx::format_class format_class)
|
|
|
|
|
: viewable_image(GL_TEXTURE_2D, width, height, 1, 1, sized_format, format_class)
|
2018-04-07 12:19:49 +02:00
|
|
|
{}
|
2017-02-16 19:29:56 +01:00
|
|
|
|
|
|
|
|
// Internal pitch is the actual row length in bytes of the openGL texture
|
2022-01-09 21:07:18 +01:00
|
|
|
void set_native_pitch(u32 pitch)
|
2017-02-16 19:29:56 +01:00
|
|
|
{
|
|
|
|
|
native_pitch = pitch;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-09 21:07:18 +01:00
|
|
|
void set_surface_dimensions(u16 w, u16 h, u32 pitch)
|
2019-03-19 21:46:21 +01:00
|
|
|
{
|
|
|
|
|
surface_width = w;
|
|
|
|
|
surface_height = h;
|
|
|
|
|
rsx_pitch = pitch;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-09 21:07:18 +01:00
|
|
|
void set_rsx_pitch(u32 pitch)
|
2017-02-16 19:29:56 +01:00
|
|
|
{
|
|
|
|
|
rsx_pitch = pitch;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-25 16:03:14 +01:00
|
|
|
bool is_depth_surface() const override
|
|
|
|
|
{
|
2021-12-07 18:46:31 +01:00
|
|
|
return !!(aspect() & gl::image_aspect::depth);
|
2019-02-25 16:03:14 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-10 22:04:13 +02:00
|
|
|
void release_ref(texture* t) const override
|
|
|
|
|
{
|
|
|
|
|
static_cast<gl::render_target*>(t)->release();
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 09:32:04 +01:00
|
|
|
viewable_image* get_surface(rsx::surface_access /*access_type*/) override
|
2017-09-08 16:52:13 +02:00
|
|
|
{
|
2019-05-20 16:14:02 +02:00
|
|
|
// TODO
|
2022-03-13 09:32:04 +01:00
|
|
|
return static_cast<gl::viewable_image*>(this);
|
2017-09-08 16:52:13 +02:00
|
|
|
}
|
2017-02-16 19:29:56 +01:00
|
|
|
|
2018-04-07 12:19:49 +02:00
|
|
|
u32 raw_handle() const
|
2018-03-23 16:05:56 +01:00
|
|
|
{
|
2017-09-08 16:52:13 +02:00
|
|
|
return id();
|
2017-02-16 19:29:56 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-26 15:24:43 +02:00
|
|
|
bool matches_dimensions(u16 _width, u16 _height) const
|
|
|
|
|
{
|
2018-04-29 08:41:51 +02:00
|
|
|
//Use forward scaling to account for rounding and clamping errors
|
2020-11-17 21:56:33 +01:00
|
|
|
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(_width, _height);
|
|
|
|
|
return (scaled_w == width()) && (scaled_h == height());
|
2017-09-08 16:52:13 +02:00
|
|
|
}
|
2018-12-16 12:57:22 +01:00
|
|
|
|
2020-01-26 11:28:28 +01:00
|
|
|
void memory_barrier(gl::command_context& cmd, rsx::surface_access access);
|
2021-05-08 18:08:32 +02:00
|
|
|
void read_barrier(gl::command_context& cmd) { memory_barrier(cmd, rsx::surface_access::shader_read); }
|
|
|
|
|
void write_barrier(gl::command_context& cmd) { memory_barrier(cmd, rsx::surface_access::shader_write); }
|
2017-02-16 19:29:56 +01:00
|
|
|
};
|
2018-09-19 12:16:26 +02:00
|
|
|
|
|
|
|
|
struct framebuffer_holder : public gl::fbo, public rsx::ref_counted
|
|
|
|
|
{
|
|
|
|
|
using gl::fbo::fbo;
|
|
|
|
|
};
|
2019-05-07 20:51:53 +02:00
|
|
|
|
|
|
|
|
static inline gl::render_target* as_rtt(gl::texture* t)
|
|
|
|
|
{
|
2020-12-09 08:47:45 +01:00
|
|
|
return ensure(dynamic_cast<gl::render_target*>(t));
|
2019-05-07 20:51:53 +02:00
|
|
|
}
|
2017-02-16 19:29:56 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-19 18:43:16 +01:00
|
|
|
struct gl_render_target_traits
|
|
|
|
|
{
|
2016-07-22 01:31:58 +02:00
|
|
|
using surface_storage_type = std::unique_ptr<gl::render_target>;
|
|
|
|
|
using surface_type = gl::render_target*;
|
2019-05-07 20:51:53 +02:00
|
|
|
using command_list_type = gl::command_context&;
|
2016-01-19 18:43:16 +01:00
|
|
|
using download_buffer_object = std::vector<u8>;
|
2019-05-07 20:51:53 +02:00
|
|
|
using barrier_descriptor_t = rsx::deferred_clipped_region<gl::render_target*>;
|
2016-01-19 18:43:16 +01:00
|
|
|
|
|
|
|
|
static
|
2016-07-22 01:31:58 +02:00
|
|
|
std::unique_ptr<gl::render_target> create_new_surface(
|
2018-12-12 09:58:44 +01:00
|
|
|
u32 address,
|
2016-01-19 18:43:16 +01:00
|
|
|
rsx::surface_color_format surface_color_format,
|
2020-12-18 08:39:54 +01:00
|
|
|
usz width, usz height, usz pitch,
|
2019-05-21 19:56:48 +02:00
|
|
|
rsx::surface_antialiasing antialias
|
2016-01-19 18:43:16 +01:00
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
auto format = rsx::internals::surface_color_format_to_gl(surface_color_format);
|
2020-11-17 21:56:33 +01:00
|
|
|
const auto [width_, height_] = rsx::apply_resolution_scale<true>(static_cast<u16>(width), static_cast<u16>(height));
|
2017-02-16 19:29:56 +01:00
|
|
|
|
2020-11-17 21:56:33 +01:00
|
|
|
std::unique_ptr<gl::render_target> result(new gl::render_target(width_, height_,
|
|
|
|
|
static_cast<GLenum>(format.internal_format), RSX_FORMAT_CLASS_COLOR));
|
2019-07-05 14:12:17 +02:00
|
|
|
|
|
|
|
|
result->set_aa_mode(antialias);
|
2022-01-09 21:07:18 +01:00
|
|
|
result->set_native_pitch(static_cast<u32>(width) * get_format_block_size_in_bytes(surface_color_format) * result->samples_x);
|
|
|
|
|
result->set_surface_dimensions(static_cast<u16>(width), static_cast<u16>(height), static_cast<u32>(pitch));
|
2019-05-13 19:53:00 +02:00
|
|
|
result->set_format(surface_color_format);
|
2016-01-19 18:43:16 +01:00
|
|
|
|
2019-12-03 23:34:23 +01:00
|
|
|
std::array<GLenum, 4> native_layout = { static_cast<GLenum>(format.swizzle.a), static_cast<GLenum>(format.swizzle.r), static_cast<GLenum>(format.swizzle.g), static_cast<GLenum>(format.swizzle.b) };
|
2018-04-07 12:19:49 +02:00
|
|
|
result->set_native_component_layout(native_layout);
|
2017-06-30 23:24:41 +02:00
|
|
|
|
2019-05-14 18:50:45 +02:00
|
|
|
result->memory_usage_flags = rsx::surface_usage_flags::attachment;
|
|
|
|
|
result->state_flags = rsx::surface_state_flags::erase_bkgnd;
|
2019-02-28 11:29:53 +01:00
|
|
|
result->queue_tag(address);
|
2019-05-10 22:04:13 +02:00
|
|
|
result->add_ref();
|
2016-01-19 18:43:16 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
2016-07-22 01:31:58 +02:00
|
|
|
std::unique_ptr<gl::render_target> create_new_surface(
|
2018-12-12 09:58:44 +01:00
|
|
|
u32 address,
|
2020-08-15 13:07:18 +02:00
|
|
|
rsx::surface_depth_format2 surface_depth_format,
|
2020-12-18 08:39:54 +01:00
|
|
|
usz width, usz height, usz pitch,
|
2019-05-21 19:56:48 +02:00
|
|
|
rsx::surface_antialiasing antialias
|
2016-01-19 18:43:16 +01:00
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
auto format = rsx::internals::surface_depth_format_to_gl(surface_depth_format);
|
2020-11-17 21:56:33 +01:00
|
|
|
const auto [width_, height_] = rsx::apply_resolution_scale<true>(static_cast<u16>(width), static_cast<u16>(height));
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<gl::render_target> result(new gl::render_target(width_, height_,
|
|
|
|
|
static_cast<GLenum>(format.internal_format), rsx::classify_format(surface_depth_format)));
|
2016-01-19 18:43:16 +01:00
|
|
|
|
2019-07-05 14:12:17 +02:00
|
|
|
result->set_aa_mode(antialias);
|
2022-01-09 21:07:18 +01:00
|
|
|
result->set_surface_dimensions(static_cast<u16>(width), static_cast<u16>(height), static_cast<u32>(pitch));
|
2019-07-05 14:12:17 +02:00
|
|
|
result->set_format(surface_depth_format);
|
2022-01-09 21:07:18 +01:00
|
|
|
result->set_native_pitch(static_cast<u32>(width) * get_format_block_size_in_bytes(surface_depth_format) * result->samples_x);
|
2019-07-05 14:12:17 +02:00
|
|
|
|
|
|
|
|
std::array<GLenum, 4> native_layout = { GL_RED, GL_RED, GL_RED, GL_RED };
|
2018-04-07 12:19:49 +02:00
|
|
|
result->set_native_component_layout(native_layout);
|
2017-06-30 23:24:41 +02:00
|
|
|
|
2019-05-14 18:50:45 +02:00
|
|
|
result->memory_usage_flags = rsx::surface_usage_flags::attachment;
|
|
|
|
|
result->state_flags = rsx::surface_state_flags::erase_bkgnd;
|
2019-02-28 11:29:53 +01:00
|
|
|
result->queue_tag(address);
|
2019-05-10 22:04:13 +02:00
|
|
|
result->add_ref();
|
2016-01-19 18:43:16 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-07 20:51:53 +02:00
|
|
|
static
|
|
|
|
|
void clone_surface(
|
2019-07-15 18:36:29 +02:00
|
|
|
gl::command_context& cmd,
|
2019-05-07 20:51:53 +02:00
|
|
|
std::unique_ptr<gl::render_target>& sink, gl::render_target* ref,
|
|
|
|
|
u32 address, barrier_descriptor_t& prev)
|
|
|
|
|
{
|
|
|
|
|
if (!sink)
|
|
|
|
|
{
|
2019-12-03 23:34:23 +01:00
|
|
|
auto internal_format = static_cast<GLenum>(ref->get_internal_format());
|
2020-11-17 21:56:33 +01:00
|
|
|
const auto [new_w, new_h] = rsx::apply_resolution_scale<true>(prev.width, prev.height,
|
2022-03-05 16:42:53 +01:00
|
|
|
ref->get_surface_width<rsx::surface_metrics::pixels>(), ref->get_surface_height<rsx::surface_metrics::pixels>());
|
2019-05-07 20:51:53 +02:00
|
|
|
|
2020-09-05 17:27:24 +02:00
|
|
|
sink = std::make_unique<gl::render_target>(new_w, new_h, internal_format, ref->format_class());
|
2019-05-10 22:04:13 +02:00
|
|
|
sink->add_ref();
|
2019-05-14 18:50:45 +02:00
|
|
|
|
|
|
|
|
sink->memory_usage_flags = rsx::surface_usage_flags::storage;
|
|
|
|
|
sink->state_flags = rsx::surface_state_flags::erase_bkgnd;
|
2019-05-13 19:53:00 +02:00
|
|
|
sink->format_info = ref->format_info;
|
2019-05-14 18:50:45 +02:00
|
|
|
|
2019-05-21 19:56:48 +02:00
|
|
|
sink->set_spp(ref->get_spp());
|
2022-01-09 21:07:18 +01:00
|
|
|
sink->set_native_pitch(static_cast<u32>(prev.width) * ref->get_bpp() * ref->samples_x);
|
2019-08-27 21:05:10 +02:00
|
|
|
sink->set_rsx_pitch(ref->get_rsx_pitch());
|
2019-05-13 19:53:00 +02:00
|
|
|
sink->set_surface_dimensions(prev.width, prev.height, ref->get_rsx_pitch());
|
|
|
|
|
sink->set_native_component_layout(ref->get_native_component_layout());
|
|
|
|
|
sink->queue_tag(address);
|
|
|
|
|
}
|
2019-05-07 20:51:53 +02:00
|
|
|
|
|
|
|
|
prev.target = sink.get();
|
|
|
|
|
|
2019-07-15 18:36:29 +02:00
|
|
|
if (!sink->old_contents.empty())
|
|
|
|
|
{
|
|
|
|
|
// Deal with this, likely only needs to clear
|
|
|
|
|
if (sink->surface_width > prev.width || sink->surface_height > prev.height)
|
|
|
|
|
{
|
|
|
|
|
sink->write_barrier(cmd);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sink->clear_rw_barrier();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 21:05:10 +02:00
|
|
|
sink->set_rsx_pitch(ref->get_rsx_pitch());
|
2019-05-07 20:51:53 +02:00
|
|
|
sink->set_old_contents_region(prev, false);
|
|
|
|
|
sink->last_use_tag = ref->last_use_tag;
|
2020-08-01 13:27:13 +02:00
|
|
|
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
|
2019-05-07 20:51:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
2019-05-21 19:56:48 +02:00
|
|
|
bool is_compatible_surface(const gl::render_target* surface, const gl::render_target* ref, u16 width, u16 height, u8 sample_count)
|
2019-05-07 20:51:53 +02:00
|
|
|
{
|
|
|
|
|
return (surface->get_internal_format() == ref->get_internal_format() &&
|
2019-05-21 19:56:48 +02:00
|
|
|
surface->get_spp() == sample_count &&
|
2022-03-05 16:42:53 +01:00
|
|
|
surface->get_surface_width<rsx::surface_metrics::pixels>() >= width &&
|
|
|
|
|
surface->get_surface_height<rsx::surface_metrics::pixels>() >= height);
|
2017-08-13 23:27:19 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-21 19:56:48 +02:00
|
|
|
static
|
|
|
|
|
void prepare_surface_for_drawing(gl::command_context&, gl::render_target* surface)
|
2019-05-13 18:39:50 +02:00
|
|
|
{
|
2019-05-21 19:56:48 +02:00
|
|
|
surface->memory_usage_flags |= rsx::surface_usage_flags::attachment;
|
2019-05-13 18:39:50 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-21 19:56:48 +02:00
|
|
|
static
|
|
|
|
|
void prepare_surface_for_sampling(gl::command_context&, gl::render_target*)
|
|
|
|
|
{}
|
2016-01-19 18:43:16 +01:00
|
|
|
|
2018-06-03 13:52:21 +02:00
|
|
|
static
|
2020-12-18 08:39:54 +01:00
|
|
|
bool surface_is_pitch_compatible(const std::unique_ptr<gl::render_target> &surface, usz pitch)
|
2018-06-03 13:52:21 +02:00
|
|
|
{
|
2019-03-15 16:00:12 +01:00
|
|
|
return surface->get_rsx_pitch() == pitch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
2020-12-18 08:39:54 +01:00
|
|
|
void invalidate_surface_contents(gl::command_context&, gl::render_target *surface, u32 address, usz pitch)
|
2019-03-15 16:00:12 +01:00
|
|
|
{
|
2022-01-09 21:07:18 +01:00
|
|
|
surface->set_rsx_pitch(static_cast<u32>(pitch));
|
2018-12-12 09:58:44 +01:00
|
|
|
surface->queue_tag(address);
|
2019-05-11 12:16:46 +02:00
|
|
|
surface->last_use_tag = 0;
|
2019-06-08 22:47:46 +02:00
|
|
|
surface->stencil_init_flags = 0;
|
2019-05-14 18:50:45 +02:00
|
|
|
surface->memory_usage_flags = rsx::surface_usage_flags::unknown;
|
2020-08-01 13:27:13 +02:00
|
|
|
surface->raster_type = rsx::surface_raster_type::linear;
|
2018-06-03 13:52:21 +02:00
|
|
|
}
|
2017-06-14 00:36:41 +02:00
|
|
|
|
2017-10-31 19:01:24 +01:00
|
|
|
static
|
2019-05-10 22:04:13 +02:00
|
|
|
void notify_surface_invalidated(const std::unique_ptr<gl::render_target>& surface)
|
|
|
|
|
{
|
2019-07-13 16:52:55 +02:00
|
|
|
if (!surface->old_contents.empty())
|
2019-05-11 12:16:46 +02:00
|
|
|
{
|
|
|
|
|
// TODO: Retire the deferred writes
|
|
|
|
|
surface->clear_rw_barrier();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-10 22:04:13 +02:00
|
|
|
surface->release();
|
|
|
|
|
}
|
2017-10-31 19:01:24 +01:00
|
|
|
|
2018-06-03 13:52:21 +02:00
|
|
|
static
|
2019-05-30 17:38:18 +02:00
|
|
|
void notify_surface_persist(const std::unique_ptr<gl::render_target>& /*surface*/)
|
2019-05-20 16:14:02 +02:00
|
|
|
{}
|
2018-06-03 13:52:21 +02:00
|
|
|
|
2019-05-10 22:04:13 +02:00
|
|
|
static
|
|
|
|
|
void notify_surface_reused(const std::unique_ptr<gl::render_target>& surface)
|
|
|
|
|
{
|
2019-05-14 18:50:45 +02:00
|
|
|
surface->state_flags |= rsx::surface_state_flags::erase_bkgnd;
|
2019-05-10 22:04:13 +02:00
|
|
|
surface->add_ref();
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-19 18:43:16 +01:00
|
|
|
static
|
2019-05-21 19:56:48 +02:00
|
|
|
bool int_surface_matches_properties(
|
|
|
|
|
const std::unique_ptr<gl::render_target> &surface,
|
|
|
|
|
gl::texture::internal_format format,
|
2020-12-18 08:39:54 +01:00
|
|
|
usz width, usz height,
|
2019-05-21 19:56:48 +02:00
|
|
|
rsx::surface_antialiasing antialias,
|
|
|
|
|
bool check_refs = false)
|
2016-01-19 18:43:16 +01:00
|
|
|
{
|
2019-05-21 19:56:48 +02:00
|
|
|
if (check_refs && surface->has_refs())
|
2017-07-18 12:44:36 +02:00
|
|
|
return false;
|
|
|
|
|
|
2019-05-21 19:56:48 +02:00
|
|
|
return surface->get_internal_format() == format &&
|
|
|
|
|
surface->get_spp() == get_format_sample_count(antialias) &&
|
2019-12-03 23:34:23 +01:00
|
|
|
surface->matches_dimensions(static_cast<u16>(width), static_cast<u16>(height));
|
2016-01-19 18:43:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
2019-05-21 19:56:48 +02:00
|
|
|
bool surface_matches_properties(
|
|
|
|
|
const std::unique_ptr<gl::render_target> &surface,
|
|
|
|
|
rsx::surface_color_format format,
|
2020-12-18 08:39:54 +01:00
|
|
|
usz width, usz height,
|
2019-05-21 19:56:48 +02:00
|
|
|
rsx::surface_antialiasing antialias,
|
|
|
|
|
bool check_refs=false)
|
2016-01-19 18:43:16 +01:00
|
|
|
{
|
2019-08-13 15:29:30 +02:00
|
|
|
const auto internal_fmt = rsx::internals::surface_color_format_to_gl(format).internal_format;
|
2019-05-21 19:56:48 +02:00
|
|
|
return int_surface_matches_properties(surface, internal_fmt, width, height, antialias, check_refs);
|
2016-01-19 18:43:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
2019-05-21 19:56:48 +02:00
|
|
|
bool surface_matches_properties(
|
|
|
|
|
const std::unique_ptr<gl::render_target> &surface,
|
2020-08-15 13:07:18 +02:00
|
|
|
rsx::surface_depth_format2 format,
|
2020-12-18 08:39:54 +01:00
|
|
|
usz width, usz height,
|
2019-05-21 19:56:48 +02:00
|
|
|
rsx::surface_antialiasing antialias,
|
|
|
|
|
bool check_refs = false)
|
2016-01-19 18:43:16 +01:00
|
|
|
{
|
2019-05-21 19:56:48 +02:00
|
|
|
const auto internal_fmt = rsx::internals::surface_depth_format_to_gl(format).internal_format;
|
|
|
|
|
return int_surface_matches_properties(surface, internal_fmt, width, height, antialias, check_refs);
|
2016-01-19 18:43:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
2019-05-21 19:56:48 +02:00
|
|
|
gl::render_target* get(const std::unique_ptr<gl::render_target> &in)
|
2016-01-19 18:43:16 +01:00
|
|
|
{
|
|
|
|
|
return in.get();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-02-02 08:04:55 +01:00
|
|
|
struct gl_render_targets : public rsx::surface_store<gl_render_target_traits>
|
2016-01-19 18:43:16 +01:00
|
|
|
{
|
2019-05-10 22:04:13 +02:00
|
|
|
void destroy()
|
|
|
|
|
{
|
|
|
|
|
invalidate_all();
|
|
|
|
|
invalidated_resources.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-01 20:11:33 +02:00
|
|
|
std::vector<GLuint> free_invalidated(gl::command_context& cmd)
|
2018-02-02 08:04:55 +01:00
|
|
|
{
|
2020-06-01 20:11:33 +02:00
|
|
|
// Do not allow more than 256M of RSX memory to be used by RTTs
|
2020-07-23 22:13:51 +02:00
|
|
|
if (check_memory_usage(256 * 0x100000))
|
2020-06-01 20:11:33 +02:00
|
|
|
{
|
2020-07-23 22:13:51 +02:00
|
|
|
handle_memory_pressure(cmd, rsx::problem_severity::moderate);
|
2020-06-01 20:11:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-19 12:16:26 +02:00
|
|
|
std::vector<GLuint> removed;
|
2018-02-02 08:04:55 +01:00
|
|
|
invalidated_resources.remove_if([&](auto &rtt)
|
|
|
|
|
{
|
2019-05-10 22:04:13 +02:00
|
|
|
if (rtt->unused_check_count() >= 2)
|
2018-09-19 12:16:26 +02:00
|
|
|
{
|
|
|
|
|
removed.push_back(rtt->id());
|
2018-02-02 08:04:55 +01:00
|
|
|
return true;
|
2018-09-19 12:16:26 +02:00
|
|
|
}
|
2018-02-02 08:04:55 +01:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
});
|
2018-09-19 12:16:26 +02:00
|
|
|
|
|
|
|
|
return removed;
|
2018-02-02 08:04:55 +01:00
|
|
|
}
|
2016-01-19 18:43:16 +01:00
|
|
|
};
|