panfrost: Make panfrost_bo_wait take a wait_readers bool
[mesa.git] / src / gallium / drivers / panfrost / pan_context.c
index 5614ee4535ae20d7a923c2736f902f732bda42fd..ca383a8a8bedb8026e82664adc94e4e2c3547ca5 100644 (file)
@@ -54,6 +54,7 @@
 #include "pan_cmdstream.h"
 #include "pan_util.h"
 #include "pandecode/decode.h"
+#include "util/pan_lower_framebuffer.h"
 
 struct midgard_tiler_descriptor
 panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count)
@@ -274,6 +275,13 @@ panfrost_flush(
                 pandecode_next_frame();
 }
 
+static void
+panfrost_texture_barrier(struct pipe_context *pipe, unsigned flags)
+{
+        struct panfrost_context *ctx = pan_context(pipe);
+        panfrost_flush_all_batches(ctx, false);
+}
+
 #define DEFINE_CASE(c) case PIPE_PRIM_##c: return MALI_##c;
 
 static int
@@ -664,6 +672,27 @@ panfrost_variant_matches(
                 }
         }
 
+        if (variant->outputs_read) {
+                struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
+
+                unsigned i;
+                BITSET_FOREACH_SET(i, &variant->outputs_read, 8) {
+                        enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
+
+                        if ((fb->nr_cbufs > i) && fb->cbufs[i])
+                                fmt = fb->cbufs[i]->format;
+
+                        const struct util_format_description *desc =
+                                util_format_description(fmt);
+
+                        if (pan_format_class_load(desc, dev->quirks) == PAN_FORMAT_NATIVE)
+                                fmt = PIPE_FORMAT_NONE;
+
+                        if (variant->rt_formats[i] != fmt)
+                                return false;
+                }
+        }
+
         /* Point sprites TODO on bifrost, always pass */
         if (is_fragment && rasterizer && (rasterizer->sprite_coord_enable |
                                           variant->point_sprite_mask)
@@ -777,6 +806,22 @@ panfrost_bind_shader_state(
                 if (type == PIPE_SHADER_FRAGMENT) {
                         v->alpha_state = ctx->depth_stencil->alpha;
 
+                        struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
+                        for (unsigned i = 0; i < fb->nr_cbufs; ++i) {
+                                enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
+
+                                if ((fb->nr_cbufs > i) && fb->cbufs[i])
+                                        fmt = fb->cbufs[i]->format;
+
+                                const struct util_format_description *desc =
+                                        util_format_description(fmt);
+
+                                if (pan_format_class_load(desc, dev->quirks) == PAN_FORMAT_NATIVE)
+                                        fmt = PIPE_FORMAT_NONE;
+
+                                v->rt_formats[i] = fmt;
+                        }
+
                         /* Point sprites are TODO on Bifrost */
                         if (ctx->rasterizer && !(dev->quirks & IS_BIFROST)) {
                                 v->point_sprite_mask = ctx->rasterizer->base.sprite_coord_enable;
@@ -885,32 +930,6 @@ panfrost_set_stencil_ref(
         ctx->stencil_ref = *ref;
 }
 
-static enum mali_texture_type
-panfrost_translate_texture_type(enum pipe_texture_target t) {
-        switch (t)
-        {
-        case PIPE_BUFFER:
-        case PIPE_TEXTURE_1D:
-        case PIPE_TEXTURE_1D_ARRAY:
-                return MALI_TEX_1D;
-
-        case PIPE_TEXTURE_2D:
-        case PIPE_TEXTURE_2D_ARRAY:
-        case PIPE_TEXTURE_RECT:
-                return MALI_TEX_2D;
-
-        case PIPE_TEXTURE_3D:
-                return MALI_TEX_3D;
-
-        case PIPE_TEXTURE_CUBE:
-        case PIPE_TEXTURE_CUBE_ARRAY:
-                return MALI_TEX_CUBE;
-
-        default:
-                unreachable("Unknown target");
-        }
-}
-
 void
 panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
                                 struct pipe_context *pctx,
@@ -918,8 +937,17 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
 {
         struct panfrost_device *device = pan_device(pctx->screen);
         struct panfrost_resource *prsrc = (struct panfrost_resource *)texture;
+        enum pipe_format format = so->base.format;
         assert(prsrc->bo);
 
+        /* Format to access the stencil portion of a Z32_S8 texture */
+        if (so->base.format == PIPE_FORMAT_X32_S8X24_UINT) {
+                assert(prsrc->separate_stencil);
+                texture = &prsrc->separate_stencil->base;
+                prsrc = (struct panfrost_resource *)texture;
+                format = texture->format;
+        }
+
         so->texture_bo = prsrc->bo->gpu;
         so->layout = prsrc->layout;
 
@@ -958,7 +986,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
 
         if (device->quirks & IS_BIFROST) {
                 const struct util_format_description *desc =
-                        util_format_description(so->base.format);
+                        util_format_description(format);
                 unsigned char composed_swizzle[4];
                 util_format_compose_swizzles(desc->swizzle, user_swizzle, composed_swizzle);
 
@@ -967,16 +995,17 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
                                 so->base.u.tex.last_level,
                                 so->base.u.tex.first_layer,
                                 so->base.u.tex.last_layer,
+                                texture->nr_samples,
                                 type, prsrc->layout);
 
-                so->bo = pan_bo_create(device, size, 0);
+                so->bo = panfrost_bo_create(device, size, 0);
 
                 so->bifrost_descriptor = rzalloc(pctx, struct bifrost_texture_descriptor);
                 panfrost_new_texture_bifrost(
                                 so->bifrost_descriptor,
                                 texture->width0, texture->height0,
                                 depth, array_size,
-                                so->base.format,
+                                format,
                                 type, prsrc->layout,
                                 so->base.u.tex.first_level,
                                 so->base.u.tex.last_level,
@@ -994,16 +1023,17 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
                                 so->base.u.tex.last_level,
                                 so->base.u.tex.first_layer,
                                 so->base.u.tex.last_layer,
+                                texture->nr_samples,
                                 type, prsrc->layout);
                 size += sizeof(struct mali_texture_descriptor);
 
-                so->bo = pan_bo_create(device, size, 0);
+                so->bo = panfrost_bo_create(device, size, 0);
 
                 panfrost_new_texture(
                                 so->bo->cpu,
                                 texture->width0, texture->height0,
                                 depth, array_size,
-                                so->base.format,
+                                format,
                                 type, prsrc->layout,
                                 so->base.u.tex.first_level,
                                 so->base.u.tex.last_level,
@@ -1128,6 +1158,13 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx,
         util_copy_framebuffer_state(&ctx->pipe_framebuffer, fb);
         ctx->batch = NULL;
         panfrost_invalidate_frame(ctx);
+
+        /* We may need to generate a new variant if the fragment shader is
+         * keyed to the framebuffer format (due to EXT_framebuffer_fetch) */
+        struct panfrost_shader_variants *fs = ctx->shader[PIPE_SHADER_FRAGMENT];
+
+        if (fs && fs->variant_count && fs->variants[fs->active_variant].outputs_read)
+                ctx->base.bind_fs_state(&ctx->base, fs);
 }
 
 static void *
@@ -1174,6 +1211,15 @@ panfrost_set_sample_mask(struct pipe_context *pipe,
         ctx->sample_mask = sample_mask;
 }
 
+static void
+panfrost_set_min_samples(struct pipe_context *pipe,
+                         unsigned min_samples)
+{
+        struct panfrost_context *ctx = pan_context(pipe);
+        ctx->min_samples = min_samples;
+}
+
+
 static void
 panfrost_set_clip_state(struct pipe_context *pipe,
                         const struct pipe_clip_state *clip)
@@ -1279,7 +1325,7 @@ panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q)
         case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
                 /* Allocate a bo for the query results to be stored */
                 if (!query->bo) {
-                        query->bo = pan_bo_create(
+                        query->bo = panfrost_bo_create(
                                         pan_device(ctx->base.screen),
                                         sizeof(unsigned), 0);
                 }
@@ -1345,7 +1391,7 @@ panfrost_get_query_result(struct pipe_context *pipe,
         case PIPE_QUERY_OCCLUSION_PREDICATE:
         case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
                 panfrost_flush_batches_accessing_bo(ctx, query->bo, PAN_BO_ACCESS_WRITE);
-                panfrost_bo_wait(query->bo, INT64_MAX, PAN_BO_ACCESS_WRITE);
+                panfrost_bo_wait(query->bo, INT64_MAX, false);
 
                 /* Read back the query results */
                 unsigned *result = (unsigned *) query->bo->cpu;
@@ -1444,6 +1490,7 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
         gallium->flush = panfrost_flush;
         gallium->clear = panfrost_clear;
         gallium->draw_vbo = panfrost_draw_vbo;
+        gallium->texture_barrier = panfrost_texture_barrier;
 
         gallium->set_vertex_buffers = panfrost_set_vertex_buffers;
         gallium->set_constant_buffer = panfrost_set_constant_buffer;
@@ -1480,6 +1527,7 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
         gallium->delete_depth_stencil_alpha_state = panfrost_delete_depth_stencil_state;
 
         gallium->set_sample_mask = panfrost_set_sample_mask;
+        gallium->set_min_samples = panfrost_set_min_samples;
 
         gallium->set_clip_state = panfrost_set_clip_state;
         gallium->set_viewport_states = panfrost_set_viewport_states;
@@ -1528,6 +1576,11 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
         panfrost_batch_init(ctx);
         panfrost_invalidate_frame(ctx);
 
+        if (!(dev->quirks & IS_BIFROST)) {
+                for (unsigned c = 0; c < PIPE_MAX_COLOR_BUFS; ++c)
+                        ctx->blit_blend.rt[c].shaders = _mesa_hash_table_u64_create(ctx);
+        }
+
         /* By default mask everything on */
         ctx->sample_mask = ~0;