cairo-drm-intel-brw-eu-emit.c [plain text]
#include "cairoint.h"
#include "cairo-drm-intel-brw-eu.h"
#include <string.h>
static void guess_execution_size( struct brw_instruction *insn,
struct brw_reg reg )
{
if (reg.width == BRW_WIDTH_8 &&
insn->header.compression_control == BRW_COMPRESSION_COMPRESSED)
insn->header.execution_size = BRW_EXECUTE_16;
else
insn->header.execution_size = reg.width;
}
void
brw_instruction_set_destination (struct brw_instruction *insn,
struct brw_reg dest)
{
insn->bits1.da1.dest_reg_file = dest.file;
insn->bits1.da1.dest_reg_type = dest.type;
insn->bits1.da1.dest_address_mode = dest.address_mode;
if (dest.address_mode == BRW_ADDRESS_DIRECT) {
insn->bits1.da1.dest_reg_nr = dest.nr;
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits1.da1.dest_subreg_nr = dest.subnr;
if (dest.hstride == BRW_HORIZONTAL_STRIDE_0)
dest.hstride = BRW_HORIZONTAL_STRIDE_1;
insn->bits1.da1.dest_horiz_stride = dest.hstride;
} else {
insn->bits1.da16.dest_subreg_nr = dest.subnr / 16;
insn->bits1.da16.dest_writemask = dest.dw1.bits.writemask;
}
} else {
insn->bits1.ia1.dest_subreg_nr = dest.subnr;
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits1.ia1.dest_indirect_offset = dest.dw1.bits.indirect_offset;
if (dest.hstride == BRW_HORIZONTAL_STRIDE_0)
dest.hstride = BRW_HORIZONTAL_STRIDE_1;
insn->bits1.ia1.dest_horiz_stride = dest.hstride;
} else {
insn->bits1.ia16.dest_indirect_offset = dest.dw1.bits.indirect_offset;
}
}
guess_execution_size(insn, dest);
}
void
brw_instruction_set_source0 (struct brw_instruction *insn,
struct brw_reg reg)
{
assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
insn->bits1.da1.src0_reg_file = reg.file;
insn->bits1.da1.src0_reg_type = reg.type;
insn->bits2.da1.src0_abs = reg.abs;
insn->bits2.da1.src0_negate = reg.negate;
insn->bits2.da1.src0_address_mode = reg.address_mode;
if (reg.file == BRW_IMMEDIATE_VALUE) {
insn->bits3.ud = reg.dw1.ud;
insn->bits1.da1.src1_reg_file = 0;
insn->bits1.da1.src1_reg_type = reg.type;
} else {
if (reg.address_mode == BRW_ADDRESS_DIRECT) {
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits2.da1.src0_subreg_nr = reg.subnr;
insn->bits2.da1.src0_reg_nr = reg.nr;
} else {
insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
insn->bits2.da16.src0_reg_nr = reg.nr;
}
} else {
insn->bits2.ia1.src0_subreg_nr = reg.subnr;
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits2.ia1.src0_indirect_offset = reg.dw1.bits.indirect_offset;
} else {
insn->bits2.ia16.src0_subreg_nr = reg.dw1.bits.indirect_offset;
}
}
if (insn->header.access_mode == BRW_ALIGN_1) {
if (reg.width == BRW_WIDTH_1 &&
insn->header.execution_size == BRW_EXECUTE_1) {
insn->bits2.da1.src0_horiz_stride = BRW_HORIZONTAL_STRIDE_0;
insn->bits2.da1.src0_width = BRW_WIDTH_1;
insn->bits2.da1.src0_vert_stride = BRW_VERTICAL_STRIDE_0;
} else {
insn->bits2.da1.src0_horiz_stride = reg.hstride;
insn->bits2.da1.src0_width = reg.width;
insn->bits2.da1.src0_vert_stride = reg.vstride;
}
} else {
insn->bits2.da16.src0_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X);
insn->bits2.da16.src0_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y);
insn->bits2.da16.src0_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z);
insn->bits2.da16.src0_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W);
if (reg.vstride == BRW_VERTICAL_STRIDE_8)
insn->bits2.da16.src0_vert_stride = BRW_VERTICAL_STRIDE_4;
else
insn->bits2.da16.src0_vert_stride = reg.vstride;
}
}
}
void brw_set_src1( struct brw_instruction *insn,
struct brw_reg reg )
{
assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
insn->bits1.da1.src1_reg_file = reg.file;
insn->bits1.da1.src1_reg_type = reg.type;
insn->bits3.da1.src1_abs = reg.abs;
insn->bits3.da1.src1_negate = reg.negate;
assert(insn->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE);
if (reg.file == BRW_IMMEDIATE_VALUE) {
insn->bits3.ud = reg.dw1.ud;
}
else {
assert (reg.address_mode == BRW_ADDRESS_DIRECT);
if (insn->header.access_mode == BRW_ALIGN_1) {
insn->bits3.da1.src1_subreg_nr = reg.subnr;
insn->bits3.da1.src1_reg_nr = reg.nr;
}
else {
insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
insn->bits3.da16.src1_reg_nr = reg.nr;
}
if (insn->header.access_mode == BRW_ALIGN_1) {
if (reg.width == BRW_WIDTH_1 &&
insn->header.execution_size == BRW_EXECUTE_1) {
insn->bits3.da1.src1_horiz_stride = BRW_HORIZONTAL_STRIDE_0;
insn->bits3.da1.src1_width = BRW_WIDTH_1;
insn->bits3.da1.src1_vert_stride = BRW_VERTICAL_STRIDE_0;
}
else {
insn->bits3.da1.src1_horiz_stride = reg.hstride;
insn->bits3.da1.src1_width = reg.width;
insn->bits3.da1.src1_vert_stride = reg.vstride;
}
}
else {
insn->bits3.da16.src1_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X);
insn->bits3.da16.src1_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y);
insn->bits3.da16.src1_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z);
insn->bits3.da16.src1_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W);
if (reg.vstride == BRW_VERTICAL_STRIDE_8)
insn->bits3.da16.src1_vert_stride = BRW_VERTICAL_STRIDE_4;
else
insn->bits3.da16.src1_vert_stride = reg.vstride;
}
}
}
static void brw_set_math_message( struct brw_instruction *insn,
uint32_t msg_length,
uint32_t response_length,
uint32_t function,
uint32_t integer_type,
int low_precision,
int saturate,
uint32_t dataType )
{
brw_set_src1 (insn, brw_imm_d (0));
insn->bits3.math.function = function;
insn->bits3.math.int_type = integer_type;
insn->bits3.math.precision = low_precision;
insn->bits3.math.saturate = saturate;
insn->bits3.math.data_type = dataType;
insn->bits3.math.response_length = response_length;
insn->bits3.math.msg_length = msg_length;
insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH;
insn->bits3.math.end_of_thread = 0;
}
static void brw_set_urb_message( struct brw_instruction *insn,
int allocate,
int used,
uint32_t msg_length,
uint32_t response_length,
int end_of_thread,
int complete,
uint32_t offset,
uint32_t swizzle_control )
{
brw_set_src1 (insn, brw_imm_d (0));
insn->bits3.urb.opcode = 0;
insn->bits3.urb.offset = offset;
insn->bits3.urb.swizzle_control = swizzle_control;
insn->bits3.urb.allocate = allocate;
insn->bits3.urb.used = used;
insn->bits3.urb.complete = complete;
insn->bits3.urb.response_length = response_length;
insn->bits3.urb.msg_length = msg_length;
insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB;
insn->bits3.urb.end_of_thread = end_of_thread;
}
void
brw_instruction_set_dp_write_message (struct brw_instruction *insn,
uint32_t binding_table_index,
uint32_t msg_control,
uint32_t msg_type,
uint32_t msg_length,
uint32_t pixel_scoreboard_clear,
uint32_t response_length,
uint32_t end_of_thread)
{
brw_set_src1 (insn, brw_imm_d (0));
insn->bits3.dp_write.binding_table_index = binding_table_index;
insn->bits3.dp_write.msg_control = msg_control;
insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
insn->bits3.dp_write.msg_type = msg_type;
insn->bits3.dp_write.send_commit_msg = 0;
insn->bits3.dp_write.response_length = response_length;
insn->bits3.dp_write.msg_length = msg_length;
insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
insn->bits3.urb.end_of_thread = end_of_thread;
}
static void brw_set_dp_read_message( struct brw_instruction *insn,
uint32_t binding_table_index,
uint32_t msg_control,
uint32_t msg_type,
uint32_t target_cache,
uint32_t msg_length,
uint32_t response_length,
uint32_t end_of_thread )
{
brw_set_src1 (insn, brw_imm_d (0));
insn->bits3.dp_read.binding_table_index = binding_table_index;
insn->bits3.dp_read.msg_control = msg_control;
insn->bits3.dp_read.msg_type = msg_type;
insn->bits3.dp_read.target_cache = target_cache;
insn->bits3.dp_read.response_length = response_length;
insn->bits3.dp_read.msg_length = msg_length;
insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ;
insn->bits3.dp_read.end_of_thread = end_of_thread;
}
static void
brw_set_sampler_message (struct brw_instruction *insn,
cairo_bool_t is_g4x,
uint32_t binding_table_index,
uint32_t sampler,
uint32_t msg_type,
uint32_t response_length,
uint32_t msg_length,
cairo_bool_t eot)
{
brw_set_src1 (insn, brw_imm_d (0));
if (is_g4x) {
insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
insn->bits3.sampler_g4x.sampler = sampler;
insn->bits3.sampler_g4x.msg_type = msg_type;
insn->bits3.sampler_g4x.response_length = response_length;
insn->bits3.sampler_g4x.msg_length = msg_length;
insn->bits3.sampler_g4x.end_of_thread = eot;
insn->bits3.sampler_g4x.msg_target = BRW_MESSAGE_TARGET_SAMPLER;
} else {
insn->bits3.sampler.binding_table_index = binding_table_index;
insn->bits3.sampler.sampler = sampler;
insn->bits3.sampler.msg_type = msg_type;
insn->bits3.sampler.return_format = BRW_SAMPLER_RETURN_FORMAT_FLOAT32;
insn->bits3.sampler.response_length = response_length;
insn->bits3.sampler.msg_length = msg_length;
insn->bits3.sampler.end_of_thread = eot;
insn->bits3.sampler.msg_target = BRW_MESSAGE_TARGET_SAMPLER;
}
}
struct brw_instruction *
brw_next_instruction (struct brw_compile *p,
uint32_t opcode)
{
struct brw_instruction *insn;
assert(p->nr_insn + 1 < BRW_EU_MAX_INSN);
insn = &p->store[p->nr_insn++];
memcpy(insn, p->current, sizeof(*insn));
if (p->current->header.destreg__conditonalmod) {
p->current->header.destreg__conditonalmod = 0;
p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
}
insn->header.opcode = opcode;
return insn;
}
static struct brw_instruction *brw_alu1( struct brw_compile *p,
uint32_t opcode,
struct brw_reg dest,
struct brw_reg src )
{
struct brw_instruction *insn = brw_next_instruction(p, opcode);
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src);
return insn;
}
static struct brw_instruction *brw_alu2(struct brw_compile *p,
uint32_t opcode,
struct brw_reg dest,
struct brw_reg src0,
struct brw_reg src1 )
{
struct brw_instruction *insn = brw_next_instruction(p, opcode);
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src0);
brw_set_src1(insn, src1);
return insn;
}
#define ALU1(OP) \
struct brw_instruction *brw_##OP(struct brw_compile *p, \
struct brw_reg dest, \
struct brw_reg src0) \
{ \
return brw_alu1(p, BRW_OPCODE_##OP, dest, src0); \
}
#define ALU2(OP) \
struct brw_instruction *brw_##OP(struct brw_compile *p, \
struct brw_reg dest, \
struct brw_reg src0, \
struct brw_reg src1) \
{ \
return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1); \
}
ALU1(MOV)
ALU2(SEL)
ALU1(NOT)
ALU2(AND)
ALU2(OR)
ALU2(XOR)
ALU2(SHR)
ALU2(SHL)
ALU2(RSR)
ALU2(RSL)
ALU2(ASR)
ALU2(ADD)
ALU2(MUL)
ALU1(FRC)
ALU1(RNDD)
ALU1(RNDZ)
ALU2(MAC)
ALU2(MACH)
ALU1(LZD)
ALU2(DP4)
ALU2(DPH)
ALU2(DP3)
ALU2(DP2)
ALU2(LINE)
void brw_NOP(struct brw_compile *p)
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_NOP);
brw_instruction_set_destination(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
brw_instruction_set_source0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
brw_set_src1(insn, brw_imm_ud(0x0));
}
struct brw_instruction *brw_JMPI(struct brw_compile *p,
struct brw_reg dest,
struct brw_reg src0,
struct brw_reg src1)
{
struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1);
p->current->header.predicate_control = BRW_PREDICATE_NONE;
return insn;
}
struct brw_instruction *brw_IF(struct brw_compile *p, uint32_t execute_size)
{
struct brw_instruction *insn;
if (p->single_program_flow) {
assert(execute_size == BRW_EXECUTE_1);
insn = brw_next_instruction(p, BRW_OPCODE_ADD);
insn->header.predicate_inverse = 1;
} else {
insn = brw_next_instruction(p, BRW_OPCODE_IF);
}
brw_instruction_set_destination (insn, brw_ip_reg ());
brw_instruction_set_source0 (insn, brw_ip_reg ());
brw_set_src1 (insn, brw_imm_d (0));
insn->header.execution_size = execute_size;
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.predicate_control = BRW_PREDICATE_NORMAL;
insn->header.mask_control = BRW_MASK_ENABLE;
if (!p->single_program_flow)
insn->header.thread_control = BRW_THREAD_SWITCH;
p->current->header.predicate_control = BRW_PREDICATE_NONE;
return insn;
}
struct brw_instruction *brw_ELSE(struct brw_compile *p,
struct brw_instruction *if_insn)
{
struct brw_instruction *insn;
if (p->single_program_flow) {
insn = brw_next_instruction(p, BRW_OPCODE_ADD);
} else {
insn = brw_next_instruction(p, BRW_OPCODE_ELSE);
}
brw_instruction_set_destination (insn, brw_ip_reg ());
brw_instruction_set_source0 (insn, brw_ip_reg ());
brw_set_src1 (insn, brw_imm_d (0));
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = if_insn->header.execution_size;
insn->header.mask_control = BRW_MASK_ENABLE;
if (!p->single_program_flow)
insn->header.thread_control = BRW_THREAD_SWITCH;
if (p->single_program_flow) {
assert(if_insn->header.opcode == BRW_OPCODE_ADD);
if_insn->bits3.ud = (insn - if_insn + 1) * 16;
} else {
assert(if_insn->header.opcode == BRW_OPCODE_IF);
if_insn->bits3.if_else.jump_count = insn - if_insn;
if_insn->bits3.if_else.pop_count = 1;
if_insn->bits3.if_else.pad0 = 0;
}
return insn;
}
void brw_ENDIF(struct brw_compile *p,
struct brw_instruction *patch_insn)
{
if (p->single_program_flow) {
struct brw_instruction *next = &p->store[p->nr_insn];
assert(patch_insn->header.opcode == BRW_OPCODE_ADD);
patch_insn->bits3.ud = (next - patch_insn) * 16;
} else {
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_ENDIF);
brw_instruction_set_destination(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
brw_instruction_set_source0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
brw_set_src1 (insn, brw_imm_d (0));
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = patch_insn->header.execution_size;
insn->header.mask_control = BRW_MASK_ENABLE;
insn->header.thread_control = BRW_THREAD_SWITCH;
assert(patch_insn->bits3.if_else.jump_count == 0);
if (patch_insn->header.opcode == BRW_OPCODE_IF) {
patch_insn->header.opcode = BRW_OPCODE_IFF;
patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
patch_insn->bits3.if_else.pop_count = 0;
patch_insn->bits3.if_else.pad0 = 0;
} else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) {
patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
patch_insn->bits3.if_else.pop_count = 1;
patch_insn->bits3.if_else.pad0 = 0;
} else {
assert(0);
}
insn->bits3.if_else.jump_count = 0;
insn->bits3.if_else.pop_count = 1;
insn->bits3.if_else.pad0 = 0;
}
}
struct brw_instruction *brw_BREAK(struct brw_compile *p)
{
struct brw_instruction *insn;
insn = brw_next_instruction(p, BRW_OPCODE_BREAK);
brw_instruction_set_destination(insn, brw_ip_reg());
brw_instruction_set_source0(insn, brw_ip_reg());
brw_set_src1(insn, brw_imm_d (0));
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = BRW_EXECUTE_8;
insn->bits3.if_else.pad0 = 0;
return insn;
}
struct brw_instruction *brw_CONT(struct brw_compile *p)
{
struct brw_instruction *insn;
insn = brw_next_instruction(p, BRW_OPCODE_CONTINUE);
brw_instruction_set_destination(insn, brw_ip_reg());
brw_instruction_set_source0(insn, brw_ip_reg());
brw_set_src1 (insn, brw_imm_d (0));
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = BRW_EXECUTE_8;
insn->bits3.if_else.pad0 = 0;
return insn;
}
struct brw_instruction *brw_DO(struct brw_compile *p, uint32_t execute_size)
{
if (p->single_program_flow) {
return &p->store[p->nr_insn];
} else {
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_DO);
brw_instruction_set_destination(insn, brw_null_reg());
brw_instruction_set_source0(insn, brw_null_reg());
brw_set_src1(insn, brw_null_reg());
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.execution_size = execute_size;
insn->header.predicate_control = BRW_PREDICATE_NONE;
return insn;
}
}
struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *do_insn)
{
struct brw_instruction *insn;
if (p->single_program_flow)
insn = brw_next_instruction(p, BRW_OPCODE_ADD);
else
insn = brw_next_instruction(p, BRW_OPCODE_WHILE);
brw_instruction_set_destination(insn, brw_ip_reg());
brw_instruction_set_source0(insn, brw_ip_reg());
brw_set_src1 (insn, brw_imm_d (0));
insn->header.compression_control = BRW_COMPRESSION_NONE;
if (p->single_program_flow) {
insn->header.execution_size = BRW_EXECUTE_1;
insn->bits3.d = (do_insn - insn) * 16;
} else {
insn->header.execution_size = do_insn->header.execution_size;
assert(do_insn->header.opcode == BRW_OPCODE_DO);
insn->bits3.if_else.jump_count = do_insn - insn + 1;
insn->bits3.if_else.pop_count = 0;
insn->bits3.if_else.pad0 = 0;
}
p->current->header.predicate_control = BRW_PREDICATE_NONE;
return insn;
}
void brw_land_fwd_jump(struct brw_compile *p,
struct brw_instruction *jmp_insn)
{
struct brw_instruction *landing = &p->store[p->nr_insn];
assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE);
jmp_insn->bits3.ud = (landing - jmp_insn) - 1;
}
void brw_CMP(struct brw_compile *p,
struct brw_reg dest,
uint32_t conditional,
struct brw_reg src0,
struct brw_reg src1)
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_CMP);
insn->header.destreg__conditonalmod = conditional;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src0);
brw_set_src1(insn, src1);
if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE &&
dest.nr == 0) {
p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
p->flag_value = 0xff;
}
}
void brw_math( struct brw_compile *p,
struct brw_reg dest,
uint32_t function,
uint32_t saturate,
uint32_t msg_reg_nr,
struct brw_reg src,
uint32_t data_type,
uint32_t precision )
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_SEND);
uint32_t msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1;
uint32_t response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1;
insn->header.predicate_control = 0;
insn->header.destreg__conditonalmod = msg_reg_nr;
response_length = 1;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src);
brw_set_math_message(insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
precision,
saturate,
data_type);
}
void brw_math_16( struct brw_compile *p,
struct brw_reg dest,
uint32_t function,
uint32_t saturate,
uint32_t msg_reg_nr,
struct brw_reg src,
uint32_t precision )
{
struct brw_instruction *insn;
uint32_t msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1;
uint32_t response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1;
brw_push_insn_state(p);
brw_set_predicate_control_flag_value(p, 0xff);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
insn = brw_next_instruction(p, BRW_OPCODE_SEND);
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src);
brw_set_math_message(insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
precision,
saturate,
BRW_MATH_DATA_VECTOR);
insn = brw_next_instruction(p, BRW_OPCODE_SEND);
insn->header.compression_control = BRW_COMPRESSION_2NDHALF;
insn->header.destreg__conditonalmod = msg_reg_nr+1;
brw_instruction_set_destination(insn, offset(dest,1));
brw_instruction_set_source0(insn, src);
brw_set_math_message(insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
precision,
saturate,
BRW_MATH_DATA_VECTOR);
brw_pop_insn_state(p);
}
void brw_dp_WRITE_16( struct brw_compile *p,
struct brw_reg src,
uint32_t msg_reg_nr,
uint32_t scratch_offset )
{
{
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_MOV (p,
retype (brw_vec1_grf (0, 2), BRW_REGISTER_TYPE_D),
brw_imm_d (scratch_offset));
brw_pop_insn_state(p);
}
{
uint32_t msg_length = 3;
struct brw_reg dest = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW);
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_SEND);
insn->header.predicate_control = 0;
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src);
brw_instruction_set_dp_write_message(insn,
255,
BRW_DATAPORT_OWORD_BLOCK_4_OWORDS,
BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE,
msg_length,
0,
0,
0);
}
}
void brw_dp_READ_16( struct brw_compile *p,
struct brw_reg dest,
uint32_t msg_reg_nr,
uint32_t scratch_offset )
{
{
brw_push_insn_state(p);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_mask_control(p, BRW_MASK_DISABLE);
brw_MOV (p,
retype (brw_vec1_grf (0, 2), BRW_REGISTER_TYPE_D),
brw_imm_d (scratch_offset));
brw_pop_insn_state(p);
}
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_SEND);
insn->header.predicate_control = 0;
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, retype(brw_vec8_grf(0), BRW_REGISTER_TYPE_UW));
brw_set_dp_read_message(insn,
255,
3,
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ,
1,
1,
2,
0);
}
}
void brw_fb_WRITE(struct brw_compile *p,
struct brw_reg dest,
uint32_t msg_reg_nr,
struct brw_reg src0,
uint32_t binding_table_index,
uint32_t msg_length,
uint32_t response_length,
int eot)
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_SEND);
insn->header.predicate_control = 0;
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src0);
brw_instruction_set_dp_write_message(insn,
binding_table_index,
BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE,
BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE,
msg_length,
1,
response_length,
eot);
}
void brw_SAMPLE (struct brw_compile *p,
struct brw_reg dest,
uint32_t msg_reg_nr,
struct brw_reg src0,
uint32_t binding_table_index,
uint32_t sampler,
uint32_t writemask,
uint32_t msg_type,
uint32_t response_length,
uint32_t msg_length,
cairo_bool_t eot)
{
int need_stall = 0;
if(writemask == 0) {
return;
}
if (writemask != WRITEMASK_XYZW) {
uint32_t dst_offset = 0;
uint32_t i, newmask = 0, len = 0;
for (i = 0; i < 4; i++) {
if (writemask & (1<<i))
break;
dst_offset += 2;
}
for (; i < 4; i++) {
if (!(writemask & (1<<i)))
break;
newmask |= 1<<i;
len++;
}
if (newmask != writemask) {
need_stall = 1;
}
else {
struct brw_reg m1 = brw_message_reg(msg_reg_nr);
newmask = ~newmask & WRITEMASK_XYZW;
brw_push_insn_state(p);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_mask_control(p, BRW_MASK_DISABLE);
brw_MOV(p, m1, brw_vec8_grf(0));
brw_MOV(p, get_element_ud(m1, 2), brw_imm_ud(newmask << 12));
brw_pop_insn_state(p);
src0 = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW);
dest = offset(dest, dst_offset);
response_length = len * 2;
}
}
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_SEND);
insn->header.predicate_control = 0;
insn->header.compression_control = BRW_COMPRESSION_NONE;
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_instruction_set_destination(insn, dest);
brw_instruction_set_source0(insn, src0);
brw_set_sampler_message (insn, p->is_g4x,
binding_table_index,
sampler,
msg_type,
response_length,
msg_length,
eot);
}
if (need_stall)
{
struct brw_reg reg = vec8(offset(dest, response_length-1));
brw_push_insn_state(p);
brw_set_compression_control(p, 0);
brw_MOV(p, reg, reg);
brw_pop_insn_state(p);
}
}
void brw_urb_WRITE(struct brw_compile *p,
struct brw_reg dest,
uint32_t msg_reg_nr,
struct brw_reg src0,
int allocate,
int used,
uint32_t msg_length,
uint32_t response_length,
int eot,
int writes_complete,
uint32_t offset,
uint32_t swizzle)
{
struct brw_instruction *insn = brw_next_instruction(p, BRW_OPCODE_SEND);
assert(msg_length < 16);
brw_instruction_set_destination (insn, dest);
brw_instruction_set_source0 (insn, src0);
brw_set_src1 (insn, brw_imm_d (0));
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_set_urb_message (insn,
allocate,
used,
msg_length,
response_length,
eot,
writes_complete,
offset,
swizzle);
}