X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fprogram%2Fir_to_mesa.cpp;h=053912a84100bf43831656744262d8180f81de9c;hb=f0ccc5457aa7302960f1c43e2e8243edab61991d;hp=11207dd82892ffae8590fdfc330a48361e3fbfc3;hpb=0ac78dc92582a59d4319ebce019b4caa41fb432d;p=mesa.git diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 11207dd8289..053912a8410 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -30,12 +30,12 @@ */ #include -#include "main/compiler.h" #include "main/macros.h" #include "main/mtypes.h" #include "main/shaderapi.h" #include "main/shaderobj.h" #include "main/uniforms.h" +#include "main/glspirv.h" #include "compiler/glsl/ast.h" #include "compiler/glsl/ir.h" #include "compiler/glsl/ir_expression_flattening.h" @@ -507,7 +507,12 @@ storage_type_size(const struct glsl_type *type, bool bindless) switch (type->base_type) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: + case GLSL_TYPE_UINT8: + case GLSL_TYPE_INT8: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: case GLSL_TYPE_BOOL: if (type->is_matrix()) { return type->matrix_columns; @@ -589,7 +594,7 @@ ir_to_mesa_visitor::get_temp(const glsl_type *type) src.reladdr = NULL; next_temp += type_size(type); - if (type->is_array() || type->is_record()) { + if (type->is_array() || type->is_struct()) { src.swizzle = SWIZZLE_NOOP; } else { src.swizzle = swizzle_for_size(type->vector_elements); @@ -613,11 +618,6 @@ ir_to_mesa_visitor::find_variable_storage(const ir_variable *var) void ir_to_mesa_visitor::visit(ir_variable *ir) { - if (strcmp(ir->name, "gl_FragCoord") == 0) { - this->prog->OriginUpperLeft = ir->data.origin_upper_left; - this->prog->PixelCenterInteger = ir->data.pixel_center_integer; - } - if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { unsigned int i; const ir_state_slot *const slots = ir->get_state_slots(); @@ -661,7 +661,7 @@ ir_to_mesa_visitor::visit(ir_variable *ir) for (unsigned int i = 0; i < ir->get_num_state_slots(); i++) { int index = _mesa_add_state_reference(this->prog->Parameters, - (gl_state_index *)slots[i].tokens); + slots[i].tokens); if (storage->file == PROGRAM_STATE_VAR) { if (storage->index == -1) { @@ -1128,29 +1128,13 @@ ir_to_mesa_visitor::visit(ir_expression *ir) break; case ir_binop_mod: /* Floating point should be lowered by MOD_TO_FLOOR in the compiler. */ - assert(ir->type->is_integer()); + assert(ir->type->is_integer_32()); emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); break; case ir_binop_less: emit(ir, OPCODE_SLT, result_dst, op[0], op[1]); break; - case ir_binop_greater: - /* Negating the operands (as opposed to switching the order of the - * operands) produces the correct result when both are +/-Inf. - */ - op[0].negate = ~op[0].negate; - op[1].negate = ~op[1].negate; - emit(ir, OPCODE_SLT, result_dst, op[0], op[1]); - break; - case ir_binop_lequal: - /* Negating the operands (as opposed to switching the order of the - * operands) produces the correct result when both are +/-Inf. - */ - op[0].negate = ~op[0].negate; - op[1].negate = ~op[1].negate; - emit(ir, OPCODE_SGE, result_dst, op[0], op[1]); - break; case ir_binop_gequal: emit(ir, OPCODE_SGE, result_dst, op[0], op[1]); break; @@ -1695,7 +1679,7 @@ calc_sampler_offsets(struct gl_shader_program *prog, ir_dereference *deref, ir_dereference_record *deref_record = deref->as_dereference_record(); unsigned field_index = deref_record->field_idx; *location += - deref_record->record->type->record_location_offset(field_index); + deref_record->record->type->struct_location_offset(field_index); calc_sampler_offsets(prog, deref_record->record->as_dereference(), offset, array_elements, location); break; @@ -1758,10 +1742,6 @@ ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) /* a is - 0 + - 0 + * (a < 0) T F F ( a < 0) T F F * (0 < a) F F T (-a < 0) F F T - * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) - * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) - * (a > 0) F F T (-a < 0) F F T - * (0 > a) T F F ( a < 0) T F F * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) * @@ -1775,16 +1755,6 @@ ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) negate = zero_on_left; break; - case ir_binop_greater: - switch_order = false; - negate = !zero_on_left; - break; - - case ir_binop_lequal: - switch_order = true; - negate = !zero_on_left; - break; - case ir_binop_gequal: switch_order = true; negate = zero_on_left; @@ -1909,11 +1879,12 @@ ir_to_mesa_visitor::visit(ir_constant *ir) * get lucky, copy propagation will eliminate the extra moves. */ - if (ir->type->is_record()) { + if (ir->type->is_struct()) { src_reg temp_base = get_temp(ir->type); dst_reg temp = dst_reg(temp_base); - foreach_in_list(ir_constant, field_value, &ir->components) { + for (i = 0; i < ir->type->length; i++) { + ir_constant *const field_value = ir->get_record_field(i); int size = type_size(field_value->type); assert(size > 0); @@ -1921,7 +1892,7 @@ ir_to_mesa_visitor::visit(ir_constant *ir) field_value->accept(this); src = this->result; - for (i = 0; i < (unsigned int)size; i++) { + for (unsigned j = 0; j < (unsigned int)size; j++) { emit(ir, OPCODE_MOV, temp, src); src.index++; @@ -1940,7 +1911,7 @@ ir_to_mesa_visitor::visit(ir_constant *ir) assert(size > 0); for (i = 0; i < ir->type->length; i++) { - ir->array_elements[i]->accept(this); + ir->const_elements[i]->accept(this); src = this->result; for (int j = 0; j < size; j++) { emit(ir, OPCODE_MOV, temp, src); @@ -2460,12 +2431,41 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name, if (type->contains_opaque() && !var->data.bindless) return; + /* Add the uniform to the param list */ assert(_mesa_lookup_parameter_index(params, name) < 0); + int index = _mesa_lookup_parameter_index(params, name); + + unsigned num_params = type->arrays_of_arrays_size(); + num_params = MAX2(num_params, 1); + num_params *= type->without_array()->matrix_columns; + + bool is_dual_slot = type->without_array()->is_dual_slot(); + if (is_dual_slot) + num_params *= 2; + + _mesa_reserve_parameter_storage(params, num_params); + index = params->NumParameters; + + if (ctx->Const.PackedDriverUniformStorage) { + for (unsigned i = 0; i < num_params; i++) { + unsigned dmul = type->without_array()->is_64bit() ? 2 : 1; + unsigned comps = type->without_array()->vector_elements * dmul; + if (is_dual_slot) { + if (i & 0x1) + comps -= 4; + else + comps = 4; + } - unsigned size = storage_type_size(type, var->data.bindless) * 4; - - int index = _mesa_add_parameter(params, PROGRAM_UNIFORM, name, size, - type->gl_type, NULL, NULL); + _mesa_add_parameter(params, PROGRAM_UNIFORM, name, comps, + type->gl_type, NULL, NULL, false); + } + } else { + for (unsigned i = 0; i < num_params; i++) { + _mesa_add_parameter(params, PROGRAM_UNIFORM, name, 4, + type->gl_type, NULL, NULL, true); + } + } /* The first part of the uniform that's processed determines the base * location of the whole uniform (for structures). @@ -2506,8 +2506,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_context *ctx, void _mesa_associate_uniform_storage(struct gl_context *ctx, struct gl_shader_program *shader_program, - struct gl_program *prog, - bool propagate_to_storage) + struct gl_program *prog) { struct gl_program_parameter_list *params = prog->Parameters; gl_shader_stage shader_type = prog->info.stage; @@ -2539,7 +2538,13 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, if (location != last_location) { enum gl_uniform_driver_format format = uniform_native; unsigned columns = 0; - int dmul = 4 * sizeof(float); + + int dmul; + if (ctx->Const.PackedDriverUniformStorage && !prog->is_arb_asm) { + dmul = storage->type->vector_elements * sizeof(float); + } else { + dmul = 4 * sizeof(float); + } switch (storage->type->base_type) { case GLSL_TYPE_UINT64: @@ -2547,6 +2552,8 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, dmul *= 2; /* fallthrough */ case GLSL_TYPE_UINT: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_UINT8: assert(ctx->Const.NativeIntegers); format = uniform_native; columns = 1; @@ -2556,6 +2563,8 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, dmul *= 2; /* fallthrough */ case GLSL_TYPE_INT: + case GLSL_TYPE_INT16: + case GLSL_TYPE_INT8: format = (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float; columns = 1; @@ -2565,6 +2574,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, dmul *= 2; /* fallthrough */ case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: format = uniform_native; columns = storage->type->matrix_columns; break; @@ -2589,9 +2599,10 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, break; } + unsigned pvo = params->ParameterValueOffset[i]; _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul, format, - ¶ms->ParameterValues[i]); + ¶ms->ParameterValues[pvo]); /* When a bindless sampler/image is bound to a texture/image unit, we * have to overwrite the constant value by the resident handle @@ -2608,11 +2619,11 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, if (storage->type->without_array()->is_sampler()) { assert(unit >= 0 && unit < prog->sh.NumBindlessSamplers); prog->sh.BindlessSamplers[unit].data = - ¶ms->ParameterValues[i] + j; + ¶ms->ParameterValues[pvo] + 4 * j; } else if (storage->type->without_array()->is_image()) { assert(unit >= 0 && unit < prog->sh.NumBindlessImages); prog->sh.BindlessImages[unit].data = - ¶ms->ParameterValues[i] + j; + ¶ms->ParameterValues[pvo] + 4 * j; } } } @@ -2621,8 +2632,22 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, * data from the linker's backing store. This will cause values from * initializers in the source code to be copied over. */ - if (propagate_to_storage) { - unsigned array_elements = MAX2(1, storage->array_elements); + unsigned array_elements = MAX2(1, storage->array_elements); + if (ctx->Const.PackedDriverUniformStorage && !prog->is_arb_asm && + (storage->is_bindless || !storage->type->contains_opaque())) { + const int dmul = storage->type->is_64bit() ? 2 : 1; + const unsigned components = + storage->type->vector_elements * + storage->type->matrix_columns; + + for (unsigned s = 0; s < storage->num_driver_storage; s++) { + gl_constant_value *uni_storage = (gl_constant_value *) + storage->driver_storage[s].data; + memcpy(uni_storage, storage->storage, + sizeof(storage->storage[0]) * components * + array_elements * dmul); + } + } else { _mesa_propagate_uniforms_to_driver_storage(storage, 0, array_elements); } @@ -2977,13 +3002,13 @@ get_mesa_program(struct gl_context *ctx, prog->info.fs.depth_layout = shader_program->FragDepthLayout; } - _mesa_optimize_program(ctx, prog, prog); + _mesa_optimize_program(prog, prog); /* This has to be done last. Any operation that can cause * prog->ParameterValues to get reallocated (e.g., anything that adds a * program constant) has to happen before creating this linkage. */ - _mesa_associate_uniform_storage(ctx, shader_program, prog, true); + _mesa_associate_uniform_storage(ctx, shader_program, prog); if (!shader_program->data->LinkStatus) { goto fail_exit; } @@ -3025,6 +3050,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) do_mat_op_to_vec(ir); lower_instructions(ir, (MOD_TO_FLOOR | DIV_TO_MUL_RCP | EXP_TO_EXP2 | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP + | MUL64_TO_MUL_AND_MUL_HIGH | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); progress = do_common_optimization(ir, true, true, @@ -3093,34 +3119,57 @@ void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { unsigned int i; + bool spirv = false; _mesa_clear_shader_program_data(ctx, prog); - prog->data->LinkStatus = linking_success; + prog->data = _mesa_create_shader_program_data(); + + prog->data->LinkStatus = LINKING_SUCCESS; for (i = 0; i < prog->NumShaders; i++) { if (!prog->Shaders[i]->CompileStatus) { - linker_error(prog, "linking with uncompiled shader"); + linker_error(prog, "linking with uncompiled/unspecialized shader"); + } + + if (!i) { + spirv = (prog->Shaders[i]->spirv_data != NULL); + } else if (spirv && !prog->Shaders[i]->spirv_data) { + /* The GL_ARB_gl_spirv spec adds a new bullet point to the list of + * reasons LinkProgram can fail: + * + * "All the shader objects attached to do not have the + * same value for the SPIR_V_BINARY_ARB state." + */ + linker_error(prog, + "not all attached shaders have the same " + "SPIR_V_BINARY_ARB state"); } } + prog->data->spirv = spirv; if (prog->data->LinkStatus) { - link_shaders(ctx, prog); + if (!spirv) + link_shaders(ctx, prog); + else + _mesa_spirv_link_shaders(ctx, prog); } - if (prog->data->LinkStatus) { - /* Reset sampler validated to true, validation happens via the - * LinkShader call below. - */ + /* If LinkStatus is LINKING_SUCCESS, then reset sampler validated to true. + * Validation happens via the LinkShader call below. If LinkStatus is + * LINKING_SKIPPED, then SamplersValidated will have been restored from the + * shader cache. + */ + if (prog->data->LinkStatus == LINKING_SUCCESS) { prog->SamplersValidated = GL_TRUE; + } - if (!ctx->Driver.LinkShader(ctx, prog)) { - prog->data->LinkStatus = linking_failure; - } + if (prog->data->LinkStatus && !ctx->Driver.LinkShader(ctx, prog)) { + prog->data->LinkStatus = LINKING_FAILURE; } /* Return early if we are loading the shader from on-disk cache */ - if (prog->data->LinkStatus == linking_skipped) + if (prog->data->LinkStatus == LINKING_SKIPPED) return; if (ctx->_Shader->Flags & GLSL_DUMP) {