* IN THE SOFTWARE.
*/
-#include "glsl/ir.h"
+#include "compiler/glsl/ir.h"
#include "main/shaderimage.h"
#include "brw_fs.h"
#include "brw_fs_surface_builder.h"
break;
}
case MESA_SHADER_FRAGMENT:
- if (var->data.index > 0) {
+ if (key->force_dual_color_blend &&
+ var->data.location == FRAG_RESULT_DATA1) {
+ this->dual_src_output = reg;
+ this->do_dual_src = true;
+ } else if (var->data.index > 0) {
assert(var->data.location == FRAG_RESULT_DATA0);
assert(var->data.index == 1);
this->dual_src_output = reg;
case nir_op_fmin:
case nir_op_imin:
case nir_op_umin:
- if (devinfo->gen >= 6) {
- inst = bld.emit(BRW_OPCODE_SEL, result, op[0], op[1]);
- inst->conditional_mod = BRW_CONDITIONAL_L;
- } else {
- bld.CMP(bld.null_reg_d(), op[0], op[1], BRW_CONDITIONAL_L);
- inst = bld.SEL(result, op[0], op[1]);
- inst->predicate = BRW_PREDICATE_NORMAL;
- }
+ inst = bld.emit(BRW_OPCODE_SEL, result, op[0], op[1]);
+ inst->conditional_mod = BRW_CONDITIONAL_L;
inst->saturate = instr->dest.saturate;
break;
case nir_op_fmax:
case nir_op_imax:
case nir_op_umax:
- if (devinfo->gen >= 6) {
- inst = bld.emit(BRW_OPCODE_SEL, result, op[0], op[1]);
- inst->conditional_mod = BRW_CONDITIONAL_GE;
- } else {
- bld.CMP(bld.null_reg_d(), op[0], op[1], BRW_CONDITIONAL_GE);
- inst = bld.SEL(result, op[0], op[1]);
- inst->predicate = BRW_PREDICATE_NORMAL;
- }
+ inst = bld.emit(BRW_OPCODE_SEL, result, op[0], op[1]);
+ inst->conditional_mod = BRW_CONDITIONAL_GE;
inst->saturate = instr->dest.saturate;
break;
case nir_op_ubitfield_extract:
case nir_op_ibitfield_extract:
+ unreachable("should have been lowered");
+ case nir_op_ubfe:
+ case nir_op_ibfe:
bld.BFE(result, op[2], op[1], op[0]);
break;
case nir_op_bfm:
break;
case nir_op_bitfield_insert:
- unreachable("not reached: should be handled by "
- "lower_instructions::bitfield_insert_to_bfm_bfi");
+ unreachable("not reached: should have been lowered");
case nir_op_ishl:
bld.SHL(result, op[0], op[1]);
inst->predicate = BRW_PREDICATE_NORMAL;
break;
+ case nir_op_extract_u8:
+ case nir_op_extract_i8: {
+ nir_const_value *byte = nir_src_as_const_value(instr->src[1].src);
+ bld.emit(SHADER_OPCODE_EXTRACT_BYTE,
+ result, op[0], brw_imm_ud(byte->u[0]));
+ break;
+ }
+
+ case nir_op_extract_u16:
+ case nir_op_extract_i16: {
+ nir_const_value *word = nir_src_as_const_value(instr->src[1].src);
+ bld.emit(SHADER_OPCODE_EXTRACT_WORD,
+ result, op[0], brw_imm_ud(word->u[0]));
+ break;
+ }
+
default:
unreachable("unhandled instruction");
}
static brw_reg_type
get_image_base_type(const glsl_type *type)
{
- switch ((glsl_base_type)type->sampler_type) {
+ switch ((glsl_base_type)type->sampled_type) {
case GLSL_TYPE_UINT:
return BRW_REGISTER_TYPE_UD;
case GLSL_TYPE_INT:
fs_inst *inst;
if (indirect_offset.file == BAD_FILE) {
- /* Replicate the patch handle to all enabled channels */
- fs_reg patch_handle = bld.vgrf(BRW_REGISTER_TYPE_UD, 1);
- bld.MOV(patch_handle, retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD));
-
- inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, dest, patch_handle);
- inst->mlen = 1;
+ /* Arbitrarily only push up to 32 vec4 slots worth of data,
+ * which is 16 registers (since each holds 2 vec4 slots).
+ */
+ const unsigned max_push_slots = 32;
+ if (imm_offset < max_push_slots) {
+ fs_reg src = fs_reg(ATTR, imm_offset / 2, dest.type);
+ for (int i = 0; i < instr->num_components; i++) {
+ bld.MOV(offset(dest, bld, i),
+ component(src, 4 * (imm_offset % 2) + i));
+ }
+ tes_prog_data->base.urb_read_length =
+ MAX2(tes_prog_data->base.urb_read_length,
+ DIV_ROUND_UP(imm_offset + 1, 2));
+ } else {
+ /* Replicate the patch handle to all enabled channels */
+ const fs_reg srcs[] = {
+ retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD)
+ };
+ fs_reg patch_handle = bld.vgrf(BRW_REGISTER_TYPE_UD, 1);
+ bld.LOAD_PAYLOAD(patch_handle, srcs, ARRAY_SIZE(srcs), 0);
+
+ inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, dest, patch_handle);
+ inst->mlen = 1;
+ inst->offset = imm_offset;
+ inst->base_mrf = -1;
+ inst->regs_written = instr->num_components;
+ }
} else {
/* Indirect indexing - use per-slot offsets as well. */
const fs_reg srcs[] = {
inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8_PER_SLOT, dest, payload);
inst->mlen = 2;
+ inst->offset = imm_offset;
+ inst->base_mrf = -1;
+ inst->regs_written = instr->num_components;
}
- inst->offset = imm_offset;
- inst->base_mrf = -1;
- inst->regs_written = instr->num_components;
break;
}
default:
void
fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr)
{
+ unsigned texture = instr->texture_index;
unsigned sampler = instr->sampler_index;
+ fs_reg texture_reg(brw_imm_ud(texture));
fs_reg sampler_reg(brw_imm_ud(sampler));
int gather_component = instr->component;
instr->is_array;
int lod_components = 0;
- int UNUSED offset_components = 0;
fs_reg coordinate, shadow_comparitor, lod, lod2, sample_index, mcs, tex_offset;
case nir_tex_src_ms_index:
sample_index = retype(src, BRW_REGISTER_TYPE_UD);
break;
- case nir_tex_src_offset:
- tex_offset = retype(src, BRW_REGISTER_TYPE_D);
- if (instr->is_array)
- offset_components = instr->coord_components - 1;
- else
- offset_components = instr->coord_components;
+
+ case nir_tex_src_offset: {
+ nir_const_value *const_offset =
+ nir_src_as_const_value(instr->src[i].src);
+ if (const_offset) {
+ tex_offset = brw_imm_ud(brw_texture_offset(const_offset->i, 3));
+ } else {
+ tex_offset = retype(src, BRW_REGISTER_TYPE_D);
+ }
break;
+ }
+
case nir_tex_src_projector:
unreachable("should be lowered");
- case nir_tex_src_sampler_offset: {
- /* Figure out the highest possible sampler index and mark it as used */
- uint32_t max_used = sampler + instr->sampler_array_size - 1;
+ case nir_tex_src_texture_offset: {
+ /* Figure out the highest possible texture index and mark it as used */
+ uint32_t max_used = texture + instr->texture_array_size - 1;
if (instr->op == nir_texop_tg4 && devinfo->gen < 8) {
max_used += stage_prog_data->binding_table.gather_texture_start;
} else {
}
brw_mark_surface_used(prog_data, max_used);
+ /* Emit code to evaluate the actual indexing expression */
+ texture_reg = vgrf(glsl_type::uint_type);
+ bld.ADD(texture_reg, src, brw_imm_ud(texture));
+ texture_reg = bld.emit_uniformize(texture_reg);
+ break;
+ }
+
+ case nir_tex_src_sampler_offset: {
/* Emit code to evaluate the actual indexing expression */
sampler_reg = vgrf(glsl_type::uint_type);
bld.ADD(sampler_reg, src, brw_imm_ud(sampler));
if (instr->op == nir_texop_txf_ms ||
instr->op == nir_texop_samples_identical) {
if (devinfo->gen >= 7 &&
- key_tex->compressed_multisample_layout_mask & (1 << sampler)) {
- mcs = emit_mcs_fetch(coordinate, instr->coord_components, sampler_reg);
+ key_tex->compressed_multisample_layout_mask & (1 << texture)) {
+ mcs = emit_mcs_fetch(coordinate, instr->coord_components, texture_reg);
} else {
mcs = brw_imm_ud(0u);
}
}
- for (unsigned i = 0; i < 3; i++) {
- if (instr->const_offset[i] != 0) {
- assert(offset_components == 0);
- tex_offset = brw_imm_ud(brw_texture_offset(instr->const_offset, 3));
- break;
- }
- }
-
enum glsl_base_type dest_base_type =
brw_glsl_base_type_for_nir_type (instr->dest_type);
fs_reg dst = retype(get_nir_dest(instr->dest), BRW_REGISTER_TYPE_D);
fs_inst *inst = bld.emit(SHADER_OPCODE_SAMPLEINFO, dst,
bld.vgrf(BRW_REGISTER_TYPE_D, 1),
- sampler_reg);
+ texture_reg, texture_reg);
inst->mlen = 1;
inst->header_size = 1;
inst->base_mrf = -1;
emit_texture(op, dest_type, coordinate, instr->coord_components,
shadow_comparitor, lod, lod2, lod_components, sample_index,
- tex_offset, mcs, gather_component,
- is_cube_array, sampler, sampler_reg);
+ tex_offset, mcs, gather_component, is_cube_array,
+ texture, texture_reg, sampler, sampler_reg);
fs_reg dest = get_nir_dest(instr->dest);
dest.type = this->result.type;