Merge remote-tracking branch 'mesa-public/master' into vulkan
This commit is contained in:
1
src/compiler/.gitignore
vendored
Normal file
1
src/compiler/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
glsl_compiler
|
@@ -220,9 +220,11 @@ YACC_GEN = $(AM_V_YACC)$(YACC) $(YFLAGS)
|
||||
LEX_GEN = $(AM_V_LEX)$(LEX) $(LFLAGS)
|
||||
|
||||
glsl/glsl_parser.cpp glsl/glsl_parser.h: glsl/glsl_parser.yy
|
||||
$(MKDIR_GEN)
|
||||
$(YACC_GEN) -o $@ -p "_mesa_glsl_" --defines=$(builddir)/glsl/glsl_parser.h $(srcdir)/glsl/glsl_parser.yy
|
||||
|
||||
glsl/glsl_lexer.cpp: glsl/glsl_lexer.ll
|
||||
$(MKDIR_GEN)
|
||||
$(LEX_GEN) -o $@ $(srcdir)/glsl/glsl_lexer.ll
|
||||
|
||||
glsl/glcpp/glcpp-parse.c glsl/glcpp/glcpp-parse.h: glsl/glcpp/glcpp-parse.y
|
||||
|
1
src/compiler/glsl/.gitignore
vendored
1
src/compiler/glsl/.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
glsl_compiler
|
||||
glsl_lexer.cpp
|
||||
glsl_parser.cpp
|
||||
glsl_parser.h
|
||||
|
@@ -291,6 +291,10 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
|
||||
if (!state->is_version(120, 0))
|
||||
return false;
|
||||
|
||||
/* ESSL does not allow implicit conversions */
|
||||
if (state->es_shader)
|
||||
return false;
|
||||
|
||||
/* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
|
||||
*
|
||||
* "There are no implicit array or structure conversions. For
|
||||
|
@@ -661,7 +661,7 @@ private:
|
||||
BA1(roundEven)
|
||||
BA1(ceil)
|
||||
BA1(fract)
|
||||
B2(mod)
|
||||
BA2(mod)
|
||||
BA1(modf)
|
||||
BA2(min)
|
||||
BA2(max)
|
||||
@@ -1242,23 +1242,23 @@ builtin_builder::create_builtins()
|
||||
FD(fract)
|
||||
|
||||
add_function("mod",
|
||||
_mod(glsl_type::float_type, glsl_type::float_type),
|
||||
_mod(glsl_type::vec2_type, glsl_type::float_type),
|
||||
_mod(glsl_type::vec3_type, glsl_type::float_type),
|
||||
_mod(glsl_type::vec4_type, glsl_type::float_type),
|
||||
_mod(always_available, glsl_type::float_type, glsl_type::float_type),
|
||||
_mod(always_available, glsl_type::vec2_type, glsl_type::float_type),
|
||||
_mod(always_available, glsl_type::vec3_type, glsl_type::float_type),
|
||||
_mod(always_available, glsl_type::vec4_type, glsl_type::float_type),
|
||||
|
||||
_mod(glsl_type::vec2_type, glsl_type::vec2_type),
|
||||
_mod(glsl_type::vec3_type, glsl_type::vec3_type),
|
||||
_mod(glsl_type::vec4_type, glsl_type::vec4_type),
|
||||
_mod(always_available, glsl_type::vec2_type, glsl_type::vec2_type),
|
||||
_mod(always_available, glsl_type::vec3_type, glsl_type::vec3_type),
|
||||
_mod(always_available, glsl_type::vec4_type, glsl_type::vec4_type),
|
||||
|
||||
_mod(glsl_type::double_type, glsl_type::double_type),
|
||||
_mod(glsl_type::dvec2_type, glsl_type::double_type),
|
||||
_mod(glsl_type::dvec3_type, glsl_type::double_type),
|
||||
_mod(glsl_type::dvec4_type, glsl_type::double_type),
|
||||
_mod(fp64, glsl_type::double_type, glsl_type::double_type),
|
||||
_mod(fp64, glsl_type::dvec2_type, glsl_type::double_type),
|
||||
_mod(fp64, glsl_type::dvec3_type, glsl_type::double_type),
|
||||
_mod(fp64, glsl_type::dvec4_type, glsl_type::double_type),
|
||||
|
||||
_mod(glsl_type::dvec2_type, glsl_type::dvec2_type),
|
||||
_mod(glsl_type::dvec3_type, glsl_type::dvec3_type),
|
||||
_mod(glsl_type::dvec4_type, glsl_type::dvec4_type),
|
||||
_mod(fp64, glsl_type::dvec2_type, glsl_type::dvec2_type),
|
||||
_mod(fp64, glsl_type::dvec3_type, glsl_type::dvec3_type),
|
||||
_mod(fp64, glsl_type::dvec4_type, glsl_type::dvec4_type),
|
||||
NULL);
|
||||
|
||||
FD(modf)
|
||||
@@ -3452,9 +3452,10 @@ UNOPA(ceil, ir_unop_ceil)
|
||||
UNOPA(fract, ir_unop_fract)
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_mod(const glsl_type *x_type, const glsl_type *y_type)
|
||||
builtin_builder::_mod(builtin_available_predicate avail,
|
||||
const glsl_type *x_type, const glsl_type *y_type)
|
||||
{
|
||||
return binop(always_available, ir_binop_mod, x_type, x_type, y_type);
|
||||
return binop(avail, ir_binop_mod, x_type, x_type, y_type);
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
|
@@ -328,6 +328,11 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type,
|
||||
this->fields[this->num_fields].sample = 0;
|
||||
this->fields[this->num_fields].patch = 0;
|
||||
this->fields[this->num_fields].precision = GLSL_PRECISION_NONE;
|
||||
this->fields[this->num_fields].image_read_only = 0;
|
||||
this->fields[this->num_fields].image_write_only = 0;
|
||||
this->fields[this->num_fields].image_coherent = 0;
|
||||
this->fields[this->num_fields].image_volatile = 0;
|
||||
this->fields[this->num_fields].image_restrict = 0;
|
||||
this->num_fields++;
|
||||
}
|
||||
|
||||
@@ -1201,7 +1206,12 @@ builtin_variable_generator::generate_varyings()
|
||||
/* gl_Position and gl_PointSize are not visible from fragment shaders. */
|
||||
if (state->stage != MESA_SHADER_FRAGMENT) {
|
||||
add_varying(VARYING_SLOT_POS, vec4_t, "gl_Position");
|
||||
add_varying(VARYING_SLOT_PSIZ, float_t, "gl_PointSize");
|
||||
if (!state->es_shader ||
|
||||
state->stage == MESA_SHADER_VERTEX ||
|
||||
(state->stage == MESA_SHADER_GEOMETRY &&
|
||||
state->OES_geometry_point_size_enable)) {
|
||||
add_varying(VARYING_SLOT_PSIZ, float_t, "gl_PointSize");
|
||||
}
|
||||
}
|
||||
|
||||
if (state->is_version(130, 0)) {
|
||||
|
@@ -2386,6 +2386,13 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
|
||||
add_builtin_define(parser, "GL_OES_texture_storage_multisample_2d_array", 1);
|
||||
if (extensions->ARB_blend_func_extended)
|
||||
add_builtin_define(parser, "GL_EXT_blend_func_extended", 1);
|
||||
|
||||
if (version >= 310) {
|
||||
if (extensions->OES_geometry_shader) {
|
||||
add_builtin_define(parser, "GL_OES_geometry_point_size", 1);
|
||||
add_builtin_define(parser, "GL_OES_geometry_shader", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
|
||||
|
@@ -600,6 +600,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
|
||||
/* OES extensions go here, sorted alphabetically.
|
||||
*/
|
||||
EXT(OES_EGL_image_external, false, true, OES_EGL_image_external),
|
||||
EXT(OES_geometry_point_size, false, true, OES_geometry_shader),
|
||||
EXT(OES_geometry_shader, false, true, OES_geometry_shader),
|
||||
EXT(OES_standard_derivatives, false, true, OES_standard_derivatives),
|
||||
EXT(OES_texture_3D, false, true, dummy_true),
|
||||
@@ -1867,59 +1868,76 @@ do_common_optimization(exec_list *ir, bool linked,
|
||||
const struct gl_shader_compiler_options *options,
|
||||
bool native_integers)
|
||||
{
|
||||
const bool debug = false;
|
||||
GLboolean progress = GL_FALSE;
|
||||
|
||||
progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
|
||||
#define OPT(PASS, ...) do { \
|
||||
if (debug) { \
|
||||
fprintf(stderr, "START GLSL optimization %s\n", #PASS); \
|
||||
const bool opt_progress = PASS(__VA_ARGS__); \
|
||||
progress = opt_progress || progress; \
|
||||
if (opt_progress) \
|
||||
_mesa_print_ir(stderr, ir, NULL); \
|
||||
fprintf(stderr, "GLSL optimization %s: %s progress\n", \
|
||||
#PASS, opt_progress ? "made" : "no"); \
|
||||
} else { \
|
||||
progress = PASS(__VA_ARGS__) || progress; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
OPT(lower_instructions, ir, SUB_TO_ADD_NEG);
|
||||
|
||||
if (linked) {
|
||||
progress = do_function_inlining(ir) || progress;
|
||||
progress = do_dead_functions(ir) || progress;
|
||||
progress = do_structure_splitting(ir) || progress;
|
||||
OPT(do_function_inlining, ir);
|
||||
OPT(do_dead_functions, ir);
|
||||
OPT(do_structure_splitting, ir);
|
||||
}
|
||||
progress = do_if_simplification(ir) || progress;
|
||||
progress = opt_flatten_nested_if_blocks(ir) || progress;
|
||||
progress = opt_conditional_discard(ir) || progress;
|
||||
progress = do_copy_propagation(ir) || progress;
|
||||
progress = do_copy_propagation_elements(ir) || progress;
|
||||
OPT(do_if_simplification, ir);
|
||||
OPT(opt_flatten_nested_if_blocks, ir);
|
||||
OPT(opt_conditional_discard, ir);
|
||||
OPT(do_copy_propagation, ir);
|
||||
OPT(do_copy_propagation_elements, ir);
|
||||
|
||||
if (options->OptimizeForAOS && !linked)
|
||||
progress = opt_flip_matrices(ir) || progress;
|
||||
OPT(opt_flip_matrices, ir);
|
||||
|
||||
if (linked && options->OptimizeForAOS) {
|
||||
progress = do_vectorize(ir) || progress;
|
||||
OPT(do_vectorize, ir);
|
||||
}
|
||||
|
||||
if (linked)
|
||||
progress = do_dead_code(ir, uniform_locations_assigned) || progress;
|
||||
OPT(do_dead_code, ir, uniform_locations_assigned);
|
||||
else
|
||||
progress = do_dead_code_unlinked(ir) || progress;
|
||||
progress = do_dead_code_local(ir) || progress;
|
||||
progress = do_tree_grafting(ir) || progress;
|
||||
progress = do_constant_propagation(ir) || progress;
|
||||
OPT(do_dead_code_unlinked, ir);
|
||||
OPT(do_dead_code_local, ir);
|
||||
OPT(do_tree_grafting, ir);
|
||||
OPT(do_constant_propagation, ir);
|
||||
if (linked)
|
||||
progress = do_constant_variable(ir) || progress;
|
||||
OPT(do_constant_variable, ir);
|
||||
else
|
||||
progress = do_constant_variable_unlinked(ir) || progress;
|
||||
progress = do_constant_folding(ir) || progress;
|
||||
progress = do_minmax_prune(ir) || progress;
|
||||
progress = do_rebalance_tree(ir) || progress;
|
||||
progress = do_algebraic(ir, native_integers, options) || progress;
|
||||
progress = do_lower_jumps(ir) || progress;
|
||||
progress = do_vec_index_to_swizzle(ir) || progress;
|
||||
progress = lower_vector_insert(ir, false) || progress;
|
||||
progress = do_swizzle_swizzle(ir) || progress;
|
||||
progress = do_noop_swizzle(ir) || progress;
|
||||
OPT(do_constant_variable_unlinked, ir);
|
||||
OPT(do_constant_folding, ir);
|
||||
OPT(do_minmax_prune, ir);
|
||||
OPT(do_rebalance_tree, ir);
|
||||
OPT(do_algebraic, ir, native_integers, options);
|
||||
OPT(do_lower_jumps, ir);
|
||||
OPT(do_vec_index_to_swizzle, ir);
|
||||
OPT(lower_vector_insert, ir, false);
|
||||
OPT(do_swizzle_swizzle, ir);
|
||||
OPT(do_noop_swizzle, ir);
|
||||
|
||||
progress = optimize_split_arrays(ir, linked) || progress;
|
||||
progress = optimize_redundant_jumps(ir) || progress;
|
||||
OPT(optimize_split_arrays, ir, linked);
|
||||
OPT(optimize_redundant_jumps, ir);
|
||||
|
||||
loop_state *ls = analyze_loop_variables(ir);
|
||||
if (ls->loop_found) {
|
||||
progress = set_loop_controls(ir, ls) || progress;
|
||||
progress = unroll_loops(ir, ls, options) || progress;
|
||||
OPT(set_loop_controls, ir, ls);
|
||||
OPT(unroll_loops, ir, ls, options);
|
||||
}
|
||||
delete ls;
|
||||
|
||||
#undef OPT
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
|
@@ -591,6 +591,8 @@ struct _mesa_glsl_parse_state {
|
||||
*/
|
||||
bool OES_EGL_image_external_enable;
|
||||
bool OES_EGL_image_external_warn;
|
||||
bool OES_geometry_point_size_enable;
|
||||
bool OES_geometry_point_size_warn;
|
||||
bool OES_geometry_shader_enable;
|
||||
bool OES_geometry_shader_warn;
|
||||
bool OES_standard_derivatives_enable;
|
||||
|
@@ -471,10 +471,11 @@ private:
|
||||
*/
|
||||
class parcel_out_uniform_storage : public program_resource_visitor {
|
||||
public:
|
||||
parcel_out_uniform_storage(struct string_to_uint_map *map,
|
||||
parcel_out_uniform_storage(struct gl_shader_program *prog,
|
||||
struct string_to_uint_map *map,
|
||||
struct gl_uniform_storage *uniforms,
|
||||
union gl_constant_value *values)
|
||||
: map(map), uniforms(uniforms), values(values)
|
||||
: prog(prog), map(map), uniforms(uniforms), values(values)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -492,8 +493,7 @@ public:
|
||||
memset(this->targets, 0, sizeof(this->targets));
|
||||
}
|
||||
|
||||
void set_and_process(struct gl_shader_program *prog,
|
||||
ir_variable *var)
|
||||
void set_and_process(ir_variable *var)
|
||||
{
|
||||
current_var = var;
|
||||
field_counter = 0;
|
||||
@@ -643,6 +643,16 @@ private:
|
||||
uniform->opaque[shader_type].index = this->next_image;
|
||||
uniform->opaque[shader_type].active = true;
|
||||
|
||||
/* Set image access qualifiers */
|
||||
const GLenum access =
|
||||
(current_var->data.image_read_only ? GL_READ_ONLY :
|
||||
current_var->data.image_write_only ? GL_WRITE_ONLY :
|
||||
GL_READ_WRITE);
|
||||
|
||||
for (unsigned j = 0; j < MAX2(1, uniform->array_elements); ++j)
|
||||
prog->_LinkedShaders[shader_type]->
|
||||
ImageAccess[this->next_image + j] = access;
|
||||
|
||||
/* Increment the image index by 1 for non-arrays and by the
|
||||
* number of array elements for arrays.
|
||||
*/
|
||||
@@ -844,6 +854,11 @@ private:
|
||||
this->values += values_for_type(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current program being processed.
|
||||
*/
|
||||
struct gl_shader_program *prog;
|
||||
|
||||
struct string_to_uint_map *map;
|
||||
|
||||
struct gl_uniform_storage *uniforms;
|
||||
@@ -1007,40 +1022,6 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
link_set_image_access_qualifiers(struct gl_shader_program *prog,
|
||||
gl_shader *sh, unsigned shader_stage,
|
||||
ir_variable *var, const glsl_type *type,
|
||||
char **name, size_t name_length)
|
||||
{
|
||||
/* Handle arrays of arrays */
|
||||
if (type->is_array() && type->fields.array->is_array()) {
|
||||
for (unsigned i = 0; i < type->length; i++) {
|
||||
size_t new_length = name_length;
|
||||
|
||||
/* Append the subscript to the current variable name */
|
||||
ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
|
||||
|
||||
link_set_image_access_qualifiers(prog, sh, shader_stage, var,
|
||||
type->fields.array, name,
|
||||
new_length);
|
||||
}
|
||||
} else {
|
||||
unsigned id = 0;
|
||||
bool found = prog->UniformHash->get(id, *name);
|
||||
assert(found);
|
||||
(void) found;
|
||||
const gl_uniform_storage *storage = &prog->UniformStorage[id];
|
||||
const unsigned index = storage->opaque[shader_stage].index;
|
||||
const GLenum access = (var->data.image_read_only ? GL_READ_ONLY :
|
||||
var->data.image_write_only ? GL_WRITE_ONLY :
|
||||
GL_READ_WRITE);
|
||||
|
||||
for (unsigned j = 0; j < MAX2(1, storage->array_elements); ++j)
|
||||
sh->ImageAccess[index + j] = access;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the hidden uniform hash map with the uniform hash map so that the
|
||||
* hidden uniforms will be given indicies at the end of the uniform storage
|
||||
@@ -1148,7 +1129,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
|
||||
union gl_constant_value *data_end = &data[num_data_slots];
|
||||
#endif
|
||||
|
||||
parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data);
|
||||
parcel_out_uniform_storage parcel(prog, prog->UniformHash, uniforms, data);
|
||||
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
@@ -1163,7 +1144,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
|
||||
var->data.mode != ir_var_shader_storage))
|
||||
continue;
|
||||
|
||||
parcel.set_and_process(prog, var);
|
||||
parcel.set_and_process(var);
|
||||
}
|
||||
|
||||
prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used;
|
||||
@@ -1301,29 +1282,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
|
||||
prog->NumHiddenUniforms = hidden_uniforms;
|
||||
prog->UniformStorage = uniforms;
|
||||
|
||||
/**
|
||||
* Scan the program for image uniforms and store image unit access
|
||||
* information into the gl_shader data structure.
|
||||
*/
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
gl_shader *sh = prog->_LinkedShaders[i];
|
||||
|
||||
if (sh == NULL)
|
||||
continue;
|
||||
|
||||
foreach_in_list(ir_instruction, node, sh->ir) {
|
||||
ir_variable *var = node->as_variable();
|
||||
|
||||
if (var && var->data.mode == ir_var_uniform &&
|
||||
var->type->contains_image()) {
|
||||
char *name_copy = ralloc_strdup(NULL, var->name);
|
||||
link_set_image_access_qualifiers(prog, sh, i, var, var->type,
|
||||
&name_copy, strlen(var->name));
|
||||
ralloc_free(name_copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
link_set_uniform_initializers(prog, boolean_true);
|
||||
|
||||
return;
|
||||
|
@@ -967,11 +967,16 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((consumer_var == NULL && producer_var->type->contains_integer()) ||
|
||||
bool needs_flat_qualifier = consumer_var == NULL &&
|
||||
(producer_var->type->contains_integer() ||
|
||||
producer_var->type->contains_double());
|
||||
|
||||
if (needs_flat_qualifier ||
|
||||
(consumer_stage != -1 && consumer_stage != MESA_SHADER_FRAGMENT)) {
|
||||
/* Since this varying is not being consumed by the fragment shader, its
|
||||
* interpolation type varying cannot possibly affect rendering.
|
||||
* Also, this variable is non-flat and is (or contains) an integer.
|
||||
* Also, this variable is non-flat and is (or contains) an integer
|
||||
* or a double.
|
||||
* If the consumer stage is unknown, don't modify the interpolation
|
||||
* type as it could affect rendering later with separate shaders.
|
||||
*
|
||||
|
@@ -4633,8 +4633,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
&prog->NumShaderStorageBlocks,
|
||||
&prog->SsboInterfaceBlockIndex);
|
||||
|
||||
/* FINISHME: Assign fragment shader output locations. */
|
||||
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
if (prog->_LinkedShaders[i] == NULL)
|
||||
continue;
|
||||
|
@@ -327,6 +327,7 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx,
|
||||
unsigned *const_offset,
|
||||
bool *row_major,
|
||||
int *matrix_columns,
|
||||
const glsl_struct_field **struct_field,
|
||||
unsigned packing)
|
||||
{
|
||||
*offset = new(mem_ctx) ir_constant(0u);
|
||||
@@ -442,8 +443,11 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx,
|
||||
intra_struct_offset = glsl_align(intra_struct_offset, field_align);
|
||||
|
||||
if (strcmp(struct_type->fields.structure[i].name,
|
||||
deref_record->field) == 0)
|
||||
deref_record->field) == 0) {
|
||||
if (struct_field)
|
||||
*struct_field = &struct_type->fields.structure[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (packing == GLSL_INTERFACE_PACKING_STD430)
|
||||
intra_struct_offset += type->std430_size(field_row_major);
|
||||
|
@@ -57,6 +57,7 @@ public:
|
||||
void setup_buffer_access(void *mem_ctx, ir_variable *var, ir_rvalue *deref,
|
||||
ir_rvalue **offset, unsigned *const_offset,
|
||||
bool *row_major, int *matrix_columns,
|
||||
const glsl_struct_field **struct_field,
|
||||
unsigned packing);
|
||||
};
|
||||
|
||||
|
@@ -142,7 +142,7 @@ lower_shared_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
|
||||
|
||||
setup_buffer_access(mem_ctx, var, deref,
|
||||
&offset, &const_offset,
|
||||
&row_major, &matrix_columns, packing);
|
||||
&row_major, &matrix_columns, NULL, packing);
|
||||
|
||||
/* Now that we've calculated the offset to the start of the
|
||||
* dereference, walk over the type and emit loads into a temporary.
|
||||
@@ -210,7 +210,7 @@ lower_shared_reference_visitor::handle_assignment(ir_assignment *ir)
|
||||
|
||||
setup_buffer_access(mem_ctx, var, deref,
|
||||
&offset, &const_offset,
|
||||
&row_major, &matrix_columns, packing);
|
||||
&row_major, &matrix_columns, NULL, packing);
|
||||
|
||||
deref = new(mem_ctx) ir_dereference_variable(store_var);
|
||||
|
||||
@@ -370,7 +370,7 @@ lower_shared_reference_visitor::lower_shared_atomic_intrinsic(ir_call *ir)
|
||||
|
||||
setup_buffer_access(mem_ctx, var, deref,
|
||||
&offset, &const_offset,
|
||||
&row_major, &matrix_columns, packing);
|
||||
&row_major, &matrix_columns, NULL, packing);
|
||||
|
||||
assert(offset);
|
||||
assert(!row_major);
|
||||
|
@@ -45,7 +45,7 @@ class lower_ubo_reference_visitor :
|
||||
public lower_buffer_access::lower_buffer_access {
|
||||
public:
|
||||
lower_ubo_reference_visitor(struct gl_shader *shader)
|
||||
: shader(shader)
|
||||
: shader(shader), struct_field(NULL), variable(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
bool *row_major,
|
||||
int *matrix_columns,
|
||||
unsigned packing);
|
||||
uint32_t ssbo_access_params();
|
||||
ir_expression *ubo_load(void *mem_ctx, const struct glsl_type *type,
|
||||
ir_rvalue *offset);
|
||||
ir_call *ssbo_load(void *mem_ctx, const struct glsl_type *type,
|
||||
@@ -104,6 +105,8 @@ public:
|
||||
|
||||
struct gl_shader *shader;
|
||||
struct gl_uniform_buffer_variable *ubo_var;
|
||||
const struct glsl_struct_field *struct_field;
|
||||
ir_variable *variable;
|
||||
ir_rvalue *uniform_block;
|
||||
bool progress;
|
||||
};
|
||||
@@ -288,8 +291,9 @@ lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx,
|
||||
|
||||
*const_offset = ubo_var->Offset;
|
||||
|
||||
this->struct_field = NULL;
|
||||
setup_buffer_access(mem_ctx, var, deref, offset, const_offset, row_major,
|
||||
matrix_columns, packing);
|
||||
matrix_columns, &this->struct_field, packing);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -317,6 +321,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
|
||||
this->buffer_access_type =
|
||||
var->is_in_shader_storage_block() ?
|
||||
ssbo_load_access : ubo_load_access;
|
||||
this->variable = var;
|
||||
|
||||
/* Compute the offset to the start if the dereference as well as other
|
||||
* information we need to configure the write
|
||||
@@ -370,6 +375,24 @@ shader_storage_buffer_object(const _mesa_glsl_parse_state *state)
|
||||
return state->ARB_shader_storage_buffer_object_enable;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lower_ubo_reference_visitor::ssbo_access_params()
|
||||
{
|
||||
assert(variable);
|
||||
|
||||
if (variable->is_interface_instance()) {
|
||||
assert(struct_field);
|
||||
|
||||
return ((struct_field->image_coherent ? ACCESS_COHERENT : 0) |
|
||||
(struct_field->image_restrict ? ACCESS_RESTRICT : 0) |
|
||||
(struct_field->image_volatile ? ACCESS_VOLATILE : 0));
|
||||
} else {
|
||||
return ((variable->data.image_coherent ? ACCESS_COHERENT : 0) |
|
||||
(variable->data.image_restrict ? ACCESS_RESTRICT : 0) |
|
||||
(variable->data.image_volatile ? ACCESS_VOLATILE : 0));
|
||||
}
|
||||
}
|
||||
|
||||
ir_call *
|
||||
lower_ubo_reference_visitor::ssbo_store(void *mem_ctx,
|
||||
ir_rvalue *deref,
|
||||
@@ -394,6 +417,10 @@ lower_ubo_reference_visitor::ssbo_store(void *mem_ctx,
|
||||
ir_variable(glsl_type::uint_type, "write_mask" , ir_var_function_in);
|
||||
sig_params.push_tail(writemask_ref);
|
||||
|
||||
ir_variable *access_ref = new(mem_ctx)
|
||||
ir_variable(glsl_type::uint_type, "access" , ir_var_function_in);
|
||||
sig_params.push_tail(access_ref);
|
||||
|
||||
ir_function_signature *sig = new(mem_ctx)
|
||||
ir_function_signature(glsl_type::void_type, shader_storage_buffer_object);
|
||||
assert(sig);
|
||||
@@ -408,6 +435,7 @@ lower_ubo_reference_visitor::ssbo_store(void *mem_ctx,
|
||||
call_params.push_tail(offset->clone(mem_ctx, NULL));
|
||||
call_params.push_tail(deref->clone(mem_ctx, NULL));
|
||||
call_params.push_tail(new(mem_ctx) ir_constant(write_mask));
|
||||
call_params.push_tail(new(mem_ctx) ir_constant(ssbo_access_params()));
|
||||
return new(mem_ctx) ir_call(sig, NULL, &call_params);
|
||||
}
|
||||
|
||||
@@ -426,6 +454,10 @@ lower_ubo_reference_visitor::ssbo_load(void *mem_ctx,
|
||||
ir_variable(glsl_type::uint_type, "offset_ref" , ir_var_function_in);
|
||||
sig_params.push_tail(offset_ref);
|
||||
|
||||
ir_variable *access_ref = new(mem_ctx)
|
||||
ir_variable(glsl_type::uint_type, "access" , ir_var_function_in);
|
||||
sig_params.push_tail(access_ref);
|
||||
|
||||
ir_function_signature *sig =
|
||||
new(mem_ctx) ir_function_signature(type, shader_storage_buffer_object);
|
||||
assert(sig);
|
||||
@@ -444,6 +476,7 @@ lower_ubo_reference_visitor::ssbo_load(void *mem_ctx,
|
||||
exec_list call_params;
|
||||
call_params.push_tail(this->uniform_block->clone(mem_ctx, NULL));
|
||||
call_params.push_tail(offset->clone(mem_ctx, NULL));
|
||||
call_params.push_tail(new(mem_ctx) ir_constant(ssbo_access_params()));
|
||||
|
||||
return new(mem_ctx) ir_call(sig, deref_result, &call_params);
|
||||
}
|
||||
@@ -499,6 +532,7 @@ lower_ubo_reference_visitor::write_to_memory(void *mem_ctx,
|
||||
unsigned packing = var->get_interface_type()->interface_packing;
|
||||
|
||||
this->buffer_access_type = ssbo_store_access;
|
||||
this->variable = var;
|
||||
|
||||
/* Compute the offset to the start if the dereference as well as other
|
||||
* information we need to configure the write
|
||||
@@ -678,6 +712,7 @@ lower_ubo_reference_visitor::process_ssbo_unsized_array_length(ir_rvalue **rvalu
|
||||
int unsized_array_stride = calculate_unsized_array_stride(deref, packing);
|
||||
|
||||
this->buffer_access_type = ssbo_unsized_array_length_access;
|
||||
this->variable = var;
|
||||
|
||||
/* Compute the offset to the start if the dereference as well as other
|
||||
* information we need to calculate the length.
|
||||
@@ -910,6 +945,7 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir)
|
||||
unsigned packing = var->get_interface_type()->interface_packing;
|
||||
|
||||
this->buffer_access_type = ssbo_atomic_access;
|
||||
this->variable = var;
|
||||
|
||||
setup_for_load_or_store(mem_ctx, var, deref,
|
||||
&offset, &const_offset,
|
||||
|
@@ -361,11 +361,12 @@ tree_grafting_basic_block(ir_instruction *bb_first,
|
||||
if (!lhs_var)
|
||||
continue;
|
||||
|
||||
if (lhs_var->data.mode == ir_var_function_out ||
|
||||
lhs_var->data.mode == ir_var_function_inout ||
|
||||
lhs_var->data.mode == ir_var_shader_out ||
|
||||
lhs_var->data.mode == ir_var_shader_storage)
|
||||
continue;
|
||||
if (lhs_var->data.mode == ir_var_function_out ||
|
||||
lhs_var->data.mode == ir_var_function_inout ||
|
||||
lhs_var->data.mode == ir_var_shader_out ||
|
||||
lhs_var->data.mode == ir_var_shader_storage ||
|
||||
lhs_var->data.mode == ir_var_shader_shared)
|
||||
continue;
|
||||
|
||||
ir_variable_refcount_entry *entry = info->refs->get_variable_entry(lhs_var);
|
||||
|
||||
|
@@ -164,6 +164,11 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||
this->fields.structure[i].sample = fields[i].sample;
|
||||
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
||||
this->fields.structure[i].patch = fields[i].patch;
|
||||
this->fields.structure[i].image_read_only = fields[i].image_read_only;
|
||||
this->fields.structure[i].image_write_only = fields[i].image_write_only;
|
||||
this->fields.structure[i].image_coherent = fields[i].image_coherent;
|
||||
this->fields.structure[i].image_volatile = fields[i].image_volatile;
|
||||
this->fields.structure[i].image_restrict = fields[i].image_restrict;
|
||||
this->fields.structure[i].precision = fields[i].precision;
|
||||
}
|
||||
|
||||
@@ -1330,6 +1335,13 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired,
|
||||
if (this == desired)
|
||||
return true;
|
||||
|
||||
/* ESSL does not allow implicit conversions. If there is no state, we're
|
||||
* doing intra-stage function linking where these checks have already been
|
||||
* done.
|
||||
*/
|
||||
if (state && state->es_shader)
|
||||
return false;
|
||||
|
||||
/* There is no conversion among matrix types. */
|
||||
if (this->matrix_columns > 1 || desired->matrix_columns > 1)
|
||||
return false;
|
||||
|
@@ -885,7 +885,8 @@ struct glsl_struct_field {
|
||||
glsl_struct_field(const struct glsl_type *_type, const char *_name)
|
||||
: type(_type), name(_name), location(-1), interpolation(0), centroid(0),
|
||||
sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0),
|
||||
precision(GLSL_PRECISION_NONE)
|
||||
precision(GLSL_PRECISION_NONE), image_read_only(0), image_write_only(0),
|
||||
image_coherent(0), image_volatile(0), image_restrict(0)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
@@ -139,7 +139,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
|
||||
b->shader->options->lower_pack_unorm_2x16);
|
||||
|
||||
nir_ssa_def *word =
|
||||
nir_extract_uword(b, instr->src[0].src.ssa, nir_imm_int(b, 0));
|
||||
nir_extract_u16(b, instr->src[0].src.ssa, nir_imm_int(b, 0));
|
||||
nir_ssa_def *val =
|
||||
nir_ior(b, nir_ishl(b, nir_channel(b, word, 1), nir_imm_int(b, 16)),
|
||||
nir_channel(b, word, 0));
|
||||
@@ -154,7 +154,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
|
||||
b->shader->options->lower_pack_unorm_4x8);
|
||||
|
||||
nir_ssa_def *byte =
|
||||
nir_extract_ubyte(b, instr->src[0].src.ssa, nir_imm_int(b, 0));
|
||||
nir_extract_u8(b, instr->src[0].src.ssa, nir_imm_int(b, 0));
|
||||
nir_ssa_def *val =
|
||||
nir_ior(b, nir_ior(b, nir_ishl(b, nir_channel(b, byte, 3), nir_imm_int(b, 24)),
|
||||
nir_ishl(b, nir_channel(b, byte, 2), nir_imm_int(b, 16))),
|
||||
|
@@ -238,15 +238,15 @@ unpack_2x16("unorm")
|
||||
unpack_4x8("unorm")
|
||||
unpack_2x16("half")
|
||||
|
||||
unop_horiz("pack_uvec2_to_uint", 0, tuint, 2, tuint, """
|
||||
dst = (src0.x & 0xffff) | (src0.y >> 16);
|
||||
unop_horiz("pack_uvec2_to_uint", 1, tuint, 2, tuint, """
|
||||
dst.x = (src0.x & 0xffff) | (src0.y >> 16);
|
||||
""")
|
||||
|
||||
unop_horiz("pack_uvec4_to_uint", 0, tuint, 4, tuint, """
|
||||
dst = (src0.x << 0) |
|
||||
(src0.y << 8) |
|
||||
(src0.z << 16) |
|
||||
(src0.w << 24);
|
||||
unop_horiz("pack_uvec4_to_uint", 1, tuint, 4, tuint, """
|
||||
dst.x = (src0.x << 0) |
|
||||
(src0.y << 8) |
|
||||
(src0.z << 16) |
|
||||
(src0.w << 24);
|
||||
""")
|
||||
|
||||
# Lowered floating point unpacking operations.
|
||||
@@ -562,12 +562,12 @@ dst.y = src1.x;
|
||||
""")
|
||||
|
||||
# Byte extraction
|
||||
binop("extract_ubyte", tuint, "", "(uint8_t)(src0 >> (src1 * 8))")
|
||||
binop("extract_ibyte", tint, "", "(int8_t)(src0 >> (src1 * 8))")
|
||||
binop("extract_u8", tuint, "", "(uint8_t)(src0 >> (src1 * 8))")
|
||||
binop("extract_i8", tint, "", "(int8_t)(src0 >> (src1 * 8))")
|
||||
|
||||
# Word extraction
|
||||
binop("extract_uword", tuint, "", "(uint16_t)(src0 >> (src1 * 16))")
|
||||
binop("extract_iword", tint, "", "(int16_t)(src0 >> (src1 * 16))")
|
||||
binop("extract_u16", tuint, "", "(uint16_t)(src0 >> (src1 * 16))")
|
||||
binop("extract_i16", tint, "", "(int16_t)(src0 >> (src1 * 16))")
|
||||
|
||||
|
||||
def triop(name, ty, const_expr):
|
||||
|
@@ -248,19 +248,19 @@ optimizations = [
|
||||
('ubfe', 'value', 'offset', 'bits')),
|
||||
'options->lower_bitfield_extract'),
|
||||
|
||||
(('extract_ibyte', a, b),
|
||||
('ishr', ('ishl', a, ('imul', ('isub', 3, b), 8)), 8),
|
||||
(('extract_i8', a, b),
|
||||
('ishr', ('ishl', a, ('imul', ('isub', 3, b), 8)), 24),
|
||||
'options->lower_extract_byte'),
|
||||
|
||||
(('extract_ubyte', a, b),
|
||||
(('extract_u8', a, b),
|
||||
('iand', ('ushr', a, ('imul', b, 8)), 0xff),
|
||||
'options->lower_extract_byte'),
|
||||
|
||||
(('extract_iword', a, b),
|
||||
(('extract_i16', a, b),
|
||||
('ishr', ('ishl', a, ('imul', ('isub', 1, b), 16)), 16),
|
||||
'options->lower_extract_word'),
|
||||
|
||||
(('extract_uword', a, b),
|
||||
(('extract_u16', a, b),
|
||||
('iand', ('ushr', a, ('imul', b, 16)), 0xffff),
|
||||
'options->lower_extract_word'),
|
||||
|
||||
@@ -285,30 +285,30 @@ optimizations = [
|
||||
'options->lower_pack_snorm_4x8'),
|
||||
|
||||
(('unpack_unorm_2x16', 'v'),
|
||||
('fdiv', ('u2f', ('vec4', ('extract_uword', 'v', 0),
|
||||
('extract_uword', 'v', 1), 0, 0)),
|
||||
('fdiv', ('u2f', ('vec2', ('extract_u16', 'v', 0),
|
||||
('extract_u16', 'v', 1))),
|
||||
65535.0),
|
||||
'options->lower_unpack_unorm_2x16'),
|
||||
|
||||
(('unpack_unorm_4x8', 'v'),
|
||||
('fdiv', ('u2f', ('vec4', ('extract_ubyte', 'v', 0),
|
||||
('extract_ubyte', 'v', 1),
|
||||
('extract_ubyte', 'v', 2),
|
||||
('extract_ubyte', 'v', 3))),
|
||||
('fdiv', ('u2f', ('vec4', ('extract_u8', 'v', 0),
|
||||
('extract_u8', 'v', 1),
|
||||
('extract_u8', 'v', 2),
|
||||
('extract_u8', 'v', 3))),
|
||||
255.0),
|
||||
'options->lower_unpack_unorm_4x8'),
|
||||
|
||||
(('unpack_snorm_2x16', 'v'),
|
||||
('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_iword', 'v', 0),
|
||||
('extract_iword', 'v', 1), 0, 0)),
|
||||
('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec2', ('extract_i16', 'v', 0),
|
||||
('extract_i16', 'v', 1))),
|
||||
32767.0))),
|
||||
'options->lower_unpack_snorm_2x16'),
|
||||
|
||||
(('unpack_snorm_4x8', 'v'),
|
||||
('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_ibyte', 'v', 0),
|
||||
('extract_ibyte', 'v', 1),
|
||||
('extract_ibyte', 'v', 2),
|
||||
('extract_ibyte', 'v', 3))),
|
||||
('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_i8', 'v', 0),
|
||||
('extract_i8', 'v', 1),
|
||||
('extract_i8', 'v', 2),
|
||||
('extract_i8', 'v', 3))),
|
||||
127.0))),
|
||||
'options->lower_unpack_snorm_4x8'),
|
||||
]
|
||||
|
@@ -544,6 +544,16 @@ enum gl_frag_depth_layout
|
||||
FRAG_DEPTH_LAYOUT_UNCHANGED
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Buffer access qualifiers
|
||||
*/
|
||||
enum gl_buffer_access_qualifier
|
||||
{
|
||||
ACCESS_COHERENT = 1,
|
||||
ACCESS_RESTRICT = 2,
|
||||
ACCESS_VOLATILE = 4,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user