diff options
author | Connor Abbott <cwabbott0@gmail.com> | 2017-09-12 20:16:22 -0400 |
---|---|---|
committer | Jordan Justen <jordan.l.justen@intel.com> | 2017-10-25 12:36:20 -0700 |
commit | 7686f0b316883087c7668c9df3adebcaae684132 (patch) | |
tree | 194bd716c609fc6dfb0f7871c1af77c8ad40a720 /src/compiler/glsl_types.cpp | |
parent | 9626128f32d712fe4576011c7e1d40fe9ec45186 (diff) |
glsl: move shader_cache type handling to glsl_types
Not sure if this is the best place to put it, but we're going to need
this for NIR too.
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Diffstat (limited to 'src/compiler/glsl_types.cpp')
-rw-r--r-- | src/compiler/glsl_types.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 99cc696c19b..a7fc7ff7f6b 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -2065,3 +2065,174 @@ glsl_type::coordinate_components() const #include "compiler/builtin_type_macros.h" /** @} */ + +static void +get_struct_type_field_and_pointer_sizes(size_t *s_field_size, + size_t *s_field_ptrs) +{ + *s_field_size = sizeof(glsl_struct_field); + *s_field_ptrs = + sizeof(((glsl_struct_field *)0)->type) + + sizeof(((glsl_struct_field *)0)->name); +} + +void +encode_type_to_blob(struct blob *blob, const glsl_type *type) +{ + uint32_t encoding; + + if (!type) { + blob_write_uint32(blob, 0); + return; + } + + switch (type->base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + encoding = (type->base_type << 24) | + (type->vector_elements << 4) | + (type->matrix_columns); + break; + case GLSL_TYPE_SAMPLER: + encoding = (type->base_type) << 24 | + (type->sampler_dimensionality << 4) | + (type->sampler_shadow << 3) | + (type->sampler_array << 2) | + (type->sampled_type); + break; + case GLSL_TYPE_SUBROUTINE: + encoding = type->base_type << 24; + blob_write_uint32(blob, encoding); + blob_write_string(blob, type->name); + return; + case GLSL_TYPE_IMAGE: + encoding = (type->base_type) << 24 | + (type->sampler_dimensionality << 3) | + (type->sampler_array << 2) | + (type->sampled_type); + break; + case GLSL_TYPE_ATOMIC_UINT: + encoding = (type->base_type << 24); + break; + case GLSL_TYPE_ARRAY: + blob_write_uint32(blob, (type->base_type) << 24); + blob_write_uint32(blob, type->length); + encode_type_to_blob(blob, type->fields.array); + return; + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: + blob_write_uint32(blob, (type->base_type) << 24); + blob_write_string(blob, type->name); + blob_write_uint32(blob, type->length); + + size_t s_field_size, s_field_ptrs; + get_struct_type_field_and_pointer_sizes(&s_field_size, &s_field_ptrs); + + for (unsigned i = 0; i < type->length; i++) { + encode_type_to_blob(blob, type->fields.structure[i].type); + blob_write_string(blob, type->fields.structure[i].name); + + /* Write the struct field skipping the pointers */ + blob_write_bytes(blob, + ((char *)&type->fields.structure[i]) + s_field_ptrs, + s_field_size - s_field_ptrs); + } + + if (type->is_interface()) { + blob_write_uint32(blob, type->interface_packing); + blob_write_uint32(blob, type->interface_row_major); + } + return; + case GLSL_TYPE_VOID: + case GLSL_TYPE_ERROR: + default: + assert(!"Cannot encode type!"); + encoding = 0; + break; + } + + blob_write_uint32(blob, encoding); +} + +const glsl_type * +decode_type_from_blob(struct blob_reader *blob) +{ + uint32_t u = blob_read_uint32(blob); + + if (u == 0) { + return NULL; + } + + glsl_base_type base_type = (glsl_base_type) (u >> 24); + + switch (base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + return glsl_type::get_instance(base_type, (u >> 4) & 0x0f, u & 0x0f); + case GLSL_TYPE_SAMPLER: + return glsl_type::get_sampler_instance((enum glsl_sampler_dim) ((u >> 4) & 0x07), + (u >> 3) & 0x01, + (u >> 2) & 0x01, + (glsl_base_type) ((u >> 0) & 0x03)); + case GLSL_TYPE_SUBROUTINE: + return glsl_type::get_subroutine_instance(blob_read_string(blob)); + case GLSL_TYPE_IMAGE: + return glsl_type::get_image_instance((enum glsl_sampler_dim) ((u >> 3) & 0x07), + (u >> 2) & 0x01, + (glsl_base_type) ((u >> 0) & 0x03)); + case GLSL_TYPE_ATOMIC_UINT: + return glsl_type::atomic_uint_type; + case GLSL_TYPE_ARRAY: { + unsigned length = blob_read_uint32(blob); + return glsl_type::get_array_instance(decode_type_from_blob(blob), + length); + } + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: { + char *name = blob_read_string(blob); + unsigned num_fields = blob_read_uint32(blob); + + size_t s_field_size, s_field_ptrs; + get_struct_type_field_and_pointer_sizes(&s_field_size, &s_field_ptrs); + + glsl_struct_field *fields = + (glsl_struct_field *) malloc(s_field_size * num_fields); + for (unsigned i = 0; i < num_fields; i++) { + fields[i].type = decode_type_from_blob(blob); + fields[i].name = blob_read_string(blob); + + blob_copy_bytes(blob, ((uint8_t *) &fields[i]) + s_field_ptrs, + s_field_size - s_field_ptrs); + } + + const glsl_type *t; + if (base_type == GLSL_TYPE_INTERFACE) { + enum glsl_interface_packing packing = + (glsl_interface_packing) blob_read_uint32(blob); + bool row_major = blob_read_uint32(blob); + t = glsl_type::get_interface_instance(fields, num_fields, packing, + row_major, name); + } else { + t = glsl_type::get_record_instance(fields, num_fields, name); + } + + free(fields); + return t; + } + case GLSL_TYPE_VOID: + case GLSL_TYPE_ERROR: + default: + assert(!"Cannot decode type!"); + return NULL; + } +} |