diff options
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 101 |
1 files changed, 90 insertions, 11 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index dda2d84b5b3..31968bb5db9 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -294,6 +294,76 @@ ntq_umul(struct vc4_compile *c, struct qreg src0, struct qreg src1) qir_uniform_ui(c, 24))); } +static struct qreg +ntq_scale_depth_texture(struct vc4_compile *c, struct qreg src) +{ + struct qreg depthf = qir_ITOF(c, qir_SHR(c, src, + qir_uniform_ui(c, 8))); + return qir_FMUL(c, depthf, qir_uniform_f(c, 1.0f/0xffffff)); +} + +/** + * Emits a lowered TXF_MS from an MSAA texture. + * + * The addressing math has been lowered in NIR, and now we just need to read + * it like a UBO. + */ +static void +ntq_emit_txf(struct vc4_compile *c, nir_tex_instr *instr) +{ + uint32_t tile_width = 32; + uint32_t tile_height = 32; + uint32_t tile_size = (tile_height * tile_width * + VC4_MAX_SAMPLES * sizeof(uint32_t)); + + unsigned unit = instr->sampler_index; + uint32_t w = align(c->key->tex[unit].msaa_width, tile_width); + uint32_t w_tiles = w / tile_width; + uint32_t h = align(c->key->tex[unit].msaa_height, tile_height); + uint32_t h_tiles = h / tile_height; + uint32_t size = w_tiles * h_tiles * tile_size; + + struct qreg addr; + assert(instr->num_srcs == 1); + assert(instr->src[0].src_type == nir_tex_src_coord); + addr = ntq_get_src(c, instr->src[0].src, 0); + + /* Perform the clamping required by kernel validation. */ + addr = qir_MAX(c, addr, qir_uniform_ui(c, 0)); + addr = qir_MIN(c, addr, qir_uniform_ui(c, size - 4)); + + qir_TEX_DIRECT(c, addr, qir_uniform(c, QUNIFORM_TEXTURE_MSAA_ADDR, unit)); + + struct qreg tex = qir_TEX_RESULT(c); + c->num_texture_samples++; + + struct qreg texture_output[4]; + enum pipe_format format = c->key->tex[unit].format; + if (util_format_is_depth_or_stencil(format)) { + struct qreg scaled = ntq_scale_depth_texture(c, tex); + for (int i = 0; i < 4; i++) + texture_output[i] = scaled; + } else { + struct qreg tex_result_unpacked[4]; + for (int i = 0; i < 4; i++) + tex_result_unpacked[i] = qir_UNPACK_8_F(c, tex, i); + + const uint8_t *format_swiz = + vc4_get_format_swizzle(c->key->tex[unit].format); + for (int i = 0; i < 4; i++) { + texture_output[i] = + get_swizzled_channel(c, tex_result_unpacked, + format_swiz[i]); + } + } + + struct qreg *dest = ntq_get_dest(c, &instr->dest); + for (int i = 0; i < 4; i++) { + dest[i] = get_swizzled_channel(c, texture_output, + c->key->tex[unit].swizzle[i]); + } +} + static void ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr) { @@ -301,6 +371,11 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr) bool is_txb = false, is_txl = false, has_proj = false; unsigned unit = instr->sampler_index; + if (instr->op == nir_texop_txf) { + ntq_emit_txf(c, instr); + return; + } + for (unsigned i = 0; i < instr->num_srcs; i++) { switch (instr->src[i].src_type) { case nir_tex_src_coord: @@ -396,11 +471,7 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr) struct qreg unpacked[4]; if (util_format_is_depth_or_stencil(format)) { - struct qreg depthf = qir_ITOF(c, qir_SHR(c, tex, - qir_uniform_ui(c, 8))); - struct qreg normalized = qir_FMUL(c, depthf, - qir_uniform_f(c, 1.0f/0xffffff)); - + struct qreg normalized = ntq_scale_depth_texture(c, tex); struct qreg depth_output; struct qreg one = qir_uniform_f(c, 1.0f); @@ -1712,6 +1783,7 @@ vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage, nir_lower_clip_vs(c->s, c->key->ucp_enables); vc4_nir_lower_io(c); + vc4_nir_lower_txf_ms(c); nir_lower_idiv(c->s); nir_lower_load_const_to_scalar(c->s); @@ -1947,12 +2019,19 @@ vc4_setup_shared_key(struct vc4_context *vc4, struct vc4_key *key, struct pipe_sampler_state *sampler_state = texstate->samplers[i]; - if (sampler) { - key->tex[i].format = sampler->format; - key->tex[i].swizzle[0] = sampler->swizzle_r; - key->tex[i].swizzle[1] = sampler->swizzle_g; - key->tex[i].swizzle[2] = sampler->swizzle_b; - key->tex[i].swizzle[3] = sampler->swizzle_a; + if (!sampler) + continue; + + key->tex[i].format = sampler->format; + key->tex[i].swizzle[0] = sampler->swizzle_r; + key->tex[i].swizzle[1] = sampler->swizzle_g; + key->tex[i].swizzle[2] = sampler->swizzle_b; + key->tex[i].swizzle[3] = sampler->swizzle_a; + + if (sampler->texture->nr_samples) { + key->tex[i].msaa_width = sampler->texture->width0; + key->tex[i].msaa_height = sampler->texture->height0; + } else if (sampler){ key->tex[i].compare_mode = sampler_state->compare_mode; key->tex[i].compare_func = sampler_state->compare_func; key->tex[i].wrap_s = sampler_state->wrap_s; |