Sfoglia il codice sorgente

mesa: rework GLSL array code generation

We now express arrays in terms of indirect addressing.  For example:
  dst = a[i];
becomes:
  MOV dst, TEMP[1 + TEMP[2].y];
At instruction-emit time indirect addressing is converted into ARL/
ADDR-relative form:
  ARL ADDR.x, TEMP[2].y;
  MOV dst, TEMP[1 + ADDR.x];
This fixes a number of array-related issues.  Arrays of arrays and complex
array/struct nesting works now.
There may be some regressions, but more work is coming.
tags/mesa_7_3_rc1
Brian Paul 16 anni fa
parent
commit
ae0ff8097b

+ 11
- 21
src/mesa/shader/slang/slang_codegen.c Vedi File

@@ -3116,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);
@@ -3149,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;
}
@@ -3257,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 {

+ 254
- 128
src/mesa/shader/slang/slang_emit.c Vedi File

@@ -261,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);
}
@@ -304,6 +307,8 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st)
}
dst->WriteMask = writemask;
}

dst->RelAddr = relAddr;
}


@@ -318,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);
}
@@ -413,19 +420,131 @@ new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
}


static struct prog_instruction *
emit_arl_load(slang_emit_info *emitInfo,
enum register_file file, GLint index, GLuint swizzle)
{
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 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_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,
const slang_ir_storage *src3)
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;
@@ -433,33 +552,17 @@ emit_instruction(slang_emit_info *emitInfo,
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);

return inst;
}

for (i = 0; i < 3; i++) {
if (src[i])
storage_to_src_reg(&inst->SrcReg[i], src[i]);
}

/**
* Emit an ARL instruction.
*/
static struct prog_instruction *
emit_arl_instruction(slang_emit_info *emitInfo,
GLint addrReg,
const slang_ir_storage *src)
{
struct prog_instruction *inst;
/* 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;
}

@@ -1220,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
@@ -1678,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)
* 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 *
move_block(slang_emit_info *emitInfo,
GLuint size, GLboolean relAddr,
const slang_ir_storage *dst,
const slang_ir_storage *src)
emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
{
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;

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.
*/
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);
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;

@@ -1762,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;

if (indexStore->IsIndirect) {
/* need to put the array index into a temporary since we can't
* directly support a[b[i]] constructs.
*/


/* 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);
/*indexStore = tempstore();*/
}

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);
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);

/* allocate a constant containing the element size */
constant_to_storage(emitInfo, (float) elemSizeVec, &elemSizeStore);

/* MUL temp, index, elemSize */
inst = emit_instruction(emitInfo, OPCODE_MUL,
&indexTemp, /* dest */
n->Children[1]->Store, /* the index */
/* 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);
indexStore = indexTemp;
}
else {
/* simply load address reg w/ array index */
inst = emit_arl_instruction(emitInfo, 0, n->Children[1]->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;
}

/* copy from array element to temp storage */
move_block(emitInfo, n->Store->Size, GL_TRUE,
n->Store, n->Children[0]->Store);
/* 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 */
}
@@ -1837,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;

@@ -1855,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 */
}

@@ -1917,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 *
@@ -2138,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;
@@ -2207,7 +2333,7 @@ _slang_emit_code(slang_ir_node *n, slang_var_table *vt,
emitInfo.prog = prog;
emitInfo.Subroutines = NULL;
emitInfo.NumSubroutines = 0;
emitInfo.MaxInstructions = 0;
emitInfo.MaxInstructions = prog->NumInstructions;

emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;

+ 50
- 0
src/mesa/shader/slang/slang_ir.c Vedi 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)

+ 51
- 6
src/mesa/shader/slang/slang_ir.h Vedi 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);

+ 5
- 5
src/mesa/shader/slang/slang_vartable.h Vedi 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 */

Loading…
Annulla
Salva