1969
* Generate a new slang_function to satisfy a call to an array constructor.
1970
* Ex: float[3](1., 2., 3.)
1972
static slang_function *
1973
_slang_make_array_constructor(slang_assemble_ctx *A, slang_operation *oper)
1975
slang_type_specifier_type baseType;
1976
slang_function *fun;
1979
fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
1983
baseType = slang_type_specifier_type_from_string((char *) oper->a_id);
1985
num_elements = oper->num_children;
1987
/* function header, return type */
1989
fun->header.a_name = oper->a_id;
1990
fun->header.type.qualifier = SLANG_QUAL_NONE;
1991
fun->header.type.specifier.type = SLANG_SPEC_ARRAY;
1992
fun->header.type.specifier._array =
1993
slang_type_specifier_new(baseType, NULL, NULL);
1994
fun->header.type.array_len = num_elements;
1997
/* function parameters (= number of elements) */
2000
for (i = 0; i < num_elements; i++) {
2002
printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
2004
slang_variable *p = slang_variable_scope_grow(fun->parameters);
2006
_mesa_snprintf(name, sizeof(name), "p%d", i);
2007
p->a_name = slang_atom_pool_atom(A->atoms, name);
2008
p->type.qualifier = SLANG_QUAL_CONST;
2009
p->type.specifier.type = baseType;
2011
fun->param_count = fun->parameters->num_variables;
2014
/* Add __retVal to params */
2016
slang_variable *p = slang_variable_scope_grow(fun->parameters);
2017
slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
2019
p->a_name = a_retVal;
2020
p->type = fun->header.type;
2021
p->type.qualifier = SLANG_QUAL_OUT;
2022
p->type.specifier.type = baseType;
2026
/* function body is:
2036
slang_variable_scope *scope;
2037
slang_variable *var;
2040
fun->body = slang_operation_new(1);
2041
fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
2042
fun->body->num_children = num_elements + 2;
2043
fun->body->children = slang_operation_new(num_elements + 2);
2045
scope = fun->body->locals;
2046
scope->outer_scope = fun->parameters;
2048
/* create local var 't' */
2049
var = slang_variable_scope_grow(scope);
2050
var->a_name = slang_atom_pool_atom(A->atoms, "ttt");
2051
var->type = fun->header.type;/*XXX copy*/
2055
slang_operation *decl;
2057
decl = &fun->body->children[0];
2058
decl->type = SLANG_OPER_VARIABLE_DECL;
2059
decl->locals = _slang_variable_scope_new(scope);
2060
decl->a_id = var->a_name;
2063
/* assign params to elements of t */
2064
for (i = 0; i < num_elements; i++) {
2065
slang_operation *assign = &fun->body->children[1 + i];
2067
assign->type = SLANG_OPER_ASSIGN;
2068
assign->locals = _slang_variable_scope_new(scope);
2069
assign->num_children = 2;
2070
assign->children = slang_operation_new(2);
2073
slang_operation *lhs = &assign->children[0];
2075
lhs->type = SLANG_OPER_SUBSCRIPT;
2076
lhs->locals = _slang_variable_scope_new(scope);
2077
lhs->num_children = 2;
2078
lhs->children = slang_operation_new(2);
2080
lhs->children[0].type = SLANG_OPER_IDENTIFIER;
2081
lhs->children[0].a_id = var->a_name;
2082
lhs->children[0].locals = _slang_variable_scope_new(scope);
2084
lhs->children[1].type = SLANG_OPER_LITERAL_INT;
2085
lhs->children[1].literal[0] = (GLfloat) i;
2089
slang_operation *rhs = &assign->children[1];
2091
rhs->type = SLANG_OPER_IDENTIFIER;
2092
rhs->locals = _slang_variable_scope_new(scope);
2093
rhs->a_id = fun->parameters->variables[i]->a_name;
2099
slang_operation *ret = &fun->body->children[num_elements + 1];
2101
ret->type = SLANG_OPER_RETURN;
2102
ret->locals = _slang_variable_scope_new(scope);
2103
ret->num_children = 1;
2104
ret->children = slang_operation_new(1);
2105
ret->children[0].type = SLANG_OPER_IDENTIFIER;
2106
ret->children[0].a_id = var->a_name;
2107
ret->children[0].locals = _slang_variable_scope_new(scope);
2112
slang_print_function(fun, 1);
1926
2119
static GLboolean
1927
2120
_slang_is_vec_mat_type(const char *name)
2268
* Generate for-loop using high-level IR_LOOP instruction.
2469
* Recursively count the number of operations rooted at 'oper'.
2470
* This gives some kind of indication of the size/complexity of an operation.
2473
sizeof_operation(const slang_operation *oper)
2476
GLuint count = 1; /* me */
2478
for (i = 0; i < oper->num_children; i++) {
2479
count += sizeof_operation(&oper->children[i]);
2490
* Determine if a for-loop can be unrolled.
2491
* At this time, only a rather narrow class of for loops can be unrolled.
2492
* See code for details.
2493
* When a loop can't be unrolled because it's too large we'll emit a
2494
* message to the log.
2497
_slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
2501
const char *varName;
2504
assert(oper->type == SLANG_OPER_FOR);
2505
assert(oper->num_children == 4);
2507
/* children[0] must be either "int i=constant" or "i=constant" */
2508
if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
2509
slang_variable *var;
2511
if (oper->children[0].children[0].type != SLANG_OPER_VARIABLE_DECL)
2514
varId = oper->children[0].children[0].a_id;
2516
var = _slang_variable_locate(oper->children[0].children[0].locals,
2520
if (!var->initializer)
2522
if (var->initializer->type != SLANG_OPER_LITERAL_INT)
2524
start = (GLint) var->initializer->literal[0];
2526
else if (oper->children[0].type == SLANG_OPER_EXPRESSION) {
2527
if (oper->children[0].children[0].type != SLANG_OPER_ASSIGN)
2529
if (oper->children[0].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
2531
if (oper->children[0].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
2534
varId = oper->children[0].children[0].children[0].a_id;
2536
start = (GLint) oper->children[0].children[0].children[1].literal[0];
2542
/* children[1] must be "i<constant" */
2543
if (oper->children[1].type != SLANG_OPER_EXPRESSION)
2545
if (oper->children[1].children[0].type != SLANG_OPER_LESS)
2547
if (oper->children[1].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
2549
if (oper->children[1].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
2552
end = (GLint) oper->children[1].children[0].children[1].literal[0];
2554
/* children[2] must be "i++" or "++i" */
2555
if (oper->children[2].type != SLANG_OPER_POSTINCREMENT &&
2556
oper->children[2].type != SLANG_OPER_PREINCREMENT)
2558
if (oper->children[2].children[0].type != SLANG_OPER_IDENTIFIER)
2561
/* make sure the same variable name is used in all places */
2562
if ((oper->children[1].children[0].children[0].a_id != varId) ||
2563
(oper->children[2].children[0].a_id != varId))
2566
varName = (const char *) varId;
2568
/* children[3], the loop body, can't be too large */
2569
bodySize = sizeof_operation(&oper->children[3]);
2570
if (bodySize > MAX_FOR_LOOP_UNROLL_BODY_SIZE) {
2571
slang_info_log_print(A->log,
2572
"Note: 'for (%s ... )' body is too large/complex"
2579
return GL_FALSE; /* degenerate case */
2581
if (end - start > MAX_FOR_LOOP_UNROLL_ITERATIONS) {
2582
slang_info_log_print(A->log,
2583
"Note: 'for (%s=%d; %s<%d; ++%s)' is too"
2584
" many iterations to unroll",
2585
varName, start, varName, end, varName);
2589
if ((end - start) * bodySize > MAX_FOR_LOOP_UNROLL_COMPLEXITY) {
2590
slang_info_log_print(A->log,
2591
"Note: 'for (%s=%d; %s<%d; ++%s)' will generate"
2592
" too much code to unroll",
2593
varName, start, varName, end, varName);
2597
return GL_TRUE; /* we can unroll the loop */
2602
* Unroll a for-loop.
2603
* First we determine the number of iterations to unroll.
2604
* Then for each iteration:
2605
* make a copy of the loop body
2606
* replace instances of the loop variable with the current iteration value
2607
* generate IR code for the body
2608
* \return pointer to generated IR code or NULL if error, out of memory, etc.
2610
static slang_ir_node *
2611
_slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
2613
GLint start, end, iter;
2614
slang_ir_node *n, *root = NULL;
2617
if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
2618
/* for (int i=0; ... */
2619
slang_variable *var;
2621
varId = oper->children[0].children[0].a_id;
2622
var = _slang_variable_locate(oper->children[0].children[0].locals,
2624
start = (GLint) var->initializer->literal[0];
2628
varId = oper->children[0].children[0].children[0].a_id;
2629
start = (GLint) oper->children[0].children[0].children[1].literal[0];
2632
end = (GLint) oper->children[1].children[0].children[1].literal[0];
2634
for (iter = start; iter < end; iter++) {
2635
slang_operation *body;
2637
/* make a copy of the loop body */
2638
body = slang_operation_new(1);
2642
if (!slang_operation_copy(body, &oper->children[3]))
2645
/* in body, replace instances of 'varId' with literal 'iter' */
2647
slang_variable *oldVar;
2648
slang_operation *newOper;
2650
oldVar = _slang_variable_locate(oper->locals, varId, GL_TRUE);
2652
/* undeclared loop variable */
2653
slang_operation_delete(body);
2657
newOper = slang_operation_new(1);
2658
newOper->type = SLANG_OPER_LITERAL_INT;
2659
newOper->literal_size = 1;
2660
newOper->literal[0] = iter;
2662
/* replace instances of the loop variable with newOper */
2663
slang_substitute(A, body, 1, &oldVar, &newOper, GL_FALSE);
2666
/* do IR codegen for body */
2667
n = _slang_gen_operation(A, body);
2668
root = new_seq(root, n);
2670
slang_operation_delete(body);
2678
* Generate IR for a for-loop. Unrolling will be done when possible.
2270
2680
static slang_ir_node *
2271
2681
_slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper)
2274
* init code (child[0])
2276
* BREAK if !expr (child[1])
2277
* body code (child[3])
2279
* incr code (child[2]) // XXX continue here
2281
slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body, *init, *incr;
2283
init = _slang_gen_operation(A, &oper->children[0]);
2284
loop = new_loop(NULL);
2286
/* save old, push new loop */
2287
prevLoop = A->CurLoop;
2290
cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
2291
breakIf = new_break_if_true(A->CurLoop, cond);
2292
body = _slang_gen_operation(A, &oper->children[3]);
2293
incr = _slang_gen_operation(A, &oper->children[2]);
2295
loop->Children[0] = new_seq(breakIf, body);
2296
loop->Children[1] = incr; /* tail code */
2298
/* pop loop, restore prev */
2299
A->CurLoop = prevLoop;
2301
return new_seq(init, loop);
2683
GLboolean unroll = _slang_can_unroll_for_loop(A, oper);
2686
slang_ir_node *code = _slang_unroll_for_loop(A, oper);
2691
/* conventional for-loop code generation */
2694
* init code (child[0])
2696
* BREAK if !expr (child[1])
2697
* body code (child[3])
2699
* incr code (child[2]) // XXX continue here
2701
slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body, *init, *incr;
2702
init = _slang_gen_operation(A, &oper->children[0]);
2703
loop = new_loop(NULL);
2705
/* save old, push new loop */
2706
prevLoop = A->CurLoop;
2709
cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
2710
breakIf = new_break_if_true(A->CurLoop, cond);
2711
body = _slang_gen_operation(A, &oper->children[3]);
2712
incr = _slang_gen_operation(A, &oper->children[2]);
2714
loop->Children[0] = new_seq(breakIf, body);
2715
loop->Children[1] = incr; /* tail code */
2717
/* pop loop, restore prev */
2718
A->CurLoop = prevLoop;
2720
return new_seq(init, loop);
2482
* Generate IR node for allocating/declaring a variable.
2902
* Generate program constants for an array.
2903
* Ex: const vec2[3] v = vec2[3](vec2(1,1), vec2(2,2), vec2(3,3));
2904
* This will allocate and initialize three vector constants, storing
2905
* the array in constant memory, not temporaries like a non-const array.
2906
* This can also be used for uniform array initializers.
2907
* \return GL_TRUE for success, GL_FALSE if failure (semantic error, etc).
2910
make_constant_array(slang_assemble_ctx *A,
2911
slang_variable *var,
2912
slang_operation *initializer)
2914
struct gl_program *prog = A->program;
2915
const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
2916
const char *varName = (char *) var->a_name;
2917
const GLuint numElements = initializer->num_children;
2923
var->store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -6, -6);
2925
size = var->store->Size;
2927
assert(var->type.qualifier == SLANG_QUAL_CONST ||
2928
var->type.qualifier == SLANG_QUAL_UNIFORM);
2929
assert(initializer->type == SLANG_OPER_CALL);
2930
assert(initializer->array_constructor);
2932
values = (GLfloat *) _mesa_malloc(numElements * 4 * sizeof(GLfloat));
2934
/* convert constructor params into ordinary floats */
2935
for (i = 0; i < numElements; i++) {
2936
const slang_operation *op = &initializer->children[i];
2937
if (op->type != SLANG_OPER_LITERAL_FLOAT) {
2938
/* unsupported type for this optimization */
2942
for (j = 0; j < op->literal_size; j++) {
2943
values[i * 4 + j] = op->literal[j];
2945
for ( ; j < 4; j++) {
2946
values[i * 4 + j] = 0.0f;
2950
/* slightly different paths for constants vs. uniforms */
2951
if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
2952
var->store->File = PROGRAM_UNIFORM;
2953
var->store->Index = _mesa_add_uniform(prog->Parameters, varName,
2954
size, datatype, values);
2957
var->store->File = PROGRAM_CONSTANT;
2958
var->store->Index = _mesa_add_named_constant(prog->Parameters, varName,
2961
assert(var->store->Size == size);
2971
* Generate IR node for allocating/declaring a variable (either a local or
2973
* Generally, this involves allocating an slang_ir_storage instance for the
2974
* variable, choosing a register file (temporary, constant, etc).
2975
* For ordinary variables we do not yet allocate storage though. We do that
2976
* when we find the first actual use of the variable to avoid allocating temp
2977
* regs that will never get used.
2978
* At this time, uniforms are always allocated space in this function.
2980
* \param initializer Optional initializer expression for the variable.
2484
2982
static slang_ir_node *
2485
_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
2983
_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var,
2984
slang_operation *initializer)
2986
const char *varName = (const char *) var->a_name;
2987
const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
2988
slang_ir_node *varDecl, *n;
2989
slang_ir_storage *store;
2990
GLint arrayLen, size, totalSize; /* if array then totalSize > size */
2991
enum register_file file;
2489
2993
/*assert(!var->declared);*/
2490
2994
var->declared = GL_TRUE;
2492
n = new_node0(IR_VAR_DECL);
2494
_slang_attach_storage(n, var);
2496
assert(n->Store == var->store);
2498
assert(n->Store->Index < 0);
2500
if (is_sampler_type(&var->type)) {
2501
n->Store->File = PROGRAM_SAMPLER;
2504
n->Store->File = PROGRAM_TEMPORARY;
2507
n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
2509
if (n->Store->Size <= 0) {
2510
slang_info_log_error(A->log, "invalid declaration for '%s'",
2511
(char*) var->a_name);
2996
/* determine GPU register file for simple cases */
2997
if (is_sampler_type(&var->type)) {
2998
file = PROGRAM_SAMPLER;
3000
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
3001
file = PROGRAM_UNIFORM;
3004
file = PROGRAM_TEMPORARY;
3007
totalSize = size = _slang_sizeof_type_specifier(&var->type.specifier);
3009
slang_info_log_error(A->log, "invalid declaration for '%s'", varName);
3013
arrayLen = _slang_array_length(var);
3014
totalSize = _slang_array_size(size, arrayLen);
3016
/* Allocate IR node for the declaration */
3017
varDecl = new_node0(IR_VAR_DECL);
3021
_slang_attach_storage(varDecl, var); /* undefined storage at first */
3023
assert(varDecl->Store == var->store);
3024
assert(varDecl->Store);
3025
assert(varDecl->Store->Index < 0);
3028
assert(store == varDecl->Store);
3031
/* Fill in storage fields which we now know. store->Index/Swizzle may be
3032
* set for some cases below. Otherwise, store->Index/Swizzle will be set
3036
store->Size = totalSize;
3038
/* if there's an initializer, generate IR for the expression */
3040
slang_ir_node *varRef, *init;
3042
if (var->type.qualifier == SLANG_QUAL_CONST) {
3043
/* if the variable is const, the initializer must be a const
3044
* expression as well.
2515
printf("%s var %p %s store=%p index=%d size=%d\n",
2516
__FUNCTION__, (void *) var, (char *) var->a_name,
2517
(void *) n->Store, n->Store->Index, n->Store->Size);
2520
if (var->array_len > 0) {
2521
/* this is an array */
2522
/* cannot be const-qualified */
2523
if (var->type.qualifier == SLANG_QUAL_CONST) {
2524
slang_info_log_error(A->log, "array '%s' cannot be const",
2525
(char*) var->a_name);
3047
if (!_slang_is_constant_expr(initializer)) {
3048
slang_info_log_error(A->log,
3049
"initializer for %s not constant", varName);
2529
/* round up element size to mult of 4 */
2530
GLint sz = (n->Store->Size + 3) & ~3;
2531
/* mult by array size */
2532
sz *= var->array_len;
2533
n->Store->Size = sz;
2537
assert(n->Store->Size > 0);
2539
/* setup default swizzle for storing the variable */
2540
switch (n->Store->Size) {
2542
n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
2543
SWIZZLE_NIL, SWIZZLE_NIL);
2546
n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
2547
SWIZZLE_Z, SWIZZLE_NIL);
2550
/* Note that float-sized vars may be allocated in any x/y/z/w
2551
* slot, but that won't be determined until code emit time.
2553
n->Store->Swizzle = SWIZZLE_NOOP;
3055
/* IR for the variable we're initializing */
3056
varRef = new_var(A, var);
3058
slang_info_log_error(A->log, "out of memory");
3062
/* constant-folding, etc here */
3063
_slang_simplify(initializer, &A->space, A->atoms);
3065
/* look for simple constant-valued variables and uniforms */
3066
if (var->type.qualifier == SLANG_QUAL_CONST ||
3067
var->type.qualifier == SLANG_QUAL_UNIFORM) {
3069
if (initializer->type == SLANG_OPER_CALL &&
3070
initializer->array_constructor) {
3071
/* array initializer */
3072
if (make_constant_array(A, var, initializer))
3075
else if (initializer->type == SLANG_OPER_LITERAL_FLOAT ||
3076
initializer->type == SLANG_OPER_LITERAL_INT) {
3077
/* simple float/vector initializer */
3078
if (store->File == PROGRAM_UNIFORM) {
3079
store->Index = _mesa_add_uniform(A->program->Parameters,
3081
totalSize, datatype,
3082
initializer->literal);
3083
store->Swizzle = _slang_var_swizzle(size, 0);
3088
store->File = PROGRAM_CONSTANT;
3089
store->Index = _mesa_add_named_constant(A->program->Parameters,
3091
initializer->literal,
3093
store->Swizzle = _slang_var_swizzle(size, 0);
3100
/* IR for initializer */
3101
init = _slang_gen_operation(A, initializer);
3105
/* XXX remove this when type checking is added above */
3106
if (init->Store && init->Store->Size != totalSize) {
3107
slang_info_log_error(A->log, "invalid assignment (wrong types)");
3111
/* assign RHS to LHS */
3112
n = new_node2(IR_COPY, varRef, init);
3113
n = new_seq(varDecl, n);
3116
/* no initializer */
3120
if (store->File == PROGRAM_UNIFORM && store->Index < 0) {
3121
/* always need to allocate storage for uniforms at this point */
3122
store->Index = _mesa_add_uniform(A->program->Parameters, varName,
3123
totalSize, datatype, NULL);
3124
store->Swizzle = _slang_var_swizzle(size, 0);
3128
printf("%s var %p %s store=%p index=%d size=%d\n",
3129
__FUNCTION__, (void *) var, (char *) varName,
3130
(void *) store, store->Index, store->Size);
2883
varDecl = _slang_gen_var_decl(A, v);
2887
3462
/* check if the var has an initializer */
2888
3463
if (oper->num_children > 0) {
2889
3464
assert(oper->num_children == 1);
2890
3465
initializer = &oper->children[0];
2892
else if (v->initializer) {
2893
initializer = v->initializer;
3467
else if (var->initializer) {
3468
initializer = var->initializer;
2896
3471
initializer = NULL;
2899
if (v->type.qualifier == SLANG_QUAL_CONST && !initializer) {
2900
slang_info_log_error(A->log,
2901
"const-qualified variable '%s' requires initializer",
2907
3474
if (initializer) {
2908
slang_ir_node *var, *init;
2910
/* type check/compare var and initializer */
3475
/* check/compare var type and initializer type */
2911
3476
if (!_slang_assignment_compatible(A, oper, initializer)) {
2912
3477
slang_info_log_error(A->log, "incompatible types in assignment");
2916
var = new_var(A, oper, oper->a_id);
2918
slang_info_log_error(A->log, "undefined variable '%s'", varName);
2922
if (v->type.qualifier == SLANG_QUAL_CONST) {
2923
/* if the variable is const, the initializer must be a const
2924
* expression as well.
2927
if (!_slang_is_constant_expr(initializer)) {
2928
slang_info_log_error(A->log,
2929
"initializer for %s not constant", varName);
2935
_slang_simplify(initializer, &A->space, A->atoms);
2937
init = _slang_gen_operation(A, initializer);
2941
/*assert(init->Store);*/
2943
/* XXX remove this when type checking is added above */
2944
if (init->Store && var->Store->Size != init->Store->Size) {
2945
slang_info_log_error(A->log, "invalid assignment (wrong types)");
2949
n = new_node2(IR_COPY, var, init);
2950
n = new_seq(varDecl, n);
3482
if (var->type.qualifier == SLANG_QUAL_CONST) {
3483
slang_info_log_error(A->log,
3484
"const-qualified variable '%s' requires initializer",
3490
/* Generate IR node */
3491
varDecl = _slang_gen_var_decl(A, var, initializer);
2961
* Generate IR tree for a variable (such as in an expression).
3500
* Generate IR tree for a reference to a variable (such as in an expression).
3501
* This is different from a variable declaration.
2963
3503
static slang_ir_node *
2964
3504
_slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper)
3728
4298
#if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */
3729
4299
/* disallow rect samplers */
3730
if (var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECT ||
3731
var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECTSHADOW) {
4300
if (is_rect_sampler_spec(&var->type.specifier)) {
3732
4301
slang_info_log_error(A->log, "invalid sampler type for '%s'", varName);
3733
4302
return GL_FALSE;
4305
(void) is_rect_sampler_spec; /* silence warning */
3737
4308
GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
3738
store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
4309
store = _slang_new_ir_storage_sampler(sampNum, texIndex, totalSize);
4311
/* If we have a sampler array, then we need to allocate the
4312
* additional samplers to ensure we don't allocate them elsewhere.
4313
* We can't directly use _mesa_add_sampler() as that checks the
4314
* varName and gets a match, so we call _mesa_add_parameter()
4315
* directly and use the last sampler number from the call above.
4318
GLint a = arrayLen - 1;
4320
for (i = 0; i < a; i++) {
4321
GLfloat value = (GLfloat)(i + sampNum + 1);
4322
(void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER,
4323
varName, 1, datatype, &value, NULL, 0x0);
3740
4327
if (dbg) printf("SAMPLER ");
3742
4329
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
3743
4330
/* Uniform variable */
3744
const GLint totalSize = array_size(size, var->array_len);
3745
4331
const GLuint swizzle = _slang_var_swizzle(totalSize, 0);