i965: Add support for pull constants to the new FS backend.
Fixes glsl-fs-uniform-array-5, but not 6 which fails in ir_to_mesa.
This commit is contained in:
@@ -173,8 +173,6 @@ struct brw_fragment_program {
|
||||
GLuint id; /**< serial no. to identify frag progs, never re-used */
|
||||
GLboolean isGLSL; /**< really, any IF/LOOP/CONT/BREAK instructions */
|
||||
|
||||
GLboolean use_const_buffer;
|
||||
|
||||
/** for debugging, which texture units are referenced */
|
||||
GLbitfield tex_units_used;
|
||||
};
|
||||
@@ -204,12 +202,14 @@ struct brw_wm_prog_data {
|
||||
GLuint total_scratch;
|
||||
|
||||
GLuint nr_params; /**< number of float params/constants */
|
||||
GLuint nr_pull_params;
|
||||
GLboolean error;
|
||||
|
||||
/* Pointer to tracked values (only valid once
|
||||
* _mesa_load_state_parameters has been called at runtime).
|
||||
*/
|
||||
const GLfloat *param[BRW_MAX_CURBE];
|
||||
const GLfloat *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
|
||||
const GLfloat *pull_param[MAX_UNIFORMS * 4];
|
||||
};
|
||||
|
||||
struct brw_sf_prog_data {
|
||||
|
@@ -900,14 +900,19 @@ void brw_math2(struct brw_compile *p,
|
||||
void brw_oword_block_read(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset);
|
||||
uint32_t offset,
|
||||
uint32_t bind_table_index);
|
||||
|
||||
void brw_dp_READ_4( struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
GLboolean relAddr,
|
||||
GLuint location,
|
||||
GLuint bind_table_index );
|
||||
void brw_oword_block_read_scratch(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset);
|
||||
|
||||
void brw_oword_block_write_scratch(struct brw_compile *p,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset);
|
||||
|
||||
void brw_dp_READ_4_vs( struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
@@ -920,11 +925,6 @@ void brw_dp_READ_4_vs_relative(struct brw_compile *p,
|
||||
GLuint offset,
|
||||
GLuint bind_table_index);
|
||||
|
||||
void brw_oword_block_write(struct brw_compile *p,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset);
|
||||
|
||||
/* If/else/endif. Works by manipulating the execution flags on each
|
||||
* channel.
|
||||
*/
|
||||
|
@@ -1359,10 +1359,10 @@ void brw_math_16( struct brw_compile *p,
|
||||
* The offset must be aligned to oword size (16 bytes). Used for
|
||||
* register spilling.
|
||||
*/
|
||||
void brw_oword_block_write(struct brw_compile *p,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset)
|
||||
void brw_oword_block_write_scratch(struct brw_compile *p,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset)
|
||||
{
|
||||
struct intel_context *intel = &p->brw->intel;
|
||||
uint32_t msg_control;
|
||||
@@ -1458,11 +1458,11 @@ void brw_oword_block_write(struct brw_compile *p,
|
||||
* spilling.
|
||||
*/
|
||||
void
|
||||
brw_oword_block_read(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset)
|
||||
brw_oword_block_read_scratch(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
struct brw_reg mrf,
|
||||
int num_regs,
|
||||
GLuint offset)
|
||||
{
|
||||
uint32_t msg_control;
|
||||
int rlen;
|
||||
@@ -1517,65 +1517,57 @@ brw_oword_block_read(struct brw_compile *p,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a float[4] vector from the data port Data Cache (const buffer).
|
||||
* Location (in buffer) should be a multiple of 16.
|
||||
* Used for fetching shader constants.
|
||||
* If relAddr is true, we'll do an indirect fetch using the address register.
|
||||
*/
|
||||
void brw_dp_READ_4( struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
GLboolean relAddr,
|
||||
GLuint location,
|
||||
GLuint bind_table_index )
|
||||
void brw_oword_block_read(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
struct brw_reg mrf,
|
||||
uint32_t offset,
|
||||
uint32_t bind_table_index)
|
||||
{
|
||||
/* XXX: relAddr not implemented */
|
||||
GLuint msg_reg_nr = 1;
|
||||
{
|
||||
struct brw_reg b;
|
||||
brw_push_insn_state(p);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
|
||||
brw_set_mask_control(p, BRW_MASK_DISABLE);
|
||||
mrf = retype(mrf, BRW_REGISTER_TYPE_UD);
|
||||
|
||||
/* Setup MRF[1] with location/offset into const buffer */
|
||||
b = brw_message_reg(msg_reg_nr);
|
||||
b = retype(b, BRW_REGISTER_TYPE_UD);
|
||||
/* XXX I think we're setting all the dwords of MRF[1] to 'location'.
|
||||
* when the docs say only dword[2] should be set. Hmmm. But it works.
|
||||
*/
|
||||
brw_MOV(p, b, brw_imm_ud(location));
|
||||
brw_pop_insn_state(p);
|
||||
}
|
||||
brw_push_insn_state(p);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
|
||||
brw_set_mask_control(p, BRW_MASK_DISABLE);
|
||||
|
||||
{
|
||||
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
|
||||
|
||||
insn->header.predicate_control = BRW_PREDICATE_NONE;
|
||||
insn->header.compression_control = BRW_COMPRESSION_NONE;
|
||||
insn->header.destreg__conditionalmod = msg_reg_nr;
|
||||
insn->header.mask_control = BRW_MASK_DISABLE;
|
||||
|
||||
/* cast dest to a uword[8] vector */
|
||||
dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW);
|
||||
brw_MOV(p, mrf, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
|
||||
|
||||
brw_set_dest(insn, dest);
|
||||
brw_set_src0(insn, brw_null_reg());
|
||||
/* set message header global offset field (reg 0, element 2) */
|
||||
brw_MOV(p,
|
||||
retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
|
||||
mrf.nr,
|
||||
2), BRW_REGISTER_TYPE_UD),
|
||||
brw_imm_ud(offset));
|
||||
|
||||
brw_set_dp_read_message(p->brw,
|
||||
insn,
|
||||
bind_table_index,
|
||||
0, /* msg_control (0 means 1 Oword) */
|
||||
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
|
||||
0, /* source cache = data cache */
|
||||
1, /* msg_length */
|
||||
1, /* response_length (1 Oword) */
|
||||
0); /* eot */
|
||||
}
|
||||
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
|
||||
insn->header.destreg__conditionalmod = mrf.nr;
|
||||
|
||||
/* cast dest to a uword[8] vector */
|
||||
dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW);
|
||||
|
||||
brw_set_dest(insn, dest);
|
||||
brw_set_src0(insn, brw_null_reg());
|
||||
|
||||
brw_set_dp_read_message(p->brw,
|
||||
insn,
|
||||
bind_table_index,
|
||||
BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW,
|
||||
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ,
|
||||
0, /* source cache = data cache */
|
||||
1, /* msg_length */
|
||||
1, /* response_length (1 reg, 2 owords!) */
|
||||
0); /* eot */
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read float[4] constant(s) from VS constant buffer.
|
||||
* For relative addressing, two float[4] constants will be read into 'dest'.
|
||||
|
@@ -286,6 +286,7 @@ fs_visitor::setup_uniform_values(int loc, const glsl_type *type)
|
||||
case GLSL_TYPE_BOOL:
|
||||
vec_values = fp->Base.Parameters->ParameterValues[loc];
|
||||
for (unsigned int i = 0; i < type->vector_elements; i++) {
|
||||
assert(c->prog_data.nr_params < ARRAY_SIZE(c->prog_data.param));
|
||||
c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
|
||||
}
|
||||
return 1;
|
||||
@@ -2230,7 +2231,8 @@ fs_visitor::generate_spill(fs_inst *inst, struct brw_reg src)
|
||||
brw_MOV(p,
|
||||
retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_UD),
|
||||
retype(src, BRW_REGISTER_TYPE_UD));
|
||||
brw_oword_block_write(p, brw_message_reg(inst->base_mrf), 1, inst->offset);
|
||||
brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf), 1,
|
||||
inst->offset);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2251,8 +2253,39 @@ fs_visitor::generate_unspill(fs_inst *inst, struct brw_reg dst)
|
||||
if (intel->gen == 4 && !intel->is_g4x)
|
||||
brw_MOV(p, brw_null_reg(), dst);
|
||||
|
||||
brw_oword_block_read(p, dst, brw_message_reg(inst->base_mrf), 1,
|
||||
inst->offset);
|
||||
brw_oword_block_read_scratch(p, dst, brw_message_reg(inst->base_mrf), 1,
|
||||
inst->offset);
|
||||
|
||||
if (intel->gen == 4 && !intel->is_g4x) {
|
||||
/* gen4 errata: destination from a send can't be used as a
|
||||
* destination until it's been read. Just read it so we don't
|
||||
* have to worry.
|
||||
*/
|
||||
brw_MOV(p, brw_null_reg(), dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fs_visitor::generate_pull_constant_load(fs_inst *inst, struct brw_reg dst)
|
||||
{
|
||||
assert(inst->mlen != 0);
|
||||
|
||||
/* Clear any post destination dependencies that would be ignored by
|
||||
* the block read. See the B-Spec for pre-gen5 send instruction.
|
||||
*
|
||||
* This could use a better solution, since texture sampling and
|
||||
* math reads could potentially run into it as well -- anywhere
|
||||
* that we have a SEND with a destination that is a register that
|
||||
* was written but not read within the last N instructions (what's
|
||||
* N? unsure). This is rare because of dead code elimination, but
|
||||
* not impossible.
|
||||
*/
|
||||
if (intel->gen == 4 && !intel->is_g4x)
|
||||
brw_MOV(p, brw_null_reg(), dst);
|
||||
|
||||
brw_oword_block_read(p, dst, brw_message_reg(inst->base_mrf),
|
||||
inst->offset, SURF_INDEX_FRAG_CONST_BUFFER);
|
||||
|
||||
if (intel->gen == 4 && !intel->is_g4x) {
|
||||
/* gen4 errata: destination from a send can't be used as a
|
||||
@@ -2433,6 +2466,66 @@ fs_visitor::split_virtual_grfs()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose accesses from the UNIFORM file to demote to using the pull
|
||||
* constant buffer.
|
||||
*
|
||||
* We allow a fragment shader to have more than the specified minimum
|
||||
* maximum number of fragment shader uniform components (64). If
|
||||
* there are too many of these, they'd fill up all of register space.
|
||||
* So, this will push some of them out to the pull constant buffer and
|
||||
* update the program to load them.
|
||||
*/
|
||||
void
|
||||
fs_visitor::setup_pull_constants()
|
||||
{
|
||||
/* Only allow 16 registers (128 uniform components) as push constants. */
|
||||
unsigned int max_uniform_components = 16 * 8;
|
||||
if (c->prog_data.nr_params <= max_uniform_components)
|
||||
return;
|
||||
|
||||
/* Just demote the end of the list. We could probably do better
|
||||
* here, demoting things that are rarely used in the program first.
|
||||
*/
|
||||
int pull_uniform_base = max_uniform_components;
|
||||
int pull_uniform_count = c->prog_data.nr_params - pull_uniform_base;
|
||||
|
||||
foreach_iter(exec_list_iterator, iter, this->instructions) {
|
||||
fs_inst *inst = (fs_inst *)iter.get();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (inst->src[i].file != UNIFORM)
|
||||
continue;
|
||||
|
||||
int uniform_nr = inst->src[i].hw_reg + inst->src[i].reg_offset;
|
||||
if (uniform_nr < pull_uniform_base)
|
||||
continue;
|
||||
|
||||
fs_reg dst = fs_reg(this, glsl_type::float_type);
|
||||
fs_inst *pull = new(mem_ctx) fs_inst(FS_OPCODE_PULL_CONSTANT_LOAD,
|
||||
dst);
|
||||
pull->offset = ((uniform_nr - pull_uniform_base) * 4) & ~15;
|
||||
pull->ir = inst->ir;
|
||||
pull->annotation = inst->annotation;
|
||||
pull->base_mrf = 14;
|
||||
pull->mlen = 1;
|
||||
|
||||
inst->insert_before(pull);
|
||||
|
||||
inst->src[i].file = GRF;
|
||||
inst->src[i].reg = dst.reg;
|
||||
inst->src[i].reg_offset = 0;
|
||||
inst->src[i].smear = (uniform_nr - pull_uniform_base) & 3;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < pull_uniform_count; i++) {
|
||||
c->prog_data.pull_param[i] = c->prog_data.param[pull_uniform_base + i];
|
||||
}
|
||||
c->prog_data.nr_params -= pull_uniform_count;
|
||||
c->prog_data.nr_pull_params = pull_uniform_count;
|
||||
}
|
||||
|
||||
void
|
||||
fs_visitor::calculate_live_intervals()
|
||||
{
|
||||
@@ -2721,6 +2814,7 @@ fs_visitor::register_coalesce()
|
||||
scan_inst->src[i].reg_offset = inst->src[0].reg_offset;
|
||||
scan_inst->src[i].abs |= inst->src[0].abs;
|
||||
scan_inst->src[i].negate ^= inst->src[0].negate;
|
||||
scan_inst->src[i].smear = inst->src[0].smear;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2749,7 +2843,7 @@ fs_visitor::compute_to_mrf()
|
||||
inst->predicated ||
|
||||
inst->dst.file != MRF || inst->src[0].file != GRF ||
|
||||
inst->dst.type != inst->src[0].type ||
|
||||
inst->src[0].abs || inst->src[0].negate)
|
||||
inst->src[0].abs || inst->src[0].negate || inst->src[0].smear != -1)
|
||||
continue;
|
||||
|
||||
/* Can't compute-to-MRF this GRF if someone else was going to
|
||||
@@ -2897,8 +2991,13 @@ static struct brw_reg brw_reg_from_fs_reg(fs_reg *reg)
|
||||
case GRF:
|
||||
case ARF:
|
||||
case MRF:
|
||||
brw_reg = brw_vec8_reg(reg->file,
|
||||
reg->hw_reg, 0);
|
||||
if (reg->smear == -1) {
|
||||
brw_reg = brw_vec8_reg(reg->file,
|
||||
reg->hw_reg, 0);
|
||||
} else {
|
||||
brw_reg = brw_vec1_reg(reg->file,
|
||||
reg->hw_reg, reg->smear);
|
||||
}
|
||||
brw_reg = retype(brw_reg, reg->type);
|
||||
break;
|
||||
case IMM:
|
||||
@@ -3136,6 +3235,10 @@ fs_visitor::generate_code()
|
||||
generate_unspill(inst, dst);
|
||||
break;
|
||||
|
||||
case FS_OPCODE_PULL_CONSTANT_LOAD:
|
||||
generate_pull_constant_load(inst, dst);
|
||||
break;
|
||||
|
||||
case FS_OPCODE_FB_WRITE:
|
||||
generate_fb_write(inst);
|
||||
break;
|
||||
@@ -3221,6 +3324,7 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
v.emit_fb_writes();
|
||||
|
||||
v.split_virtual_grfs();
|
||||
v.setup_pull_constants();
|
||||
|
||||
v.assign_curb_setup();
|
||||
v.assign_urb_setup();
|
||||
|
@@ -76,6 +76,7 @@ enum fs_opcodes {
|
||||
FS_OPCODE_DISCARD_AND,
|
||||
FS_OPCODE_SPILL,
|
||||
FS_OPCODE_UNSPILL,
|
||||
FS_OPCODE_PULL_CONSTANT_LOAD,
|
||||
};
|
||||
|
||||
|
||||
@@ -100,6 +101,7 @@ public:
|
||||
this->negate = 0;
|
||||
this->abs = 0;
|
||||
this->hw_reg = -1;
|
||||
this->smear = -1;
|
||||
}
|
||||
|
||||
/** Generic unset register constructor. */
|
||||
@@ -162,6 +164,7 @@ public:
|
||||
bool negate;
|
||||
bool abs;
|
||||
struct brw_reg fixed_hw_reg;
|
||||
int smear; /* -1, or a channel of the reg to smear to all channels. */
|
||||
|
||||
/** Value for file == BRW_IMMMEDIATE_FILE */
|
||||
union {
|
||||
@@ -366,6 +369,7 @@ public:
|
||||
int choose_spill_reg(struct ra_graph *g);
|
||||
void spill_reg(int spill_reg);
|
||||
void split_virtual_grfs();
|
||||
void setup_pull_constants();
|
||||
void calculate_live_intervals();
|
||||
bool propagate_constants();
|
||||
bool register_coalesce();
|
||||
@@ -384,6 +388,7 @@ public:
|
||||
void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
|
||||
void generate_spill(fs_inst *inst, struct brw_reg src);
|
||||
void generate_unspill(fs_inst *inst, struct brw_reg dst);
|
||||
void generate_pull_constant_load(fs_inst *inst, struct brw_reg dst);
|
||||
|
||||
void emit_dummy_fs();
|
||||
fs_reg *emit_fragcoord_interpolation(ir_variable *ir);
|
||||
|
@@ -401,6 +401,7 @@ fs_visitor::spill_reg(int spill_reg)
|
||||
spill_src.reg_offset = 0;
|
||||
spill_src.abs = false;
|
||||
spill_src.negate = false;
|
||||
spill_src.smear = -1;
|
||||
|
||||
for (int chan = 0; chan < size; chan++) {
|
||||
fs_inst *spill_inst = new(mem_ctx) fs_inst(FS_OPCODE_SPILL,
|
||||
|
@@ -1576,7 +1576,7 @@ static void emit_spill( struct brw_wm_compile *c,
|
||||
mov (1) r0.2<1>:d 0x00000080:d { Align1 NoMask }
|
||||
send (16) null.0<1>:uw m1 r0.0<8;8,1>:uw 0x053003ff:ud { Align1 }
|
||||
*/
|
||||
brw_oword_block_write(p, brw_message_reg(1), 2, slot);
|
||||
brw_oword_block_write_scratch(p, brw_message_reg(1), 2, slot);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -307,21 +307,20 @@ static void prealloc_reg(struct brw_wm_compile *c)
|
||||
|
||||
/* use a real constant buffer, or just use a section of the GRF? */
|
||||
/* XXX this heuristic may need adjustment... */
|
||||
if ((nr_params + nr_temps) * 4 + reg_index > 80)
|
||||
c->fp->use_const_buffer = GL_TRUE;
|
||||
else
|
||||
c->fp->use_const_buffer = GL_FALSE;
|
||||
if ((nr_params + nr_temps) * 4 + reg_index > 80) {
|
||||
for (i = 0; i < nr_params; i++) {
|
||||
float *pv = c->fp->program.Base.Parameters->ParameterValues[i];
|
||||
for (j = 0; j < 4; j++) {
|
||||
c->prog_data.pull_param[c->prog_data.nr_pull_params] = &pv[j];
|
||||
c->prog_data.nr_pull_params++;
|
||||
}
|
||||
}
|
||||
|
||||
c->prog_data.nr_params = 0;
|
||||
}
|
||||
/*printf("WM use_const_buffer = %d\n", c->fp->use_const_buffer);*/
|
||||
|
||||
if (c->fp->use_const_buffer) {
|
||||
/* We'll use a real constant buffer and fetch constants from
|
||||
* it with a dataport read message.
|
||||
*/
|
||||
|
||||
/* number of float constants in CURBE */
|
||||
c->prog_data.nr_params = 0;
|
||||
}
|
||||
else {
|
||||
if (!c->prog_data.nr_pull_params) {
|
||||
const struct gl_program_parameter_list *plist =
|
||||
c->fp->program.Base.Parameters;
|
||||
int index = 0;
|
||||
@@ -463,7 +462,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
|
||||
* They'll be found in these registers.
|
||||
* XXX alloc these on demand!
|
||||
*/
|
||||
if (c->fp->use_const_buffer) {
|
||||
if (c->prog_data.nr_pull_params) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
c->current_const[i].index = -1;
|
||||
c->current_const[i].reg = brw_vec8_grf(alloc_grf(c), 0);
|
||||
@@ -501,12 +500,11 @@ static void fetch_constants(struct brw_wm_compile *c,
|
||||
#endif
|
||||
|
||||
/* need to fetch the constant now */
|
||||
brw_dp_READ_4(p,
|
||||
c->current_const[i].reg, /* writeback dest */
|
||||
src->RelAddr, /* relative indexing? */
|
||||
16 * src->Index, /* byte offset */
|
||||
SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */
|
||||
);
|
||||
brw_oword_block_read(p,
|
||||
c->current_const[i].reg,
|
||||
brw_message_reg(1),
|
||||
16 * src->Index,
|
||||
SURF_INDEX_FRAG_CONST_BUFFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,7 +604,7 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c,
|
||||
}
|
||||
}
|
||||
|
||||
if (c->fp->use_const_buffer &&
|
||||
if (c->prog_data.nr_pull_params &&
|
||||
(src->File == PROGRAM_STATE_VAR ||
|
||||
src->File == PROGRAM_CONSTANT ||
|
||||
src->File == PROGRAM_UNIFORM)) {
|
||||
@@ -729,7 +727,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
|
||||
#endif
|
||||
|
||||
/* fetch any constants that this instruction needs */
|
||||
if (c->fp->use_const_buffer)
|
||||
if (c->prog_data.nr_pull_params)
|
||||
fetch_constants(c, inst);
|
||||
|
||||
if (inst->Opcode != OPCODE_ARL) {
|
||||
|
@@ -319,13 +319,14 @@ prepare_wm_constants(struct brw_context *brw)
|
||||
struct intel_context *intel = &brw->intel;
|
||||
struct brw_fragment_program *fp =
|
||||
(struct brw_fragment_program *) brw->fragment_program;
|
||||
const struct gl_program_parameter_list *params = fp->program.Base.Parameters;
|
||||
const int size = params->NumParameters * 4 * sizeof(GLfloat);
|
||||
const int size = brw->wm.prog_data->nr_pull_params * sizeof(float);
|
||||
float *constants;
|
||||
unsigned int i;
|
||||
|
||||
_mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
|
||||
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
if (!fp->use_const_buffer) {
|
||||
if (brw->wm.prog_data->nr_pull_params == 0) {
|
||||
if (brw->wm.const_bo) {
|
||||
drm_intel_bo_unreference(brw->wm.const_bo);
|
||||
brw->wm.const_bo = NULL;
|
||||
@@ -335,11 +336,18 @@ prepare_wm_constants(struct brw_context *brw)
|
||||
}
|
||||
|
||||
drm_intel_bo_unreference(brw->wm.const_bo);
|
||||
brw->wm.const_bo = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer",
|
||||
brw->wm.const_bo = drm_intel_bo_alloc(intel->bufmgr, "WM const bo",
|
||||
size, 64);
|
||||
|
||||
/* _NEW_PROGRAM_CONSTANTS */
|
||||
drm_intel_bo_subdata(brw->wm.const_bo, 0, size, params->ParameterValues);
|
||||
drm_intel_gem_bo_map_gtt(brw->wm.const_bo);
|
||||
constants = brw->wm.const_bo->virtual;
|
||||
for (i = 0; i < brw->wm.prog_data->nr_pull_params; i++) {
|
||||
constants[i] = *brw->wm.prog_data->pull_param[i];
|
||||
}
|
||||
drm_intel_gem_bo_unmap_gtt(brw->wm.const_bo);
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_WM_CONSTBUF;
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_wm_constants = {
|
||||
|
@@ -87,7 +87,7 @@ upload_wm_state(struct brw_context *brw)
|
||||
brw_fragment_program_const(brw->fragment_program);
|
||||
uint32_t dw2, dw4, dw5, dw6;
|
||||
|
||||
if (fp->use_const_buffer || brw->wm.prog_data->nr_params == 0) {
|
||||
if (brw->wm.prog_data->nr_params == 0) {
|
||||
/* Disable the push constant buffers. */
|
||||
BEGIN_BATCH(5);
|
||||
OUT_BATCH(CMD_3D_CONSTANT_PS_STATE << 16 | (5 - 2));
|
||||
|
Reference in New Issue
Block a user