From: Samuel Iglesias Gonsalvez <sigles...@igalia.com> Signed-off-by: Samuel Iglesias Gonsalvez <sigles...@igalia.com> --- src/mesa/drivers/dri/i965/brw_defines.h | 1 + src/mesa/drivers/dri/i965/brw_fs.cpp | 1 + src/mesa/drivers/dri/i965/brw_fs.h | 3 ++ .../dri/i965/brw_fs_channel_expressions.cpp | 2 + src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 47 +++++++++++++++++++ src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 54 ++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 3 ++ 7 files changed, 111 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index bb2c12d..9e6e35a 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -953,6 +953,7 @@ enum opcode { FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD_GEN7, FS_OPCODE_VARYING_PULL_CONSTANT_LOAD, FS_OPCODE_VARYING_PULL_CONSTANT_LOAD_GEN7, + FS_OPCODE_UNSIZED_ARRAY_LENGTH, FS_OPCODE_MOV_DISPATCH_TO_FLAGS, FS_OPCODE_DISCARD_JUMP, FS_OPCODE_SET_OMASK, diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 1019670..e6f176c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1050,6 +1050,7 @@ fs_visitor::implied_mrf_writes(fs_inst *inst) return 1; case FS_OPCODE_FB_WRITE: return 2; + case FS_OPCODE_UNSIZED_ARRAY_LENGTH: case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD: case SHADER_OPCODE_GEN4_SCRATCH_READ: return 1; diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 67d2df4..40b7ec2 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -578,6 +578,9 @@ private: struct brw_reg *src); void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src, struct brw_reg sampler_index); + void generate_unsized_array_length(fs_inst *inst, struct brw_reg dst, + struct brw_reg src, + struct brw_reg surf_index); void generate_math_gen6(fs_inst *inst, struct brw_reg dst, struct brw_reg src0, diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp index b8ed6b6..7ffddc4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp @@ -430,6 +430,8 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir) case ir_triop_vector_insert: case ir_quadop_bitfield_insert: case ir_quadop_vector: + case ir_unop_ssbo_unsized_array_length: + case ir_triop_ssbo_unsized_array_length: unreachable("should have been lowered"); case ir_unop_unpack_half_2x16_split_x: diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index 5a71a9b..eb98b4b 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -530,6 +530,50 @@ fs_generator::generate_math_g45(fs_inst *inst, } void +fs_generator::generate_unsized_array_length(fs_inst *inst, + struct brw_reg dst, + struct brw_reg src, + struct brw_reg surf_index) +{ + assert(brw->gen >= 7); + assert(surf_index.file == BRW_IMMEDIATE_VALUE); + + uint32_t simd_mode; + int rlen = 4; + + switch (inst->exec_size) { + case 8: + simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8; + break; + case 16: + simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16; + break; + default: + unreachable("Invalid width for texture instruction"); + } + + if (simd_mode == BRW_SAMPLER_SIMD_MODE_SIMD16) { + rlen = 8; + dst = vec16(dst); + } + + brw_SAMPLE(p, + retype(dst, BRW_REGISTER_TYPE_UW), + inst->base_mrf, + src, + surf_index.dw1.ud, + 0, + GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO, + rlen, /* response length */ + inst->mlen, + inst->header_size > 0, + simd_mode, + BRW_SAMPLER_RETURN_FORMAT_SINT32); + + brw_mark_surface_used(prog_data, surf_index.dw1.ud); +} + +void fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src, struct brw_reg sampler_index) { @@ -1935,6 +1979,9 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) src[0].subnr = 4 * type_sz(src[0].type); brw_MOV(p, dst, stride(src[0], 8, 4, 1)); break; + case FS_OPCODE_UNSIZED_ARRAY_LENGTH: + generate_unsized_array_length(inst, dst, src[0], src[1]); + break; case SHADER_OPCODE_TEX: case FS_OPCODE_TXB: case SHADER_OPCODE_TXD: diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index a3c10cb..179b5af 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1288,6 +1288,57 @@ fs_visitor::visit(ir_expression *ir) emit_lrp(this->result, op[0], op[1], op[2]); break; + case ir_triop_ssbo_unsized_array_length: { + ir_constant *const_uniform_block = ir->operands[0]->as_constant(); + unsigned ubo_index = const_uniform_block->value.u[0]; + ir_constant *const_offset_ir = ir->operands[1]->as_constant(); + int const_offset = const_offset_ir ? const_offset_ir->value.u[0] : 0; + ir_constant *const_stride_ir = ir->operands[2]->as_constant(); + unsigned unsized_array_stride = const_stride_ir ? const_stride_ir->value.u[0] : 1; + int reg_width = dispatch_width / 8; + + assert(shader->base.UniformBlocks[ubo_index].IsBuffer); + + /* Set LOD = 0 */ + fs_reg source = fs_reg(0); + + int mlen = 1 * reg_width; + fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen), + BRW_REGISTER_TYPE_UD, dispatch_width); + emit(LOAD_PAYLOAD(src_payload, &source, 1, 0)); + + fs_reg surf_index = fs_reg(prog_data->binding_table.ubo_start + ubo_index); + fs_reg buffer_size = vgrf(glsl_type::int_type); + + fs_inst *inst = emit(FS_OPCODE_UNSIZED_ARRAY_LENGTH, buffer_size, + src_payload, surf_index); + inst->header_size = 0; + inst->base_mrf = -1; + inst->mlen = mlen; + inst->regs_written = 4 * reg_width; + emit(inst); + + /* array.length() = + max((buffer_object_size - offset_of_array) / stride_of_array, 0) */ + fs_reg temp = vgrf(glsl_type::float_type); + emit(ADD(buffer_size, buffer_size, fs_reg(-const_offset))); + + emit(MOV(temp, buffer_size)); + + assert(unsized_array_stride > 0); + + fs_reg stride = fs_reg((float)1/unsized_array_stride); + emit(MUL(temp, temp, stride)); + emit(MOV(this->result, fs_reg(0))); + emit(CMP(reg_null_f, temp, fs_reg(0), BRW_CONDITIONAL_G)); + emit(IF(BRW_PREDICATE_NORMAL)); + { + emit(MOV(this->result, temp)); + } + emit(BRW_OPCODE_ENDIF); + break; + } + case ir_triop_csel: case ir_unop_interpolate_at_centroid: case ir_binop_interpolate_at_offset: @@ -1308,6 +1359,9 @@ fs_visitor::visit(ir_expression *ir) case ir_unop_frexp_exp: unreachable("fp64 todo"); break; + case ir_unop_ssbo_unsized_array_length: + unreachable("not reached: should be handled by lower_ubo_reference"); + break; } } diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index ff95afa..4872b63 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -548,6 +548,9 @@ brw_instruction_name(enum opcode op) case FS_OPCODE_PIXEL_Y: return "pixel_y"; + case FS_OPCODE_UNSIZED_ARRAY_LENGTH: + return "fs_unsized_array_length"; + case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD: return "uniform_pull_const"; case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD_GEN7: -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev