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