case nir_op_f2d:
case nir_op_i2d:
case nir_op_u2d:
+ case nir_op_f2i64:
+ case nir_op_f2u64:
+ case nir_op_i2i64:
+ case nir_op_i2u64:
+ case nir_op_u2i64:
+ case nir_op_u2u64:
+ case nir_op_b2i64:
/* CHV PRM, vol07, 3D Media GPGPU Engine, Register Region Restrictions:
*
* "When source or destination is 64b (...), regioning in Align1
* data elements aligned to 64-bit. This restriction does not apply to
* BDW and later.
*/
- if (devinfo->is_cherryview || devinfo->is_broxton) {
+ if (nir_dest_bit_size(instr->dest.dest) == 64 &&
+ nir_src_bit_size(instr->src[0].src) == 32 &&
+ (devinfo->is_cherryview || devinfo->is_broxton)) {
fs_reg tmp = bld.vgrf(result.type, 1);
tmp = subscript(tmp, op[0].type, 0);
inst = bld.MOV(tmp, op[0]);
case nir_op_d2f:
case nir_op_d2i:
case nir_op_d2u:
- inst = bld.MOV(result, op[0]);
- inst->saturate = instr->dest.saturate;
+ if (instr->op == nir_op_b2i64) {
+ bld.MOV(result, negate(op[0]));
+ } else {
+ inst = bld.MOV(result, op[0]);
+ inst->saturate = instr->dest.saturate;
+ }
break;
case nir_op_f2i:
break;
}
+ case nir_op_pack_int_2x32_split:
+ bld.emit(FS_OPCODE_PACK, result, op[0], op[1]);
+ break;
+
+ case nir_op_unpack_int_2x32_split_x:
+ case nir_op_unpack_int_2x32_split_y: {
+ if (instr->op == nir_op_unpack_int_2x32_split_x)
+ bld.MOV(result, subscript(op[0], BRW_REGISTER_TYPE_UD, 0));
+ else
+ bld.MOV(result, subscript(op[0], BRW_REGISTER_TYPE_UD, 1));
+ break;
+ }
+
case nir_op_fpow:
inst = bld.emit(SHADER_OPCODE_POW, result, op[0], op[1]);
inst->saturate = instr->dest.saturate;
bld.MOV(patch_handle,
retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UD));
- if (imm_offset == 0) {
- /* This is a read of gl_TessLevelInner[], which lives in the
- * Patch URB header. The layout depends on the domain.
- */
- dst.type = BRW_REGISTER_TYPE_F;
- switch (tcs_key->tes_primitive_mode) {
- case GL_QUADS: {
- /* DWords 3-2 (reversed) */
- fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F, 4);
-
- inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, tmp, patch_handle);
- inst->offset = 0;
- inst->mlen = 1;
- inst->size_written = 4 * REG_SIZE;
-
- /* dst.xy = tmp.wz */
- bld.MOV(dst, offset(tmp, bld, 3));
- bld.MOV(offset(dst, bld, 1), offset(tmp, bld, 2));
- break;
- }
- case GL_TRIANGLES:
- /* DWord 4; hardcode offset = 1 and size_written = REG_SIZE */
- inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, dst, patch_handle);
- inst->offset = 1;
- inst->mlen = 1;
- inst->size_written = REG_SIZE;
- break;
- case GL_ISOLINES:
- /* All channels are undefined. */
- break;
- default:
- unreachable("Bogus tessellation domain");
- }
- } else if (imm_offset == 1) {
- /* This is a read of gl_TessLevelOuter[], which lives in the
- * Patch URB header. The layout depends on the domain.
- */
- dst.type = BRW_REGISTER_TYPE_F;
-
- fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F, 4);
- inst = bld.emit(SHADER_OPCODE_URB_READ_SIMD8, tmp, patch_handle);
- inst->offset = 1;
- inst->mlen = 1;
- inst->size_written = 4 * REG_SIZE;
-
- /* Reswizzle: WZYX */
- fs_reg srcs[4] = {
- offset(tmp, bld, 3),
- offset(tmp, bld, 2),
- offset(tmp, bld, 1),
- offset(tmp, bld, 0),
- };
-
- unsigned num_components;
- switch (tcs_key->tes_primitive_mode) {
- case GL_QUADS:
- num_components = 4;
- break;
- case GL_TRIANGLES:
- num_components = 3;
- break;
- case GL_ISOLINES:
- /* Isolines are not reversed; swizzle .zw -> .xy */
- srcs[0] = offset(tmp, bld, 2);
- srcs[1] = offset(tmp, bld, 3);
- num_components = 2;
- break;
- default:
- unreachable("Bogus tessellation domain");
- }
- bld.LOAD_PAYLOAD(dst, srcs, num_components, 0);
- } else {
+ {
if (first_component != 0) {
unsigned read_components =
instr->num_components + first_component;
if (indirect_offset.file != BAD_FILE) {
srcs[header_regs++] = indirect_offset;
- } else if (!is_passthrough_shader) {
- if (imm_offset == 0) {
- value.type = BRW_REGISTER_TYPE_F;
-
- mask &= (1 << tesslevel_inner_components(tcs_key->tes_primitive_mode)) - 1;
-
- /* This is a write to gl_TessLevelInner[], which lives in the
- * Patch URB header. The layout depends on the domain.
- */
- switch (tcs_key->tes_primitive_mode) {
- case GL_QUADS:
- /* gl_TessLevelInner[].xy lives at DWords 3-2 (reversed).
- * We use an XXYX swizzle to reverse put .xy in the .wz
- * channels, and use a .zw writemask.
- */
- mask = writemask_for_backwards_vector(mask);
- swiz = BRW_SWIZZLE4(0, 0, 1, 0);
- break;
- case GL_TRIANGLES:
- /* gl_TessLevelInner[].x lives at DWord 4, so we set the
- * writemask to X and bump the URB offset by 1.
- */
- imm_offset = 1;
- break;
- case GL_ISOLINES:
- /* Skip; gl_TessLevelInner[] doesn't exist for isolines. */
- return;
- default:
- unreachable("Bogus tessellation domain");
- }
- } else if (imm_offset == 1) {
- /* This is a write to gl_TessLevelOuter[] which lives in the
- * Patch URB Header at DWords 4-7. However, it's reversed, so
- * instead of .xyzw we have .wzyx.
- */
- value.type = BRW_REGISTER_TYPE_F;
-
- mask &= (1 << tesslevel_outer_components(tcs_key->tes_primitive_mode)) - 1;
-
- if (tcs_key->tes_primitive_mode == GL_ISOLINES) {
- /* Isolines .xy should be stored in .zw, in order. */
- swiz = BRW_SWIZZLE4(0, 0, 0, 1);
- mask <<= 2;
- } else {
- /* Other domains are reversed; store .wzyx instead of .xyzw */
- swiz = BRW_SWIZZLE_WZYX;
- mask = writemask_for_backwards_vector(mask);
- }
- }
}
if (mask == 0)
}
break;
- case nir_intrinsic_load_tess_level_outer:
- /* When the TES reads gl_TessLevelOuter, we ensure that the patch header
- * appears as a push-model input. So, we can simply use the ATTR file
- * rather than issuing URB read messages. The data is stored in the
- * high DWords in reverse order - DWord 7 contains .x, DWord 6 contains
- * .y, and so on.
- */
- switch (tes_prog_data->domain) {
- case BRW_TESS_DOMAIN_QUAD:
- for (unsigned i = 0; i < 4; i++)
- bld.MOV(offset(dest, bld, i), component(fs_reg(ATTR, 0), 7 - i));
- break;
- case BRW_TESS_DOMAIN_TRI:
- for (unsigned i = 0; i < 3; i++)
- bld.MOV(offset(dest, bld, i), component(fs_reg(ATTR, 0), 7 - i));
- break;
- case BRW_TESS_DOMAIN_ISOLINE:
- for (unsigned i = 0; i < 2; i++)
- bld.MOV(offset(dest, bld, i), component(fs_reg(ATTR, 0), 6 + i));
- break;
- }
- break;
-
- case nir_intrinsic_load_tess_level_inner:
- /* When the TES reads gl_TessLevelInner, we ensure that the patch header
- * appears as a push-model input. So, we can simply use the ATTR file
- * rather than issuing URB read messages.
- */
- switch (tes_prog_data->domain) {
- case BRW_TESS_DOMAIN_QUAD:
- bld.MOV(dest, component(fs_reg(ATTR, 0), 3));
- bld.MOV(offset(dest, bld, 1), component(fs_reg(ATTR, 0), 2));
- break;
- case BRW_TESS_DOMAIN_TRI:
- bld.MOV(dest, component(fs_reg(ATTR, 0), 4));
- break;
- case BRW_TESS_DOMAIN_ISOLINE:
- /* ignore - value is undefined */
- break;
- }
- break;
-
case nir_intrinsic_load_input:
case nir_intrinsic_load_per_vertex_input: {
fs_reg indirect_offset = get_indirect_offset(instr);
* and we have to split it if necessary.
*/
const unsigned type_size = type_sz(dest.type);
- const fs_builder ubld = bld.exec_all().group(4, 0);
- const fs_reg packed_consts = ubld.vgrf(BRW_REGISTER_TYPE_F);
+ const unsigned block_sz = 64; /* Fetch one cacheline at a time. */
+ const fs_builder ubld = bld.exec_all().group(block_sz / 4, 0);
+ const fs_reg packed_consts = ubld.vgrf(BRW_REGISTER_TYPE_UD);
for (unsigned c = 0; c < instr->num_components;) {
const unsigned base = const_offset->u32[0] + c * type_size;
-
- /* Number of usable components in the next 16B-aligned load */
+ /* Number of usable components in the next block-aligned load. */
const unsigned count = MIN2(instr->num_components - c,
- (16 - base % 16) / type_size);
+ (block_sz - base % block_sz) / type_size);
ubld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
- packed_consts, surf_index, brw_imm_ud(base & ~15));
+ packed_consts, surf_index,
+ brw_imm_ud(base & ~(block_sz - 1)));
const fs_reg consts =
- retype(byte_offset(packed_consts, base & 15), dest.type);
+ retype(byte_offset(packed_consts, base & (block_sz - 1)),
+ dest.type);
for (unsigned d = 0; d < count; d++)
bld.MOV(offset(dest, bld, c + d), component(consts, d));
* instruction allows to set the 64-bit immediate value.
*/
if (devinfo->is_haswell) {
- const fs_builder ubld = bld.exec_all();
+ const fs_builder ubld = bld.exec_all().group(1, 0);
fs_reg dst = ubld.vgrf(BRW_REGISTER_TYPE_DF, 1);
ubld.DIM(dst, brw_imm_df(v));
return component(dst, 0);