Merge commit 'origin/master' into gallium-0.2

This commit is contained in:
Alan Hourihane 2008-11-20 13:44:13 +00:00
commit ef2bf418b4
13 changed files with 696 additions and 364 deletions

View file

@ -186,7 +186,7 @@ void intel_flush_prim(struct intel_context *intel)
OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
S0_VB_ENABLE_830);
/* S1
/* S2
* This is somewhat unfortunate -- VB width is tied up with
* vertex format data that we've already uploaded through
* _3DSTATE_VFT[01]_CMD. We may want to replace emits of VFT state with

View file

@ -308,6 +308,15 @@ decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)
case 0x10:
instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n");
return 1;
case 0x01:
instr_out(data, hw_offset, 0, "3DSTATE_MAP_COORD_SET_I830\n");
return 1;
case 0x0a:
instr_out(data, hw_offset, 0, "3DSTATE_MAP_CUBE_I830\n");
return 1;
case 0x05:
instr_out(data, hw_offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n");
return 1;
}
instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
@ -316,33 +325,39 @@ decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)
}
static int
decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830)
{
unsigned int len, i, c, opcode, word, map, sampler, instr;
struct {
uint32_t opcode;
int i830_only;
int min_len;
int max_len;
char *name;
} opcodes_3d_1d[] = {
{ 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" },
{ 0x86, 4, 4, "3DSTATE_CHROMA_KEY" },
{ 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" },
{ 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
{ 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
{ 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
{ 0x98, 2, 2, "3DSTATE_DEFAULT_Z" },
{ 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
{ 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },
{ 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" },
{ 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" },
{ 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
{ 0x9e, 4, 4, "3DSTATE_MONO_FILTER" },
{ 0x89, 4, 4, "3DSTATE_FOG_MODE" },
{ 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
{ 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" },
{ 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" },
{ 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
{ 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" },
{ 0x9c, 0, 1, 1, "3DSTATE_CLEAR_PARAMETERS" },
{ 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
{ 0x99, 0, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
{ 0x9a, 0, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
{ 0x98, 0, 2, 2, "3DSTATE_DEFAULT_Z" },
{ 0x97, 0, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
{ 0x85, 0, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },
{ 0x80, 0, 5, 5, "3DSTATE_DRAWING_RECTANGLE" },
{ 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
{ 0x9d, 0, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
{ 0x9e, 0, 4, 4, "3DSTATE_MONO_FILTER" },
{ 0x89, 0, 4, 4, "3DSTATE_FOG_MODE" },
{ 0x8f, 0, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
{ 0x81, 0, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" },
{ 0x83, 0, 2, 2, "3DSTATE_SPAN_STIPPLE" },
{ 0x8c, 1, 2, 2, "3DSTATE_MAP_COORD_TRANSFORM_I830" },
{ 0x8b, 1, 2, 2, "3DSTATE_MAP_VERTEX_TRANSFORM_I830" },
{ 0x8d, 1, 3, 3, "3DSTATE_W_STATE_I830" },
{ 0x01, 1, 2, 2, "3DSTATE_COLOR_FACTOR_I830" },
{ 0x02, 1, 2, 2, "3DSTATE_MAP_COORD_SETBIND_I830" },
};
switch ((data[0] & 0x00ff0000) >> 16) {
@ -488,6 +503,8 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
}
return len;
case 0x01:
if (i830)
break;
instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n");
len = (data[0] & 0x0000003f) + 2;
i = 1;
@ -513,6 +530,9 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]);
opcode++)
{
if (opcodes_3d_1d[opcode].i830_only && !i830)
continue;
if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) {
len = 1;
@ -756,7 +776,7 @@ decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
case 0x1f:
return decode_3d_primitive(data, count, hw_offset, failures);
case 0x1d:
return decode_3d_1d(data, count, hw_offset, failures);
return decode_3d_1d(data, count, hw_offset, failures, 0);
case 0x1c:
return decode_3d_1c(data, count, hw_offset, failures);
}
@ -999,6 +1019,73 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
return 1;
}
static int
decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)
{
unsigned int opcode;
struct {
uint32_t opcode;
int min_len;
int max_len;
char *name;
} opcodes_3d[] = {
{ 0x02, 1, 1, "3DSTATE_MODES_3" },
{ 0x03, 1, 1, "3DSTATE_ENABLES_1"},
{ 0x04, 1, 1, "3DSTATE_ENABLES_2"},
{ 0x05, 1, 1, "3DSTATE_VFT0"},
{ 0x06, 1, 1, "3DSTATE_AA"},
{ 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
{ 0x08, 1, 1, "3DSTATE_MODES_1" },
{ 0x09, 1, 1, "3DSTATE_STENCIL_TEST" },
{ 0x0a, 1, 1, "3DSTATE_VFT1"},
{ 0x0b, 1, 1, "3DSTATE_INDPT_ALPHA_BLEND" },
{ 0x0c, 1, 1, "3DSTATE_MODES_5" },
{ 0x0d, 1, 1, "3DSTATE_MAP_BLEND_OP" },
{ 0x0e, 1, 1, "3DSTATE_MAP_BLEND_ARG" },
{ 0x0f, 1, 1, "3DSTATE_MODES_2" },
{ 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
{ 0x16, 1, 1, "3DSTATE_MODES_4" },
};
switch ((data[0] & 0x1f000000) >> 24) {
case 0x1f:
return decode_3d_primitive(data, count, hw_offset, failures);
case 0x1d:
return decode_3d_1d(data, count, hw_offset, failures, 1);
case 0x1c:
return decode_3d_1c(data, count, hw_offset, failures);
}
for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
opcode++) {
if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
unsigned int len = 1, i;
instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
if (opcodes_3d[opcode].max_len > 1) {
len = (data[0] & 0xff) + 2;
if (len < opcodes_3d[opcode].min_len ||
len > opcodes_3d[opcode].max_len)
{
fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
}
}
for (i = 1; i < len; i++) {
if (i >= count)
BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
instr_out(data, hw_offset, i, "dword %d\n", i);
}
return len;
}
}
instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
(*failures)++;
return 1;
}
/**
* Decodes an i830-i915 batch buffer, writing the output to stdout.
*
@ -1028,9 +1115,12 @@ intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid)
if (IS_965(devid)) {
index += decode_3d_965(data + index, count - index,
hw_offset + index * 4, &failures);
} else {
} else if (IS_9XX(devid)) {
index += decode_3d(data + index, count - index,
hw_offset + index * 4, &failures);
} else {
index += decode_3d_i830(data + index, count - index,
hw_offset + index * 4, &failures);
}
break;
default:

View file

@ -80,7 +80,7 @@
*/
#define S0_VB_OFFSET_MASK_830 0xffffff8
#define S0_VB_PITCH_SHIFT_830 1
#define S0_VB_ENABLE_830 0
#define S0_VB_ENABLE_830 (1<<0)
/** @} */
#define S1_VERTEX_WIDTH_SHIFT 24
@ -100,8 +100,8 @@
#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4))
#define S2_TEXCOORD_NONE (~0)
#define S2_TEX_COUNT_SHIFT_830 12
#define S2_VERTEX_0_WIDTH_SHIFT_830 0
#define S2_VERTEX_1_WIDTH_SHIFT_830 6
#define S2_VERTEX_1_WIDTH_SHIFT_830 0
#define S2_VERTEX_0_WIDTH_SHIFT_830 6
/* S3 not interesting */
#define S4_POINT_WIDTH_SHIFT 23

View file

@ -1689,7 +1689,7 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
/* compute luminance values */
if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
if (transferOps & IMAGE_CLAMP_BIT) {
for (i = 0; i < n; i++) {
GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
luminance[i] = CLAMP(sum, 0.0F, 1.0F);

View file

@ -297,10 +297,13 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
for (i=0;i<MAX_TEXTURE_UNITS;i++) {
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
GLenum format;
if (!texUnit->_ReallyEnabled || !texUnit->Enabled)
continue;
format = texUnit->_Current->Image[0][texUnit->_Current->BaseLevel]->_BaseFormat;
key->unit[i].enabled = 1;
key->enabled_units |= (1<<i);
key->nr_enabled_units = i+1;
@ -308,7 +311,9 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
key->unit[i].source_index =
translate_tex_src_bit(texUnit->_ReallyEnabled);
key->unit[i].shadow = texUnit->_Current->CompareMode == GL_COMPARE_R_TO_TEXTURE;
key->unit[i].shadow = ((texUnit->_Current->CompareMode == GL_COMPARE_R_TO_TEXTURE) &&
((format == GL_DEPTH_COMPONENT) ||
(format == GL_DEPTH_STENCIL_EXT)));
key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB;
key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA;

View file

@ -3719,6 +3719,14 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
/* general case: convert row to RGBA format */
GLfloat rgba[MAX_WIDTH][4];
GLint col;
GLbitfield transferOps = 0x0;
if (type == GL_FLOAT &&
((ctx->Color.ClampReadColor == GL_TRUE) ||
(ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
texImage->TexFormat->DataType != GL_FLOAT)))
transferOps |= IMAGE_CLAMP_BIT;
for (col = 0; col < width; col++) {
(*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
if (texImage->TexFormat->BaseFormat == GL_ALPHA) {
@ -3743,7 +3751,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
}
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
format, type, dest,
&ctx->Pack, 0x0 /*image xfer ops*/);
&ctx->Pack, transferOps /*image xfer ops*/);
} /* format */
} /* row */
} /* img */

View file

@ -837,10 +837,8 @@ parameter_type_specifier_3
* <init_declarator_list> ::= <single_declaration>
* | <init_declarator_list> "," <identifier>
* | <init_declarator_list> "," <identifier> "[" "]"
* | <init_declarator_list> "," <identifier> "["
* <constant_expression> "]"
* | <init_declarator_list> "," <identifier> "="
* <initializer>
* | <init_declarator_list> "," <identifier> "[" <constant_expression> "]"
* | <init_declarator_list> "," <identifier> "=" <initializer>
*/
init_declarator_list
single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and
@ -860,10 +858,9 @@ init_declarator_list_5
* <single_declaration> ::= <fully_specified_type>
* | <fully_specified_type> <identifier>
* | <fully_specified_type> <identifier> "[" "]"
* | <fully_specified_type> <identifier> "["
* <constant_expression> "]"
* | <fully_specified_type> <identifier> "[" <constant_expression> "]"
* | <fully_specified_type> <identifier> "=" <initializer>
*/
*/
single_declaration
single_declaration_nospace .or single_declaration_space;
single_declaration_space
@ -924,12 +921,12 @@ centroid_qualifier
/*
* <type_qualifier> ::= "const"
* | "attribute" // Vertex only.
* | "varying"
* | "uniform"
* | "__fixed_output"
* | "__fixed_input"
* <type_qualifier> ::= "const"
* | "attribute" // Vertex only.
* | "varying"
* | "uniform"
* | "__fixed_output"
* | "__fixed_input"
*
* note: this is an extension to the standard language specification,
* normally slang disallows __fixed_output and __fixed_input type qualifiers
@ -1013,7 +1010,7 @@ type_specifier_nospace
/*
* <struct_specifier> ::= "struct" <identifier> "{" <struct_declaration_list> "}"
* | "struct" "{" <struct_declaration_list> "}"
* | "struct" "{" <struct_declaration_list> "}"
*/
struct_specifier
"struct" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and
@ -1025,7 +1022,7 @@ struct_specifier_2
/*
* <struct_declaration_list> ::= <struct_declaration>
* | <struct_declaration_list> <struct_declaration>
* | <struct_declaration_list> <struct_declaration>
*/
struct_declaration_list
struct_declaration .and .loop struct_declaration .emit FIELD_NEXT;
@ -1042,7 +1039,7 @@ struct_declaration_nospace
/*
* <struct_declarator_list> ::= <struct_declarator>
* | <struct_declarator_list> "," <struct_declarator>
* | <struct_declarator_list> "," <struct_declarator>
*/
struct_declarator_list
struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT;

View file

@ -1477,6 +1477,8 @@ _slang_simple_writemask(GLuint writemask, GLuint swizzle)
* Convert the given swizzle into a writemask. In some cases this
* is trivial, in other cases, we'll need to also swizzle the right
* hand side to put components in the right places.
* See comment above for more info.
* XXX this function could be simplified and should probably be renamed.
* \param swizzle the incoming swizzle
* \param writemaskOut returns the writemask
* \param swizzleOut swizzle to apply to the right-hand-side
@ -3114,7 +3116,7 @@ _slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
/* oper->a_id is the field name */
slang_ir_node *base, *n;
slang_typeinfo field_ti;
GLint fieldSize, fieldOffset = -1, swz;
GLint fieldSize, fieldOffset = -1;
/* type of field */
slang_typeinfo_construct(&field_ti);
@ -3147,22 +3149,12 @@ _slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
if (!n)
return NULL;
/* setup the storage info for this node */
swz = fieldOffset % 4;
n->Field = (char *) oper->a_id;
n->Store = _slang_new_ir_storage_relative(fieldOffset / 4,
fieldSize,
base->Store);
if (fieldSize == 1)
n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
else if (fieldSize == 2)
n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_NIL, SWIZZLE_NIL);
else if (fieldSize == 3)
n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_NIL);
/* Store the field's offset in storage->Index */
n->Store = _slang_new_ir_storage(base->Store->File,
fieldOffset,
fieldSize);
return n;
}
@ -3255,12 +3247,12 @@ _slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper)
}
elem = new_node2(IR_ELEMENT, array, index);
elem->Store = _slang_new_ir_storage_relative(constIndex,
elemSize,
array->Store);
assert(elem->Store->Parent);
/* XXX try to do some array bounds checking here */
/* The storage info here will be updated during code emit */
elem->Store = _slang_new_ir_storage(array->Store->File,
array->Store->Index,
elemSize);
return elem;
}
else {

View file

@ -167,6 +167,16 @@ typedef struct slang_output_ctx_
/* _slang_compile() */
/* Debugging aid, print file/line where parsing error is detected */
#define RETURN0 \
do { \
if (0) \
printf("slang error at %s:%d\n", __FILE__, __LINE__); \
return 0; \
} while (0)
static void
parse_identifier_str(slang_parse_ctx * C, char **id)
{
@ -223,7 +233,7 @@ parse_float(slang_parse_ctx * C, float *number)
_mesa_strlen(exponent) + 3) * sizeof(char));
if (whole == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
slang_string_copy(whole, integral);
@ -247,7 +257,7 @@ check_revision(slang_parse_ctx * C)
{
if (*C->I != REVISION) {
slang_info_log_error(C->L, "Internal compiler error.");
return 0;
RETURN0;
}
C->I++;
return 1;
@ -387,23 +397,23 @@ parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
o.structs = st->structs;
if (!parse_type_specifier(C, &o, sp))
return 0;
RETURN0;
do {
slang_atom a_name;
slang_variable *var = slang_variable_scope_grow(st->fields);
if (!var) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
a_name = parse_identifier(C);
if (_slang_locate_variable(st->fields, a_name, GL_FALSE)) {
slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);
return 0;
RETURN0;
}
if (!parse_struct_field_var(C, &o, var, a_name, sp))
return 0;
RETURN0;
}
while (*C->I++ != FIELD_NONE);
@ -419,26 +429,26 @@ parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
/* parse struct name (if any) and make sure it is unique in current scope */
a_name = parse_identifier(C);
if (a_name == SLANG_ATOM_NULL)
return 0;
RETURN0;
name = slang_atom_pool_id(C->atoms, a_name);
if (name[0] != '\0'
&& slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
slang_info_log_error(C->L, "%s: duplicate type name.", name);
return 0;
RETURN0;
}
/* set-up a new struct */
*st = (slang_struct *) _slang_alloc(sizeof(slang_struct));
if (*st == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
if (!slang_struct_construct(*st)) {
_slang_free(*st);
*st = NULL;
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
(**st).a_name = a_name;
(**st).structs->outer_scope = O->structs;
@ -450,7 +460,7 @@ parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
slang_type_specifier_ctr(&sp);
if (!parse_struct_field(C, O, *st, &sp)) {
slang_type_specifier_dtr(&sp);
return 0;
RETURN0;
}
slang_type_specifier_dtr(&sp);
}
@ -468,14 +478,14 @@ parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
* sizeof(slang_struct));
if (O->structs->structs == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
s = &O->structs->structs[O->structs->num_structs];
if (!slang_struct_construct(s))
return 0;
RETURN0;
O->structs->num_structs++;
if (!slang_struct_copy(s, *st))
return 0;
RETURN0;
}
return 1;
@ -498,7 +508,7 @@ parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant)
*variant = SLANG_INVARIANT;
return 1;
default:
return 0;
RETURN0;
}
}
@ -519,7 +529,7 @@ parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid)
*centroid = SLANG_CENTROID;
return 1;
default:
return 0;
RETURN0;
}
}
@ -560,7 +570,7 @@ parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
*qual = SLANG_QUAL_FIXEDINPUT;
break;
default:
return 0;
RETURN0;
}
return 1;
}
@ -698,7 +708,7 @@ parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
case TYPE_SPECIFIER_STRUCT:
spec->type = SLANG_SPEC_STRUCT;
if (!parse_struct(C, O, &spec->_struct))
return 0;
RETURN0;
break;
case TYPE_SPECIFIER_TYPENAME:
spec->type = SLANG_SPEC_STRUCT;
@ -708,31 +718,31 @@ parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
a_name = parse_identifier(C);
if (a_name == NULL)
return 0;
RETURN0;
stru = slang_struct_scope_find(O->structs, a_name, 1);
if (stru == NULL) {
slang_info_log_error(C->L, "undeclared type name '%s'",
slang_atom_pool_id(C->atoms, a_name));
return 0;
RETURN0;
}
spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
if (spec->_struct == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
if (!slang_struct_construct(spec->_struct)) {
_slang_free(spec->_struct);
spec->_struct = NULL;
return 0;
RETURN0;
}
if (!slang_struct_copy(spec->_struct, stru))
return 0;
RETURN0;
}
break;
default:
return 0;
RETURN0;
}
return 1;
}
@ -762,7 +772,7 @@ parse_type_precision(slang_parse_ctx *C,
*precision = SLANG_PREC_HIGH;
return 1;
default:
return 0;
RETURN0;
}
}
@ -771,36 +781,36 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
slang_fully_specified_type * type)
{
if (!parse_type_variant(C, &type->variant))
return 0;
RETURN0;
if (!parse_type_centroid(C, &type->centroid))
return 0;
RETURN0;
if (!parse_type_qualifier(C, &type->qualifier))
return 0;
RETURN0;
if (!parse_type_precision(C, &type->precision))
return 0;
RETURN0;
if (!parse_type_specifier(C, O, &type->specifier))
return 0;
RETURN0;
if (!O->allow_invariant && type->variant == SLANG_INVARIANT) {
slang_info_log_error(C->L,
"'invariant' keyword not allowed (perhaps set #version 120)");
return 0;
RETURN0;
}
if (!O->allow_centroid && type->centroid == SLANG_CENTROID) {
slang_info_log_error(C->L,
"'centroid' keyword not allowed (perhaps set #version 120)");
return 0;
RETURN0;
}
else if (type->centroid == SLANG_CENTROID &&
type->qualifier != SLANG_QUAL_VARYING) {
slang_info_log_error(C->L,
"'centroid' keyword only allowed for varying vars");
return 0;
RETURN0;
}
@ -809,7 +819,7 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
type->variant == SLANG_INVARIANT) {
slang_info_log_error(C->L,
"invariant qualifer only allowed for varying vars");
return 0;
RETURN0;
}
*/
@ -824,7 +834,7 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
/* only default is allowed */
if (type->precision != SLANG_PREC_DEFAULT) {
slang_info_log_error(C->L, "precision qualifiers not allowed");
return 0;
RETURN0;
}
}
@ -935,7 +945,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
while (*C->I != OP_END)
if (!parse_child_operation(C, O, oper, 1))
return 0;
RETURN0;
C->I++;
break;
case OP_BLOCK_BEGIN_NEW_SCOPE:
@ -947,7 +957,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
o.vars = oper->locals;
while (*C->I != OP_END)
if (!parse_child_operation(C, &o, oper, 1))
return 0;
RETURN0;
C->I++;
}
break;
@ -963,7 +973,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
* than one declarators
*/
if (!parse_declaration(C, O))
return 0;
RETURN0;
if (first_var < O->vars->num_variables) {
const unsigned int num_vars = O->vars->num_variables - first_var;
unsigned int i;
@ -972,7 +982,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
oper->children = slang_operation_new(num_vars);
if (oper->children == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
for (i = first_var; i < O->vars->num_variables; i++) {
slang_operation *o = &oper->children[i - first_var];
@ -983,7 +993,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
if (!legal_identifier(o->a_id)) {
slang_info_log_error(C->L, "illegal variable name '%s'",
(char *) o->a_id);
return 0;
RETURN0;
}
}
}
@ -996,10 +1006,10 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
oper->type = SLANG_OPER_ASM;
oper->a_id = parse_identifier(C);
if (oper->a_id == SLANG_ATOM_NULL)
return 0;
RETURN0;
while (*C->I != OP_END) {
if (!parse_child_operation(C, O, oper, 0))
return 0;
RETURN0;
}
C->I++;
break;
@ -1015,21 +1025,21 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
case OP_RETURN:
oper->type = SLANG_OPER_RETURN;
if (!parse_child_operation(C, O, oper, 0))
return 0;
RETURN0;
break;
case OP_EXPRESSION:
oper->type = SLANG_OPER_EXPRESSION;
if (!parse_child_operation(C, O, oper, 0))
return 0;
RETURN0;
break;
case OP_IF:
oper->type = SLANG_OPER_IF;
if (!parse_child_operation(C, O, oper, 0))
return 0;
RETURN0;
if (!parse_child_operation(C, O, oper, 1))
return 0;
RETURN0;
if (!parse_child_operation(C, O, oper, 1))
return 0;
RETURN0;
break;
case OP_WHILE:
{
@ -1038,17 +1048,17 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
oper->type = SLANG_OPER_WHILE;
o.vars = oper->locals;
if (!parse_child_operation(C, &o, oper, 1))
return 0;
RETURN0;
if (!parse_child_operation(C, &o, oper, 1))
return 0;
RETURN0;
}
break;
case OP_DO:
oper->type = SLANG_OPER_DO;
if (!parse_child_operation(C, O, oper, 1))
return 0;
RETURN0;
if (!parse_child_operation(C, O, oper, 0))
return 0;
RETURN0;
break;
case OP_FOR:
{
@ -1057,13 +1067,13 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
oper->type = SLANG_OPER_FOR;
o.vars = oper->locals;
if (!parse_child_operation(C, &o, oper, 1))
return 0;
RETURN0;
if (!parse_child_operation(C, &o, oper, 1))
return 0;
RETURN0;
if (!parse_child_operation(C, &o, oper, 0))
return 0;
RETURN0;
if (!parse_child_operation(C, &o, oper, 1))
return 0;
RETURN0;
}
break;
case OP_PRECISION:
@ -1077,7 +1087,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
}
break;
default:
return 0;
RETURN0;
}
return 1;
}
@ -1092,7 +1102,7 @@ handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
op->children = slang_operation_new(n);
if (op->children == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
op->num_children = n;
@ -1110,7 +1120,7 @@ handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
*total_ops * sizeof(slang_operation));
if (*ops == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
return 1;
}
@ -1143,12 +1153,12 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
(num_ops + 1) * sizeof(slang_operation));
if (ops == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
op = &ops[num_ops];
if (!slang_operation_construct(op)) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
num_ops++;
op->locals->outer_scope = O->vars;
@ -1160,7 +1170,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
case OP_PUSH_BOOL:
op->type = SLANG_OPER_LITERAL_BOOL;
if (!parse_number(C, &number))
return 0;
RETURN0;
op->literal[0] =
op->literal[1] =
op->literal[2] =
@ -1170,7 +1180,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
case OP_PUSH_INT:
op->type = SLANG_OPER_LITERAL_INT;
if (!parse_number(C, &number))
return 0;
RETURN0;
op->literal[0] =
op->literal[1] =
op->literal[2] =
@ -1180,7 +1190,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
case OP_PUSH_FLOAT:
op->type = SLANG_OPER_LITERAL_FLOAT;
if (!parse_float(C, &op->literal[0]))
return 0;
RETURN0;
op->literal[1] =
op->literal[2] =
op->literal[3] = op->literal[0];
@ -1190,37 +1200,37 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
op->type = SLANG_OPER_IDENTIFIER;
op->a_id = parse_identifier(C);
if (op->a_id == SLANG_ATOM_NULL)
return 0;
RETURN0;
break;
case OP_SEQUENCE:
op->type = SLANG_OPER_SEQUENCE;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_ASSIGN:
op->type = SLANG_OPER_ASSIGN;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_ADDASSIGN:
op->type = SLANG_OPER_ADDASSIGN;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_SUBASSIGN:
op->type = SLANG_OPER_SUBASSIGN;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_MULASSIGN:
op->type = SLANG_OPER_MULASSIGN;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_DIVASSIGN:
op->type = SLANG_OPER_DIVASSIGN;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
/*case OP_MODASSIGN: */
/*case OP_LSHASSIGN: */
@ -1231,22 +1241,22 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
case OP_SELECT:
op->type = SLANG_OPER_SELECT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
return 0;
RETURN0;
break;
case OP_LOGICALOR:
op->type = SLANG_OPER_LOGICALOR;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_LOGICALXOR:
op->type = SLANG_OPER_LOGICALXOR;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_LOGICALAND:
op->type = SLANG_OPER_LOGICALAND;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
/*case OP_BITOR: */
/*case OP_BITXOR: */
@ -1254,95 +1264,95 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
case OP_EQUAL:
op->type = SLANG_OPER_EQUAL;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_NOTEQUAL:
op->type = SLANG_OPER_NOTEQUAL;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_LESS:
op->type = SLANG_OPER_LESS;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_GREATER:
op->type = SLANG_OPER_GREATER;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_LESSEQUAL:
op->type = SLANG_OPER_LESSEQUAL;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_GREATEREQUAL:
op->type = SLANG_OPER_GREATEREQUAL;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
/*case OP_LSHIFT: */
/*case OP_RSHIFT: */
case OP_ADD:
op->type = SLANG_OPER_ADD;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_SUBTRACT:
op->type = SLANG_OPER_SUBTRACT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_MULTIPLY:
op->type = SLANG_OPER_MULTIPLY;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_DIVIDE:
op->type = SLANG_OPER_DIVIDE;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
/*case OP_MODULUS: */
case OP_PREINCREMENT:
op->type = SLANG_OPER_PREINCREMENT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
case OP_PREDECREMENT:
op->type = SLANG_OPER_PREDECREMENT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
case OP_PLUS:
op->type = SLANG_OPER_PLUS;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
case OP_MINUS:
op->type = SLANG_OPER_MINUS;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
case OP_NOT:
op->type = SLANG_OPER_NOT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
/*case OP_COMPLEMENT: */
case OP_SUBSCRIPT:
op->type = SLANG_OPER_SUBSCRIPT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
return 0;
RETURN0;
break;
case OP_CALL:
op->type = SLANG_OPER_CALL;
op->a_id = parse_identifier(C);
if (op->a_id == SLANG_ATOM_NULL)
return 0;
RETURN0;
while (*C->I != OP_END)
if (!parse_child_operation(C, O, op, 0))
return 0;
RETURN0;
C->I++;
if (!C->parsing_builtin
@ -1352,7 +1362,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
id = slang_atom_pool_id(C->atoms, op->a_id);
if (!is_constructor_name(id, op->a_id, O->structs)) {
slang_info_log_error(C->L, "%s: undeclared function name.", id);
return 0;
RETURN0;
}
}
break;
@ -1360,22 +1370,22 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
op->type = SLANG_OPER_FIELD;
op->a_id = parse_identifier(C);
if (op->a_id == SLANG_ATOM_NULL)
return 0;
RETURN0;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
case OP_POSTINCREMENT:
op->type = SLANG_OPER_POSTINCREMENT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
case OP_POSTDECREMENT:
op->type = SLANG_OPER_POSTDECREMENT;
if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
return 0;
RETURN0;
break;
default:
return 0;
RETURN0;
}
}
C->I++;
@ -1406,7 +1416,7 @@ parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
* two at most) because not all combinations are valid
*/
if (!parse_type_qualifier(C, &param->type.qualifier))
return 0;
RETURN0;
param_qual = *C->I++;
switch (param_qual) {
@ -1414,7 +1424,7 @@ parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
if (param->type.qualifier != SLANG_QUAL_CONST
&& param->type.qualifier != SLANG_QUAL_NONE) {
slang_info_log_error(C->L, "Invalid type qualifier.");
return 0;
RETURN0;
}
break;
case PARAM_QUALIFIER_OUT:
@ -1422,7 +1432,7 @@ parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
param->type.qualifier = SLANG_QUAL_OUT;
else {
slang_info_log_error(C->L, "Invalid type qualifier.");
return 0;
RETURN0;
}
break;
case PARAM_QUALIFIER_INOUT:
@ -1430,11 +1440,11 @@ parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
param->type.qualifier = SLANG_QUAL_INOUT;
else {
slang_info_log_error(C->L, "Invalid type qualifier.");
return 0;
RETURN0;
}
break;
default:
return 0;
RETURN0;
}
/* parse precision qualifier (lowp, mediump, highp */
@ -1444,10 +1454,10 @@ parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
/* parse parameter's type specifier and name */
if (!parse_type_specifier(C, O, &param->type.specifier))
return 0;
RETURN0;
param->a_name = parse_identifier(C);
if (param->a_name == SLANG_ATOM_NULL)
return 0;
RETURN0;
/* if the parameter is an array, parse its size (the size must be
* explicitly defined
@ -1564,13 +1574,13 @@ parse_operator_name(slang_parse_ctx * C)
slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
if (atom == SLANG_ATOM_NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
C->I++;
return atom;
}
}
return 0;
RETURN0;
}
@ -1581,7 +1591,7 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
GLuint functype;
/* parse function type and name */
if (!parse_fully_specified_type(C, O, &func->header.type))
return 0;
RETURN0;
functype = *C->I++;
switch (functype) {
@ -1589,35 +1599,35 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
func->kind = SLANG_FUNC_ORDINARY;
func->header.a_name = parse_identifier(C);
if (func->header.a_name == SLANG_ATOM_NULL)
return 0;
RETURN0;
break;
case FUNCTION_CONSTRUCTOR:
func->kind = SLANG_FUNC_CONSTRUCTOR;
if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)
return 0;
RETURN0;
func->header.a_name =
slang_atom_pool_atom(C->atoms,
slang_type_specifier_type_to_string
(func->header.type.specifier.type));
if (func->header.a_name == SLANG_ATOM_NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
break;
case FUNCTION_OPERATOR:
func->kind = SLANG_FUNC_OPERATOR;
func->header.a_name = parse_operator_name(C);
if (func->header.a_name == SLANG_ATOM_NULL)
return 0;
RETURN0;
break;
default:
return 0;
RETURN0;
}
if (!legal_identifier(func->header.a_name)) {
slang_info_log_error(C->L, "illegal function name '%s'",
(char *) func->header.a_name);
return 0;
RETURN0;
}
/* parse function parameters */
@ -1625,10 +1635,10 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
slang_variable *p = slang_variable_scope_grow(func->parameters);
if (!p) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
if (!parse_parameter_declaration(C, O, p))
return 0;
RETURN0;
}
/* if the function returns a value, append a hidden __retVal 'out'
@ -1662,19 +1672,19 @@ parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
slang_output_ctx o = *O;
if (!parse_function_prototype(C, O, func))
return 0;
RETURN0;
/* create function's body operation */
func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));
if (func->body == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
if (!slang_operation_construct(func->body)) {
_slang_free(func->body);
func->body = NULL;
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
/* to parse the body the parse context is modified in order to
@ -1683,7 +1693,7 @@ parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
C->global_scope = GL_FALSE;
o.vars = func->parameters;
if (!parse_statement(C, &o, func->body))
return 0;
RETURN0;
C->global_scope = GL_TRUE;
return 1;
@ -1779,46 +1789,46 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
slang_info_log_error(C->L,
"declaration of '%s' conflicts with previous declaration",
(char *) a_name);
return 0;
RETURN0;
}
/* make room for the new variable and initialize it */
var = slang_variable_scope_grow(O->vars);
if (!var) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
/* copy the declarator qualifier type, parse the identifier */
var->type.qualifier = type->qualifier;
var->a_name = a_name;
if (var->a_name == SLANG_ATOM_NULL)
return 0;
RETURN0;
switch (*C->I++) {
case VARIABLE_NONE:
/* simple variable declarator - just copy the specifier */
if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
return 0;
RETURN0;
break;
case VARIABLE_INITIALIZER:
/* initialized variable - copy the specifier and parse the expression */
if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
return 0;
RETURN0;
var->initializer =
(slang_operation *) _slang_alloc(sizeof(slang_operation));
if (var->initializer == NULL) {
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
if (!slang_operation_construct(var->initializer)) {
_slang_free(var->initializer);
var->initializer = NULL;
slang_info_log_memory(C->L);
return 0;
RETURN0;
}
if (!parse_expression(C, O, var->initializer))
return 0;
RETURN0;
break;
case VARIABLE_ARRAY_UNKNOWN:
/* unsized array - mark it as array and copy the specifier to
@ -1834,7 +1844,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
return GL_FALSE;
break;
default:
return 0;
RETURN0;
}
/* allocate global address space for a variable with a known size */
@ -1858,7 +1868,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
A.log = C->L;
A.curFuncEndLabel = NULL;
if (!_slang_codegen_global_variable(&A, var, C->type))
return 0;
RETURN0;
}
/* initialize global variable */
@ -1871,7 +1881,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
A.space.structs = O->structs;
A.space.vars = O->vars;
if (!initialize_global(&A, var))
return 0;
RETURN0;
}
}
return 1;
@ -1888,17 +1898,17 @@ parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
/* parse the fully specified type, common to all declarators */
if (!slang_fully_specified_type_construct(&type))
return 0;
RETURN0;
if (!parse_fully_specified_type(C, O, &type)) {
slang_fully_specified_type_destruct(&type);
return 0;
RETURN0;
}
/* parse declarators, pass-in the parsed type */
do {
if (!parse_init_declarator(C, O, &type)) {
slang_fully_specified_type_destruct(&type);
return 0;
RETURN0;
}
}
while (*C->I++ == DECLARATOR_NEXT);
@ -2005,18 +2015,18 @@ parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
switch (*C->I++) {
case DECLARATION_INIT_DECLARATOR_LIST:
if (!parse_init_declarator_list(C, O))
return 0;
RETURN0;
break;
case DECLARATION_FUNCTION_PROTOTYPE:
{
slang_function *dummy_func;
if (!parse_function(C, O, 0, &dummy_func))
return 0;
RETURN0;
}
break;
default:
return 0;
RETURN0;
}
return 1;
}
@ -2028,7 +2038,7 @@ parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
if (!O->allow_precision) {
slang_info_log_error(C->L, "syntax error at \"precision\"");
return 0;
RETURN0;
}
precision = *C->I++;
@ -2041,7 +2051,7 @@ parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
default:
_mesa_problem(NULL, "unexpected precision %d at %s:%d\n",
precision, __FILE__, __LINE__);
return 0;
RETURN0;
}
type = *C->I++;
@ -2061,7 +2071,7 @@ parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
default:
_mesa_problem(NULL, "unexpected type %d at %s:%d\n",
type, __FILE__, __LINE__);
return 0;
RETURN0;
}
assert(type < TYPE_SPECIFIER_COUNT);
@ -2108,7 +2118,7 @@ parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
}
else {
slang_info_log_error(C->L, "syntax error at \"invariant\"");
return 0;
RETURN0;
}
}

View file

@ -60,6 +60,8 @@ typedef struct
struct gl_program **Subroutines;
GLuint NumSubroutines;
GLuint MaxInstructions; /**< size of prog->Instructions[] buffer */
/* code-gen options */
GLboolean EmitHighLevelInstructions;
GLboolean EmitCondCodes;
@ -259,13 +261,16 @@ fix_swizzle(GLuint swizzle)
static void
storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st)
{
const GLboolean relAddr = st->RelAddr;
const GLint size = st->Size;
GLint index = st->Index;
GLuint swizzle = st->Swizzle;
assert(index >= 0);
/* if this is storage relative to some parent storage, walk up the tree */
while (st->Parent) {
st = st->Parent;
assert(st->Index >= 0);
index += st->Index;
swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
}
@ -302,6 +307,8 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st)
}
dst->WriteMask = writemask;
}
dst->RelAddr = relAddr;
}
@ -316,8 +323,10 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
GLuint swizzle = st->Swizzle;
/* if this is storage relative to some parent storage, walk up the tree */
assert(index >= 0);
while (st->Parent) {
st = st->Parent;
assert(st->Index >= 0);
index += st->Index;
swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle);
}
@ -387,9 +396,17 @@ new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
_mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1);
}
#endif
prog->Instructions = _mesa_realloc_instructions(prog->Instructions,
prog->NumInstructions,
prog->NumInstructions + 1);
assert(prog->NumInstructions <= emitInfo->MaxInstructions);
if (prog->NumInstructions == emitInfo->MaxInstructions) {
/* grow the instruction buffer */
emitInfo->MaxInstructions += 20;
prog->Instructions =
_mesa_realloc_instructions(prog->Instructions,
prog->NumInstructions,
emitInfo->MaxInstructions);
}
inst = prog->Instructions + prog->NumInstructions;
prog->NumInstructions++;
_mesa_init_instructions(inst, 1);
@ -403,60 +420,149 @@ new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
}
/**
* Emit a new instruction with given opcode, operands.
*/
static struct prog_instruction *
emit_instruction(slang_emit_info *emitInfo,
gl_inst_opcode opcode,
const slang_ir_storage *dst,
const slang_ir_storage *src1,
const slang_ir_storage *src2,
const slang_ir_storage *src3)
emit_arl_load(slang_emit_info *emitInfo,
enum register_file file, GLint index, GLuint swizzle)
{
struct gl_program *prog = emitInfo->prog;
struct prog_instruction *inst;
prog->Instructions = _mesa_realloc_instructions(prog->Instructions,
prog->NumInstructions,
prog->NumInstructions + 1);
inst = prog->Instructions + prog->NumInstructions;
prog->NumInstructions++;
_mesa_init_instructions(inst, 1);
inst->Opcode = opcode;
inst->BranchTarget = -1; /* invalid */
if (dst)
storage_to_dst_reg(&inst->DstReg, dst);
if (src1)
storage_to_src_reg(&inst->SrcReg[0], src1);
if (src2)
storage_to_src_reg(&inst->SrcReg[1], src2);
if (src3)
storage_to_src_reg(&inst->SrcReg[2], src3);
struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL);
inst->SrcReg[0].File = file;
inst->SrcReg[0].Index = index;
inst->SrcReg[0].Swizzle = swizzle;
inst->DstReg.File = PROGRAM_ADDRESS;
inst->DstReg.Index = 0;
inst->DstReg.WriteMask = WRITEMASK_X;
return inst;
}
/**
* Emit an ARL instruction.
* Emit a new instruction with given opcode, operands.
* At this point the instruction may have multiple indirect register
* loads/stores. We convert those into ARL loads and address-relative
* operands. See comments inside.
* At some point in the future we could directly emit indirectly addressed
* registers in Mesa GPU instructions.
*/
static struct prog_instruction *
emit_arl_instruction(slang_emit_info *emitInfo,
GLint addrReg,
const slang_ir_storage *src)
emit_instruction(slang_emit_info *emitInfo,
gl_inst_opcode opcode,
const slang_ir_storage *dst,
const slang_ir_storage *src0,
const slang_ir_storage *src1,
const slang_ir_storage *src2)
{
struct prog_instruction *inst;
GLuint numIndirect = 0;
const slang_ir_storage *src[3];
slang_ir_storage newSrc[3], newDst;
GLuint i;
GLboolean isTemp[3];
isTemp[0] = isTemp[1] = isTemp[2] = GL_FALSE;
src[0] = src0;
src[1] = src1;
src[2] = src2;
/* count up how many operands are indirect loads */
for (i = 0; i < 3; i++) {
if (src[i] && src[i]->IsIndirect)
numIndirect++;
}
if (dst && dst->IsIndirect)
numIndirect++;
/* Take special steps for indirect register loads.
* If we had multiple address registers this would be simpler.
* For example, this GLSL code:
* x[i] = y[j] + z[k];
* would translate into something like:
* ARL ADDR.x, i;
* ARL ADDR.y, j;
* ARL ADDR.z, k;
* ADD TEMP[ADDR.x+5], TEMP[ADDR.y+9], TEMP[ADDR.z+4];
* But since we currently only have one address register we have to do this:
* ARL ADDR.x, i;
* MOV t1, TEMP[ADDR.x+9];
* ARL ADDR.x, j;
* MOV t2, TEMP[ADDR.x+4];
* ARL ADDR.x, k;
* ADD TEMP[ADDR.x+5], t1, t2;
* The code here figures this out...
*/
if (numIndirect > 0) {
for (i = 0; i < 3; i++) {
if (src[i] && src[i]->IsIndirect) {
/* load the ARL register with the indirect register */
emit_arl_load(emitInfo,
src[i]->IndirectFile,
src[i]->IndirectIndex,
src[i]->IndirectSwizzle);
if (numIndirect > 1) {
/* Need to load src[i] into a temporary register */
slang_ir_storage srcRelAddr;
alloc_local_temp(emitInfo, &newSrc[i], src[i]->Size);
isTemp[i] = GL_TRUE;
/* set RelAddr flag on src register */
srcRelAddr = *src[i];
srcRelAddr.RelAddr = GL_TRUE;
srcRelAddr.IsIndirect = GL_FALSE; /* not really needed */
/* MOV newSrc, srcRelAddr; */
inst = emit_instruction(emitInfo,
OPCODE_MOV,
&newSrc[i],
&srcRelAddr,
NULL,
NULL);
src[i] = &newSrc[i];
}
else {
/* just rewrite the src[i] storage to be ARL-relative */
newSrc[i] = *src[i];
newSrc[i].RelAddr = GL_TRUE;
newSrc[i].IsIndirect = GL_FALSE; /* not really needed */
src[i] = &newSrc[i];
}
}
}
}
/* Take special steps for indirect dest register write */
if (dst && dst->IsIndirect) {
/* load the ARL register with the indirect register */
emit_arl_load(emitInfo,
dst->IndirectFile,
dst->IndirectIndex,
dst->IndirectSwizzle);
newDst = *dst;
newDst.RelAddr = GL_TRUE;
newDst.IsIndirect = GL_FALSE;
dst = &newDst;
}
/* OK, emit the instruction and its dst, src regs */
inst = new_instruction(emitInfo, opcode);
if (!inst)
return NULL;
if (dst)
storage_to_dst_reg(&inst->DstReg, dst);
for (i = 0; i < 3; i++) {
if (src[i])
storage_to_src_reg(&inst->SrcReg[i], src[i]);
}
/* Free any temp registers that we allocated above */
for (i = 0; i < 3; i++) {
if (isTemp[i])
_slang_free_temp(emitInfo->vt, &newSrc[i]);
}
assert(addrReg == 0); /* only one addr reg at this time */
inst = new_instruction(emitInfo, OPCODE_ARL);
storage_to_src_reg(&inst->SrcReg[0], src);
inst->DstReg.File = PROGRAM_ADDRESS;
inst->DstReg.Index = addrReg;
inst->DstReg.WriteMask = WRITEMASK_X;
return inst;
}
@ -1034,13 +1140,17 @@ emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
struct gl_program *progSave;
struct prog_instruction *inst;
GLuint subroutineId;
GLuint maxInstSave;
assert(n->Opcode == IR_CALL);
assert(n->Label);
/* save/push cur program */
maxInstSave = emitInfo->MaxInstructions;
progSave = emitInfo->prog;
emitInfo->prog = new_subroutine(emitInfo, &subroutineId);
emitInfo->MaxInstructions = emitInfo->prog->NumInstructions;
_slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
emitInfo->prog);
@ -1072,6 +1182,7 @@ emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
/* pop/restore cur program */
emitInfo->prog = progSave;
emitInfo->MaxInstructions = maxInstSave;
/* emit the function call */
inst = new_instruction(emitInfo, OPCODE_CAL);
@ -1212,7 +1323,8 @@ emit_copy(slang_emit_info *emitInfo, slang_ir_node *n)
if (inst &&
_slang_is_temp(emitInfo->vt, n->Children[1]->Store) &&
(inst->DstReg.File == n->Children[1]->Store->File) &&
(inst->DstReg.Index == n->Children[1]->Store->Index)) {
(inst->DstReg.Index == n->Children[1]->Store->Index) &&
!n->Children[0]->Store->IsIndirect) {
/* Peephole optimization:
* The Right-Hand-Side has its results in a temporary place.
* Modify the RHS (and the prev instruction) to store its results
@ -1670,80 +1782,38 @@ emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
inst = emit(emitInfo, n->Children[0]);
/* setup storage info, if needed */
if (!n->Store->Parent)
n->Store->Parent = n->Children[0]->Store;
#if 0
assert(n->Store->Parent);
/* Apply this node's swizzle to parent's storage */
GLuint swizzle = n->Store->Swizzle;
_slang_copy_ir_storage(n->Store, n->Store->Parent);
n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle);
assert(!n->Store->Parent);
#endif
return inst;
}
/**
* Move a block registers from src to dst (or move a single register).
* \param size size of block, in floats (<=4 means one register)
*/
static struct prog_instruction *
move_block(slang_emit_info *emitInfo,
GLuint size, GLboolean relAddr,
const slang_ir_storage *dst,
const slang_ir_storage *src)
{
struct prog_instruction *inst;
if (size > 4) {
/* move matrix/struct etc (block of registers) */
slang_ir_storage dstStore = *dst;
slang_ir_storage srcStore = *src;
dstStore.Size = 4;
srcStore.Size = 4;
while (size >= 4) {
inst = emit_instruction(emitInfo, OPCODE_MOV,
&dstStore,
&srcStore,
NULL,
NULL);
inst->SrcReg[0].RelAddr = relAddr;
inst_comment(inst, "IR_COPY block");
srcStore.Index++;
dstStore.Index++;
size -= 4;
}
}
else {
/* single register move */
inst = emit_instruction(emitInfo,
OPCODE_MOV,
dst,
src,
NULL,
NULL);
inst->SrcReg[0].RelAddr = relAddr;
}
return inst;
}
/**
* Dereference array element. Just resolve storage for the array
* element represented by this node.
* This is typically where Indirect addressing comes into play.
* See comments on struct slang_ir_storage.
* Dereference array element: element == array[index]
* This basically involves emitting code for computing the array index
* and updating the node/element's storage info.
*/
static struct prog_instruction *
emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
{
assert(n->Opcode == IR_ELEMENT);
assert(n->Store);
assert(n->Store->File == PROGRAM_UNDEFINED);
assert(n->Store->Parent);
assert(n->Store->Size > 0);
slang_ir_storage *arrayStore, *indexStore;
const int elemSize = n->Store->Size; /* number of floats */
const GLint elemSizeVec = (elemSize + 3) / 4; /* number of vec4 */
struct prog_instruction *inst;
assert(n->Opcode == IR_ELEMENT);
assert(elemSize > 0);
/* special case for built-in state variables, like light state */
{
slang_ir_storage *root = n->Store;
assert(!root->Parent);
while (root->Parent)
root = root->Parent;
@ -1754,69 +1824,98 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
}
}
/* do codegen for array */
/* do codegen for array itself */
emit(emitInfo, n->Children[0]);
arrayStore = n->Children[0]->Store;
/* The initial array element storage is the array's storage,
* then modified below.
*/
_slang_copy_ir_storage(n->Store, arrayStore);
if (n->Children[1]->Opcode == IR_FLOAT) {
/* Constant array index.
* Set Store's index to be the offset of the array element in
* the register file.
*/
/* Constant array index */
const GLint element = (GLint) n->Children[1]->Value[0];
const GLint sz = (n->Store->Size + 3) / 4; /* size in slots/registers */
n->Store->Index = sz * element;
assert(n->Store->Parent);
/* this element's storage is the array's storage, plus constant offset */
n->Store->Index += elemSizeVec * element;
}
else {
/* Variable array index */
struct prog_instruction *inst;
/* do codegen for array index expression */
emit(emitInfo, n->Children[1]);
indexStore = n->Children[1]->Store;
/* allocate temp storage for the array element */
assert(n->Store->Index < 0);
n->Store->File = PROGRAM_TEMPORARY;
n->Store->Parent = NULL;
alloc_node_storage(emitInfo, n, -1);
if (indexStore->IsIndirect) {
/* need to put the array index into a temporary since we can't
* directly support a[b[i]] constructs.
*/
if (n->Store->Size > 4) {
/* need to multiply the index by the element size */
const GLint elemSize = (n->Store->Size + 3) / 4;
slang_ir_storage indexTemp, elemSizeStore;
/* constant containing the element size */
constant_to_storage(emitInfo, (float) elemSize, &elemSizeStore);
/*indexStore = tempstore();*/
}
if (elemSize > 4) {
/* need to multiply array index by array element size */
struct prog_instruction *inst;
slang_ir_storage *indexTemp;
slang_ir_storage elemSizeStore;
/* allocate 1 float indexTemp */
alloc_local_temp(emitInfo, &indexTemp, 1);
indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
_slang_alloc_temp(emitInfo->vt, indexTemp);
/* MUL temp, index, elemSize */
inst = emit_instruction(emitInfo, OPCODE_MUL,
&indexTemp, /* dest */
n->Children[1]->Store, /* the index */
/* allocate a constant containing the element size */
constant_to_storage(emitInfo, (float) elemSizeVec, &elemSizeStore);
/* multiply array index by element size */
inst = emit_instruction(emitInfo,
OPCODE_MUL,
indexTemp, /* dest */
indexStore, /* the index */
&elemSizeStore,
NULL);
/* load ADDR[0].X = temp */
inst = emit_arl_instruction(emitInfo, 0, &indexTemp);
_slang_free_temp(emitInfo->vt, &indexTemp);
}
else {
/* simply load address reg w/ array index */
inst = emit_arl_instruction(emitInfo, 0, n->Children[1]->Store);
indexStore = indexTemp;
}
/* copy from array element to temp storage */
move_block(emitInfo, n->Store->Size, GL_TRUE,
n->Store, n->Children[0]->Store);
if (arrayStore->IsIndirect) {
/* ex: in a[i][j], a[i] (the arrayStore) is indirect */
/* Need to add indexStore to arrayStore->Indirect store */
slang_ir_storage indirectArray;
slang_ir_storage *indexTemp;
_slang_init_ir_storage(&indirectArray,
arrayStore->IndirectFile,
arrayStore->IndirectIndex,
1,
arrayStore->IndirectSwizzle);
/* allocate 1 float indexTemp */
indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
_slang_alloc_temp(emitInfo->vt, indexTemp);
inst = emit_instruction(emitInfo,
OPCODE_ADD,
indexTemp, /* dest */
indexStore, /* the index */
&indirectArray, /* indirect array base */
NULL);
indexStore = indexTemp;
}
/* update the array element storage info */
n->Store->IsIndirect = GL_TRUE;
n->Store->IndirectFile = indexStore->File;
n->Store->IndirectIndex = indexStore->Index;
n->Store->IndirectSwizzle = indexStore->Swizzle;
}
/* if array element size is one, make sure we only access X */
if (n->Store->Size == 1)
n->Store->Swizzle = SWIZZLE_XXXX;
n->Store->Size = elemSize;
return NULL; /* no instruction */
}
@ -1829,9 +1928,11 @@ static struct prog_instruction *
emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
{
slang_ir_storage *root = n->Store;
GLint fieldOffset, fieldSize;
assert(n->Opcode == IR_FIELD);
assert(!root->Parent);
while (root->Parent)
root = root->Parent;
@ -1847,12 +1948,45 @@ emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
slang_info_log_error(emitInfo->log, "Error parsing state variable");
return NULL;
}
return NULL;
}
else {
/* do codegen for struct */
emit(emitInfo, n->Children[0]);
assert(n->Children[0]->Store->Index >= 0);
}
fieldOffset = n->Store->Index;
fieldSize = n->Store->Size;
_slang_copy_ir_storage(n->Store, n->Children[0]->Store);
n->Store->Index = n->Children[0]->Store->Index + fieldOffset / 4;
/* XXX test this:
n->Store->Index += fieldOffset / 4;
*/
switch (fieldSize) {
case 1:
{
GLint swz = fieldOffset % 4;
n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
}
break;
case 2:
n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_NIL, SWIZZLE_NIL);
break;
case 3:
n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_NIL);
break;
default:
n->Store->Swizzle = SWIZZLE_XYZW;
}
assert(n->Store->Index >= 0);
return NULL; /* no instruction */
}
@ -1909,7 +2043,7 @@ emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n)
/**
* Emit code for a reference to a variable.
* Actually, no code is generated but we may do some memory alloation.
* Actually, no code is generated but we may do some memory allocation.
* In particular, state vars (uniforms) are allocated on an as-needed basis.
*/
static struct prog_instruction *
@ -2130,7 +2264,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo)
total += emitInfo->Subroutines[i]->NumInstructions;
}
/* adjust BrancTargets within the functions */
/* adjust BranchTargets within the functions */
for (i = 0; i < emitInfo->NumSubroutines; i++) {
struct gl_program *sub = emitInfo->Subroutines[i];
GLuint j;
@ -2199,6 +2333,7 @@ _slang_emit_code(slang_ir_node *n, slang_var_table *vt,
emitInfo.prog = prog;
emitInfo.Subroutines = NULL;
emitInfo.NumSubroutines = 0;
emitInfo.MaxInstructions = prog->NumInstructions;
emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;

View file

@ -116,6 +116,20 @@ _slang_ir_info(slang_ir_opcode opcode)
}
void
_slang_init_ir_storage(slang_ir_storage *st,
enum register_file file, GLint index, GLint size,
GLuint swizzle)
{
st->File = file;
st->Index = index;
st->Size = size;
st->Swizzle = swizzle;
st->Parent = NULL;
st->IsIndirect = GL_FALSE;
}
/**
* Return a new slang_ir_storage object.
*/
@ -130,6 +144,7 @@ _slang_new_ir_storage(enum register_file file, GLint index, GLint size)
st->Size = size;
st->Swizzle = SWIZZLE_NOOP;
st->Parent = NULL;
st->IsIndirect = GL_FALSE;
}
return st;
}
@ -150,6 +165,7 @@ _slang_new_ir_storage_swz(enum register_file file, GLint index, GLint size,
st->Size = size;
st->Swizzle = swizzle;
st->Parent = NULL;
st->IsIndirect = GL_FALSE;
}
return st;
}
@ -170,11 +186,45 @@ _slang_new_ir_storage_relative(GLint index, GLint size,
st->Size = size;
st->Swizzle = SWIZZLE_NOOP;
st->Parent = parent;
st->IsIndirect = GL_FALSE;
}
return st;
}
slang_ir_storage *
_slang_new_ir_storage_indirect(enum register_file file,
GLint index,
GLint size,
enum register_file indirectFile,
GLint indirectIndex,
GLuint indirectSwizzle)
{
slang_ir_storage *st;
st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
if (st) {
st->File = file;
st->Index = index;
st->Size = size;
st->Swizzle = SWIZZLE_NOOP;
st->IsIndirect = GL_TRUE;
st->IndirectFile = indirectFile;
st->IndirectIndex = indirectIndex;
st->IndirectSwizzle = indirectSwizzle;
}
return st;
}
/* XXX temporary function */
void
_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src)
{
*dst = *src;
dst->Parent = NULL;
}
static const char *
_slang_ir_name(slang_ir_opcode opcode)

View file

@ -140,24 +140,53 @@ typedef enum
/**
* Describes where data storage is allocated.
* Describes where data/variables are stored in the various register files.
*
* In the simple case, the File, Index and Size fields indicate where
* a variable is stored. For example, a vec3 variable may be stored
* as (File=PROGRAM_TEMPORARY, Index=6, Size=3). Or, File[Index].
* Or, a program input like color may be stored as
* (File=PROGRAM_INPUT,Index=3,Size=4);
*
* For single-float values, the Swizzle field indicates which component
* of the vector contains the float.
*
* If IsIndirect is set, the storage is accessed through an indirect
* register lookup. The value in question will be located at:
* File[Index + IndirectFile[IndirectIndex]]
*
* This is primary used for indexing arrays. For example, consider this
* GLSL code:
* uniform int i;
* float a[10];
* float x = a[i];
*
* here, storage for a[i] would be described by (File=PROGRAM_TEMPORAY,
* Index=aPos, IndirectFile=PROGRAM_UNIFORM, IndirectIndex=iPos), which
* would mean TEMP[aPos + UNIFORM[iPos]]
*/
struct _slang_ir_storage
struct slang_ir_storage_
{
enum register_file File; /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */
GLint Index; /**< -1 means unallocated */
GLint Size; /**< number of floats */
GLuint Swizzle;
GLuint Swizzle; /**< Swizzle AND writemask info */
GLint RefCount; /**< Used during IR tree delete */
GLboolean RelAddr;
GLboolean RelAddr; /* we'll remove this eventually */
GLboolean IsIndirect;
enum register_file IndirectFile;
GLint IndirectIndex;
GLuint IndirectSwizzle;
/** If Parent is non-null, Index is relative to parent.
* The other fields are ignored.
*/
struct _slang_ir_storage *Parent;
struct slang_ir_storage_ *Parent;
};
typedef struct _slang_ir_storage slang_ir_storage;
typedef struct slang_ir_storage_ slang_ir_storage;
/**
@ -199,6 +228,11 @@ extern const slang_ir_info *
_slang_ir_info(slang_ir_opcode opcode);
extern void
_slang_init_ir_storage(slang_ir_storage *st,
enum register_file file, GLint index, GLint size,
GLuint swizzle);
extern slang_ir_storage *
_slang_new_ir_storage(enum register_file file, GLint index, GLint size);
@ -212,6 +246,17 @@ _slang_new_ir_storage_relative(GLint index, GLint size,
slang_ir_storage *parent);
extern slang_ir_storage *
_slang_new_ir_storage_indirect(enum register_file file,
GLint index,
GLint size,
enum register_file indirectFile,
GLint indirectIndex,
GLuint indirectSwizzle);
extern void
_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src);
extern void
_slang_free_ir_tree(slang_ir_node *n);

View file

@ -2,7 +2,7 @@
#ifndef SLANG_VARTABLE_H
#define SLANG_VARTABLE_H
struct _slang_ir_storage;
struct slang_ir_storage_;
typedef struct slang_var_table_ slang_var_table;
@ -27,16 +27,16 @@ extern struct slang_variable_ *
_slang_find_variable(const slang_var_table *t, slang_atom name);
extern GLboolean
_slang_alloc_var(slang_var_table *t, struct _slang_ir_storage *store);
_slang_alloc_var(slang_var_table *t, struct slang_ir_storage_ *store);
extern GLboolean
_slang_alloc_temp(slang_var_table *t, struct _slang_ir_storage *store);
_slang_alloc_temp(slang_var_table *t, struct slang_ir_storage_ *store);
extern void
_slang_free_temp(slang_var_table *t, struct _slang_ir_storage *store);
_slang_free_temp(slang_var_table *t, struct slang_ir_storage_ *store);
extern GLboolean
_slang_is_temp(const slang_var_table *t, const struct _slang_ir_storage *store);
_slang_is_temp(const slang_var_table *t, const struct slang_ir_storage_ *store);
#endif /* SLANG_VARTABLE_H */