diff options
author | Jason Ekstrand <[email protected]> | 2015-11-14 08:23:27 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-11-14 08:23:27 -0800 |
commit | b5d4027c356f177f82c9ec52c138e7f85f3dbe95 (patch) | |
tree | 565f1e6cdfe425f55c30778ec5969596ba7f6219 | |
parent | 1469ccb7464836c752fa2664c36d8fae7e80606c (diff) | |
parent | c7d504ad937b084a345fd6252784435d451ab03e (diff) |
Merge branch 'wip/i965-separate-sampler-tex' into vulkan
-rw-r--r-- | src/glsl/nir/nir.c | 8 | ||||
-rw-r--r-- | src/glsl/nir/nir.h | 28 | ||||
-rw-r--r-- | src/glsl/nir/nir_instr_set.c | 13 | ||||
-rw-r--r-- | src/glsl/nir/nir_lower_samplers.c | 15 | ||||
-rw-r--r-- | src/glsl/nir/nir_print.c | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_blorp_blit_eu.cpp | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 47 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 20 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 25 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 27 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 12 | ||||
-rw-r--r-- | src/mesa/program/prog_to_nir.c | 1 |
16 files changed, 181 insertions, 74 deletions
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c index bb7a5fa5835..3157ff82d99 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -488,8 +488,10 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs) for (unsigned i = 0; i < num_srcs; i++) src_init(&instr->src[i].src); + instr->texture_index = 0; + instr->texture_array_size = 0; + instr->texture = NULL; instr->sampler_index = 0; - instr->sampler_array_size = 0; instr->sampler = NULL; return instr; @@ -1007,6 +1009,10 @@ visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state) if (!visit_src(&instr->src[i].src, cb, state)) return false; + if (instr->texture != NULL) + if (!visit_deref_src(instr->texture, cb, state)) + return false; + if (instr->sampler != NULL) if (!visit_deref_src(instr->sampler, cb, state)) return false; diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h index 1215e58dfb8..df0e6f1f54a 100644 --- a/src/glsl/nir/nir.h +++ b/src/glsl/nir/nir.h @@ -955,6 +955,7 @@ typedef enum { nir_tex_src_ms_index, /* MSAA sample index */ nir_tex_src_ddx, nir_tex_src_ddy, + nir_tex_src_texture_offset, /* < dynamically uniform indirect offset */ nir_tex_src_sampler_offset, /* < dynamically uniform indirect offset */ nir_num_tex_src_types } nir_tex_src_type; @@ -1002,6 +1003,24 @@ typedef struct { /* gather component selector */ unsigned component : 2; + /** The texture index + * + * If this texture instruction has a nir_tex_src_texture_offset source, + * then the texture index is given by texture_index + texture_offset. + */ + unsigned texture_index; + + /** The size of the texture array or 0 if it's not an array */ + unsigned texture_array_size; + + /** The texture deref + * + * If both this and `sampler` are both NULL, use texture_index instead. + * If `texture` is NULL, but `sampler` is non-NULL, then the texture is + * implied from the sampler. + */ + nir_deref_var *texture; + /** The sampler index * * If this texture instruction has a nir_tex_src_sampler_offset source, @@ -1009,10 +1028,11 @@ typedef struct { */ unsigned sampler_index; - /** The size of the sampler array or 0 if it's not an array */ - unsigned sampler_array_size; - - nir_deref_var *sampler; /* if this is NULL, use sampler_index instead */ + /** The sampler deref + * + * If this is null, use sampler_index instead. + */ + nir_deref_var *sampler; } nir_tex_instr; static inline unsigned diff --git a/src/glsl/nir/nir_instr_set.c b/src/glsl/nir/nir_instr_set.c index d3f939fe805..eb021326097 100644 --- a/src/glsl/nir/nir_instr_set.c +++ b/src/glsl/nir/nir_instr_set.c @@ -155,8 +155,9 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr) hash = HASH(hash, instr->const_offset); unsigned component = instr->component; hash = HASH(hash, component); + hash = HASH(hash, instr->texture_index); + hash = HASH(hash, instr->texture_array_size); hash = HASH(hash, instr->sampler_index); - hash = HASH(hash, instr->sampler_array_size); assert(!instr->sampler); @@ -305,13 +306,15 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2) memcmp(tex1->const_offset, tex2->const_offset, sizeof(tex1->const_offset)) != 0 || tex1->component != tex2->component || - tex1->sampler_index != tex2->sampler_index || - tex1->sampler_array_size != tex2->sampler_array_size) { + tex1->texture_index != tex2->texture_index || + tex1->texture_array_size != tex2->texture_array_size || + tex1->sampler_index != tex2->sampler_index) { return false; } /* Don't support un-lowered sampler derefs currently. */ - assert(!tex1->sampler && !tex2->sampler); + assert(!tex1->texture && !tex1->sampler && + !tex2->texture && !tex2->sampler); return true; } @@ -422,7 +425,7 @@ instr_can_rewrite(nir_instr *instr) nir_tex_instr *tex = nir_instr_as_tex(instr); /* Don't support un-lowered sampler derefs currently. */ - if (tex->sampler) + if (tex->texture || tex->sampler) return false; return true; diff --git a/src/glsl/nir/nir_lower_samplers.c b/src/glsl/nir/nir_lower_samplers.c index 5df79a69a06..19deafab37a 100644 --- a/src/glsl/nir/nir_lower_samplers.c +++ b/src/glsl/nir/nir_lower_samplers.c @@ -95,6 +95,9 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr if (instr->sampler == NULL) return; + /* GLSL only has combined textures/samplers */ + assert(instr->texture == NULL); + instr->sampler_index = 0; unsigned location = instr->sampler->var->data.location; unsigned array_elements = 1; @@ -107,7 +110,7 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr if (indirect) { /* First, we have to resize the array of texture sources */ nir_tex_src *new_srcs = rzalloc_array(instr, nir_tex_src, - instr->num_srcs + 1); + instr->num_srcs + 2); for (unsigned i = 0; i < instr->num_srcs; i++) { new_srcs[i].src_type = instr->src[i].src_type; @@ -121,13 +124,19 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr /* Now we can go ahead and move the source over to being a * first-class texture source. */ + instr->src[instr->num_srcs].src_type = nir_tex_src_texture_offset; + instr->num_srcs++; + nir_instr_rewrite_src(&instr->instr, + &instr->src[instr->num_srcs - 1].src, + nir_src_for_ssa(indirect)); + instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset; instr->num_srcs++; nir_instr_rewrite_src(&instr->instr, &instr->src[instr->num_srcs - 1].src, nir_src_for_ssa(indirect)); - instr->sampler_array_size = array_elements; + instr->texture_array_size = array_elements; } if (location > shader_program->NumUniformStorage - 1 || @@ -140,6 +149,8 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr shader_program->UniformStorage[location].opaque[stage].index; instr->sampler = NULL; + + instr->texture_index = instr->sampler_index; } typedef struct { diff --git a/src/glsl/nir/nir_print.c b/src/glsl/nir/nir_print.c index f7f5fdf3181..2db209d434d 100644 --- a/src/glsl/nir/nir_print.c +++ b/src/glsl/nir/nir_print.c @@ -551,6 +551,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) case nir_tex_src_ddy: fprintf(fp, "(ddy)"); break; + case nir_tex_src_texture_offset: + fprintf(fp, "(texture_offset)"); + break; case nir_tex_src_sampler_offset: fprintf(fp, "(sampler_offset)"); break; @@ -581,13 +584,18 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) fprintf(fp, "%u (gather_component), ", instr->component); } + if (instr->texture) { + assert(instr->sampler); + fprintf(fp, " (texture)"); + } if (instr->sampler) { print_deref(instr->sampler, state); + fprintf(fp, " (sampler)"); } else { - fprintf(fp, "%u", instr->sampler_index); + assert(instr->texture == NULL); + fprintf(fp, "%u (texture) %u (sampler)", + instr->texture_index, instr->sampler_index); } - - fprintf(fp, " (sampler)"); } static void diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.cpp index 5308d175416..7fa4ce87f18 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit_eu.cpp @@ -85,7 +85,7 @@ brw_blorp_eu_emitter::emit_texture_lookup(const struct brw_reg &dst, unsigned msg_length) { fs_inst *inst = new (mem_ctx) fs_inst(op, 16, dst, brw_message_reg(base_mrf), - fs_reg(0u)); + fs_reg(0u), fs_reg(0u)); inst->base_mrf = base_mrf; inst->mlen = msg_length; diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 3bec7285ef5..250d4097e38 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -735,15 +735,15 @@ fs_inst::components_read(unsigned i) const case SHADER_OPCODE_LOD_LOGICAL: case SHADER_OPCODE_TG4_LOGICAL: case SHADER_OPCODE_TG4_OFFSET_LOGICAL: - assert(src[8].file == IMM && src[9].file == IMM); + assert(src[9].file == IMM && src[10].file == IMM); /* Texture coordinates. */ if (i == 0) - return src[8].ud; + return src[9].ud; /* Texture derivatives. */ else if ((i == 2 || i == 3) && opcode == SHADER_OPCODE_TXD_LOGICAL) - return src[9].ud; + return src[10].ud; /* Texture offset. */ - else if (i == 7) + else if (i == 8) return 2; /* MCS */ else if (i == 5 && opcode == SHADER_OPCODE_TXF_CMS_W_LOGICAL) @@ -3634,6 +3634,7 @@ lower_sampler_logical_send_gen4(const fs_builder &bld, fs_inst *inst, opcode op, const fs_reg &coordinate, const fs_reg &shadow_c, const fs_reg &lod, const fs_reg &lod2, + const fs_reg &surface, const fs_reg &sampler, unsigned coord_components, unsigned grad_components) @@ -3726,8 +3727,9 @@ lower_sampler_logical_send_gen4(const fs_builder &bld, fs_inst *inst, opcode op, inst->opcode = op; inst->src[0] = reg_undef; - inst->src[1] = sampler; - inst->resize_sources(2); + inst->src[1] = surface; + inst->src[2] = sampler; + inst->resize_sources(3); inst->base_mrf = msg_begin.nr; inst->mlen = msg_end.nr - msg_begin.nr; inst->header_size = 1; @@ -3739,6 +3741,7 @@ lower_sampler_logical_send_gen5(const fs_builder &bld, fs_inst *inst, opcode op, const fs_reg &shadow_c, fs_reg lod, fs_reg lod2, const fs_reg &sample_index, + const fs_reg &surface, const fs_reg &sampler, const fs_reg &offset_value, unsigned coord_components, @@ -3821,8 +3824,9 @@ lower_sampler_logical_send_gen5(const fs_builder &bld, fs_inst *inst, opcode op, inst->opcode = op; inst->src[0] = reg_undef; - inst->src[1] = sampler; - inst->resize_sources(2); + inst->src[1] = surface; + inst->src[2] = sampler; + inst->resize_sources(3); inst->base_mrf = message.nr; inst->mlen = msg_end.nr - message.nr; inst->header_size = header_size; @@ -3846,7 +3850,9 @@ lower_sampler_logical_send_gen7(const fs_builder &bld, fs_inst *inst, opcode op, const fs_reg &shadow_c, fs_reg lod, fs_reg lod2, const fs_reg &sample_index, - const fs_reg &mcs, const fs_reg &sampler, + const fs_reg &mcs, + const fs_reg &surface, + const fs_reg &sampler, fs_reg offset_value, unsigned coord_components, unsigned grad_components) @@ -4049,8 +4055,9 @@ lower_sampler_logical_send_gen7(const fs_builder &bld, fs_inst *inst, opcode op, /* Generate the SEND. */ inst->opcode = op; inst->src[0] = src_payload; - inst->src[1] = sampler; - inst->resize_sources(2); + inst->src[1] = surface; + inst->src[2] = sampler; + inst->resize_sources(3); inst->base_mrf = -1; inst->mlen = mlen; inst->header_size = header_size; @@ -4069,25 +4076,27 @@ lower_sampler_logical_send(const fs_builder &bld, fs_inst *inst, opcode op) const fs_reg &lod2 = inst->src[3]; const fs_reg &sample_index = inst->src[4]; const fs_reg &mcs = inst->src[5]; - const fs_reg &sampler = inst->src[6]; - const fs_reg &offset_value = inst->src[7]; - assert(inst->src[8].file == IMM && inst->src[9].file == IMM); - const unsigned coord_components = inst->src[8].ud; - const unsigned grad_components = inst->src[9].ud; + const fs_reg &surface = inst->src[6]; + const fs_reg &sampler = inst->src[7]; + const fs_reg &offset_value = inst->src[8]; + assert(inst->src[9].file == IMM && inst->src[10].file == IMM); + const unsigned coord_components = inst->src[9].ud; + const unsigned grad_components = inst->src[10].ud; if (devinfo->gen >= 7) { lower_sampler_logical_send_gen7(bld, inst, op, coordinate, shadow_c, lod, lod2, sample_index, - mcs, sampler, offset_value, + mcs, surface, sampler, offset_value, coord_components, grad_components); } else if (devinfo->gen >= 5) { lower_sampler_logical_send_gen5(bld, inst, op, coordinate, shadow_c, lod, lod2, sample_index, - sampler, offset_value, + surface, sampler, offset_value, coord_components, grad_components); } else { lower_sampler_logical_send_gen4(bld, inst, op, coordinate, - shadow_c, lod, lod2, sampler, + shadow_c, lod, lod2, + surface, sampler, coord_components, grad_components); } } diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index f40e58b8ca0..9b56afd292f 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -116,7 +116,7 @@ public: void setup_uniform_clipplane_values(gl_clip_plane *clip_planes); void compute_clip_distance(gl_clip_plane *clip_planes); - uint32_t gather_channel(int orig_chan, uint32_t sampler); + uint32_t gather_channel(int orig_chan, uint32_t surface, uint32_t sampler); void swizzle_result(ir_texture_opcode op, int dest_components, fs_reg orig_val, uint32_t sampler); @@ -231,6 +231,8 @@ public: int gather_component, bool is_cube_array, bool is_rect, + uint32_t surface, + fs_reg surface_reg, uint32_t sampler, fs_reg sampler_reg); fs_reg emit_mcs_fetch(const fs_reg &coordinate, unsigned components, @@ -462,6 +464,7 @@ private: void generate_linterp(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src, + struct brw_reg surface_index, struct brw_reg sampler_index); void generate_get_buffer_size(fs_inst *inst, struct brw_reg dst, struct brw_reg src, diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index 139cda3ca59..9d7fb94c397 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -679,6 +679,7 @@ fs_generator::generate_get_buffer_size(fs_inst *inst, void fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src, + struct brw_reg surface_index, struct brw_reg sampler_index) { int msg_type = -1; @@ -915,14 +916,16 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src ? prog_data->binding_table.gather_texture_start : prog_data->binding_table.texture_start; - if (sampler_index.file == BRW_IMMEDIATE_VALUE) { + if (surface_index.file == BRW_IMMEDIATE_VALUE && + sampler_index.file == BRW_IMMEDIATE_VALUE) { + uint32_t surface = surface_index.ud; uint32_t sampler = sampler_index.ud; brw_SAMPLE(p, retype(dst, BRW_REGISTER_TYPE_UW), inst->base_mrf, src, - sampler + base_binding_table_index, + surface + base_binding_table_index, sampler % 16, msg_type, rlen, @@ -931,19 +934,24 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src simd_mode, return_format); - brw_mark_surface_used(prog_data, sampler + base_binding_table_index); + brw_mark_surface_used(prog_data, surface + base_binding_table_index); } else { /* Non-const sampler index */ struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD)); + struct brw_reg surface_reg = vec1(retype(surface_index, BRW_REGISTER_TYPE_UD)); struct brw_reg sampler_reg = vec1(retype(sampler_index, BRW_REGISTER_TYPE_UD)); brw_push_insn_state(p); brw_set_default_mask_control(p, BRW_MASK_DISABLE); brw_set_default_access_mode(p, BRW_ALIGN_1); - /* addr = ((sampler * 0x101) + base_binding_table_index) & 0xfff */ - brw_MUL(p, addr, sampler_reg, brw_imm_uw(0x101)); + if (memcmp(&surface_reg, &sampler_reg, sizeof(surface_reg)) == 0) { + brw_MUL(p, addr, sampler_reg, brw_imm_uw(0x101)); + } else { + brw_SHL(p, addr, sampler_reg, brw_imm_ud(8)); + brw_OR(p, addr, addr, surface_reg); + } if (base_binding_table_index) brw_ADD(p, addr, addr, brw_imm_ud(base_binding_table_index)); brw_AND(p, addr, addr, brw_imm_ud(0xfff)); @@ -2052,7 +2060,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) case SHADER_OPCODE_TG4: case SHADER_OPCODE_TG4_OFFSET: case SHADER_OPCODE_SAMPLEINFO: - generate_tex(inst, dst, src[0], src[1]); + generate_tex(inst, dst, src[0], src[1], src[2]); break; case FS_OPCODE_DDX_COARSE: case FS_OPCODE_DDX_FINE: diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index a47b6ce50cc..3a666b8debc 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -2522,7 +2522,9 @@ fs_visitor::nir_emit_ssbo_atomic(const fs_builder &bld, 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(texture); fs_reg sampler_reg(sampler); int gather_component = instr->component; @@ -2590,9 +2592,9 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) 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 { @@ -2601,6 +2603,14 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) 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, fs_reg(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, fs_reg(sampler)); sampler_reg = bld.emit_uniformize(sampler_reg); @@ -2614,8 +2624,8 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) if (instr->op == nir_texop_txf_ms) { 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 = fs_reg(0u); } @@ -2652,7 +2662,7 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) 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; @@ -2665,7 +2675,8 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) 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, is_rect, sampler, sampler_reg); + is_cube_array, is_rect, + texture, texture_reg, sampler, sampler_reg); fs_reg dest = get_nir_dest(instr->dest); dest.type = this->result.type; diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index a7bd9cea7af..2647a40c730 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -198,12 +198,12 @@ fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components, /* Sample from the MCS surface attached to this multisample texture. */ fs_reg fs_visitor::emit_mcs_fetch(const fs_reg &coordinate, unsigned components, - const fs_reg &sampler) + const fs_reg &texture) { const fs_reg dest = vgrf(glsl_type::uvec4_type); const fs_reg srcs[] = { coordinate, fs_reg(), fs_reg(), fs_reg(), fs_reg(), fs_reg(), - sampler, fs_reg(), fs_reg(components), fs_reg(0) + texture, texture, fs_reg(), fs_reg(components), fs_reg(0) }; fs_inst *inst = bld.emit(SHADER_OPCODE_TXF_MCS_LOGICAL, dest, srcs, ARRAY_SIZE(srcs)); @@ -228,6 +228,8 @@ fs_visitor::emit_texture(ir_texture_opcode op, int gather_component, bool is_cube_array, bool is_rect, + uint32_t surface, + fs_reg surface_reg, uint32_t sampler, fs_reg sampler_reg) { @@ -273,7 +275,7 @@ fs_visitor::emit_texture(ir_texture_opcode op, fs_reg dst = vgrf(glsl_type::get_instance(dest_type->base_type, 4, 1)); const fs_reg srcs[] = { coordinate, shadow_c, lod, lod2, - sample_index, mcs, sampler_reg, offset_value, + sample_index, mcs, surface_reg, sampler_reg, offset_value, fs_reg(coord_components), fs_reg(grad_components) }; enum opcode opcode; @@ -326,10 +328,10 @@ fs_visitor::emit_texture(ir_texture_opcode op, if (op == ir_tg4) { inst->offset |= - gather_channel(gather_component, sampler) << 16; /* M0.2:16-17 */ + gather_channel(gather_component, surface, sampler) << 16; /* M0.2:16-17 */ if (devinfo->gen == 6) - emit_gen6_gather_wa(key_tex->gen6_gather_wa[sampler], dst); + emit_gen6_gather_wa(key_tex->gen6_gather_wa[surface], dst); } /* fixup #layers for cube map arrays */ @@ -387,7 +389,7 @@ fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst) * Set up the gather channel based on the swizzle, for gather4. */ uint32_t -fs_visitor::gather_channel(int orig_chan, uint32_t sampler) +fs_visitor::gather_channel(int orig_chan, uint32_t surface, uint32_t sampler) { int swiz = GET_SWZ(key_tex->swizzles[sampler], orig_chan); switch (swiz) { @@ -396,7 +398,7 @@ fs_visitor::gather_channel(int orig_chan, uint32_t sampler) /* gather4 sampler is broken for green channel on RG32F -- * we must ask for blue instead. */ - if (key_tex->gather_channel_quirk_mask & (1 << sampler)) + if (key_tex->gather_channel_quirk_mask & (1 << surface)) return 2; return 1; case SWIZZLE_Z: return 2; diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index ec8abf49cd8..52d68c5a33d 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -273,9 +273,11 @@ public: src_reg offset_value, src_reg mcs, bool is_cube_array, + uint32_t surface, src_reg surface_reg, uint32_t sampler, src_reg sampler_reg); - uint32_t gather_channel(unsigned gather_component, uint32_t sampler); + uint32_t gather_channel(unsigned gather_component, + uint32_t surface, uint32_t sampler); src_reg emit_mcs_fetch(const glsl_type *coordinate_type, src_reg coordinate, src_reg sampler); void emit_gen6_gather_wa(uint8_t wa, dst_reg dst); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp index 20107ac2054..432ccb77cc3 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp @@ -108,6 +108,7 @@ generate_tex(struct brw_codegen *p, vec4_instruction *inst, struct brw_reg dst, struct brw_reg src, + struct brw_reg surface_index, struct brw_reg sampler_index) { const struct brw_device_info *devinfo = p->devinfo; @@ -263,14 +264,16 @@ generate_tex(struct brw_codegen *p, ? prog_data->base.binding_table.gather_texture_start : prog_data->base.binding_table.texture_start; - if (sampler_index.file == BRW_IMMEDIATE_VALUE) { + if (surface_index.file == BRW_IMMEDIATE_VALUE && + sampler_index.file == BRW_IMMEDIATE_VALUE) { + uint32_t surface = surface_index.ud; uint32_t sampler = sampler_index.ud; brw_SAMPLE(p, dst, inst->base_mrf, src, - sampler + base_binding_table_index, + surface + base_binding_table_index, sampler % 16, msg_type, 1, /* response length */ @@ -284,14 +287,19 @@ generate_tex(struct brw_codegen *p, /* Non-constant sampler index. */ struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD)); + struct brw_reg surface_reg = vec1(retype(surface_index, BRW_REGISTER_TYPE_UD)); struct brw_reg sampler_reg = vec1(retype(sampler_index, BRW_REGISTER_TYPE_UD)); brw_push_insn_state(p); brw_set_default_mask_control(p, BRW_MASK_DISABLE); brw_set_default_access_mode(p, BRW_ALIGN_1); - /* addr = ((sampler * 0x101) + base_binding_table_index) & 0xfff */ - brw_MUL(p, addr, sampler_reg, brw_imm_uw(0x101)); + if (memcmp(&surface_reg, &sampler_reg, sizeof(surface_reg)) == 0) { + brw_MUL(p, addr, sampler_reg, brw_imm_uw(0x101)); + } else { + brw_SHL(p, addr, sampler_reg, brw_imm_ud(8)); + brw_OR(p, addr, addr, surface_reg); + } if (base_binding_table_index) brw_ADD(p, addr, addr, brw_imm_ud(base_binding_table_index)); brw_AND(p, addr, addr, brw_imm_ud(0xfff)); @@ -1318,7 +1326,7 @@ generate_code(struct brw_codegen *p, case SHADER_OPCODE_TG4: case SHADER_OPCODE_TG4_OFFSET: case SHADER_OPCODE_SAMPLEINFO: - generate_tex(p, prog_data, inst, dst, src[0], src[1]); + generate_tex(p, prog_data, inst, dst, src[0], src[1], src[1]); break; case VS_OPCODE_URB_WRITE: diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 258dd4f6548..bf098b41590 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1580,7 +1580,9 @@ glsl_type_for_nir_alu_type(nir_alu_type alu_type, void vec4_visitor::nir_emit_texture(nir_tex_instr *instr) { + unsigned texture = instr->texture_index; unsigned sampler = instr->sampler_index; + src_reg texture_reg = src_reg(texture); src_reg sampler_reg = src_reg(sampler); src_reg coordinate; const glsl_type *coord_type = NULL; @@ -1661,8 +1663,8 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) sample_index = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, 1); assert(coord_type != NULL); if (devinfo->gen >= 7 && - key_tex->compressed_multisample_layout_mask & (1 << sampler)) { - mcs = emit_mcs_fetch(coord_type, coordinate, sampler_reg); + key_tex->compressed_multisample_layout_mask & (1 << texture)) { + mcs = emit_mcs_fetch(coord_type, coordinate, texture_reg); } else { mcs = src_reg(0u); } @@ -1674,13 +1676,12 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) offset_value = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, 2); break; - case nir_tex_src_sampler_offset: { - /* The highest sampler which may be used by this operation is + case nir_tex_src_texture_offset: { + /* The highest texture which may be used by this operation is * the last element of the array. Mark it here, because the generator * doesn't have enough information to determine the bound. */ - uint32_t array_size = instr->sampler_array_size; - uint32_t max_used = sampler + array_size - 1; + uint32_t max_used = texture + instr->texture_array_size - 1; if (instr->op == nir_texop_tg4) { max_used += prog_data->base.binding_table.gather_texture_start; } else { @@ -1692,6 +1693,15 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) /* Emit code to evaluate the actual indexing expression */ src_reg src = get_nir_src(instr->src[i].src, 1); src_reg temp(this, glsl_type::uint_type); + emit(ADD(dst_reg(temp), src, src_reg(texture))); + texture_reg = emit_uniformize(temp); + break; + } + + case nir_tex_src_sampler_offset: { + /* Emit code to evaluate the actual indexing expression */ + src_reg src = get_nir_src(instr->src[i].src, 1); + src_reg temp(this, glsl_type::uint_type); emit(ADD(dst_reg(temp), src, src_reg(sampler))); sampler_reg = emit_uniformize(temp); break; @@ -1718,7 +1728,7 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) /* Stuff the channel select bits in the top of the texture offset */ if (instr->op == nir_texop_tg4) - constant_offset |= gather_channel(instr->component, sampler) << 16; + constant_offset |= gather_channel(instr->component, texture, sampler) << 16; ir_texture_opcode op = ir_texture_opcode_for_nir_texop(instr->op); @@ -1731,7 +1741,8 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) shadow_comparitor, lod, lod2, sample_index, constant_offset, offset_value, - mcs, is_cube_array, sampler, sampler_reg); + mcs, is_cube_array, + texture, texture_reg, sampler, sampler_reg); } void diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 70a1ea4f9d4..6b8798da71c 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -878,6 +878,8 @@ vec4_visitor::emit_texture(ir_texture_opcode op, src_reg offset_value, src_reg mcs, bool is_cube_array, + uint32_t surface, + src_reg surface_reg, uint32_t sampler, src_reg sampler_reg) { @@ -937,7 +939,8 @@ vec4_visitor::emit_texture(ir_texture_opcode op, inst->dst.writemask = WRITEMASK_XYZW; inst->shadow_compare = shadow_comparitor.file != BAD_FILE; - inst->src[1] = sampler_reg; + inst->src[1] = surface_reg; + inst->src[2] = sampler_reg; /* MRF for the first parameter */ int param_base = inst->base_mrf + inst->header_size; @@ -1063,7 +1066,7 @@ vec4_visitor::emit_texture(ir_texture_opcode op, } if (devinfo->gen == 6 && op == ir_tg4) { - emit_gen6_gather_wa(key_tex->gen6_gather_wa[sampler], inst->dst); + emit_gen6_gather_wa(key_tex->gen6_gather_wa[surface], inst->dst); } swizzle_result(op, dest, @@ -1101,7 +1104,8 @@ vec4_visitor::emit_gen6_gather_wa(uint8_t wa, dst_reg dst) * Set up the gather channel based on the swizzle, for gather4. */ uint32_t -vec4_visitor::gather_channel(unsigned gather_component, uint32_t sampler) +vec4_visitor::gather_channel(unsigned gather_component, + uint32_t surface, uint32_t sampler) { int swiz = GET_SWZ(key_tex->swizzles[sampler], gather_component); switch (swiz) { @@ -1110,7 +1114,7 @@ vec4_visitor::gather_channel(unsigned gather_component, uint32_t sampler) /* gather4 sampler is broken for green channel on RG32F -- * we must ask for blue instead. */ - if (key_tex->gather_channel_quirk_mask & (1 << sampler)) + if (key_tex->gather_channel_quirk_mask & (1 << surface)) return 2; return 1; case SWIZZLE_Z: return 2; diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index 539e3c05312..d5386ee70e8 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -609,6 +609,7 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src, instr->op = op; instr->dest_type = nir_type_float; instr->is_shadow = prog_inst->TexShadow; + instr->texture_index = prog_inst->TexSrcUnit; instr->sampler_index = prog_inst->TexSrcUnit; switch (prog_inst->TexSrcTarget) { |