uint32_t gather_texture_start;
uint32_t ubo_start;
uint32_t ssbo_start;
- uint32_t abo_start;
uint32_t image_start;
uint32_t shader_time_start;
uint32_t plane_start[3];
dest = get_nir_dest(instr->dest);
switch (instr->intrinsic) {
- case nir_intrinsic_atomic_counter_inc:
- case nir_intrinsic_atomic_counter_dec:
- case nir_intrinsic_atomic_counter_read:
- case nir_intrinsic_atomic_counter_add:
- case nir_intrinsic_atomic_counter_min:
- case nir_intrinsic_atomic_counter_max:
- case nir_intrinsic_atomic_counter_and:
- case nir_intrinsic_atomic_counter_or:
- case nir_intrinsic_atomic_counter_xor:
- case nir_intrinsic_atomic_counter_exchange:
- case nir_intrinsic_atomic_counter_comp_swap: {
- if (stage == MESA_SHADER_FRAGMENT &&
- instr->intrinsic != nir_intrinsic_atomic_counter_read)
- brw_wm_prog_data(prog_data)->has_side_effects = true;
-
- /* Get some metadata from the image intrinsic. */
- const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
-
- /* Get the arguments of the atomic intrinsic. */
- const fs_reg offset = get_nir_src(instr->src[0]);
- const unsigned surface = (stage_prog_data->binding_table.abo_start +
- instr->const_index[0]);
- const fs_reg src0 = (info->num_srcs >= 2
- ? get_nir_src(instr->src[1]) : fs_reg());
- const fs_reg src1 = (info->num_srcs >= 3
- ? get_nir_src(instr->src[2]) : fs_reg());
- fs_reg tmp;
-
- assert(info->num_srcs <= 3);
-
- /* Emit a surface read or atomic op. */
- if (instr->intrinsic == nir_intrinsic_atomic_counter_read) {
- tmp = emit_untyped_read(bld, brw_imm_ud(surface), offset, 1, 1);
- } else {
- tmp = emit_untyped_atomic(bld, brw_imm_ud(surface), offset, src0,
- src1, 1, 1,
- get_atomic_counter_op(instr->intrinsic));
- }
-
- /* Assign the result. */
- bld.MOV(retype(dest, BRW_REGISTER_TYPE_UD), tmp);
-
- /* Mark the surface as used. */
- brw_mark_surface_used(stage_prog_data, surface);
- break;
- }
-
case nir_intrinsic_image_load:
case nir_intrinsic_image_store:
case nir_intrinsic_image_atomic_add:
return false;
}
-/**
- * Get the appropriate atomic op for an image atomic intrinsic.
- */
-unsigned
-get_atomic_counter_op(nir_intrinsic_op op)
-{
- switch (op) {
- case nir_intrinsic_atomic_counter_inc:
- return BRW_AOP_INC;
- case nir_intrinsic_atomic_counter_dec:
- return BRW_AOP_PREDEC;
- case nir_intrinsic_atomic_counter_add:
- return BRW_AOP_ADD;
- case nir_intrinsic_atomic_counter_min:
- return BRW_AOP_UMIN;
- case nir_intrinsic_atomic_counter_max:
- return BRW_AOP_UMAX;
- case nir_intrinsic_atomic_counter_and:
- return BRW_AOP_AND;
- case nir_intrinsic_atomic_counter_or:
- return BRW_AOP_OR;
- case nir_intrinsic_atomic_counter_xor:
- return BRW_AOP_XOR;
- case nir_intrinsic_atomic_counter_exchange:
- return BRW_AOP_MOV;
- case nir_intrinsic_atomic_counter_comp_swap:
- return BRW_AOP_CMPWR;
- default:
- unreachable("Not reachable.");
- }
-}
-
backend_shader::backend_shader(const struct brw_compiler *compiler,
void *log_data,
void *mem_ctx,
unsigned control_data_header_size_bits;
};
-unsigned get_atomic_counter_op(nir_intrinsic_op op);
-
#ifdef __cplusplus
}
#endif
break;
}
- case nir_intrinsic_atomic_counter_inc:
- case nir_intrinsic_atomic_counter_dec:
- case nir_intrinsic_atomic_counter_read:
- case nir_intrinsic_atomic_counter_add:
- case nir_intrinsic_atomic_counter_min:
- case nir_intrinsic_atomic_counter_max:
- case nir_intrinsic_atomic_counter_and:
- case nir_intrinsic_atomic_counter_or:
- case nir_intrinsic_atomic_counter_xor:
- case nir_intrinsic_atomic_counter_exchange:
- case nir_intrinsic_atomic_counter_comp_swap: {
- unsigned surf_index = prog_data->base.binding_table.abo_start +
- (unsigned) instr->const_index[0];
- const vec4_builder bld =
- vec4_builder(this).at_end().annotate(current_annotation, base_ir);
-
- /* Get some metadata from the image intrinsic. */
- const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
-
- /* Get the arguments of the atomic intrinsic. */
- src_reg offset = get_nir_src(instr->src[0], nir_type_int32,
- instr->num_components);
- const src_reg surface = brw_imm_ud(surf_index);
- const src_reg src0 = (info->num_srcs >= 2
- ? get_nir_src(instr->src[1]) : src_reg());
- const src_reg src1 = (info->num_srcs >= 3
- ? get_nir_src(instr->src[2]) : src_reg());
-
- src_reg tmp;
-
- dest = get_nir_dest(instr->dest);
-
- if (instr->intrinsic == nir_intrinsic_atomic_counter_read) {
- tmp = emit_untyped_read(bld, surface, offset, 1, 1);
- } else {
- tmp = emit_untyped_atomic(bld, surface, offset,
- src0, src1,
- 1, 1,
- get_atomic_counter_op(instr->intrinsic));
- }
-
- bld.MOV(retype(dest, tmp.type), tmp);
- brw_mark_surface_used(stage_prog_data, surf_index);
- break;
- }
-
case nir_intrinsic_load_ubo: {
nir_const_value *const_block_index = nir_src_as_const_value(instr->src[0]);
src_reg surf_index;
NIR_PASS_V(prog->nir, nir_lower_samplers, shProg);
NIR_PASS_V(prog->nir, nir_lower_atomics, shProg);
+ NIR_PASS_V(prog->nir, nir_lower_atomics_to_ssbo,
+ prog->nir->info.num_abos);
if (brw->ctx.Cache) {
struct blob writer;
stage_prog_data->binding_table.ubo_start = 0xd0d0d0d0;
}
- if (prog->info.num_ssbos) {
+ if (prog->info.num_ssbos || prog->info.num_abos) {
+ assert(prog->info.num_abos <= BRW_MAX_ABO);
assert(prog->info.num_ssbos <= BRW_MAX_SSBO);
stage_prog_data->binding_table.ssbo_start = next_binding_table_offset;
- next_binding_table_offset += prog->info.num_ssbos;
+ next_binding_table_offset += prog->info.num_abos + prog->info.num_ssbos;
} else {
stage_prog_data->binding_table.ssbo_start = 0xd0d0d0d0;
}
stage_prog_data->binding_table.gather_texture_start = 0xd0d0d0d0;
}
- if (prog->info.num_abos) {
- stage_prog_data->binding_table.abo_start = next_binding_table_offset;
- next_binding_table_offset += prog->info.num_abos;
- } else {
- stage_prog_data->binding_table.abo_start = 0xd0d0d0d0;
- }
-
if (prog->info.num_images) {
stage_prog_data->binding_table.image_start = next_binding_table_offset;
next_binding_table_offset += prog->info.num_images;
}
uint32_t *ssbo_surf_offsets =
- &stage_state->surf_offset[prog_data->binding_table.ssbo_start];
+ &stage_state->surf_offset[prog_data->binding_table.ssbo_start] +
+ prog->info.num_abos;
for (int i = 0; i < prog->info.num_ssbos; i++) {
struct gl_buffer_binding *binding =
{
struct gl_context *ctx = &brw->ctx;
uint32_t *surf_offsets =
- &stage_state->surf_offset[prog_data->binding_table.abo_start];
+ &stage_state->surf_offset[prog_data->binding_table.ssbo_start];
if (prog->info.num_abos) {
for (unsigned i = 0; i < prog->info.num_abos; i++) {