nir_intrinsic_instr *instr);
fs_reg get_nir_image_intrinsic_image(const brw::fs_builder &bld,
nir_intrinsic_instr *instr);
+ fs_reg get_nir_ssbo_intrinsic_index(const brw::fs_builder &bld,
+ nir_intrinsic_instr *instr);
void nir_emit_intrinsic(const brw::fs_builder &bld,
nir_intrinsic_instr *instr);
void nir_emit_tes_intrinsic(const brw::fs_builder &bld,
return bld.emit_uniformize(image);
}
+fs_reg
+fs_visitor::get_nir_ssbo_intrinsic_index(const brw::fs_builder &bld,
+ nir_intrinsic_instr *instr)
+{
+ /* SSBO stores are weird in that their index is in src[1] */
+ const unsigned src = instr->intrinsic == nir_intrinsic_store_ssbo ? 1 : 0;
+ nir_const_value *const_uniform_block =
+ nir_src_as_const_value(instr->src[src]);
+
+ fs_reg surf_index;
+ if (const_uniform_block) {
+ unsigned index = stage_prog_data->binding_table.ssbo_start +
+ const_uniform_block->u32[0];
+ surf_index = brw_imm_ud(index);
+ brw_mark_surface_used(prog_data, index);
+ } else {
+ surf_index = vgrf(glsl_type::uint_type);
+ bld.ADD(surf_index, get_nir_src(instr->src[src]),
+ brw_imm_ud(stage_prog_data->binding_table.ssbo_start));
+
+ /* Assume this may touch any UBO. It would be nice to provide
+ * a tighter bound, but the array information is already lowered away.
+ */
+ brw_mark_surface_used(prog_data,
+ stage_prog_data->binding_table.ssbo_start +
+ nir->info.num_ssbos - 1);
+ }
+
+ return surf_index;
+}
+
static unsigned
image_intrinsic_coord_components(nir_intrinsic_instr *instr)
{
case nir_intrinsic_load_ssbo: {
assert(devinfo->gen >= 7);
- nir_const_value *const_uniform_block =
- nir_src_as_const_value(instr->src[0]);
-
- fs_reg surf_index;
- if (const_uniform_block) {
- unsigned index = stage_prog_data->binding_table.ssbo_start +
- const_uniform_block->u32[0];
- surf_index = brw_imm_ud(index);
- brw_mark_surface_used(prog_data, index);
- } else {
- surf_index = vgrf(glsl_type::uint_type);
- bld.ADD(surf_index, get_nir_src(instr->src[0]),
- brw_imm_ud(stage_prog_data->binding_table.ssbo_start));
-
- /* Assume this may touch any UBO. It would be nice to provide
- * a tighter bound, but the array information is already lowered away.
- */
- brw_mark_surface_used(prog_data,
- stage_prog_data->binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
-
- fs_reg offset_reg;
- nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
- if (const_offset) {
- offset_reg = brw_imm_ud(const_offset->u32[0]);
- } else {
- offset_reg = retype(get_nir_src(instr->src[1]), BRW_REGISTER_TYPE_UD);
- }
+ fs_reg surf_index = get_nir_ssbo_intrinsic_index(bld, instr);
+ fs_reg offset_reg = get_nir_src_imm(instr->src[1]);
/* Read the vector */
do_untyped_vector_read(bld, dest, surf_index, offset_reg,
if (stage == MESA_SHADER_FRAGMENT)
brw_wm_prog_data(prog_data)->has_side_effects = true;
- /* Block index */
- fs_reg surf_index;
- nir_const_value *const_uniform_block =
- nir_src_as_const_value(instr->src[1]);
- if (const_uniform_block) {
- unsigned index = stage_prog_data->binding_table.ssbo_start +
- const_uniform_block->u32[0];
- surf_index = brw_imm_ud(index);
- brw_mark_surface_used(prog_data, index);
- } else {
- surf_index = vgrf(glsl_type::uint_type);
- bld.ADD(surf_index, get_nir_src(instr->src[1]),
- brw_imm_ud(stage_prog_data->binding_table.ssbo_start));
-
- brw_mark_surface_used(prog_data,
- stage_prog_data->binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
+ fs_reg surf_index = get_nir_ssbo_intrinsic_index(bld, instr);
/* Value */
fs_reg val_reg = get_nir_src(instr->src[0]);
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_dest(instr->dest);
- fs_reg surface;
- nir_const_value *const_surface = nir_src_as_const_value(instr->src[0]);
- if (const_surface) {
- unsigned surf_index = stage_prog_data->binding_table.ssbo_start +
- const_surface->u32[0];
- surface = brw_imm_ud(surf_index);
- brw_mark_surface_used(prog_data, surf_index);
- } else {
- surface = vgrf(glsl_type::uint_type);
- bld.ADD(surface, get_nir_src(instr->src[0]),
- brw_imm_ud(stage_prog_data->binding_table.ssbo_start));
-
- /* Assume this may touch any SSBO. This is the same we do for other
- * UBO/SSBO accesses with non-constant surface.
- */
- brw_mark_surface_used(prog_data,
- stage_prog_data->binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
-
+ fs_reg surface = get_nir_ssbo_intrinsic_index(bld, instr);
fs_reg offset = get_nir_src(instr->src[1]);
fs_reg data1;
if (op != BRW_AOP_INC && op != BRW_AOP_DEC && op != BRW_AOP_PREDEC)
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_dest(instr->dest);
- fs_reg surface;
- nir_const_value *const_surface = nir_src_as_const_value(instr->src[0]);
- if (const_surface) {
- unsigned surf_index = stage_prog_data->binding_table.ssbo_start +
- const_surface->u32[0];
- surface = brw_imm_ud(surf_index);
- brw_mark_surface_used(prog_data, surf_index);
- } else {
- surface = vgrf(glsl_type::uint_type);
- bld.ADD(surface, get_nir_src(instr->src[0]),
- brw_imm_ud(stage_prog_data->binding_table.ssbo_start));
-
- /* Assume this may touch any SSBO. This is the same we do for other
- * UBO/SSBO accesses with non-constant surface.
- */
- brw_mark_surface_used(prog_data,
- stage_prog_data->binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
-
+ fs_reg surface = get_nir_ssbo_intrinsic_index(bld, instr);
fs_reg offset = get_nir_src(instr->src[1]);
fs_reg data1 = get_nir_src(instr->src[2]);
fs_reg data2;
virtual void nir_emit_block(nir_block *block);
virtual void nir_emit_instr(nir_instr *instr);
virtual void nir_emit_load_const(nir_load_const_instr *instr);
+ src_reg get_nir_ssbo_intrinsic_index(nir_intrinsic_instr *instr);
virtual void nir_emit_intrinsic(nir_intrinsic_instr *instr);
virtual void nir_emit_alu(nir_alu_instr *instr);
virtual void nir_emit_jump(nir_jump_instr *instr);
unsigned num_components = 4);
src_reg get_nir_src(const nir_src &src,
unsigned num_components = 4);
+ src_reg get_nir_src_imm(const nir_src &src);
src_reg get_indirect_offset(nir_intrinsic_instr *instr);
dst_reg *nir_locals;
return get_nir_src(src, nir_type_int32, num_components);
}
+src_reg
+vec4_visitor::get_nir_src_imm(const nir_src &src)
+{
+ assert(nir_src_num_components(src) == 1);
+ assert(nir_src_bit_size(src) == 32);
+ nir_const_value *const_val = nir_src_as_const_value(src);
+ return const_val ? src_reg(brw_imm_d(const_val->i32[0])) :
+ get_nir_src(src, 1);
+}
+
src_reg
vec4_visitor::get_indirect_offset(nir_intrinsic_instr *instr)
{
nir_ssa_values[instr->def.index] = reg;
}
+src_reg
+vec4_visitor::get_nir_ssbo_intrinsic_index(nir_intrinsic_instr *instr)
+{
+ /* SSBO stores are weird in that their index is in src[1] */
+ const unsigned src = instr->intrinsic == nir_intrinsic_store_ssbo ? 1 : 0;
+
+ src_reg surf_index;
+ nir_const_value *const_uniform_block =
+ nir_src_as_const_value(instr->src[src]);
+ if (const_uniform_block) {
+ unsigned index = prog_data->base.binding_table.ssbo_start +
+ const_uniform_block->u32[0];
+ surf_index = brw_imm_ud(index);
+ brw_mark_surface_used(&prog_data->base, index);
+ } else {
+ surf_index = src_reg(this, glsl_type::uint_type);
+ emit(ADD(dst_reg(surf_index), get_nir_src(instr->src[src], 1),
+ brw_imm_ud(prog_data->base.binding_table.ssbo_start)));
+ surf_index = emit_uniformize(surf_index);
+
+ brw_mark_surface_used(&prog_data->base,
+ prog_data->base.binding_table.ssbo_start +
+ nir->info.num_ssbos - 1);
+ }
+
+ return surf_index;
+}
+
void
vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
{
case nir_intrinsic_store_ssbo: {
assert(devinfo->gen >= 7);
- /* Block index */
- src_reg surf_index;
- nir_const_value *const_uniform_block =
- nir_src_as_const_value(instr->src[1]);
- if (const_uniform_block) {
- unsigned index = prog_data->base.binding_table.ssbo_start +
- const_uniform_block->u32[0];
- surf_index = brw_imm_ud(index);
- brw_mark_surface_used(&prog_data->base, index);
- } else {
- surf_index = src_reg(this, glsl_type::uint_type);
- emit(ADD(dst_reg(surf_index), get_nir_src(instr->src[1], 1),
- brw_imm_ud(prog_data->base.binding_table.ssbo_start)));
- surf_index = emit_uniformize(surf_index);
-
- brw_mark_surface_used(&prog_data->base,
- prog_data->base.binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
-
- /* Offset */
- src_reg offset_reg;
- nir_const_value *const_offset = nir_src_as_const_value(instr->src[2]);
- if (const_offset) {
- offset_reg = brw_imm_ud(const_offset->u32[0]);
- } else {
- offset_reg = get_nir_src(instr->src[2], 1);
- }
+ src_reg surf_index = get_nir_ssbo_intrinsic_index(instr);
+ src_reg offset_reg = retype(get_nir_src_imm(instr->src[2]),
+ BRW_REGISTER_TYPE_UD);
/* Value */
src_reg val_reg = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_F, 4);
case nir_intrinsic_load_ssbo: {
assert(devinfo->gen >= 7);
- nir_const_value *const_uniform_block =
- nir_src_as_const_value(instr->src[0]);
-
- src_reg surf_index;
- if (const_uniform_block) {
- unsigned index = prog_data->base.binding_table.ssbo_start +
- const_uniform_block->u32[0];
- surf_index = brw_imm_ud(index);
-
- brw_mark_surface_used(&prog_data->base, index);
- } else {
- surf_index = src_reg(this, glsl_type::uint_type);
- emit(ADD(dst_reg(surf_index), get_nir_src(instr->src[0], 1),
- brw_imm_ud(prog_data->base.binding_table.ssbo_start)));
- surf_index = emit_uniformize(surf_index);
-
- /* Assume this may touch any UBO. It would be nice to provide
- * a tighter bound, but the array information is already lowered away.
- */
- brw_mark_surface_used(&prog_data->base,
- prog_data->base.binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
-
- src_reg offset_reg;
- nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
- if (const_offset) {
- offset_reg = brw_imm_ud(const_offset->u32[0]);
- } else {
- offset_reg = get_nir_src(instr->src[1], 1);
- }
+ src_reg surf_index = get_nir_ssbo_intrinsic_index(instr);
+ src_reg offset_reg = retype(get_nir_src_imm(instr->src[1]),
+ BRW_REGISTER_TYPE_UD);
/* Read the vector */
const vec4_builder bld = vec4_builder(this).at_end()
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_dest(instr->dest);
- src_reg surface;
- nir_const_value *const_surface = nir_src_as_const_value(instr->src[0]);
- if (const_surface) {
- unsigned surf_index = prog_data->base.binding_table.ssbo_start +
- const_surface->u32[0];
- surface = brw_imm_ud(surf_index);
- brw_mark_surface_used(&prog_data->base, surf_index);
- } else {
- surface = src_reg(this, glsl_type::uint_type);
- emit(ADD(dst_reg(surface), get_nir_src(instr->src[0]),
- brw_imm_ud(prog_data->base.binding_table.ssbo_start)));
-
- /* Assume this may touch any UBO. This is the same we do for other
- * UBO/SSBO accesses with non-constant surface.
- */
- brw_mark_surface_used(&prog_data->base,
- prog_data->base.binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
- }
-
+ src_reg surface = get_nir_ssbo_intrinsic_index(instr);
src_reg offset = get_nir_src(instr->src[1], 1);
src_reg data1;
if (op != BRW_AOP_INC && op != BRW_AOP_DEC && op != BRW_AOP_PREDEC)