mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
gallium: Implement 2D constant buffers for fragment shader in softpipe.
This commit is contained in:
parent
4367de152c
commit
835bab0143
10 changed files with 156 additions and 175 deletions
|
|
@ -302,7 +302,7 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
|
|||
unsigned num_primitives = count/num_vertices;
|
||||
unsigned inputs_from_vs = 0;
|
||||
|
||||
machine->Consts = constants;
|
||||
machine->Consts[0] = constants;
|
||||
|
||||
for (i = 0; i < shader->info.num_inputs; ++i) {
|
||||
if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID)
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
|
|||
unsigned int i, j;
|
||||
unsigned slot;
|
||||
|
||||
machine->Consts = constants;
|
||||
machine->Consts[0] = constants;
|
||||
|
||||
for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
|
||||
unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);
|
||||
|
|
|
|||
|
|
@ -953,107 +953,90 @@ micro_sub(
|
|||
}
|
||||
|
||||
static void
|
||||
fetch_src_file_channel(
|
||||
const struct tgsi_exec_machine *mach,
|
||||
const uint file,
|
||||
const uint swizzle,
|
||||
const union tgsi_exec_channel *index,
|
||||
union tgsi_exec_channel *chan )
|
||||
fetch_src_file_channel(const struct tgsi_exec_machine *mach,
|
||||
const uint file,
|
||||
const uint swizzle,
|
||||
const union tgsi_exec_channel *index,
|
||||
const union tgsi_exec_channel *index2D,
|
||||
union tgsi_exec_channel *chan)
|
||||
{
|
||||
switch( swizzle ) {
|
||||
case TGSI_SWIZZLE_X:
|
||||
case TGSI_SWIZZLE_Y:
|
||||
case TGSI_SWIZZLE_Z:
|
||||
case TGSI_SWIZZLE_W:
|
||||
switch( file ) {
|
||||
case TGSI_FILE_CONSTANT:
|
||||
assert(mach->Consts);
|
||||
if (index->i[0] < 0)
|
||||
chan->f[0] = 0.0f;
|
||||
else
|
||||
chan->f[0] = mach->Consts[index->i[0]][swizzle];
|
||||
if (index->i[1] < 0)
|
||||
chan->f[1] = 0.0f;
|
||||
else
|
||||
chan->f[1] = mach->Consts[index->i[1]][swizzle];
|
||||
if (index->i[2] < 0)
|
||||
chan->f[2] = 0.0f;
|
||||
else
|
||||
chan->f[2] = mach->Consts[index->i[2]][swizzle];
|
||||
if (index->i[3] < 0)
|
||||
chan->f[3] = 0.0f;
|
||||
else
|
||||
chan->f[3] = mach->Consts[index->i[3]][swizzle];
|
||||
break;
|
||||
uint i;
|
||||
|
||||
case TGSI_FILE_INPUT:
|
||||
case TGSI_FILE_SYSTEM_VALUE:
|
||||
chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
|
||||
chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
|
||||
chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
|
||||
chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3];
|
||||
break;
|
||||
switch (file) {
|
||||
case TGSI_FILE_CONSTANT:
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
assert(index2D->i[i] >= 0 && index2D->i[i] < PIPE_MAX_CONSTANT);
|
||||
assert(mach->Consts[index2D->i[i]]);
|
||||
|
||||
case TGSI_FILE_TEMPORARY:
|
||||
assert(index->i[0] < TGSI_EXEC_NUM_TEMPS);
|
||||
chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0];
|
||||
chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1];
|
||||
chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2];
|
||||
chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3];
|
||||
break;
|
||||
if (index->i[i] < 0) {
|
||||
chan->u[i] = 0;
|
||||
} else {
|
||||
const uint *p = (const uint *)mach->Consts[index2D->i[i]];
|
||||
|
||||
case TGSI_FILE_IMMEDIATE:
|
||||
assert( index->i[0] < (int) mach->ImmLimit );
|
||||
chan->f[0] = mach->Imms[index->i[0]][swizzle];
|
||||
assert( index->i[1] < (int) mach->ImmLimit );
|
||||
chan->f[1] = mach->Imms[index->i[1]][swizzle];
|
||||
assert( index->i[2] < (int) mach->ImmLimit );
|
||||
chan->f[2] = mach->Imms[index->i[2]][swizzle];
|
||||
assert( index->i[3] < (int) mach->ImmLimit );
|
||||
chan->f[3] = mach->Imms[index->i[3]][swizzle];
|
||||
break;
|
||||
chan->u[i] = p[index->i[i] * 4 + swizzle];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_FILE_ADDRESS:
|
||||
chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0];
|
||||
chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1];
|
||||
chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2];
|
||||
chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3];
|
||||
break;
|
||||
case TGSI_FILE_INPUT:
|
||||
case TGSI_FILE_SYSTEM_VALUE:
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
/* XXX: 2D indexing */
|
||||
chan->u[i] = mach->Inputs[index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]].xyzw[swizzle].u[i];
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_FILE_PREDICATE:
|
||||
assert(index->i[0] < TGSI_EXEC_NUM_PREDS);
|
||||
assert(index->i[1] < TGSI_EXEC_NUM_PREDS);
|
||||
assert(index->i[2] < TGSI_EXEC_NUM_PREDS);
|
||||
assert(index->i[3] < TGSI_EXEC_NUM_PREDS);
|
||||
chan->u[0] = mach->Predicates[0].xyzw[swizzle].u[0];
|
||||
chan->u[1] = mach->Predicates[0].xyzw[swizzle].u[1];
|
||||
chan->u[2] = mach->Predicates[0].xyzw[swizzle].u[2];
|
||||
chan->u[3] = mach->Predicates[0].xyzw[swizzle].u[3];
|
||||
break;
|
||||
case TGSI_FILE_TEMPORARY:
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
assert(index->i[i] < TGSI_EXEC_NUM_TEMPS);
|
||||
assert(index2D->i[i] == 0);
|
||||
|
||||
case TGSI_FILE_OUTPUT:
|
||||
/* vertex/fragment output vars can be read too */
|
||||
chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0];
|
||||
chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1];
|
||||
chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2];
|
||||
chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3];
|
||||
break;
|
||||
chan->u[i] = mach->Temps[index->i[i]].xyzw[swizzle].u[i];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
chan->u[0] = 0;
|
||||
chan->u[1] = 0;
|
||||
chan->u[2] = 0;
|
||||
chan->u[3] = 0;
|
||||
case TGSI_FILE_IMMEDIATE:
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
assert(index->i[i] >= 0 && index->i[i] < (int)mach->ImmLimit);
|
||||
assert(index2D->i[i] == 0);
|
||||
|
||||
chan->f[i] = mach->Imms[index->i[i]][swizzle];
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_FILE_ADDRESS:
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
assert(index->i[i] >= 0);
|
||||
assert(index2D->i[i] == 0);
|
||||
|
||||
chan->u[i] = mach->Addrs[index->i[i]].xyzw[swizzle].u[i];
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_FILE_PREDICATE:
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
assert(index->i[i] >= 0 && index->i[i] < TGSI_EXEC_NUM_PREDS);
|
||||
assert(index2D->i[i] == 0);
|
||||
|
||||
chan->u[i] = mach->Predicates[0].xyzw[swizzle].u[i];
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_FILE_OUTPUT:
|
||||
/* vertex/fragment output vars can be read too */
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
assert(index->i[i] >= 0);
|
||||
assert(index2D->i[i] == 0);
|
||||
|
||||
chan->u[i] = mach->Outputs[index->i[i]].xyzw[swizzle].u[i];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
chan->u[0] = 0;
|
||||
chan->u[1] = 0;
|
||||
chan->u[2] = 0;
|
||||
chan->u[3] = 0;
|
||||
assert(0);
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
chan->u[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1065,6 +1048,7 @@ fetch_source(const struct tgsi_exec_machine *mach,
|
|||
enum tgsi_exec_datatype src_datatype)
|
||||
{
|
||||
union tgsi_exec_channel index;
|
||||
union tgsi_exec_channel index2D;
|
||||
uint swizzle;
|
||||
|
||||
/* We start with a direct index into a register file.
|
||||
|
|
@ -1103,12 +1087,12 @@ fetch_source(const struct tgsi_exec_machine *mach,
|
|||
|
||||
/* get current value of address register[swizzle] */
|
||||
swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X );
|
||||
fetch_src_file_channel(
|
||||
mach,
|
||||
reg->Indirect.File,
|
||||
swizzle,
|
||||
&index2,
|
||||
&indir_index );
|
||||
fetch_src_file_channel(mach,
|
||||
reg->Indirect.File,
|
||||
swizzle,
|
||||
&index2,
|
||||
&ZeroVec,
|
||||
&indir_index);
|
||||
|
||||
/* add value of address register to the offset */
|
||||
index.i[0] += indir_index.i[0];
|
||||
|
|
@ -1129,35 +1113,15 @@ fetch_source(const struct tgsi_exec_machine *mach,
|
|||
* subscript to a register file. Effectively it means that
|
||||
* the register file is actually a 2D array of registers.
|
||||
*
|
||||
* file[3][1] == file[3*sizeof(file[1])+1],
|
||||
* file[3][1],
|
||||
* where:
|
||||
* [3] = Dimension.Index
|
||||
*/
|
||||
if (reg->Register.Dimension) {
|
||||
int array_size;
|
||||
union tgsi_exec_channel dim_index;
|
||||
|
||||
/* The size of the first-order array depends on the register file type.
|
||||
* We need to multiply the index to the first array to get an effective,
|
||||
* "flat" index that points to the beginning of the second-order array.
|
||||
*/
|
||||
switch (reg->Register.File) {
|
||||
case TGSI_FILE_INPUT:
|
||||
case TGSI_FILE_SYSTEM_VALUE:
|
||||
array_size = TGSI_EXEC_MAX_INPUT_ATTRIBS;
|
||||
break;
|
||||
case TGSI_FILE_CONSTANT:
|
||||
array_size = TGSI_EXEC_MAX_CONST_BUFFER;
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
array_size = 0;
|
||||
}
|
||||
|
||||
dim_index.i[0] =
|
||||
dim_index.i[1] =
|
||||
dim_index.i[2] =
|
||||
dim_index.i[3] = reg->Dimension.Index;
|
||||
index2D.i[0] =
|
||||
index2D.i[1] =
|
||||
index2D.i[2] =
|
||||
index2D.i[3] = reg->Dimension.Index;
|
||||
|
||||
/* Again, the second subscript index can be addressed indirectly
|
||||
* identically to the first one.
|
||||
|
|
@ -1182,45 +1146,46 @@ fetch_source(const struct tgsi_exec_machine *mach,
|
|||
index2.i[3] = reg->DimIndirect.Index;
|
||||
|
||||
swizzle = tgsi_util_get_src_register_swizzle( ®->DimIndirect, CHAN_X );
|
||||
fetch_src_file_channel(
|
||||
mach,
|
||||
reg->DimIndirect.File,
|
||||
swizzle,
|
||||
&index2,
|
||||
&indir_index );
|
||||
fetch_src_file_channel(mach,
|
||||
reg->DimIndirect.File,
|
||||
swizzle,
|
||||
&index2,
|
||||
&ZeroVec,
|
||||
&indir_index);
|
||||
|
||||
dim_index.i[0] += indir_index.i[0];
|
||||
dim_index.i[1] += indir_index.i[1];
|
||||
dim_index.i[2] += indir_index.i[2];
|
||||
dim_index.i[3] += indir_index.i[3];
|
||||
index2D.i[0] += indir_index.i[0];
|
||||
index2D.i[1] += indir_index.i[1];
|
||||
index2D.i[2] += indir_index.i[2];
|
||||
index2D.i[3] += indir_index.i[3];
|
||||
|
||||
/* for disabled execution channels, zero-out the index to
|
||||
* avoid using a potential garbage value.
|
||||
*/
|
||||
for (i = 0; i < QUAD_SIZE; i++) {
|
||||
if ((execmask & (1 << i)) == 0)
|
||||
dim_index.i[i] = 0;
|
||||
if ((execmask & (1 << i)) == 0) {
|
||||
index2D.i[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index.i[0] += dim_index.i[0] * array_size;
|
||||
index.i[1] += dim_index.i[1] * array_size;
|
||||
index.i[2] += dim_index.i[2] * array_size;
|
||||
index.i[3] += dim_index.i[3] * array_size;
|
||||
|
||||
/* If by any chance there was a need for a 3D array of register
|
||||
* files, we would have to check whether Dimension is followed
|
||||
* by a dimension register and continue the saga.
|
||||
*/
|
||||
} else {
|
||||
index2D.i[0] =
|
||||
index2D.i[1] =
|
||||
index2D.i[2] =
|
||||
index2D.i[3] = 0;
|
||||
}
|
||||
|
||||
swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
|
||||
fetch_src_file_channel(
|
||||
mach,
|
||||
reg->Register.File,
|
||||
swizzle,
|
||||
&index,
|
||||
chan );
|
||||
fetch_src_file_channel(mach,
|
||||
reg->Register.File,
|
||||
swizzle,
|
||||
&index,
|
||||
&index2D,
|
||||
chan);
|
||||
|
||||
if (reg->Register.Absolute) {
|
||||
if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
|
||||
|
|
@ -1283,12 +1248,12 @@ store_dest(struct tgsi_exec_machine *mach,
|
|||
swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X );
|
||||
|
||||
/* fetch values from the address/indirection register */
|
||||
fetch_src_file_channel(
|
||||
mach,
|
||||
reg->Indirect.File,
|
||||
swizzle,
|
||||
&index,
|
||||
&indir_index );
|
||||
fetch_src_file_channel(mach,
|
||||
reg->Indirect.File,
|
||||
swizzle,
|
||||
&index,
|
||||
&ZeroVec,
|
||||
&indir_index);
|
||||
|
||||
/* save indirection offset */
|
||||
offset = indir_index.i[0];
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ struct tgsi_exec_machine
|
|||
struct tgsi_sampler **Samplers;
|
||||
|
||||
unsigned ImmLimit;
|
||||
const float (*Consts)[4];
|
||||
const void *Consts[PIPE_MAX_CONSTANT];
|
||||
const struct tgsi_token *Tokens; /**< Declarations, instructions */
|
||||
unsigned Processor; /**< TGSI_PROCESSOR_x */
|
||||
|
||||
|
|
|
|||
|
|
@ -111,9 +111,13 @@ softpipe_destroy( struct pipe_context *pipe )
|
|||
pipe_texture_reference(&softpipe->vertex_textures[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < Elements(softpipe->constants); i++) {
|
||||
if (softpipe->constants[i]) {
|
||||
pipe_buffer_reference(&softpipe->constants[i], NULL);
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
uint j;
|
||||
|
||||
for (j = 0; j < PIPE_MAX_CONSTANT; j++) {
|
||||
if (softpipe->constants[i][j]) {
|
||||
pipe_buffer_reference(&softpipe->constants[i][j], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ struct softpipe_context {
|
|||
/** Other rendering state */
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_clip_state clip;
|
||||
struct pipe_buffer *constants[PIPE_SHADER_TYPES];
|
||||
struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT];
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_poly_stipple poly_stipple;
|
||||
struct pipe_scissor_state scissor;
|
||||
|
|
@ -92,7 +92,7 @@ struct softpipe_context {
|
|||
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
|
||||
|
||||
/** Mapped constant buffers */
|
||||
void *mapped_constants[PIPE_SHADER_TYPES];
|
||||
void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT];
|
||||
|
||||
/** Vertex format */
|
||||
struct vertex_info vertex_info;
|
||||
|
|
|
|||
|
|
@ -52,26 +52,32 @@ softpipe_map_constant_buffers(struct softpipe_context *sp)
|
|||
uint i, vssize, gssize;
|
||||
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
if (sp->constants[i] && sp->constants[i]->size)
|
||||
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i],
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
uint j;
|
||||
|
||||
for (j = 0; j < PIPE_MAX_CONSTANT; j++) {
|
||||
if (sp->constants[i][j] && sp->constants[i][j]->size) {
|
||||
sp->mapped_constants[i][j] = ws->buffer_map(ws,
|
||||
sp->constants[i][j],
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sp->constants[PIPE_SHADER_VERTEX])
|
||||
vssize = sp->constants[PIPE_SHADER_VERTEX]->size;
|
||||
if (sp->constants[PIPE_SHADER_VERTEX][0])
|
||||
vssize = sp->constants[PIPE_SHADER_VERTEX][0]->size;
|
||||
else
|
||||
vssize = 0;
|
||||
|
||||
if (sp->constants[PIPE_SHADER_GEOMETRY])
|
||||
gssize = sp->constants[PIPE_SHADER_GEOMETRY]->size;
|
||||
if (sp->constants[PIPE_SHADER_GEOMETRY][0])
|
||||
gssize = sp->constants[PIPE_SHADER_GEOMETRY][0]->size;
|
||||
else
|
||||
gssize = 0;
|
||||
|
||||
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
|
||||
sp->mapped_constants[PIPE_SHADER_VERTEX],
|
||||
sp->mapped_constants[PIPE_SHADER_VERTEX][0],
|
||||
vssize);
|
||||
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY,
|
||||
sp->mapped_constants[PIPE_SHADER_GEOMETRY],
|
||||
sp->mapped_constants[PIPE_SHADER_GEOMETRY][0],
|
||||
gssize);
|
||||
}
|
||||
|
||||
|
|
@ -91,9 +97,14 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp)
|
|||
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0);
|
||||
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
if (sp->constants[i] && sp->constants[i]->size)
|
||||
ws->buffer_unmap(ws, sp->constants[i]);
|
||||
sp->mapped_constants[i] = NULL;
|
||||
uint j;
|
||||
|
||||
for (j = 0; j < PIPE_MAX_CONSTANT; j++) {
|
||||
if (sp->constants[i][j] && sp->constants[i][j]->size) {
|
||||
ws->buffer_unmap(ws, sp->constants[i][j]);
|
||||
}
|
||||
sp->mapped_constants[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ fs_sse_run( const struct sp_fragment_shader *base,
|
|||
tgsi_set_exec_mask(machine, 1, 1, 1, 1);
|
||||
|
||||
shader->func( machine,
|
||||
machine->Consts,
|
||||
(const float (*)[4])machine->Consts[0],
|
||||
(const float (*)[4])shader->immediates,
|
||||
machine->InterpCoefs
|
||||
/*, &machine->QuadPos*/
|
||||
|
|
|
|||
|
|
@ -107,10 +107,11 @@ shade_quads(struct quad_stage *qs,
|
|||
struct quad_shade_stage *qss = quad_shade_stage( qs );
|
||||
struct softpipe_context *softpipe = qs->softpipe;
|
||||
struct tgsi_exec_machine *machine = qss->machine;
|
||||
|
||||
unsigned i, pass = 0;
|
||||
|
||||
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
||||
|
||||
for (i = 0; i < PIPE_MAX_CONSTANT; i++) {
|
||||
machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i];
|
||||
}
|
||||
machine->InterpCoefs = quads[0]->coef;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
|
|
|
|||
|
|
@ -164,12 +164,12 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
|
|||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index == 0);
|
||||
assert(index < PIPE_MAX_CONSTANT);
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
/* note: reference counting */
|
||||
pipe_buffer_reference(&softpipe->constants[shader], buf);
|
||||
pipe_buffer_reference(&softpipe->constants[shader][index], buf);
|
||||
|
||||
softpipe->dirty |= SP_NEW_CONSTANTS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue