@ -139,16 +139,12 @@ void oglEnable(GLenum cap, bool state) {
( state ? glEnable : glDisable ) ( cap ) ;
( state ? glEnable : glDisable ) ( cap ) ;
}
}
void UpdateBindless Pointers( GLenum target , GLuint64EXT * pointers , std : : size_t num_entrie s) {
void UpdateBindless SSBOs( GLenum target , const BindlessSSBO * ssbos , size_t num_ssbo s) {
if ( num_ entrie s = = 0 ) {
if ( num_ ssbo s = = 0 ) {
return ;
return ;
}
}
if ( num_entries % 2 = = 1 ) {
glProgramLocalParametersI4uivNV ( target , 0 , static_cast < GLsizei > ( num_ssbos ) ,
pointers [ num_entries ] = 0 ;
reinterpret_cast < const GLuint * > ( ssbos ) ) ;
}
const GLsizei num_vectors = static_cast < GLsizei > ( ( num_entries + 1 ) / 2 ) ;
glProgramLocalParametersI4uivNV ( target , 0 , num_vectors ,
reinterpret_cast < const GLuint * > ( pointers ) ) ;
}
}
} // Anonymous namespace
} // Anonymous namespace
@ -900,11 +896,11 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
}
}
void RasterizerOpenGL : : SetupDrawConstBuffers ( std : : size_t stage_index , Shader * shader ) {
void RasterizerOpenGL : : SetupDrawConstBuffers ( std : : size_t stage_index , Shader * shader ) {
static constexpr std : : array PARAMETER_LUT = {
static constexpr std : : array PARAMETER_LUT {
GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV , GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV ,
GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV , GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV ,
GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV , GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV ,
GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV , GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV ,
GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV };
GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV ,
} ;
MICROPROFILE_SCOPE ( OpenGL_UBO ) ;
MICROPROFILE_SCOPE ( OpenGL_UBO ) ;
const auto & stages = maxwell3d . state . shader_stages ;
const auto & stages = maxwell3d . state . shader_stages ;
const auto & shader_stage = stages [ stage_index ] ;
const auto & shader_stage = stages [ stage_index ] ;
@ -1007,8 +1003,8 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
const auto & cbufs { maxwell3d . state . shader_stages [ stage_index ] } ;
const auto & cbufs { maxwell3d . state . shader_stages [ stage_index ] } ;
const auto & entries { shader - > GetEntries ( ) . global_memory_entries } ;
const auto & entries { shader - > GetEntries ( ) . global_memory_entries } ;
std : : array < GLuint64EXT, 32 > pointer s;
std : : array < BindlessSSBO, 32 > ssbo s;
ASSERT ( entries . size ( ) < pointer s. size ( ) ) ;
ASSERT ( entries . size ( ) < ssbo s. size ( ) ) ;
const bool assembly_shaders = device . UseAssemblyShaders ( ) ;
const bool assembly_shaders = device . UseAssemblyShaders ( ) ;
u32 binding = assembly_shaders ? 0 : device . GetBaseBindings ( stage_index ) . shader_storage_buffer ;
u32 binding = assembly_shaders ? 0 : device . GetBaseBindings ( stage_index ) . shader_storage_buffer ;
@ -1016,11 +1012,11 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
const GPUVAddr addr { cbufs . const_buffers [ entry . cbuf_index ] . address + entry . cbuf_offset } ;
const GPUVAddr addr { cbufs . const_buffers [ entry . cbuf_index ] . address + entry . cbuf_offset } ;
const GPUVAddr gpu_addr { gpu_memory . Read < u64 > ( addr ) } ;
const GPUVAddr gpu_addr { gpu_memory . Read < u64 > ( addr ) } ;
const u32 size { gpu_memory . Read < u32 > ( addr + 8 ) } ;
const u32 size { gpu_memory . Read < u32 > ( addr + 8 ) } ;
SetupGlobalMemory ( binding , entry , gpu_addr , size , & pointer s[ binding ] ) ;
SetupGlobalMemory ( binding , entry , gpu_addr , size , & ssbo s[ binding ] ) ;
+ + binding ;
+ + binding ;
}
}
if ( assembly_shaders ) {
if ( assembly_shaders ) {
UpdateBindless Pointers( TARGET_LUT [ stage_index ] , pointer s. data ( ) , entries . size ( ) ) ;
UpdateBindless SSBOs( TARGET_LUT [ stage_index ] , ssbo s. data ( ) , entries . size ( ) ) ;
}
}
}
}
@ -1028,29 +1024,32 @@ void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
const auto & cbufs { kepler_compute . launch_description . const_buffer_config } ;
const auto & cbufs { kepler_compute . launch_description . const_buffer_config } ;
const auto & entries { kernel - > GetEntries ( ) . global_memory_entries } ;
const auto & entries { kernel - > GetEntries ( ) . global_memory_entries } ;
std : : array < GLuint64EXT, 32 > pointer s;
std : : array < BindlessSSBO, 32 > ssbo s;
ASSERT ( entries . size ( ) < pointer s. size ( ) ) ;
ASSERT ( entries . size ( ) < ssbo s. size ( ) ) ;
u32 binding = 0 ;
u32 binding = 0 ;
for ( const auto & entry : entries ) {
for ( const auto & entry : entries ) {
const GPUVAddr addr { cbufs [ entry . cbuf_index ] . Address ( ) + entry . cbuf_offset } ;
const GPUVAddr addr { cbufs [ entry . cbuf_index ] . Address ( ) + entry . cbuf_offset } ;
const GPUVAddr gpu_addr { gpu_memory . Read < u64 > ( addr ) } ;
const GPUVAddr gpu_addr { gpu_memory . Read < u64 > ( addr ) } ;
const u32 size { gpu_memory . Read < u32 > ( addr + 8 ) } ;
const u32 size { gpu_memory . Read < u32 > ( addr + 8 ) } ;
SetupGlobalMemory ( binding , entry , gpu_addr , size , & pointer s[ binding ] ) ;
SetupGlobalMemory ( binding , entry , gpu_addr , size , & ssbo s[ binding ] ) ;
+ + binding ;
+ + binding ;
}
}
if ( device . UseAssemblyShaders ( ) ) {
if ( device . UseAssemblyShaders ( ) ) {
UpdateBindless Pointers( GL_COMPUTE_PROGRAM_NV , pointers . data ( ) , entrie s. size ( ) ) ;
UpdateBindless SSBOs( GL_COMPUTE_PROGRAM_NV , ssbos . data ( ) , ssbo s. size ( ) ) ;
}
}
}
}
void RasterizerOpenGL : : SetupGlobalMemory ( u32 binding , const GlobalMemoryEntry & entry ,
void RasterizerOpenGL : : SetupGlobalMemory ( u32 binding , const GlobalMemoryEntry & entry ,
GPUVAddr gpu_addr , std : : size_t size ,
GPUVAddr gpu_addr , size_t size , BindlessSSBO * ssbo ) {
GLuint64EXT * pointer ) {
const size_t alignment { device . GetShaderStorageBufferAlignment ( ) } ;
const std : : size_t alignment { device . GetShaderStorageBufferAlignment ( ) } ;
const auto info = buffer_cache . UploadMemory ( gpu_addr , size , alignment , entry . is_written ) ;
const auto info = buffer_cache . UploadMemory ( gpu_addr , size , alignment , entry . is_written ) ;
if ( device . UseAssemblyShaders ( ) ) {
if ( device . UseAssemblyShaders ( ) ) {
* pointer = info . address + info . offset ;
* ssbo = BindlessSSBO {
. address = static_cast < GLuint64EXT > ( info . address + info . offset ) ,
. length = static_cast < GLsizei > ( size ) ,
. padding = 0 ,
} ;
} else {
} else {
glBindBufferRange ( GL_SHADER_STORAGE_BUFFER , binding , info . handle , info . offset ,
glBindBufferRange ( GL_SHADER_STORAGE_BUFFER , binding , info . handle , info . offset ,
static_cast < GLsizeiptr > ( size ) ) ;
static_cast < GLsizeiptr > ( size ) ) ;