#include "brw_vec4.h"
#include "brw_cfg.h"
-#include "glsl/ir_print_visitor.h"
+#include "brw_vs.h"
extern "C" {
#include "main/macros.h"
swizzles[2], swizzles[3]);
}
-bool
-vec4_instruction::is_tex()
-{
- return (opcode == SHADER_OPCODE_TEX ||
- opcode == SHADER_OPCODE_TXD ||
- opcode == SHADER_OPCODE_TXF ||
- opcode == SHADER_OPCODE_TXF_MS ||
- opcode == SHADER_OPCODE_TXL ||
- opcode == SHADER_OPCODE_TXS);
-}
-
void
dst_reg::init()
{
this->fixed_hw_reg = reg.fixed_hw_reg;
}
-bool
-vec4_instruction::is_math()
-{
- return (opcode == SHADER_OPCODE_RCP ||
- opcode == SHADER_OPCODE_RSQ ||
- opcode == SHADER_OPCODE_SQRT ||
- opcode == SHADER_OPCODE_EXP2 ||
- opcode == SHADER_OPCODE_LOG2 ||
- opcode == SHADER_OPCODE_SIN ||
- opcode == SHADER_OPCODE_COS ||
- opcode == SHADER_OPCODE_INT_QUOTIENT ||
- opcode == SHADER_OPCODE_INT_REMAINDER ||
- opcode == SHADER_OPCODE_POW);
-}
-
bool
vec4_instruction::is_send_from_grf()
{
bool
vec4_visitor::can_do_source_mods(vec4_instruction *inst)
{
- if (intel->gen == 6 && inst->is_math())
+ if (brw->gen == 6 && inst->is_math())
return false;
if (inst->is_send_from_grf())
case SHADER_OPCODE_SIN:
case SHADER_OPCODE_COS:
return 1;
+ case SHADER_OPCODE_INT_QUOTIENT:
+ case SHADER_OPCODE_INT_REMAINDER:
case SHADER_OPCODE_POW:
return 2;
case VS_OPCODE_URB_WRITE:
return 2;
case VS_OPCODE_SCRATCH_WRITE:
return 3;
+ case GS_OPCODE_URB_WRITE:
+ case GS_OPCODE_THREAD_END:
+ return 0;
case SHADER_OPCODE_SHADER_TIME_ADD:
return 0;
+ case SHADER_OPCODE_TEX:
+ case SHADER_OPCODE_TXL:
+ case SHADER_OPCODE_TXD:
+ case SHADER_OPCODE_TXF:
+ case SHADER_OPCODE_TXF_MS:
+ case SHADER_OPCODE_TXS:
+ return inst->header_present ? 1 : 0;
default:
assert(!"not reached");
return inst->mlen;
foreach_list_safe(node, &this->instructions) {
vec4_instruction *inst = (vec4_instruction *)node;
- if (inst->dst.file == GRF && this->virtual_grf_use[inst->dst.reg] <= pc) {
- inst->remove();
- progress = true;
+ if (inst->dst.file == GRF) {
+ assert(this->virtual_grf_end[inst->dst.reg] >= pc);
+ if (this->virtual_grf_end[inst->dst.reg] == pc) {
+ inst->remove();
+ progress = true;
+ }
}
pc++;
break;
default:
for (int c = 0; c < 4; c++) {
- int bit = 1 << BRW_GET_SWZ(swizzle, c);
/* Skip components of the swizzle not used by the dst. */
if (!(dst_writemask & (1 << c)))
continue;
/* We don't do the reswizzling yet, so just sanity check that we
* don't have to.
*/
- assert(bit == (1 << c));
+ assert((1 << BRW_GET_SWZ(swizzle, c)) == (1 << c));
}
break;
}
/* Can't coalesce this GRF if someone else was going to
* read it later.
*/
- if (this->virtual_grf_use[inst->src[0].reg] > ip)
+ if (this->virtual_grf_end[inst->src[0].reg] > ip)
continue;
/* We need to check interference with the final destination between this
if (scan_inst->mlen)
break;
- if (intel->gen == 6) {
+ if (brw->gen == 6) {
/* gen6 math instructions must have the destination be
* GRF, so no compute-to-MRF for them.
*/
}
void
-vec4_visitor::dump_instruction(vec4_instruction *inst)
+vec4_visitor::dump_instruction(backend_instruction *be_inst)
{
+ vec4_instruction *inst = (vec4_instruction *)be_inst;
+
printf("%s ", brw_instruction_name(inst->opcode));
switch (inst->dst.file) {
printf("\n");
}
-void
-vec4_visitor::dump_instructions()
-{
- int ip = 0;
- foreach_list_safe(node, &this->instructions) {
- vec4_instruction *inst = (vec4_instruction *)node;
- printf("%d: ", ip++);
- dump_instruction(inst);
- }
-}
-
/**
* Replace each register of type ATTR in this->instructions with a reference
* to a fixed HW register.
if (inst->dst.file == ATTR) {
int grf = attribute_map[inst->dst.reg + inst->dst.reg_offset];
+ /* All attributes used in the shader need to have been assigned a
+ * hardware register by the caller
+ */
+ assert(grf != 0);
+
struct brw_reg reg = brw_vec8_grf(grf, 0);
reg.type = inst->dst.type;
reg.dw1.bits.writemask = inst->dst.writemask;
int grf = attribute_map[inst->src[i].reg + inst->src[i].reg_offset];
+ /* All attributes used in the shader need to have been assigned a
+ * hardware register by the caller
+ */
+ assert(grf != 0);
+
struct brw_reg reg = brw_vec8_grf(grf, 0);
reg.dw1.bits.swizzle = inst->src[i].swizzle;
reg.type = inst->src[i].type;
{
int nr_attributes;
int attribute_map[VERT_ATTRIB_MAX + 1];
+ memset(attribute_map, 0, sizeof(attribute_map));
nr_attributes = 0;
for (int i = 0; i < VERT_ATTRIB_MAX; i++) {
unsigned vue_entries =
MAX2(nr_attributes, prog_data->vue_map.num_slots);
- if (intel->gen == 6)
+ if (brw->gen == 6)
prog_data->urb_entry_size = ALIGN(vue_entries, 8) / 8;
else
prog_data->urb_entry_size = ALIGN(vue_entries, 4) / 4;
int
vec4_visitor::setup_uniforms(int reg)
{
+ prog_data->dispatch_grf_start_reg = reg;
+
/* The pre-gen6 VS requires that some push constants get loaded no
* matter what, or the GPU would hang.
*/
- if (intel->gen < 6 && this->uniforms == 0) {
+ if (brw->gen < 6 && this->uniforms == 0) {
this->uniform_vector_size[this->uniforms] = 1;
+ prog_data->param = reralloc(NULL, prog_data->param, const float *, 4);
for (unsigned int i = 0; i < 4; i++) {
unsigned int slot = this->uniforms * 4 + i;
static float zero = 0.0;
prog_data->nr_params = this->uniforms * 4;
- prog_data->curb_read_length = reg - 1;
+ prog_data->curb_read_length = reg - prog_data->dispatch_grf_start_reg;
return reg;
}
void
-vec4_visitor::setup_payload(void)
+vec4_vs_visitor::setup_payload(void)
{
int reg = 0;
src_reg
vec4_visitor::get_timestamp()
{
- assert(intel->gen >= 7);
+ assert(brw->gen >= 7);
src_reg ts = src_reg(brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
BRW_ARF_TIMESTAMP,
break;
}
+ opt_schedule_instructions();
+
opt_set_dependency_control();
/* If any state parameters were appended, then ParameterValues could have
void *mem_ctx,
unsigned *final_assembly_size)
{
- struct intel_context *intel = &brw->intel;
bool start_busy = false;
float start_time = 0;
- if (unlikely(intel->perf_debug)) {
- start_busy = (intel->batch.last_bo &&
- drm_intel_bo_busy(intel->batch.last_bo));
+ if (unlikely(brw->perf_debug)) {
+ start_busy = (brw->batch.last_bo &&
+ drm_intel_bo_busy(brw->batch.last_bo));
start_time = get_time();
}
shader = (brw_shader *) prog->_LinkedShaders[MESA_SHADER_VERTEX];
if (unlikely(INTEL_DEBUG & DEBUG_VS)) {
- if (shader) {
+ if (prog) {
printf("GLSL IR for native vertex shader %d:\n", prog->Name);
_mesa_print_ir(shader->ir, NULL);
printf("\n\n");
vec4_vs_visitor v(brw, c, prog_data, prog, shader, mem_ctx);
if (!v.run()) {
- prog->LinkStatus = false;
- ralloc_strcat(&prog->InfoLog, v.fail_msg);
+ if (prog) {
+ prog->LinkStatus = false;
+ ralloc_strcat(&prog->InfoLog, v.fail_msg);
+ }
+
+ _mesa_problem(NULL, "Failed to compile vertex shader: %s\n",
+ v.fail_msg);
+
return NULL;
}
- vec4_generator g(brw, prog, &c->vp->program.Base, mem_ctx,
+ vec4_generator g(brw, prog, &c->vp->program.Base, &prog_data->base, mem_ctx,
INTEL_DEBUG & DEBUG_VS);
const unsigned *generated =g.generate_assembly(&v.instructions,
final_assembly_size);
- if (unlikely(intel->perf_debug) && shader) {
+ if (unlikely(brw->perf_debug) && shader) {
if (shader->compiled_once) {
brw_vs_debug_recompile(brw, prog, &c->key);
}
- if (start_busy && !drm_intel_bo_busy(intel->batch.last_bo)) {
+ if (start_busy && !drm_intel_bo_busy(brw->batch.last_bo)) {
perf_debug("VS compile took %.03f ms and stalled the GPU\n",
(get_time() - start_time) * 1000);
}
return generated;
}
+
+bool
+brw_vec4_prog_data_compare(const struct brw_vec4_prog_data *a,
+ const struct brw_vec4_prog_data *b)
+{
+ /* Compare all the struct up to the pointers. */
+ if (memcmp(a, b, offsetof(struct brw_vec4_prog_data, param)))
+ return false;
+
+ if (memcmp(a->param, b->param, a->nr_params * sizeof(void *)))
+ return false;
+
+ if (memcmp(a->pull_param, b->pull_param, a->nr_pull_params * sizeof(void *)))
+ return false;
+
+ return true;
+}
+
+
+void
+brw_vec4_prog_data_free(const struct brw_vec4_prog_data *prog_data)
+{
+ ralloc_free((void *)prog_data->param);
+ ralloc_free((void *)prog_data->pull_param);
+}
+
+
} /* extern "C" */