nv2a: Cache inline elements in LRU

This commit is contained in:
Matt Borgerson 2021-03-15 01:03:45 -07:00 committed by mborgerson
parent 559f105a88
commit 09e2357d02
3 changed files with 37 additions and 7 deletions

View File

@ -113,6 +113,7 @@ void gl_debug_frame_terminator(void);
_X(NV2A_PROF_GEOM_BUFFER_UPDATE_2) \
_X(NV2A_PROF_GEOM_BUFFER_UPDATE_3) \
_X(NV2A_PROF_GEOM_BUFFER_UPDATE_4) \
_X(NV2A_PROF_GEOM_BUFFER_UPDATE_5) \
_X(NV2A_PROF_SURF_DOWNLOAD) \
_X(NV2A_PROF_SURF_UPLOAD) \
_X(NV2A_PROF_SURF_TO_TEX) \

View File

@ -327,8 +327,9 @@ typedef struct PGRAPHState {
VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES];
uint8_t *converted_buffer;
Lru vertex_cache;
Lru vertex_cache, element_cache;
struct VertexLruNode *vertex_cache_entries;
struct VertexLruNode *element_cache_entries;
unsigned int inline_array_length;
uint32_t inline_array[NV2A_MAX_BATCH_LENGTH];
@ -336,7 +337,6 @@ typedef struct PGRAPHState {
unsigned int inline_elements_length;
uint32_t inline_elements[NV2A_MAX_BATCH_LENGTH];
GLuint gl_inline_elements_buffer;
unsigned int inline_buffer_length;

View File

@ -2381,10 +2381,25 @@ DEF_METHOD(NV097, SET_BEGIN_END)
pgraph_bind_vertex_attributes(d, min_element, max_element, false,
0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pg->gl_inline_elements_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
pg->inline_elements_length * sizeof(uint32_t),
pg->inline_elements, GL_STREAM_DRAW);
VertexKey k;
memset(&k, 0, sizeof(VertexKey));
k.count = pg->inline_elements_length;
k.gl_type = GL_UNSIGNED_INT;
k.gl_normalize = GL_FALSE;
k.stride = sizeof(uint32_t);
uint64_t h = fast_hash((uint8_t*)pg->inline_elements,
pg->inline_elements_length * 4);
LruNode *node = lru_lookup(&pg->element_cache, h, &k);
VertexLruNode *found = container_of(node, VertexLruNode, node);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, found->gl_buffer);
if (!found->initialized) {
nv2a_profile_inc_counter(NV2A_PROF_GEOM_BUFFER_UPDATE_5);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
pg->inline_elements_length * 4,
pg->inline_elements, GL_STATIC_DRAW);
found->initialized = true;
}
glDrawElements(pg->shader_binding->gl_primitive_mode,
pg->inline_elements_length, GL_UNSIGNED_INT,
(void *)0);
@ -3373,6 +3388,21 @@ void pgraph_init(NV2AState *d)
pg->vertex_cache.init_node = vertex_cache_entry_init;
pg->vertex_cache.compare_nodes = vertex_cache_entry_compare;
// Initialize element cache
const size_t element_cache_size = 50*1024;
lru_init(&pg->element_cache);
pg->element_cache_entries = malloc(element_cache_size * sizeof(VertexLruNode));
assert(pg->element_cache_entries != NULL);
GLuint element_cache_buffers[element_cache_size];
glGenBuffers(element_cache_size, element_cache_buffers);
for (i = 0; i < element_cache_size; i++) {
pg->element_cache_entries[i].gl_buffer = element_cache_buffers[i];
lru_add_free(&pg->element_cache, &pg->element_cache_entries[i].node);
}
pg->element_cache.init_node = vertex_cache_entry_init;
pg->element_cache.compare_nodes = vertex_cache_entry_compare;
pg->shader_cache = g_hash_table_new(shader_hash, shader_equal);
for (i=0; i<NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
@ -3383,7 +3413,6 @@ void pgraph_init(NV2AState *d)
attribute->inline_buffer_populated = false;
}
glGenBuffers(1, &pg->gl_inline_array_buffer);
glGenBuffers(1, &pg->gl_inline_elements_buffer);
glGenBuffers(1, &pg->gl_memory_buffer);
glBindBuffer(GL_ARRAY_BUFFER, pg->gl_memory_buffer);