vkd3d-shader/spirv: Cache numeric types without through the general declaration cache.

Numeric types are used very frequently, and doing a tree search
each time one is needed tends to waste a lot of time.

I ran the compilation of ~1000 DXBC-TPF shaders randomly taken from
my collection and measured the performance using callgrind and the
kcachegrind "cycle count" estimation.

BEFORE:
 * 1,764,035,136 cycles
 * 1,767,948,767 cycles
 * 1,773,927,734 cycles

AFTER:
 * 1,472,384,755 cycles
 * 1,469,506,188 cycles
 * 1,470,191,425 cycles

So callgrind would estimate a 16% improvement at least.
This commit is contained in:
Giovanni Mascellani 2024-09-19 15:00:28 +02:00 committed by Henri Verbeet
parent 3a21daa49e
commit a2aeb3a142
Notes: Henri Verbeet 2024-09-23 15:57:44 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1103
2 changed files with 23 additions and 8 deletions

View File

@ -394,6 +394,7 @@ struct vkd3d_spirv_builder
uint32_t type_bool_id; uint32_t type_bool_id;
uint32_t type_void_id; uint32_t type_void_id;
uint32_t scope_subgroup_id; uint32_t scope_subgroup_id;
uint32_t numeric_type_ids[VKD3D_SHADER_COMPONENT_TYPE_COUNT][VKD3D_VEC4_SIZE];
struct vkd3d_spirv_stream debug_stream; /* debug instructions */ struct vkd3d_spirv_stream debug_stream; /* debug instructions */
struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */ struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */
@ -1902,29 +1903,37 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build
static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
enum vkd3d_shader_component_type component_type, unsigned int component_count) enum vkd3d_shader_component_type component_type, unsigned int component_count)
{ {
uint32_t scalar_id; uint32_t scalar_id, type_id;
VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT);
VKD3D_ASSERT(1 <= component_count && component_count <= VKD3D_VEC4_SIZE);
if ((type_id = builder->numeric_type_ids[component_type][component_count - 1]))
return type_id;
if (component_count == 1) if (component_count == 1)
{ {
switch (component_type) switch (component_type)
{ {
case VKD3D_SHADER_COMPONENT_VOID: case VKD3D_SHADER_COMPONENT_VOID:
return vkd3d_spirv_get_op_type_void(builder); type_id = vkd3d_spirv_get_op_type_void(builder);
break; break;
case VKD3D_SHADER_COMPONENT_FLOAT: case VKD3D_SHADER_COMPONENT_FLOAT:
return vkd3d_spirv_get_op_type_float(builder, 32); type_id = vkd3d_spirv_get_op_type_float(builder, 32);
break; break;
case VKD3D_SHADER_COMPONENT_INT: case VKD3D_SHADER_COMPONENT_INT:
case VKD3D_SHADER_COMPONENT_UINT: case VKD3D_SHADER_COMPONENT_UINT:
return vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT); type_id = vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT);
break; break;
case VKD3D_SHADER_COMPONENT_BOOL: case VKD3D_SHADER_COMPONENT_BOOL:
return vkd3d_spirv_get_op_type_bool(builder); type_id = vkd3d_spirv_get_op_type_bool(builder);
break; break;
case VKD3D_SHADER_COMPONENT_DOUBLE: case VKD3D_SHADER_COMPONENT_DOUBLE:
return vkd3d_spirv_get_op_type_float(builder, 64); type_id = vkd3d_spirv_get_op_type_float(builder, 64);
break;
case VKD3D_SHADER_COMPONENT_UINT64: case VKD3D_SHADER_COMPONENT_UINT64:
return vkd3d_spirv_get_op_type_int(builder, 64, 0); type_id = vkd3d_spirv_get_op_type_int(builder, 64, 0);
break;
default: default:
FIXME("Unhandled component type %#x.\n", component_type); FIXME("Unhandled component type %#x.\n", component_type);
return 0; return 0;
@ -1934,8 +1943,12 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
{ {
VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID);
scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1); scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
} }
builder->numeric_type_ids[component_type][component_count - 1] = type_id;
return type_id;
} }
static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder,

View File

@ -59,6 +59,8 @@
#define VKD3D_VEC4_SIZE 4 #define VKD3D_VEC4_SIZE 4
#define VKD3D_DVEC2_SIZE 2 #define VKD3D_DVEC2_SIZE 2
#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_UINT64 + 1)
enum vkd3d_shader_error enum vkd3d_shader_error
{ {
VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE = 1, VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE = 1,