@ -153,16 +153,19 @@ void UpdateBindlessPointers(GLenum target, GLuint64EXT* pointers, std::size_t nu
} // Anonymous namespace
RasterizerOpenGL : : RasterizerOpenGL ( Core : : System & system , Core : : Frontend : : EmuWindow & emu_window ,
const Device & device , ScreenInfo & info ,
ProgramManager & program_manager , StateTracker & state_tracker )
: RasterizerAccelerated { system . Memory ( ) } , device { device } , texture_cache { system , * this , device ,
state_tracker } ,
shader_cache { * this , system , emu_window , device } , query_cache { system , * this } ,
buffer_cache { * this , system , device , STREAM_BUFFER_SIZE } ,
fence_manager { system , * this , texture_cache , buffer_cache , query_cache } , system { system } ,
screen_info { info } , program_manager { program_manager } , state_tracker { state_tracker } ,
async_shaders { emu_window } {
RasterizerOpenGL : : RasterizerOpenGL ( Core : : Frontend : : EmuWindow & emu_window , Tegra : : GPU & gpu_ ,
Core : : Memory : : Memory & cpu_memory , const Device & device_ ,
ScreenInfo & screen_info_ , ProgramManager & program_manager_ ,
StateTracker & state_tracker_ )
: RasterizerAccelerated { cpu_memory } , gpu ( gpu_ ) , maxwell3d ( gpu . Maxwell3D ( ) ) ,
kepler_compute ( gpu . KeplerCompute ( ) ) , gpu_memory ( gpu . MemoryManager ( ) ) , device ( device_ ) ,
screen_info ( screen_info_ ) , program_manager ( program_manager_ ) , state_tracker ( state_tracker_ ) ,
texture_cache ( * this , maxwell3d , gpu_memory , device , state_tracker ) ,
shader_cache ( * this , emu_window , gpu , maxwell3d , kepler_compute , gpu_memory , device ) ,
query_cache ( * this , maxwell3d , gpu_memory ) ,
buffer_cache ( * this , gpu_memory , cpu_memory , device , STREAM_BUFFER_SIZE ) ,
fence_manager ( * this , gpu , texture_cache , buffer_cache , query_cache ) ,
async_shaders ( emu_window ) {
CheckExtensions ( ) ;
unified_uniform_buffer . Create ( ) ;
@ -196,8 +199,7 @@ void RasterizerOpenGL::CheckExtensions() {
}
void RasterizerOpenGL : : SetupVertexFormat ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : VertexFormats ] ) {
return ;
}
@ -217,7 +219,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
}
flags [ Dirty : : VertexFormat0 + index ] = false ;
const auto attrib = gpu . regs . vertex_attrib_format [ index ] ;
const auto attrib = maxwell3d . regs . vertex_attrib_format [ index ] ;
const auto gl_index = static_cast < GLuint > ( index ) ;
// Disable constant attributes.
@ -241,8 +243,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
}
void RasterizerOpenGL : : SetupVertexBuffer ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : VertexBuffers ] ) {
return ;
}
@ -253,7 +254,7 @@ void RasterizerOpenGL::SetupVertexBuffer() {
const bool use_unified_memory = device . HasVertexBufferUnifiedMemory ( ) ;
// Upload all guest vertex arrays sequentially to our buffer
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
for ( std : : size_t index = 0 ; index < NUM_SUPPORTED_VERTEX_BINDINGS ; + + index ) {
if ( ! flags [ Dirty : : VertexBuffer0 + index ] ) {
continue ;
@ -290,14 +291,13 @@ void RasterizerOpenGL::SetupVertexBuffer() {
}
void RasterizerOpenGL : : SetupVertexInstances ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : VertexInstances ] ) {
return ;
}
flags [ Dirty : : VertexInstances ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
for ( std : : size_t index = 0 ; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES ; + + index ) {
if ( ! flags [ Dirty : : VertexInstance0 + index ] ) {
continue ;
@ -313,7 +313,7 @@ void RasterizerOpenGL::SetupVertexInstances() {
GLintptr RasterizerOpenGL : : SetupIndexBuffer ( ) {
MICROPROFILE_SCOPE ( OpenGL_Index ) ;
const auto & regs = system. GPU ( ) . Maxwell3D ( ) . regs ;
const auto & regs = maxwell3d . regs ;
const std : : size_t size = CalculateIndexBufferSize ( ) ;
const auto info = buffer_cache . UploadMemory ( regs . index_array . IndexStart ( ) , size ) ;
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , info . handle ) ;
@ -322,15 +322,14 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
void RasterizerOpenGL : : SetupShaders ( GLenum primitive_mode ) {
MICROPROFILE_SCOPE ( OpenGL_Shader ) ;
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
u32 clip_distances = 0 ;
for ( std : : size_t index = 0 ; index < Maxwell : : MaxShaderProgram ; + + index ) {
const auto & shader_config = gpu . regs . shader_config [ index ] ;
const auto & shader_config = maxwell3d . regs . shader_config [ index ] ;
const auto program { static_cast < Maxwell : : ShaderProgram > ( index ) } ;
// Skip stages that are not enabled
if ( ! gpu . regs . IsShaderConfigEnabled ( index ) ) {
if ( ! maxwell3d . regs . IsShaderConfigEnabled ( index ) ) {
switch ( program ) {
case Maxwell : : ShaderProgram : : Geometry :
program_manager . UseGeometryShader ( 0 ) ;
@ -391,11 +390,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
}
SyncClipEnabled ( clip_distances ) ;
gpu . dirty . flags [ Dirty : : Shaders ] = false ;
maxwell3d . dirty . flags [ Dirty : : Shaders ] = false ;
}
std : : size_t RasterizerOpenGL : : CalculateVertexArraysSize ( ) const {
const auto & regs = system. GPU ( ) . Maxwell3D ( ) . regs ;
const auto & regs = maxwell3d . regs ;
std : : size_t size = 0 ;
for ( u32 index = 0 ; index < Maxwell : : NumVertexArrays ; + + index ) {
@ -413,34 +412,27 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
}
std : : size_t RasterizerOpenGL : : CalculateIndexBufferSize ( ) const {
const auto & regs = system . GPU ( ) . Maxwell3D ( ) . regs ;
return static_cast < std : : size_t > ( regs . index_array . count ) *
static_cast < std : : size_t > ( regs . index_array . FormatSizeInBytes ( ) ) ;
return static_cast < std : : size_t > ( maxwell3d . regs . index_array . count ) *
static_cast < std : : size_t > ( maxwell3d . regs . index_array . FormatSizeInBytes ( ) ) ;
}
void RasterizerOpenGL : : LoadDiskResources ( const std : : atomic_bool & stop_loading ,
void RasterizerOpenGL : : LoadDiskResources ( u64 title_id , const std : : atomic_bool & stop_loading ,
const VideoCore : : DiskResourceLoadCallback & callback ) {
shader_cache . LoadDiskCache ( stop_loading , callback ) ;
}
void RasterizerOpenGL : : SetupDirtyFlags ( ) {
state_tracker . Initialize ( ) ;
shader_cache . LoadDiskCache ( title_id , stop_loading , callback ) ;
}
void RasterizerOpenGL : : ConfigureFramebuffers ( ) {
MICROPROFILE_SCOPE ( OpenGL_Framebuffer ) ;
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
if ( ! gpu . dirty . flags [ VideoCommon : : Dirty : : RenderTargets ] ) {
if ( ! maxwell3d . dirty . flags [ VideoCommon : : Dirty : : RenderTargets ] ) {
return ;
}
gpu . dirty . flags [ VideoCommon : : Dirty : : RenderTargets ] = false ;
maxwell3d . dirty . flags [ VideoCommon : : Dirty : : RenderTargets ] = false ;
texture_cache . GuardRenderTargets ( true ) ;
View depth_surface = texture_cache . GetDepthBufferSurface ( true ) ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
UNIMPLEMENTED_IF ( regs . rt_separate_frag_data = = 0 ) ;
// Bind the framebuffer surfaces
@ -472,8 +464,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
}
void RasterizerOpenGL : : ConfigureClearFramebuffer ( bool using_color , bool using_depth_stencil ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
texture_cache . GuardRenderTargets ( true ) ;
View color_surface ;
@ -523,12 +514,11 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_de
}
void RasterizerOpenGL : : Clear ( ) {
const auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
if ( ! gpu . ShouldExecute ( ) ) {
if ( ! maxwell3d . ShouldExecute ( ) ) {
return ;
}
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
bool use_color { } ;
bool use_depth { } ;
bool use_stencil { } ;
@ -593,7 +583,6 @@ void RasterizerOpenGL::Clear() {
void RasterizerOpenGL : : Draw ( bool is_indexed , bool is_instanced ) {
MICROPROFILE_SCOPE ( OpenGL_Drawing ) ;
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
query_cache . UpdateCounters ( ) ;
@ -641,7 +630,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
if ( invalidated ) {
// When the stream buffer has been invalidated, we have to consider vertex buffers as dirty
auto & dirty = gpu . dirty . flags ;
auto & dirty = maxwell3d . dirty . flags ;
dirty [ Dirty : : VertexBuffers ] = true ;
for ( int index = Dirty : : VertexBuffer0 ; index < = Dirty : : VertexBuffer31 ; + + index ) {
dirty [ index ] = true ;
@ -662,7 +651,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
// Setup emulation uniform buffer.
if ( ! device . UseAssemblyShaders ( ) ) {
MaxwellUniformData ubo ;
ubo . SetFromRegs ( gpu ) ;
ubo . SetFromRegs ( maxwell3d ) ;
const auto info =
buffer_cache . UploadHostMemory ( & ubo , sizeof ( ubo ) , device . GetUniformBufferAlignment ( ) ) ;
glBindBufferRange ( GL_UNIFORM_BUFFER , EmulationUniformBlockBinding , info . handle , info . offset ,
@ -671,7 +660,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
// Setup shaders and their used resources.
texture_cache . GuardSamplers ( true ) ;
const GLenum primitive_mode = MaxwellToGL : : PrimitiveTopology ( gpu . regs . draw . topology ) ;
const GLenum primitive_mode = MaxwellToGL : : PrimitiveTopology ( maxwell3d . regs . draw . topology ) ;
SetupShaders ( primitive_mode ) ;
texture_cache . GuardSamplers ( false ) ;
@ -688,14 +677,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
BeginTransformFeedback ( primitive_mode ) ;
const GLuint base_instance = static_cast < GLuint > ( gpu . regs . vb_base_instance ) ;
const GLuint base_instance = static_cast < GLuint > ( maxwell3d . regs . vb_base_instance ) ;
const GLsizei num_instances =
static_cast < GLsizei > ( is_instanced ? gpu . mme_draw . instance_count : 1 ) ;
static_cast < GLsizei > ( is_instanced ? maxwell3d . mme_draw . instance_count : 1 ) ;
if ( is_indexed ) {
const GLint base_vertex = static_cast < GLint > ( gpu . regs . vb_element_base ) ;
const GLsizei num_vertices = static_cast < GLsizei > ( gpu . regs . index_array . count ) ;
const GLint base_vertex = static_cast < GLint > ( maxwell3d . regs . vb_element_base ) ;
const GLsizei num_vertices = static_cast < GLsizei > ( maxwell3d . regs . index_array . count ) ;
const GLvoid * offset = reinterpret_cast < const GLvoid * > ( index_buffer_offset ) ;
const GLenum format = MaxwellToGL : : IndexFormat ( gpu . regs . index_array . format ) ;
const GLenum format = MaxwellToGL : : IndexFormat ( maxwell3d . regs . index_array . format ) ;
if ( num_instances = = 1 & & base_instance = = 0 & & base_vertex = = 0 ) {
glDrawElements ( primitive_mode , num_vertices , format , offset ) ;
} else if ( num_instances = = 1 & & base_instance = = 0 ) {
@ -714,8 +703,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
base_instance ) ;
}
} else {
const GLint base_vertex = static_cast < GLint > ( gpu . regs . vertex_buffer . first ) ;
const GLsizei num_vertices = static_cast < GLsizei > ( gpu . regs . vertex_buffer . count ) ;
const GLint base_vertex = static_cast < GLint > ( maxwell3d . regs . vertex_buffer . first ) ;
const GLsizei num_vertices = static_cast < GLsizei > ( maxwell3d . regs . vertex_buffer . count ) ;
if ( num_instances = = 1 & & base_instance = = 0 ) {
glDrawArrays ( primitive_mode , base_vertex , num_vertices ) ;
} else if ( base_instance = = 0 ) {
@ -730,7 +719,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
+ + num_queued_commands ;
system. GPU ( ) . TickWork ( ) ;
gpu . TickWork ( ) ;
}
void RasterizerOpenGL : : DispatchCompute ( GPUVAddr code_addr ) {
@ -753,7 +742,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
buffer_cache . Unmap ( ) ;
const auto & launch_desc = system . GPU ( ) . KeplerCompute ( ) . launch_description ;
const auto & launch_desc = kepler_compute . launch_description ;
program_manager . BindCompute ( kernel - > GetHandle ( ) ) ;
glDispatchCompute ( launch_desc . grid_dim_x , launch_desc . grid_dim_y , launch_desc . grid_dim_z ) ;
+ + num_queued_commands ;
}
@ -815,17 +805,14 @@ void RasterizerOpenGL::SyncGuestHost() {
}
void RasterizerOpenGL : : SignalSemaphore ( GPUVAddr addr , u32 value ) {
auto & gpu { system . GPU ( ) } ;
if ( ! gpu . IsAsync ( ) ) {
auto & memory_manager { gpu . MemoryManager ( ) } ;
memory_manager . Write < u32 > ( addr , value ) ;
gpu_memory . Write < u32 > ( addr , value ) ;
return ;
}
fence_manager . SignalSemaphore ( addr , value ) ;
}
void RasterizerOpenGL : : SignalSyncPoint ( u32 value ) {
auto & gpu { system . GPU ( ) } ;
if ( ! gpu . IsAsync ( ) ) {
gpu . IncrementSyncPoint ( value ) ;
return ;
@ -834,7 +821,6 @@ void RasterizerOpenGL::SignalSyncPoint(u32 value) {
}
void RasterizerOpenGL : : ReleaseFences ( ) {
auto & gpu { system . GPU ( ) } ;
if ( ! gpu . IsAsync ( ) ) {
return ;
}
@ -920,7 +906,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh
GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV } ;
MICROPROFILE_SCOPE ( OpenGL_UBO ) ;
const auto & stages = system. GPU ( ) . Maxwell3D ( ) . state . shader_stages ;
const auto & stages = maxwell3d . state . shader_stages ;
const auto & shader_stage = stages [ stage_index ] ;
const auto & entries = shader - > GetEntries ( ) ;
const bool use_unified = entries . use_unified_uniforms ;
@ -945,7 +931,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh
void RasterizerOpenGL : : SetupComputeConstBuffers ( Shader * kernel ) {
MICROPROFILE_SCOPE ( OpenGL_UBO ) ;
const auto & launch_desc = system. GPU ( ) . KeplerCompute ( ) . launch_description ;
const auto & launch_desc = kepler_compute . launch_description ;
const auto & entries = kernel - > GetEntries ( ) ;
const bool use_unified = entries . use_unified_uniforms ;
@ -1018,9 +1004,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
GL_GEOMETRY_PROGRAM_NV , GL_FRAGMENT_PROGRAM_NV ,
} ;
auto & gpu { system . GPU ( ) } ;
auto & memory_manager { gpu . MemoryManager ( ) } ;
const auto & cbufs { gpu . Maxwell3D ( ) . state . shader_stages [ stage_index ] } ;
const auto & cbufs { maxwell3d . state . shader_stages [ stage_index ] } ;
const auto & entries { shader - > GetEntries ( ) . global_memory_entries } ;
std : : array < GLuint64EXT , 32 > pointers ;
@ -1030,8 +1014,8 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
u32 binding = assembly_shaders ? 0 : device . GetBaseBindings ( stage_index ) . shader_storage_buffer ;
for ( const auto & entry : entries ) {
const GPUVAddr addr { cbufs . const_buffers [ entry . cbuf_index ] . address + entry . cbuf_offset } ;
const GPUVAddr gpu_addr { memory_manager . Read < u64 > ( addr ) } ;
const u32 size { memory_manager . Read < u32 > ( addr + 8 ) } ;
const GPUVAddr gpu_addr { gpu_ memory. Read < u64 > ( addr ) } ;
const u32 size { gpu_ memory. Read < u32 > ( addr + 8 ) } ;
SetupGlobalMemory ( binding , entry , gpu_addr , size , & pointers [ binding ] ) ;
+ + binding ;
}
@ -1041,9 +1025,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
}
void RasterizerOpenGL : : SetupComputeGlobalMemory ( Shader * kernel ) {
auto & gpu { system . GPU ( ) } ;
auto & memory_manager { gpu . MemoryManager ( ) } ;
const auto & cbufs { gpu . KeplerCompute ( ) . launch_description . const_buffer_config } ;
const auto & cbufs { kepler_compute . launch_description . const_buffer_config } ;
const auto & entries { kernel - > GetEntries ( ) . global_memory_entries } ;
std : : array < GLuint64EXT , 32 > pointers ;
@ -1052,8 +1034,8 @@ void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
u32 binding = 0 ;
for ( const auto & entry : entries ) {
const GPUVAddr addr { cbufs [ entry . cbuf_index ] . Address ( ) + entry . cbuf_offset } ;
const GPUVAddr gpu_addr { memory_manager . Read < u64 > ( addr ) } ;
const u32 size { memory_manager . Read < u32 > ( addr + 8 ) } ;
const GPUVAddr gpu_addr { gpu_ memory. Read < u64 > ( addr ) } ;
const u32 size { gpu_ memory. Read < u32 > ( addr + 8 ) } ;
SetupGlobalMemory ( binding , entry , gpu_addr , size , & pointers [ binding ] ) ;
+ + binding ;
}
@ -1077,7 +1059,6 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
void RasterizerOpenGL : : SetupDrawTextures ( std : : size_t stage_index , Shader * shader ) {
MICROPROFILE_SCOPE ( OpenGL_Texture ) ;
const auto & maxwell3d = system . GPU ( ) . Maxwell3D ( ) ;
u32 binding = device . GetBaseBindings ( stage_index ) . sampler ;
for ( const auto & entry : shader - > GetEntries ( ) . samplers ) {
const auto shader_type = static_cast < ShaderType > ( stage_index ) ;
@ -1090,11 +1071,10 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader
void RasterizerOpenGL : : SetupComputeTextures ( Shader * kernel ) {
MICROPROFILE_SCOPE ( OpenGL_Texture ) ;
const auto & compute = system . GPU ( ) . KeplerCompute ( ) ;
u32 binding = 0 ;
for ( const auto & entry : kernel - > GetEntries ( ) . samplers ) {
for ( std : : size_t i = 0 ; i < entry . size ; + + i ) {
const auto texture = GetTextureInfo ( compute, entry , ShaderType : : Compute , i ) ;
const auto texture = GetTextureInfo ( kepler_ compute, entry , ShaderType : : Compute , i ) ;
SetupTexture ( binding + + , texture , entry ) ;
}
}
@ -1118,20 +1098,18 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu
}
void RasterizerOpenGL : : SetupDrawImages ( std : : size_t stage_index , Shader * shader ) {
const auto & maxwell3d = system . GPU ( ) . Maxwell3D ( ) ;
u32 binding = device . GetBaseBindings ( stage_index ) . image ;
for ( const auto & entry : shader - > GetEntries ( ) . images ) {
const auto shader_type = static_cast < Tegra: : Engines : : ShaderType> ( stage_index ) ;
const auto shader_type = static_cast < ShaderType> ( stage_index ) ;
const auto tic = GetTextureInfo ( maxwell3d , entry , shader_type ) . tic ;
SetupImage ( binding + + , tic , entry ) ;
}
}
void RasterizerOpenGL : : SetupComputeImages ( Shader * shader ) {
const auto & compute = system . GPU ( ) . KeplerCompute ( ) ;
u32 binding = 0 ;
for ( const auto & entry : shader - > GetEntries ( ) . images ) {
const auto tic = GetTextureInfo ( compute, entry , Tegra : : Engines : : ShaderType : : Compute ) . tic ;
const auto tic = GetTextureInfo ( kepler_ compute, entry , ShaderType : : Compute ) . tic ;
SetupImage ( binding + + , tic , entry ) ;
}
}
@ -1151,9 +1129,8 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
}
void RasterizerOpenGL : : SyncViewport ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
const auto & regs = gpu . regs ;
auto & flags = maxwell3d . dirty . flags ;
const auto & regs = maxwell3d . regs ;
const bool dirty_viewport = flags [ Dirty : : Viewports ] ;
const bool dirty_clip_control = flags [ Dirty : : ClipControl ] ;
@ -1225,25 +1202,23 @@ void RasterizerOpenGL::SyncViewport() {
}
void RasterizerOpenGL : : SyncDepthClamp ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : DepthClampEnabled ] ) {
return ;
}
flags [ Dirty : : DepthClampEnabled ] = false ;
oglEnable ( GL_DEPTH_CLAMP , gpu . regs . view_volume_clip_control . depth_clamp_disabled = = 0 ) ;
oglEnable ( GL_DEPTH_CLAMP , maxwell3d . regs . view_volume_clip_control . depth_clamp_disabled = = 0 ) ;
}
void RasterizerOpenGL : : SyncClipEnabled ( u32 clip_mask ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : ClipDistances ] & & ! flags [ Dirty : : Shaders ] ) {
return ;
}
flags [ Dirty : : ClipDistances ] = false ;
clip_mask & = gpu . regs . clip_distance_enabled ;
clip_mask & = maxwell3d . regs . clip_distance_enabled ;
if ( clip_mask = = last_clip_distance_mask ) {
return ;
}
@ -1259,9 +1234,8 @@ void RasterizerOpenGL::SyncClipCoef() {
}
void RasterizerOpenGL : : SyncCullMode ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
const auto & regs = gpu . regs ;
auto & flags = maxwell3d . dirty . flags ;
const auto & regs = maxwell3d . regs ;
if ( flags [ Dirty : : CullTest ] ) {
flags [ Dirty : : CullTest ] = false ;
@ -1276,26 +1250,24 @@ void RasterizerOpenGL::SyncCullMode() {
}
void RasterizerOpenGL : : SyncPrimitiveRestart ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : PrimitiveRestart ] ) {
return ;
}
flags [ Dirty : : PrimitiveRestart ] = false ;
if ( gpu . regs . primitive_restart . enabled ) {
if ( maxwell3d . regs . primitive_restart . enabled ) {
glEnable ( GL_PRIMITIVE_RESTART ) ;
glPrimitiveRestartIndex ( gpu . regs . primitive_restart . index ) ;
glPrimitiveRestartIndex ( maxwell3d . regs . primitive_restart . index ) ;
} else {
glDisable ( GL_PRIMITIVE_RESTART ) ;
}
}
void RasterizerOpenGL : : SyncDepthTestState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto& flags = gpu . dirty . fla gs;
auto & flags = maxwell3d . dirty . flags ;
const auto & regs = maxwell3d . re gs;
const auto & regs = gpu . regs ;
if ( flags [ Dirty : : DepthMask ] ) {
flags [ Dirty : : DepthMask ] = false ;
glDepthMask ( regs . depth_write_enabled ? GL_TRUE : GL_FALSE ) ;
@ -1313,14 +1285,13 @@ void RasterizerOpenGL::SyncDepthTestState() {
}
void RasterizerOpenGL : : SyncStencilTestState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : StencilTest ] ) {
return ;
}
flags [ Dirty : : StencilTest ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
oglEnable ( GL_STENCIL_TEST , regs . stencil_enable ) ;
glStencilFuncSeparate ( GL_FRONT , MaxwellToGL : : ComparisonOp ( regs . stencil_front_func_func ) ,
@ -1345,25 +1316,24 @@ void RasterizerOpenGL::SyncStencilTestState() {
}
void RasterizerOpenGL : : SyncRasterizeEnable ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : RasterizeEnable ] ) {
return ;
}
flags [ Dirty : : RasterizeEnable ] = false ;
oglEnable ( GL_RASTERIZER_DISCARD , gpu . regs . rasterize_enable = = 0 ) ;
oglEnable ( GL_RASTERIZER_DISCARD , maxwell3d . regs . rasterize_enable = = 0 ) ;
}
void RasterizerOpenGL : : SyncPolygonModes ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : PolygonModes ] ) {
return ;
}
flags [ Dirty : : PolygonModes ] = false ;
if ( gpu . regs . fill_rectangle ) {
const auto & regs = maxwell3d . regs ;
if ( regs . fill_rectangle ) {
if ( ! GLAD_GL_NV_fill_rectangle ) {
LOG_ERROR ( Render_OpenGL , " GL_NV_fill_rectangle used and not supported " ) ;
glPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
@ -1376,27 +1346,26 @@ void RasterizerOpenGL::SyncPolygonModes() {
return ;
}
if ( gpu. regs. polygon_mode_front = = gpu . regs . polygon_mode_back ) {
if ( regs. polygon_mode_front = = regs . polygon_mode_back ) {
flags [ Dirty : : PolygonModeFront ] = false ;
flags [ Dirty : : PolygonModeBack ] = false ;
glPolygonMode ( GL_FRONT_AND_BACK , MaxwellToGL : : PolygonMode ( gpu. regs. polygon_mode_front ) ) ;
glPolygonMode ( GL_FRONT_AND_BACK , MaxwellToGL : : PolygonMode ( regs. polygon_mode_front ) ) ;
return ;
}
if ( flags [ Dirty : : PolygonModeFront ] ) {
flags [ Dirty : : PolygonModeFront ] = false ;
glPolygonMode ( GL_FRONT , MaxwellToGL : : PolygonMode ( gpu. regs. polygon_mode_front ) ) ;
glPolygonMode ( GL_FRONT , MaxwellToGL : : PolygonMode ( regs. polygon_mode_front ) ) ;
}
if ( flags [ Dirty : : PolygonModeBack ] ) {
flags [ Dirty : : PolygonModeBack ] = false ;
glPolygonMode ( GL_BACK , MaxwellToGL : : PolygonMode ( gpu. regs. polygon_mode_back ) ) ;
glPolygonMode ( GL_BACK , MaxwellToGL : : PolygonMode ( regs. polygon_mode_back ) ) ;
}
}
void RasterizerOpenGL : : SyncColorMask ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : ColorMasks ] ) {
return ;
}
@ -1405,7 +1374,7 @@ void RasterizerOpenGL::SyncColorMask() {
const bool force = flags [ Dirty : : ColorMaskCommon ] ;
flags [ Dirty : : ColorMaskCommon ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
if ( regs . color_mask_common ) {
if ( ! force & & ! flags [ Dirty : : ColorMask0 ] ) {
return ;
@ -1430,33 +1399,30 @@ void RasterizerOpenGL::SyncColorMask() {
}
void RasterizerOpenGL : : SyncMultiSampleState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : MultisampleControl ] ) {
return ;
}
flags [ Dirty : : MultisampleControl ] = false ;
const auto & regs = system. GPU ( ) . Maxwell3D ( ) . regs ;
const auto & regs = maxwell3d . regs ;
oglEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE , regs . multisample_control . alpha_to_coverage ) ;
oglEnable ( GL_SAMPLE_ALPHA_TO_ONE , regs . multisample_control . alpha_to_one ) ;
}
void RasterizerOpenGL : : SyncFragmentColorClampState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : FragmentClampColor ] ) {
return ;
}
flags [ Dirty : : FragmentClampColor ] = false ;
glClampColor ( GL_CLAMP_FRAGMENT_COLOR , gpu . regs . frag_color_clamp ? GL_TRUE : GL_FALSE ) ;
glClampColor ( GL_CLAMP_FRAGMENT_COLOR , maxwell3d . regs . frag_color_clamp ? GL_TRUE : GL_FALSE ) ;
}
void RasterizerOpenGL : : SyncBlendState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
const auto & regs = gpu . regs ;
auto & flags = maxwell3d . dirty . flags ;
const auto & regs = maxwell3d . regs ;
if ( flags [ Dirty : : BlendColor ] ) {
flags [ Dirty : : BlendColor ] = false ;
@ -1513,14 +1479,13 @@ void RasterizerOpenGL::SyncBlendState() {
}
void RasterizerOpenGL : : SyncLogicOpState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : LogicOp ] ) {
return ;
}
flags [ Dirty : : LogicOp ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
if ( regs . logic_op . enable ) {
glEnable ( GL_COLOR_LOGIC_OP ) ;
glLogicOp ( MaxwellToGL : : LogicOp ( regs . logic_op . operation ) ) ;
@ -1530,14 +1495,13 @@ void RasterizerOpenGL::SyncLogicOpState() {
}
void RasterizerOpenGL : : SyncScissorTest ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : Scissors ] ) {
return ;
}
flags [ Dirty : : Scissors ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
for ( std : : size_t index = 0 ; index < Maxwell : : NumViewports ; + + index ) {
if ( ! flags [ Dirty : : Scissor0 + index ] ) {
continue ;
@ -1556,16 +1520,15 @@ void RasterizerOpenGL::SyncScissorTest() {
}
void RasterizerOpenGL : : SyncPointState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : PointSize ] ) {
return ;
}
flags [ Dirty : : PointSize ] = false ;
oglEnable ( GL_POINT_SPRITE , gpu . regs . point_sprite_enable ) ;
oglEnable ( GL_POINT_SPRITE , maxwell3d . regs . point_sprite_enable ) ;
if ( gpu . regs . vp_point_size . enable ) {
if ( maxwell3d . regs . vp_point_size . enable ) {
// By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled.
glEnable ( GL_PROGRAM_POINT_SIZE ) ;
return ;
@ -1573,32 +1536,30 @@ void RasterizerOpenGL::SyncPointState() {
// Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid
// in OpenGL).
glPointSize ( std : : max ( 1.0f , gpu . regs . point_size ) ) ;
glPointSize ( std : : max ( 1.0f , maxwell3d . regs . point_size ) ) ;
glDisable ( GL_PROGRAM_POINT_SIZE ) ;
}
void RasterizerOpenGL : : SyncLineState ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : LineWidth ] ) {
return ;
}
flags [ Dirty : : LineWidth ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
oglEnable ( GL_LINE_SMOOTH , regs . line_smooth_enable ) ;
glLineWidth ( regs . line_smooth_enable ? regs . line_width_smooth : regs . line_width_aliased ) ;
}
void RasterizerOpenGL : : SyncPolygonOffset ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : PolygonOffset ] ) {
return ;
}
flags [ Dirty : : PolygonOffset ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
oglEnable ( GL_POLYGON_OFFSET_FILL , regs . polygon_offset_fill_enable ) ;
oglEnable ( GL_POLYGON_OFFSET_LINE , regs . polygon_offset_line_enable ) ;
oglEnable ( GL_POLYGON_OFFSET_POINT , regs . polygon_offset_point_enable ) ;
@ -1612,14 +1573,13 @@ void RasterizerOpenGL::SyncPolygonOffset() {
}
void RasterizerOpenGL : : SyncAlphaTest ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : AlphaTest ] ) {
return ;
}
flags [ Dirty : : AlphaTest ] = false ;
const auto & regs = gpu . regs ;
const auto & regs = maxwell3d . regs ;
if ( regs . alpha_test_enabled & & regs . rt_control . count > 1 ) {
LOG_WARNING ( Render_OpenGL , " Alpha testing with more than one render target is not tested " ) ;
}
@ -1633,20 +1593,19 @@ void RasterizerOpenGL::SyncAlphaTest() {
}
void RasterizerOpenGL : : SyncFramebufferSRGB ( ) {
auto & gpu = system . GPU ( ) . Maxwell3D ( ) ;
auto & flags = gpu . dirty . flags ;
auto & flags = maxwell3d . dirty . flags ;
if ( ! flags [ Dirty : : FramebufferSRGB ] ) {
return ;
}
flags [ Dirty : : FramebufferSRGB ] = false ;
oglEnable ( GL_FRAMEBUFFER_SRGB , gpu . regs . framebuffer_srgb ) ;
oglEnable ( GL_FRAMEBUFFER_SRGB , maxwell3d . regs . framebuffer_srgb ) ;
}
void RasterizerOpenGL : : SyncTransformFeedback ( ) {
// TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal
// when this is required.
const auto & regs = system. GPU ( ) . Maxwell3D ( ) . regs ;
const auto & regs = maxwell3d . regs ;
static constexpr std : : size_t STRIDE = 3 ;
std : : array < GLint , 128 * STRIDE * Maxwell : : NumTransformFeedbackBuffers > attribs ;
@ -1698,7 +1657,7 @@ void RasterizerOpenGL::SyncTransformFeedback() {
}
void RasterizerOpenGL : : BeginTransformFeedback ( GLenum primitive_mode ) {
const auto & regs = system. GPU ( ) . Maxwell3D ( ) . regs ;
const auto & regs = maxwell3d . regs ;
if ( regs . tfb_enabled = = 0 ) {
return ;
}
@ -1741,7 +1700,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) {
}
void RasterizerOpenGL : : EndTransformFeedback ( ) {
const auto & regs = system. GPU ( ) . Maxwell3D ( ) . regs ;
const auto & regs = maxwell3d . regs ;
if ( regs . tfb_enabled = = 0 ) {
return ;
}