Home | History | Annotate | Line # | Download | only in panfrost
      1 /*
      2  * Copyright (C) 2019 Alyssa Rosenzweig
      3  * Copyright (C) 2014-2017 Broadcom
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  */
     25 
     26 #include "pan_context.h"
     27 #include "util/hash_table.h"
     28 #include "util/ralloc.h"
     29 
     30 struct panfrost_job *
     31 panfrost_create_job(struct panfrost_context *ctx)
     32 {
     33         /* TODO: Don't leak */
     34         struct panfrost_job *job = rzalloc(NULL, struct panfrost_job);
     35 
     36         job->ctx = ctx;
     37 
     38         job->bos = _mesa_set_create(job,
     39                                     _mesa_hash_pointer,
     40                                     _mesa_key_pointer_equal);
     41 
     42         return job;
     43 }
     44 
     45 void
     46 panfrost_free_job(struct panfrost_context *ctx, struct panfrost_job *job)
     47 {
     48         if (!job)
     49                 return;
     50 
     51         set_foreach(job->bos, entry) {
     52                 struct panfrost_bo *bo = (struct panfrost_bo *)entry->key;
     53                 panfrost_bo_unreference(ctx->base.screen, bo);
     54         }
     55 
     56         _mesa_hash_table_remove_key(ctx->jobs, &job->key);
     57 
     58         if (ctx->job == job)
     59                 ctx->job = NULL;
     60 
     61         ralloc_free(job);
     62 }
     63 
     64 struct panfrost_job *
     65 panfrost_get_job(struct panfrost_context *ctx,
     66                 struct pipe_surface **cbufs, struct pipe_surface *zsbuf)
     67 {
     68         /* Lookup the job first */
     69 
     70         struct panfrost_job_key key = {
     71                 .cbufs = {
     72                         cbufs[0],
     73                         cbufs[1],
     74                         cbufs[2],
     75                         cbufs[3],
     76                 },
     77                 .zsbuf = zsbuf
     78         };
     79 
     80         struct hash_entry *entry = _mesa_hash_table_search(ctx->jobs, &key);
     81 
     82         if (entry)
     83                 return entry->data;
     84 
     85         /* Otherwise, let's create a job */
     86 
     87         struct panfrost_job *job = panfrost_create_job(ctx);
     88 
     89         /* Save the created job */
     90 
     91         memcpy(&job->key, &key, sizeof(key));
     92         _mesa_hash_table_insert(ctx->jobs, &job->key, job);
     93 
     94         return job;
     95 }
     96 
     97 /* Get the job corresponding to the FBO we're currently rendering into */
     98 
     99 struct panfrost_job *
    100 panfrost_get_job_for_fbo(struct panfrost_context *ctx)
    101 {
    102         /* If we already began rendering, use that */
    103 
    104         if (ctx->job)
    105                 return ctx->job;
    106 
    107         /* If not, look up the job */
    108 
    109         struct pipe_surface **cbufs = ctx->pipe_framebuffer.cbufs;
    110         struct pipe_surface *zsbuf = ctx->pipe_framebuffer.zsbuf;
    111         struct panfrost_job *job = panfrost_get_job(ctx, cbufs, zsbuf);
    112 
    113         return job;
    114 }
    115 
    116 void
    117 panfrost_job_add_bo(struct panfrost_job *job, struct panfrost_bo *bo)
    118 {
    119         if (!bo)
    120                 return;
    121 
    122         if (_mesa_set_search(job->bos, bo))
    123                 return;
    124 
    125         panfrost_bo_reference(bo);
    126         _mesa_set_add(job->bos, bo);
    127 }
    128 
    129 void
    130 panfrost_flush_jobs_writing_resource(struct panfrost_context *panfrost,
    131                                 struct pipe_resource *prsc)
    132 {
    133 #if 0
    134         struct hash_entry *entry = _mesa_hash_table_search(panfrost->write_jobs,
    135                                                            prsc);
    136         if (entry) {
    137                 struct panfrost_job *job = entry->data;
    138                 panfrost_job_submit(panfrost, job);
    139         }
    140 #endif
    141         /* TODO stub */
    142 }
    143 
    144 void
    145 panfrost_flush_jobs_reading_resource(struct panfrost_context *panfrost,
    146                                 struct pipe_resource *prsc)
    147 {
    148         struct panfrost_resource *rsc = pan_resource(prsc);
    149 
    150         panfrost_flush_jobs_writing_resource(panfrost, prsc);
    151 
    152         hash_table_foreach(panfrost->jobs, entry) {
    153                 struct panfrost_job *job = entry->data;
    154 
    155                 if (_mesa_set_search(job->bos, rsc->bo)) {
    156                         printf("TODO: submit job for flush\n");
    157                         //panfrost_job_submit(panfrost, job);
    158                         continue;
    159                 }
    160         }
    161 }
    162 
    163 static bool
    164 panfrost_job_compare(const void *a, const void *b)
    165 {
    166         return memcmp(a, b, sizeof(struct panfrost_job_key)) == 0;
    167 }
    168 
    169 static uint32_t
    170 panfrost_job_hash(const void *key)
    171 {
    172         return _mesa_hash_data(key, sizeof(struct panfrost_job_key));
    173 }
    174 
    175 void
    176 panfrost_job_init(struct panfrost_context *ctx)
    177 {
    178         /* TODO: Don't leak */
    179         ctx->jobs = _mesa_hash_table_create(NULL,
    180                                             panfrost_job_hash,
    181                                             panfrost_job_compare);
    182 
    183         ctx->write_jobs = _mesa_hash_table_create(NULL,
    184                                             _mesa_hash_pointer,
    185                                             _mesa_key_pointer_equal);
    186 
    187 }
    188