Merge branch 'wip/i965-separate-sampler-tex' into vulkan
This commit is contained in:
+7
-1
@@ -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;
|
||||
|
||||
+24
-4
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 {
|
||||
@@ -2600,6 +2602,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));
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 {
|
||||
@@ -1689,6 +1690,15 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr)
|
||||
|
||||
brw_mark_surface_used(&prog_data->base, max_used);
|
||||
|
||||
/* 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);
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user