@@ -258,7 +258,7 @@ static void shader_cache_entry_init(Lru *lru, LruNode *node, void *state)
258
258
259
259
static void shader_cache_entry_post_evict (Lru * lru , LruNode * node )
260
260
{
261
- PGRAPHVkState * r = container_of (lru , PGRAPHVkState , shader_cache );
261
+ PGRAPHVkState * r = container_of (lru , PGRAPHVkState , shader_module_cache );
262
262
ShaderBinding * snode = container_of (node , ShaderBinding , node );
263
263
264
264
ShaderModuleInfo * modules [] = {
@@ -268,7 +268,7 @@ static void shader_cache_entry_post_evict(Lru *lru, LruNode *node)
268
268
};
269
269
for (int i = 0 ; i < ARRAY_SIZE (modules ); i ++ ) {
270
270
if (modules [i ]) {
271
- pgraph_vk_destroy_shader_module (r , modules [i ]);
271
+ pgraph_vk_unref_shader_module (r , modules [i ]);
272
272
}
273
273
}
274
274
@@ -281,6 +281,60 @@ static bool shader_cache_entry_compare(Lru *lru, LruNode *node, void *key)
281
281
return memcmp (& snode -> state , key , sizeof (ShaderState ));
282
282
}
283
283
284
+ static void shader_module_cache_entry_init (Lru * lru , LruNode * node , void * key )
285
+ {
286
+ ShaderModuleCacheEntry * module =
287
+ container_of (node , ShaderModuleCacheEntry , node );
288
+ memcpy (& module -> key , key , sizeof (ShaderModuleCacheKey ));
289
+
290
+ MString * code ;
291
+
292
+ switch (module -> key .kind ) {
293
+ case VK_SHADER_STAGE_VERTEX_BIT :
294
+ code = pgraph_glsl_gen_vsh (
295
+ & module -> key .state .vsh , module -> key .glsl_options .vsh );
296
+ break ;
297
+ case VK_SHADER_STAGE_GEOMETRY_BIT :
298
+ code = pgraph_glsl_gen_geom (
299
+ & module -> key .state .geom , module -> key .glsl_options .geom );
300
+ break ;
301
+ case VK_SHADER_STAGE_FRAGMENT_BIT :
302
+ code = pgraph_glsl_gen_psh (
303
+ & module -> key .state .psh , module -> key .glsl_options .psh );
304
+ break ;
305
+ default :
306
+ assert (!"Invalid shader module kind" );
307
+ code = NULL ;
308
+ }
309
+
310
+ PGRAPHVkState * r = container_of (lru , PGRAPHVkState , shader_module_cache );
311
+ module -> module_info = pgraph_vk_create_shader_module_from_glsl (
312
+ r , module -> key .kind , mstring_get_str (code ));
313
+ pgraph_vk_ref_shader_module (module -> module_info );
314
+ mstring_unref (code );
315
+ }
316
+
317
+ static void shader_module_cache_entry_post_evict (Lru * lru , LruNode * node )
318
+ {
319
+ ShaderModuleCacheEntry * module =
320
+ container_of (node , ShaderModuleCacheEntry , node );
321
+ if (module -> module_info ) {
322
+ PGRAPHVkState * r =
323
+ container_of (lru , PGRAPHVkState , shader_module_cache );
324
+ pgraph_vk_unref_shader_module (r , module -> module_info );
325
+ module -> module_info = NULL ;
326
+ }
327
+ memset (& module -> key , 0 , sizeof (ShaderModuleCacheKey ));
328
+ }
329
+
330
+ static bool shader_module_cache_entry_compare (Lru * lru , LruNode * node ,
331
+ void * key )
332
+ {
333
+ ShaderModuleCacheEntry * module =
334
+ container_of (node , ShaderModuleCacheEntry , node );
335
+ return memcmp (& module -> key , key , sizeof (ShaderModuleCacheKey ));
336
+ }
337
+
284
338
static void shader_cache_init (PGRAPHState * pg )
285
339
{
286
340
PGRAPHVkState * r = pg -> vk_renderer_state ;
@@ -295,6 +349,22 @@ static void shader_cache_init(PGRAPHState *pg)
295
349
r -> shader_cache .init_node = shader_cache_entry_init ;
296
350
r -> shader_cache .compare_nodes = shader_cache_entry_compare ;
297
351
r -> shader_cache .post_node_evict = shader_cache_entry_post_evict ;
352
+
353
+ /* FIXME: Make this configurable */
354
+ const size_t shader_module_cache_size = 50 * 1024 ;
355
+ lru_init (& r -> shader_module_cache );
356
+ r -> shader_module_cache_entries =
357
+ g_malloc_n (shader_module_cache_size , sizeof (ShaderModuleCacheEntry ));
358
+ assert (r -> shader_module_cache_entries != NULL );
359
+ for (int i = 0 ; i < shader_module_cache_size ; i ++ ) {
360
+ lru_add_free (& r -> shader_module_cache ,
361
+ & r -> shader_module_cache_entries [i ].node );
362
+ }
363
+
364
+ r -> shader_module_cache .init_node = shader_module_cache_entry_init ;
365
+ r -> shader_module_cache .compare_nodes = shader_module_cache_entry_compare ;
366
+ r -> shader_module_cache .post_node_evict =
367
+ shader_module_cache_entry_post_evict ;
298
368
}
299
369
300
370
static void shader_cache_finalize (PGRAPHState * pg )
@@ -304,6 +374,21 @@ static void shader_cache_finalize(PGRAPHState *pg)
304
374
lru_flush (& r -> shader_cache );
305
375
g_free (r -> shader_cache_entries );
306
376
r -> shader_cache_entries = NULL ;
377
+
378
+ lru_flush (& r -> shader_module_cache );
379
+ g_free (r -> shader_module_cache_entries );
380
+ r -> shader_module_cache_entries = NULL ;
381
+ }
382
+
383
+ static ShaderModuleInfo *
384
+ get_shader_module_for_key (PGRAPHVkState * r , ShaderModuleCacheKey * key )
385
+ {
386
+ uint64_t hash = fast_hash ((void * )key , sizeof (ShaderModuleCacheKey ));
387
+ LruNode * node = lru_lookup (& r -> shader_module_cache , hash , key );
388
+ ShaderModuleCacheEntry * module =
389
+ container_of (node , ShaderModuleCacheEntry , node );
390
+ pgraph_vk_ref_shader_module (module -> module_info );
391
+ return module -> module_info ;
307
392
}
308
393
309
394
static ShaderBinding * gen_shaders (PGRAPHState * pg , ShaderState * state )
@@ -328,46 +413,36 @@ static ShaderBinding *gen_shaders(PGRAPHState *pg, ShaderState *state)
328
413
/* Ensure numeric values are printed with '.' radix, no grouping */
329
414
setlocale (LC_NUMERIC , "C" );
330
415
331
- MString * geometry_shader_code = pgraph_glsl_gen_geom (
332
- & state -> geom , ( GenGeomGlslOptions ){ . vulkan = true });
333
- if ( geometry_shader_code ) {
334
- NV2A_VK_DPRINTF ( "geometry shader: \n%s" ,
335
- mstring_get_str ( geometry_shader_code ));
336
- snode -> geometry = pgraph_vk_create_shader_module_from_glsl (
337
- r , VK_SHADER_STAGE_GEOMETRY_BIT ,
338
- mstring_get_str ( geometry_shader_code )) ;
339
- mstring_unref ( geometry_shader_code );
416
+ ShaderModuleCacheKey key ;
417
+
418
+ bool need_geometry_shader = pgraph_glsl_need_gsh ( & state -> geom );
419
+ if ( need_geometry_shader ) {
420
+ memset ( & key , 0 , sizeof ( key ));
421
+ key . kind = VK_SHADER_STAGE_GEOMETRY_BIT ;
422
+ key . state . geom = state -> geom ;
423
+ key . glsl_options . geom = ( GenGeomGlslOptions ){ . vulkan = true } ;
424
+ snode -> geometry = get_shader_module_for_key ( r , & key );
340
425
} else {
341
426
snode -> geometry = NULL ;
342
427
}
343
428
344
- MString * vertex_shader_code = pgraph_glsl_gen_vsh (
345
- & state -> vsh , (GenVshGlslOptions ){
346
- .vulkan = true,
347
- .prefix_outputs = geometry_shader_code != NULL ,
348
- .use_push_constants_for_uniform_attrs =
349
- r -> use_push_constants_for_uniform_attrs ,
350
- .ubo_binding = VSH_UBO_BINDING ,
351
- });
352
- NV2A_VK_DPRINTF ("vertex shader: \n%s" ,
353
- mstring_get_str (vertex_shader_code ));
354
- snode -> vertex = pgraph_vk_create_shader_module_from_glsl (
355
- r , VK_SHADER_STAGE_VERTEX_BIT ,
356
- mstring_get_str (vertex_shader_code ));
357
- mstring_unref (vertex_shader_code );
358
-
359
- MString * fragment_shader_code = pgraph_glsl_gen_psh (
360
- & state -> psh , (GenPshGlslOptions ){
361
- .vulkan = true,
362
- .ubo_binding = PSH_UBO_BINDING ,
363
- .tex_binding = PSH_TEX_BINDING ,
364
- });
365
- NV2A_VK_DPRINTF ("fragment shader: \n%s" ,
366
- mstring_get_str (fragment_shader_code ));
367
- snode -> fragment = pgraph_vk_create_shader_module_from_glsl (
368
- r , VK_SHADER_STAGE_FRAGMENT_BIT ,
369
- mstring_get_str (fragment_shader_code ));
370
- mstring_unref (fragment_shader_code );
429
+ memset (& key , 0 , sizeof (key ));
430
+ key .kind = VK_SHADER_STAGE_VERTEX_BIT ;
431
+ key .state .vsh = state -> vsh ;
432
+ key .glsl_options .vsh .vulkan = true;
433
+ key .glsl_options .vsh .prefix_outputs = need_geometry_shader ,
434
+ key .glsl_options .vsh .use_push_constants_for_uniform_attrs =
435
+ r -> use_push_constants_for_uniform_attrs ;
436
+ key .glsl_options .vsh .ubo_binding = VSH_UBO_BINDING ;
437
+ snode -> vertex = get_shader_module_for_key (r , & key );
438
+
439
+ memset (& key , 0 , sizeof (key ));
440
+ key .kind = VK_SHADER_STAGE_FRAGMENT_BIT ;
441
+ key .state .psh = state -> psh ;
442
+ key .glsl_options .psh .vulkan = true;
443
+ key .glsl_options .psh .ubo_binding = PSH_UBO_BINDING ;
444
+ key .glsl_options .psh .tex_binding = PSH_TEX_BINDING ;
445
+ snode -> fragment = get_shader_module_for_key (r , & key );
371
446
372
447
if (previous_numeric_locale ) {
373
448
setlocale (LC_NUMERIC , previous_numeric_locale );
0 commit comments