#include "compiler/glsl_types.h"
#include "compiler/glsl/linker.h"
#include "compiler/glsl/program.h"
+#include "compiler/glsl/shader_cache.h"
#include "program/prog_instruction.h"
#include "program/prog_optimize.h"
#include "program/prog_print.h"
return 1;
}
break;
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64:
+ if (type->vector_elements > 2)
+ return 2;
+ else
+ return 1;
case GLSL_TYPE_ARRAY:
assert(type->length > 0);
return type_size(type->fields.array) * type->length;
emit_scalar(ir, OPCODE_EX2, result_dst, op[0]);
break;
case ir_unop_exp:
+ assert(!"not reached: should be handled by exp_to_exp2");
+ break;
case ir_unop_log:
- assert(!"not reached: should be handled by ir_explog_to_explog2");
+ assert(!"not reached: should be handled by log_to_log2");
break;
case ir_unop_log2:
emit_scalar(ir, OPCODE_LG2, result_dst, op[0]);
emit(ir, OPCODE_LRP, result_dst, op[2], op[1], op[0]);
break;
+ case ir_triop_csel:
+ /* We assume that boolean true and false are 1.0 and 0.0. OPCODE_CMP
+ * selects src1 if src0 is < 0, src2 otherwise.
+ */
+ op[0].negate = ~op[0].negate;
+ emit(ir, OPCODE_CMP, result_dst, op[0], op[1], op[2]);
+ break;
+
case ir_binop_vector_extract:
case ir_triop_fma:
case ir_triop_bitfield_extract:
case ir_triop_vector_insert:
case ir_quadop_bitfield_insert:
case ir_binop_ldexp:
- case ir_triop_csel:
case ir_binop_carry:
case ir_binop_borrow:
case ir_binop_imul_high:
case ir_unop_dFdy_fine:
case ir_unop_subroutine_to_int:
case ir_unop_get_buffer_size:
- case ir_unop_vote_any:
- case ir_unop_vote_all:
- case ir_unop_vote_eq:
+ case ir_unop_bitcast_u642d:
+ case ir_unop_bitcast_i642d:
+ case ir_unop_bitcast_d2u64:
+ case ir_unop_bitcast_d2i64:
+ case ir_unop_i642i:
+ case ir_unop_u642i:
+ case ir_unop_i642u:
+ case ir_unop_u642u:
+ case ir_unop_i642b:
+ case ir_unop_i642f:
+ case ir_unop_u642f:
+ case ir_unop_i642d:
+ case ir_unop_u642d:
+ case ir_unop_i2i64:
+ case ir_unop_u2i64:
+ case ir_unop_b2i64:
+ case ir_unop_f2i64:
+ case ir_unop_d2i64:
+ case ir_unop_i2u64:
+ case ir_unop_u2u64:
+ case ir_unop_f2u64:
+ case ir_unop_d2u64:
+ case ir_unop_u642i64:
+ case ir_unop_i642u64:
+ case ir_unop_pack_int_2x32:
+ case ir_unop_unpack_int_2x32:
+ case ir_unop_pack_uint_2x32:
+ case ir_unop_unpack_uint_2x32:
+ case ir_unop_pack_sampler_2x32:
+ case ir_unop_unpack_sampler_2x32:
+ case ir_unop_pack_image_2x32:
+ case ir_unop_unpack_image_2x32:
assert(!"not supported");
break;
* get lucky, copy propagation will eliminate the extra moves.
*/
- if (ir->type->base_type == GLSL_TYPE_STRUCT) {
+ if (ir->type->is_record()) {
src_reg temp_base = get_temp(ir->type);
dst_reg temp = dst_reg(temp_base);
dst_reg mat_column = dst_reg(mat);
for (i = 0; i < ir->type->matrix_columns; i++) {
- assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+ assert(ir->type->is_float());
values = &ir->value.f[i * ir->type->vector_elements];
src = src_reg(PROGRAM_CONSTANT, -1, NULL);
emit(ir, OPCODE_RCP, coord_dst, projector);
/* In the case where we have to project the coordinates "by hand,"
- * the shadow comparitor value must also be projected.
+ * the shadow comparator value must also be projected.
*/
src_reg tmp_src = coord;
- if (ir->shadow_comparitor) {
+ if (ir->shadow_comparator) {
/* Slot the shadow value in as the second to last component of the
* coord.
*/
- ir->shadow_comparitor->accept(this);
+ ir->shadow_comparator->accept(this);
tmp_src = get_temp(glsl_type::vec4_type);
dst_reg tmp_dst = dst_reg(tmp_src);
}
/* If projection is done and the opcode is not OPCODE_TXP, then the shadow
- * comparitor was put in the correct place (and projected) by the code,
+ * comparator was put in the correct place (and projected) by the code,
* above, that handles by-hand projection.
*/
- if (ir->shadow_comparitor && (!ir->projector || opcode == OPCODE_TXP)) {
+ if (ir->shadow_comparator && (!ir->projector || opcode == OPCODE_TXP)) {
/* Slot the shadow value in as the second to last component of the
* coord.
*/
- ir->shadow_comparitor->accept(this);
+ ir->shadow_comparator->accept(this);
/* XXX This will need to be updated for cubemap array samplers. */
if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
else
inst = emit(ir, opcode, result_dst, coord);
- if (ir->shadow_comparitor)
+ if (ir->shadow_comparator)
inst->tex_shadow = GL_TRUE;
inst->sampler = get_sampler_uniform_value(ir->sampler, shader_program,
const enum glsl_interface_packing,
bool /* last_field */)
{
- unsigned int size;
-
/* atomics don't get real storage */
if (type->contains_atomic())
return;
- if (type->is_vector() || type->is_scalar()) {
- size = type->vector_elements;
- if (type->is_64bit())
- size *= 2;
- } else {
- size = type_size(type) * 4;
- }
-
gl_register_file file;
if (type->without_array()->is_sampler()) {
file = PROGRAM_SAMPLER;
int index = _mesa_lookup_parameter_index(params, name);
if (index < 0) {
+ unsigned size = type_size(type) * 4;
+
index = _mesa_add_parameter(params, file, name, size, type->gl_type,
NULL, NULL);
void
_mesa_associate_uniform_storage(struct gl_context *ctx,
- struct gl_shader_program *shader_program,
- struct gl_program_parameter_list *params)
+ struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params,
+ bool propagate_to_storage)
{
/* After adding each uniform to the parameter list, connect the storage for
* the parameter with the tracking structure used by the API for the
unsigned last_location = unsigned(~0);
for (unsigned i = 0; i < params->NumParameters; i++) {
if (params->Parameters[i].Type != PROGRAM_UNIFORM)
- continue;
+ continue;
unsigned location;
const bool found =
- shader_program->UniformHash->get(location, params->Parameters[i].Name);
+ shader_program->UniformHash->get(location, params->Parameters[i].Name);
assert(found);
if (!found)
- continue;
+ continue;
struct gl_uniform_storage *storage =
&shader_program->data->UniformStorage[location];
continue;
if (location != last_location) {
- enum gl_uniform_driver_format format = uniform_native;
-
- unsigned columns = 0;
- int dmul = 4 * sizeof(float);
- switch (storage->type->base_type) {
- case GLSL_TYPE_UINT:
- assert(ctx->Const.NativeIntegers);
- format = uniform_native;
- columns = 1;
- break;
- case GLSL_TYPE_INT:
- format =
- (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float;
- columns = 1;
- break;
+ enum gl_uniform_driver_format format = uniform_native;
+ unsigned columns = 0;
+ int dmul = 4 * sizeof(float);
- case GLSL_TYPE_DOUBLE:
- if (storage->type->vector_elements > 2)
+ switch (storage->type->base_type) {
+ case GLSL_TYPE_UINT64:
+ if (storage->type->vector_elements > 2)
dmul *= 2;
- /* fallthrough */
- case GLSL_TYPE_FLOAT:
- format = uniform_native;
- columns = storage->type->matrix_columns;
- break;
- case GLSL_TYPE_BOOL:
- format = uniform_native;
- columns = 1;
- break;
- case GLSL_TYPE_SAMPLER:
- case GLSL_TYPE_IMAGE:
+ /* fallthrough */
+ case GLSL_TYPE_UINT:
+ assert(ctx->Const.NativeIntegers);
+ format = uniform_native;
+ columns = 1;
+ break;
+ case GLSL_TYPE_INT64:
+ if (storage->type->vector_elements > 2)
+ dmul *= 2;
+ /* fallthrough */
+ case GLSL_TYPE_INT:
+ format =
+ (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float;
+ columns = 1;
+ break;
+ case GLSL_TYPE_DOUBLE:
+ if (storage->type->vector_elements > 2)
+ dmul *= 2;
+ /* fallthrough */
+ case GLSL_TYPE_FLOAT:
+ format = uniform_native;
+ columns = storage->type->matrix_columns;
+ break;
+ case GLSL_TYPE_BOOL:
+ format = uniform_native;
+ columns = 1;
+ break;
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
case GLSL_TYPE_SUBROUTINE:
- format = uniform_native;
- columns = 1;
- break;
+ format = uniform_native;
+ columns = 1;
+ break;
case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_FUNCTION:
- assert(!"Should not get here.");
- break;
- }
+ assert(!"Should not get here.");
+ break;
+ }
- _mesa_uniform_attach_driver_storage(storage,
- dmul * columns,
- dmul,
- format,
- ¶ms->ParameterValues[i]);
+ _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul,
+ format,
+ ¶ms->ParameterValues[i]);
- /* After attaching the driver's storage to the uniform, propagate any
- * data from the linker's backing store. This will cause values from
- * initializers in the source code to be copied over.
- */
- _mesa_propagate_uniforms_to_driver_storage(storage,
- 0,
- MAX2(1, storage->array_elements));
+ /* After attaching the driver's storage to the uniform, propagate any
+ * 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);
+ _mesa_propagate_uniforms_to_driver_storage(storage, 0,
+ array_elements);
+ }
- last_location = location;
+ last_location = location;
}
}
}
do_set_program_inouts(shader->ir, prog, shader->Stage);
- prog->SamplersUsed = shader->active_samplers;
prog->ShadowSamplers = shader->shadow_samplers;
- prog->ExternalSamplersUsed = gl_external_samplers(shader);
+ prog->ExternalSamplersUsed = gl_external_samplers(prog);
_mesa_update_shader_textures_used(shader_program, prog);
/* Set the gl_FragDepth layout. */
prog->info.fs.depth_layout = shader_program->FragDepthLayout;
}
- if ((ctx->_Shader->Flags & GLSL_NO_OPT) == 0) {
- _mesa_optimize_program(ctx, prog, prog);
- }
+ _mesa_optimize_program(ctx, 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->Parameters);
+ _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters,
+ true);
if (!shader_program->data->LinkStatus) {
goto fail_exit;
}
| LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP
| ((options->EmitNoPow) ? POW_TO_EXP2 : 0)));
- progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
-
progress = do_common_optimization(ir, true, true,
options, ctx->Const.NativeIntegers)
|| progress;
_mesa_clear_shader_program_data(ctx, prog);
- prog->data->LinkStatus = GL_TRUE;
+ prog->data->LinkStatus = linking_success;
for (i = 0; i < prog->NumShaders; i++) {
if (!prog->Shaders[i]->CompileStatus) {
}
if (prog->data->LinkStatus) {
+ /* Reset sampler validated to true, validation happens via the
+ * LinkShader call below.
+ */
+ prog->SamplersValidated = GL_TRUE;
+
if (!ctx->Driver.LinkShader(ctx, prog)) {
- prog->data->LinkStatus = GL_FALSE;
+ prog->data->LinkStatus = linking_failure;
}
}
+ /* Return early if we are loading the shader from on-disk cache */
+ if (prog->data->LinkStatus == linking_skipped)
+ return;
+
if (ctx->_Shader->Flags & GLSL_DUMP) {
if (!prog->data->LinkStatus) {
fprintf(stderr, "GLSL shader program %d failed to link\n", prog->Name);
fprintf(stderr, "%s\n", prog->data->InfoLog);
}
}
+
+#ifdef ENABLE_SHADER_CACHE
+ if (prog->data->LinkStatus)
+ shader_cache_write_program_metadata(ctx, prog);
+#endif
}
} /* extern "C" */