void glsl_get_natural_size_align_bytes(const struct glsl_type *type, unsigned *size, unsigned *align) { switch (type->base_type) { case GLSL_TYPE_UINT8: case GLSL_TYPE_INT8: case GLSL_TYPE_UINT16: case GLSL_TYPE_INT16: case GLSL_TYPE_FLOAT16: 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: { unsigned N = glsl_get_bit_size(type) / 8; *size = N * type->components(); *align = N; break; } case GLSL_TYPE_ARRAY: { unsigned elem_size, elem_align; glsl_get_natural_size_align_bytes(type->fields.array, &elem_size, &elem_align); *align = elem_align; *size = type->length * ALIGN_POT(elem_size, elem_align); break; } case GLSL_TYPE_STRUCT: *size = 0; *align = 0; for (unsigned i = 0; i < type->length; i++) { unsigned elem_size, elem_align; glsl_get_natural_size_align_bytes(type->fields.structure[i].type, &elem_size, &elem_align); *align = MAX2(*align, elem_align); *size = ALIGN_POT(*size, elem_align) + elem_size; } break; case GLSL_TYPE_SAMPLER: case GLSL_TYPE_ATOMIC_UINT: case GLSL_TYPE_SUBROUTINE: case GLSL_TYPE_IMAGE: case GLSL_TYPE_VOID: case GLSL_TYPE_ERROR: case GLSL_TYPE_INTERFACE: case GLSL_TYPE_FUNCTION: unreachable("type does not have a natural size"); } }
nir_foreach_instr(instr, block) { if (instr->type != nir_instr_type_intrinsic) continue; nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); if (intrin->intrinsic != nir_intrinsic_load_deref && intrin->intrinsic != nir_intrinsic_store_deref) continue; nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); if (!(deref->mode & modes)) continue; if (!deref_has_indirect(nir_src_as_deref(intrin->src[0]))) continue; nir_variable *var = nir_deref_instr_get_variable(deref); /* We set var->mode to 0 to indicate that a variable will be moved * to scratch. Don't assign a scratch location twice. */ if (var->data.mode == 0) continue; unsigned var_size, var_align; size_align(var->type, &var_size, &var_align); if (var_size <= size_threshold) continue; /* Remove it from its list */ exec_node_remove(&var->node); /* Invalid mode used to flag "moving to scratch" */ var->data.mode = 0; var->data.location = ALIGN_POT(shader->scratch_size, var_align); shader->scratch_size = var->data.location + var_size; }