summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c101
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;