2020-12-05 13:08:24 +01:00
# pragma once
2014-08-04 01:33:57 +02:00
# include "Emu/RSX/GSRender.h"
2016-09-18 13:19:26 +08:00
# include "GLHelpers.h"
# include "GLTexture.h"
# include "GLTextureCache.h"
# include "GLRenderTargets.h"
2013-11-09 23:29:49 +02:00
# include "GLProgramBuffer.h"
2016-10-11 03:55:42 +03:00
# include "GLTextOut.h"
2017-11-15 15:02:59 +03:00
# include "GLOverlays.h"
2020-03-25 00:22:21 +03:00
# include "GLShaderInterpreter.h"
2012-11-15 01:39:56 +02:00
2018-09-29 01:12:00 +03:00
# include <optional>
2020-12-22 18:04:08 +03:00
# include <unordered_map>
2018-09-29 01:12:00 +03:00
2022-06-02 20:43:46 +03:00
# include "glutils/ring_buffer.h"
2023-07-11 20:40:30 +02:00
# ifdef _MSC_VER
2012-11-15 01:39:56 +02:00
# pragma comment(lib, "opengl32.lib")
2019-09-23 13:47:13 +00:00
# endif
2012-11-15 01:39:56 +02:00
2017-07-26 19:32:13 +03:00
namespace gl
{
2023-06-09 00:09:39 +03:00
using vertex_cache = rsx : : vertex_cache : : default_vertex_cache < rsx : : vertex_cache : : uploaded_range > ;
using weak_vertex_cache = rsx : : vertex_cache : : weak_vertex_cache ;
2017-07-26 19:32:13 +03:00
using null_vertex_cache = vertex_cache ;
2017-08-10 22:40:20 +03:00
using shader_cache = rsx : : shaders_cache < void * , GLProgramBuffer > ;
2018-02-21 20:50:27 +03:00
struct vertex_upload_info
{
u32 vertex_draw_count ;
u32 allocated_vertex_count ;
2019-01-21 21:07:27 +03:00
u32 first_vertex ;
2018-02-21 20:50:27 +03:00
u32 vertex_index_base ;
2019-01-14 15:33:05 +03:00
u32 vertex_index_offset ;
2018-02-21 20:50:27 +03:00
u32 persistent_mapping_offset ;
u32 volatile_mapping_offset ;
std : : optional < std : : tuple < GLenum , u32 > > index_info ;
} ;
2017-07-26 19:32:13 +03:00
2020-01-17 19:24:33 +03:00
struct work_item
{
u32 address_to_flush = 0 ;
gl : : texture_cache : : thrashed_set section_data ;
2017-03-10 16:27:38 +03:00
2020-01-17 19:24:33 +03:00
volatile bool processed = false ;
volatile bool result = false ;
volatile bool received = false ;
2018-05-29 15:11:34 +03:00
2020-01-17 19:24:33 +03:00
void producer_wait ( )
2018-05-29 15:11:34 +03:00
{
2020-01-17 19:24:33 +03:00
while ( ! processed )
{
std : : this_thread : : yield ( ) ;
}
received = true ;
2018-05-29 15:11:34 +03:00
}
2020-01-17 19:24:33 +03:00
} ;
2018-05-29 15:11:34 +03:00
2020-01-17 19:24:33 +03:00
struct present_surface_info
{
u32 address ;
u32 format ;
u32 width ;
u32 height ;
u32 pitch ;
} ;
}
2017-02-16 21:29:56 +03:00
2018-03-05 14:09:43 +03:00
class GLGSRender : public GSRender , public : : rsx : : reports : : ZCULL_control
2017-09-08 17:52:13 +03:00
{
2018-11-24 15:54:46 +03:00
gl : : sampler_state m_fs_sampler_states [ rsx : : limits : : fragment_textures_count ] ; // Fragment textures
gl : : sampler_state m_fs_sampler_mirror_states [ rsx : : limits : : fragment_textures_count ] ; // Alternate views of fragment textures with different format (e.g Depth vs Stencil for D24S8)
gl : : sampler_state m_vs_sampler_states [ rsx : : limits : : vertex_textures_count ] ; // Vertex textures
2017-07-27 19:04:55 +03:00
2020-03-25 00:22:21 +03:00
gl : : glsl : : program * m_program = nullptr ;
2022-03-23 22:53:18 +03:00
const GLFragmentProgram * m_fragment_prog = nullptr ;
const GLVertexProgram * m_vertex_prog = nullptr ;
2020-03-25 00:22:21 +03:00
2023-01-25 15:03:52 +03:00
rsx : : flags32_t m_interpreter_state = 0 ;
2020-03-25 00:22:21 +03:00
gl : : shader_interpreter m_shader_interpreter ;
2017-07-27 19:04:55 +03:00
2017-09-08 17:52:13 +03:00
gl_render_targets m_rtts ;
2017-07-27 19:04:55 +03:00
2017-09-08 17:52:13 +03:00
gl : : texture_cache m_gl_texture_cache ;
2017-07-27 19:04:55 +03:00
2018-02-22 11:13:01 +03:00
gl : : buffer_view m_persistent_stream_view ;
gl : : buffer_view m_volatile_stream_view ;
2018-04-07 13:19:49 +03:00
std : : unique_ptr < gl : : texture > m_gl_persistent_stream_buffer ;
std : : unique_ptr < gl : : texture > m_gl_volatile_stream_buffer ;
2017-07-27 19:04:55 +03:00
2017-09-08 17:52:13 +03:00
std : : unique_ptr < gl : : ring_buffer > m_attrib_ring_buffer ;
std : : unique_ptr < gl : : ring_buffer > m_fragment_constants_buffer ;
std : : unique_ptr < gl : : ring_buffer > m_transform_constants_buffer ;
2018-10-20 17:43:00 +03:00
std : : unique_ptr < gl : : ring_buffer > m_fragment_env_buffer ;
std : : unique_ptr < gl : : ring_buffer > m_vertex_env_buffer ;
std : : unique_ptr < gl : : ring_buffer > m_texture_parameters_buffer ;
std : : unique_ptr < gl : : ring_buffer > m_vertex_layout_buffer ;
2017-09-08 17:52:13 +03:00
std : : unique_ptr < gl : : ring_buffer > m_index_ring_buffer ;
2020-03-25 00:22:21 +03:00
std : : unique_ptr < gl : : ring_buffer > m_vertex_instructions_buffer ;
std : : unique_ptr < gl : : ring_buffer > m_fragment_instructions_buffer ;
2020-05-29 00:51:36 +03:00
std : : unique_ptr < gl : : ring_buffer > m_raster_env_ring_buffer ;
2017-07-27 19:04:55 +03:00
2018-04-29 16:14:53 +03:00
// Identity buffer used to fix broken gl_VertexID on ATI stack
std : : unique_ptr < gl : : buffer > m_identity_index_buffer ;
2017-09-08 17:52:13 +03:00
std : : unique_ptr < gl : : vertex_cache > m_vertex_cache ;
std : : unique_ptr < gl : : shader_cache > m_shaders_cache ;
2017-07-27 19:04:55 +03:00
2017-09-08 17:52:13 +03:00
GLint m_min_texbuffer_alignment = 256 ;
GLint m_uniform_buffer_offset_align = 256 ;
2018-01-21 18:31:35 +03:00
GLint m_max_texbuffer_size = 65536 ;
2017-07-27 19:04:55 +03:00
2017-09-08 17:52:13 +03:00
bool manually_flush_ring_buffers = false ;
2017-07-27 19:04:55 +03:00
2017-09-08 17:52:13 +03:00
gl : : text_writer m_text_printer ;
2018-01-17 19:14:00 +03:00
gl : : ui_overlay_renderer m_ui_renderer ;
2018-03-23 14:49:15 +03:00
gl : : video_out_calibration_pass m_video_output_pass ;
2017-07-27 19:04:55 +03:00
2018-03-05 14:09:43 +03:00
shared_mutex queue_guard ;
2020-01-17 19:24:33 +03:00
std : : list < gl : : work_item > work_queue ;
2017-09-08 17:52:13 +03:00
GLProgramBuffer m_prog_buffer ;
//buffer
2018-08-09 00:48:56 +03:00
gl : : fbo * m_draw_fbo = nullptr ;
2018-09-19 13:16:26 +03:00
std : : list < gl : : framebuffer_holder > m_framebuffer_cache ;
2017-09-08 17:52:13 +03:00
gl : : fbo m_flip_fbo ;
2018-04-07 13:19:49 +03:00
std : : unique_ptr < gl : : texture > m_flip_tex_color ;
2017-09-08 17:52:13 +03:00
//vaos are mandatory for core profile
gl : : vao m_vao ;
2018-03-05 14:09:43 +03:00
shared_mutex m_sampler_mutex ;
2020-12-06 15:15:19 +03:00
atomic_t < bool > m_samplers_dirty = { true } ;
2017-10-30 15:27:22 +03:00
std : : array < std : : unique_ptr < rsx : : sampled_image_descriptor_base > , rsx : : limits : : fragment_textures_count > fs_sampler_state = { } ;
std : : array < std : : unique_ptr < rsx : : sampled_image_descriptor_base > , rsx : : limits : : vertex_textures_count > vs_sampler_state = { } ;
2018-02-02 15:25:15 +03:00
std : : unordered_map < GLenum , std : : unique_ptr < gl : : texture > > m_null_textures ;
2018-04-29 16:14:53 +03:00
std : : vector < u8 > m_scratch_buffer ;
2017-10-30 15:27:22 +03:00
2021-09-04 21:50:53 +03:00
// Occlusion query type, can be SAMPLES_PASSED or ANY_SAMPLES_PASSED
GLenum m_occlusion_type = GL_ANY_SAMPLES_PASSED ;
2017-09-08 17:52:13 +03:00
public :
2019-06-08 09:49:47 +02:00
u64 get_cycles ( ) final ;
2022-07-04 16:02:17 +03:00
GLGSRender ( utils : : serial * ar ) noexcept ;
GLGSRender ( ) noexcept : GLGSRender ( nullptr ) { }
2017-09-08 17:52:13 +03:00
private :
2018-12-29 16:28:12 +03:00
gl : : driver_state gl_state ;
2016-08-10 16:52:35 +02:00
// Return element to draw and in case of indexed draw index type and offset in index buffer
2018-02-21 20:50:27 +03:00
gl : : vertex_upload_info set_vertex_buffer ( ) ;
2017-07-31 14:38:28 +03:00
rsx : : vertex_input_layout m_vertex_layout = { } ;
2016-08-10 16:52:35 +02:00
2017-11-15 18:50:41 +03:00
void init_buffers ( rsx : : framebuffer_creation_context context , bool skip_reading = false ) ;
2017-07-31 14:38:28 +03:00
2018-07-11 23:51:29 +03:00
bool load_program ( ) ;
2018-10-28 18:58:42 +03:00
void load_program_env ( ) ;
void update_vertex_env ( const gl : : vertex_upload_info & upload_info ) ;
2017-02-16 21:29:56 +03:00
2017-11-01 16:38:37 +03:00
void update_draw_state ( ) ;
2020-03-22 13:20:31 +03:00
void load_texture_env ( ) ;
void bind_texture_env ( ) ;
2021-03-02 14:59:19 +03:00
gl : : texture * get_present_source ( gl : : present_surface_info * info , const rsx : : avconf & avconfig ) ;
2020-01-17 19:24:33 +03:00
2015-10-04 01:45:26 +03:00
public :
2016-01-06 01:15:35 +02:00
void set_viewport ( ) ;
2019-07-20 14:58:05 +03:00
void set_scissor ( bool clip_viewport ) ;
2012-11-15 01:39:56 +02:00
2020-01-17 19:24:33 +03:00
gl : : work_item & post_flush_request ( u32 address , gl : : texture_cache : : thrashed_set & flush_data ) ;
2017-03-29 22:27:29 +03:00
bool scaled_image_from_memory ( rsx : : blit_src_info & src_info , rsx : : blit_dst_info & dst_info , bool interpolate ) override ;
2017-11-17 00:52:21 +03:00
2018-03-05 14:09:43 +03:00
void begin_occlusion_query ( rsx : : reports : : occlusion_query_info * query ) override ;
void end_occlusion_query ( rsx : : reports : : occlusion_query_info * query ) override ;
bool check_occlusion_query_status ( rsx : : reports : : occlusion_query_info * query ) override ;
void get_occlusion_query_result ( rsx : : reports : : occlusion_query_info * query ) override ;
2018-03-13 16:34:31 +03:00
void discard_occlusion_query ( rsx : : reports : : occlusion_query_info * query ) override ;
2017-02-16 21:29:56 +03:00
2013-11-09 23:29:49 +02:00
protected :
2019-12-04 15:07:20 +03:00
void clear_surface ( u32 arg ) override ;
2015-10-04 01:45:26 +03:00
void begin ( ) override ;
void end ( ) override ;
2020-03-22 13:20:31 +03:00
void emit_geometry ( u32 sub_index ) override ;
2015-10-04 01:45:26 +03:00
2015-11-26 11:06:29 +03:00
void on_init_thread ( ) override ;
void on_exit ( ) override ;
2019-09-19 20:08:06 +03:00
void flip ( const rsx : : display_flip_info_t & info ) override ;
2016-02-15 12:50:14 +03:00
2023-01-07 19:20:21 +03:00
void do_local_task ( rsx : : FIFO : : state state ) override ;
2017-02-16 21:29:56 +03:00
2016-02-15 12:50:14 +03:00
bool on_access_violation ( u32 address , bool is_writing ) override ;
2019-08-25 18:47:49 +03:00
void on_invalidate_memory_range ( const utils : : address_range & range , rsx : : invalidation_cause cause ) override ;
2017-10-25 22:01:10 -05:00
void notify_tile_unbound ( u32 tile ) override ;
2019-08-25 18:47:49 +03:00
void on_semaphore_acquire_wait ( ) override ;
2013-11-19 11:30:58 +01:00
} ;