summaryrefslogtreecommitdiff
path: root/libs/cairo-1.16.0/src/drm/cairo-drm-intel-brw-eu-emit.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cairo-1.16.0/src/drm/cairo-drm-intel-brw-eu-emit.c')
-rw-r--r--libs/cairo-1.16.0/src/drm/cairo-drm-intel-brw-eu-emit.c1089
1 files changed, 0 insertions, 1089 deletions
diff --git a/libs/cairo-1.16.0/src/drm/cairo-drm-intel-brw-eu-emit.c b/libs/cairo-1.16.0/src/drm/cairo-drm-intel-brw-eu-emit.c
deleted file mode 100644
index f27b238..0000000
--- a/libs/cairo-1.16.0/src/drm/cairo-drm-intel-brw-eu-emit.c
+++ /dev/null
@@ -1,1089 +0,0 @@
-/*
- Copyright (C) Intel Corp. 2006. All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
-/*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "cairoint.h"
-#include "cairo-drm-intel-brw-eu.h"
-
-#include <string.h>
-
-/***********************************************************************
- * Internal helper for constructing instructions
- */
-
-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; /* note - definitions are compatible */
-}
-
-
-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;
-
- /* These are different sizes in align1 vs align16:
- */
- 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;
- }
- }
-
- /* NEW: Set the execution size based on dest.width and
- * insn->compression_control:
- */
- 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;
-
- /* Required to set some fields in src1 as well:
- */
- insn->bits1.da1.src1_reg_file = 0; /* arf */
- 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);
-
- /* This is an oddity of the fact we're using the same
- * descriptions for registers in align_16 as align_1:
- */
- 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;
-
- /* Only src1 can be immediate in two-argument instructions.
- */
- assert(insn->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE);
-
- if (reg.file == BRW_IMMEDIATE_VALUE) {
- insn->bits3.ud = reg.dw1.ud;
- }
- else {
- /* This is a hardware restriction, which may or may not be lifted
- * in the future:
- */
- assert (reg.address_mode == BRW_ADDRESS_DIRECT);
- //assert (reg.file == BRW_GENERAL_REGISTER_FILE);
-
- 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);
-
- /* This is an oddity of the fact we're using the same
- * descriptions for registers in align_16 as align_1:
- */
- 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) {
- /* XXX presume the driver is sane! */
- 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));
-
- /* Reset this one-shot flag: */
- 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;
-}
-
-
-/***********************************************************************
- * Convenience routines.
- */
-#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));
-}
-
-
-
-
-
-/***********************************************************************
- * Comparisons, if/else/endif
- */
-
-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;
-}
-
-/* EU takes the value from the flag register and pushes it onto some
- * sort of a stack (presumably merging with any flag value already on
- * the stack). Within an if block, the flags at the top of the stack
- * control execution on each channel of the unit, eg. on each of the
- * 16 pixel values in our wm programs.
- *
- * When the matching 'else' instruction is reached (presumably by
- * countdown of the instruction count patched in by our ELSE/ENDIF
- * functions), the relevant flags are inverted.
- *
- * When the matching 'endif' instruction is reached, the flags are
- * popped off. If the stack is now empty, normal execution resumes.
- *
- * No attempt is made to deal with stack overflow (14 elements?).
- */
-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);
- }
-
- /* Override the defaults for this instruction:
- */
- 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;
-
- /* Patch the if instruction to point at this instruction.
- */
- 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) {
- /* In single program flow mode, there's no need to execute an ENDIF,
- * since we don't need to do any stack operations, and if we're executing
- * currently, we want to just continue executing.
- */
- 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);
-
- /* Patch the if or else instructions to point at this or the next
- * instruction respectively.
- */
- if (patch_insn->header.opcode == BRW_OPCODE_IF) {
- /* Automagically turn it into an IFF:
- */
- 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);
- }
-
- /* Also pop item off the stack in the endif instruction:
- */
- 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->header.mask_control = BRW_MASK_DISABLE; */
- 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->header.mask_control = BRW_MASK_DISABLE; */
- insn->bits3.if_else.pad0 = 0;
- return insn;
-}
-
-/* DO/WHILE loop:
-*/
-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);
-
- /* Override the defaults for this instruction:
- */
- 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;
- /* insn->header.mask_control = BRW_MASK_ENABLE; */
- /* insn->header.mask_control = BRW_MASK_DISABLE; */
-
- 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;
- }
-
- /* insn->header.mask_control = BRW_MASK_ENABLE; */
-
- /* insn->header.mask_control = BRW_MASK_DISABLE; */
- p->current->header.predicate_control = BRW_PREDICATE_NONE;
- return insn;
-}
-
-
-/* FORWARD JUMPS:
-*/
-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;
-}
-
-
-
-/* To integrate with the above, it makes sense that the comparison
- * instruction should populate the flag register. It might be simpler
- * just to use the flag reg for most WM tasks?
- */
-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);
-
- /* guess_execution_size(insn, src0); */
-
-
- /* Make it so that future instructions will use the computed flag
- * value until brw_set_predicate_control_flag_value() is called
- * again.
- */
- if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE &&
- dest.nr == 0) {
- p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
- p->flag_value = 0xff;
- }
-}
-
-
-
-/***********************************************************************
- * Helpers for the various SEND message types:
- */
-
-/* Invert 8 values
-*/
-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;
-
- /* Example code doesn't set predicate_control for send
- * instructions.
- */
- 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);
-}
-
-/* Use 2 send instructions to invert 16 elements
-*/
-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;
-
- /* First instruction:
- */
- 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);
-
- /* Second instruction:
- */
- 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; /* XXX */
- 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, /* bti */
- BRW_DATAPORT_OWORD_BLOCK_4_OWORDS, /* msg_control */
- BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */
- msg_length,
- 0, /* pixel scoreboard */
- 0, /* response_length */
- 0); /* eot */
- }
-
-}
-
-
-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; /* XXX */
- insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
-
- brw_instruction_set_destination(insn, dest); /* UW? */
- brw_instruction_set_source0(insn, retype(brw_vec8_grf(0), BRW_REGISTER_TYPE_UW));
-
- brw_set_dp_read_message(insn,
- 255, /* bti */
- 3, /* msg_control */
- BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
- 1, /* target cache */
- 1, /* msg_length */
- 2, /* response_length */
- 0); /* eot */
- }
-}
-
-
-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; /* XXX */
- 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, /* msg_control */
- BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */
- msg_length,
- 1, /* pixel scoreboard */
- 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) {
- /* printf("%s: zero writemask??\n", __FUNCTION__); */
- return;
- }
-
- /* Hardware doesn't do destination dependency checking on send
- * instructions properly. Add a workaround which generates the
- * dependency by other means. In practice it seems like this bug
- * only crops up for texture samples, and only where registers are
- * written by the send and then written again later without being
- * read in between. Luckily for us, we already track that
- * information and use it to modify the writemask for the
- * instruction, so that is a guide for whether a workaround is
- * needed.
- */
- 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;
- /* printf("need stall %x %x\n", newmask , writemask); */
- }
- 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; /* XXX */
- 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));
-
- /* mov (8) r9.0<1>:f r9.0<8;8,1>:f { Align1 }
- */
- brw_push_insn_state(p);
- brw_set_compression_control(p, 0);
- brw_MOV(p, reg, reg);
- brw_pop_insn_state(p);
- }
-}
-
-/* All these variables are pretty confusing - we might be better off
- * using bitmasks and macros for this, in the old style. Or perhaps
- * just having the caller instantiate the fields in dword3 itself.
- */
-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);
-}