17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2019 Collabora, Ltd. 37ec681f3Smrg * Copyright (C) 2019 Red Hat Inc. 47ec681f3Smrg * 57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 67ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 77ec681f3Smrg * to deal in the Software without restriction, including without limitation 87ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 97ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 107ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 117ec681f3Smrg * 127ec681f3Smrg * The above copyright notice and this permission notice (including the next 137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 147ec681f3Smrg * Software. 157ec681f3Smrg * 167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 177ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 197ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 207ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 217ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 227ec681f3Smrg * SOFTWARE. 237ec681f3Smrg * 247ec681f3Smrg * Authors (Collabora): 257ec681f3Smrg * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> 267ec681f3Smrg * 277ec681f3Smrg */ 287ec681f3Smrg 297ec681f3Smrg#include "pan_context.h" 307ec681f3Smrg#include "panfrost-quirks.h" 317ec681f3Smrg#include "pan_bo.h" 327ec681f3Smrg#include "pan_shader.h" 337ec681f3Smrg#include "util/u_memory.h" 347ec681f3Smrg#include "nir_serialize.h" 357ec681f3Smrg 367ec681f3Smrg/* Compute CSOs are tracked like graphics shader CSOs, but are 377ec681f3Smrg * considerably simpler. We do not implement multiple 387ec681f3Smrg * variants/keying. So the CSO create function just goes ahead and 397ec681f3Smrg * compiles the thing. */ 407ec681f3Smrg 417ec681f3Smrgstatic void * 427ec681f3Smrgpanfrost_create_compute_state( 437ec681f3Smrg struct pipe_context *pctx, 447ec681f3Smrg const struct pipe_compute_state *cso) 457ec681f3Smrg{ 467ec681f3Smrg struct panfrost_context *ctx = pan_context(pctx); 477ec681f3Smrg struct panfrost_screen *screen = pan_screen(pctx->screen); 487ec681f3Smrg 497ec681f3Smrg struct panfrost_shader_variants *so = CALLOC_STRUCT(panfrost_shader_variants); 507ec681f3Smrg so->cbase = *cso; 517ec681f3Smrg so->is_compute = true; 527ec681f3Smrg 537ec681f3Smrg struct panfrost_shader_state *v = calloc(1, sizeof(*v)); 547ec681f3Smrg so->variants = v; 557ec681f3Smrg 567ec681f3Smrg so->variant_count = 1; 577ec681f3Smrg so->active_variant = 0; 587ec681f3Smrg 597ec681f3Smrg if (cso->ir_type == PIPE_SHADER_IR_NIR_SERIALIZED) { 607ec681f3Smrg struct blob_reader reader; 617ec681f3Smrg const struct pipe_binary_program_header *hdr = cso->prog; 627ec681f3Smrg 637ec681f3Smrg blob_reader_init(&reader, hdr->blob, hdr->num_bytes); 647ec681f3Smrg 657ec681f3Smrg const struct nir_shader_compiler_options *options = 667ec681f3Smrg screen->vtbl.get_compiler_options(); 677ec681f3Smrg 687ec681f3Smrg so->cbase.prog = nir_deserialize(NULL, options, &reader); 697ec681f3Smrg so->cbase.ir_type = PIPE_SHADER_IR_NIR; 707ec681f3Smrg } 717ec681f3Smrg 727ec681f3Smrg panfrost_shader_compile(pctx->screen, &ctx->shaders, &ctx->descs, 737ec681f3Smrg so->cbase.ir_type, so->cbase.prog, MESA_SHADER_COMPUTE, 747ec681f3Smrg v); 757ec681f3Smrg 767ec681f3Smrg /* There are no variants so we won't need the NIR again */ 777ec681f3Smrg ralloc_free((void *)so->cbase.prog); 787ec681f3Smrg so->cbase.prog = NULL; 797ec681f3Smrg 807ec681f3Smrg return so; 817ec681f3Smrg} 827ec681f3Smrg 837ec681f3Smrgstatic void 847ec681f3Smrgpanfrost_bind_compute_state(struct pipe_context *pipe, void *cso) 857ec681f3Smrg{ 867ec681f3Smrg struct panfrost_context *ctx = pan_context(pipe); 877ec681f3Smrg ctx->shader[PIPE_SHADER_COMPUTE] = cso; 887ec681f3Smrg} 897ec681f3Smrg 907ec681f3Smrgstatic void 917ec681f3Smrgpanfrost_delete_compute_state(struct pipe_context *pipe, void *cso) 927ec681f3Smrg{ 937ec681f3Smrg struct panfrost_shader_variants *so = 947ec681f3Smrg (struct panfrost_shader_variants *)cso; 957ec681f3Smrg 967ec681f3Smrg free(so->variants); 977ec681f3Smrg free(cso); 987ec681f3Smrg} 997ec681f3Smrg 1007ec681f3Smrgstatic void 1017ec681f3Smrgpanfrost_set_compute_resources(struct pipe_context *pctx, 1027ec681f3Smrg unsigned start, unsigned count, 1037ec681f3Smrg struct pipe_surface **resources) 1047ec681f3Smrg{ 1057ec681f3Smrg /* TODO */ 1067ec681f3Smrg} 1077ec681f3Smrg 1087ec681f3Smrgstatic void 1097ec681f3Smrgpanfrost_set_global_binding(struct pipe_context *pctx, 1107ec681f3Smrg unsigned first, unsigned count, 1117ec681f3Smrg struct pipe_resource **resources, 1127ec681f3Smrg uint32_t **handles) 1137ec681f3Smrg{ 1147ec681f3Smrg if (!resources) 1157ec681f3Smrg return; 1167ec681f3Smrg 1177ec681f3Smrg struct panfrost_context *ctx = pan_context(pctx); 1187ec681f3Smrg struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx); 1197ec681f3Smrg 1207ec681f3Smrg for (unsigned i = first; i < first + count; ++i) { 1217ec681f3Smrg struct panfrost_resource *rsrc = pan_resource(resources[i]); 1227ec681f3Smrg panfrost_batch_write_rsrc(batch, rsrc, PIPE_SHADER_COMPUTE); 1237ec681f3Smrg 1247ec681f3Smrg util_range_add(&rsrc->base, &rsrc->valid_buffer_range, 1257ec681f3Smrg 0, rsrc->base.width0); 1267ec681f3Smrg 1277ec681f3Smrg /* The handle points to uint32_t, but space is allocated for 64 bits */ 1287ec681f3Smrg memcpy(handles[i], &rsrc->image.data.bo->ptr.gpu, sizeof(mali_ptr)); 1297ec681f3Smrg } 1307ec681f3Smrg} 1317ec681f3Smrg 1327ec681f3Smrgstatic void 1337ec681f3Smrgpanfrost_memory_barrier(struct pipe_context *pctx, unsigned flags) 1347ec681f3Smrg{ 1357ec681f3Smrg /* TODO: Be smart and only flush the minimum needed, maybe emitting a 1367ec681f3Smrg * cache flush job if that would help */ 1377ec681f3Smrg panfrost_flush_all_batches(pan_context(pctx), "Memory barrier"); 1387ec681f3Smrg} 1397ec681f3Smrg 1407ec681f3Smrgvoid 1417ec681f3Smrgpanfrost_compute_context_init(struct pipe_context *pctx) 1427ec681f3Smrg{ 1437ec681f3Smrg pctx->create_compute_state = panfrost_create_compute_state; 1447ec681f3Smrg pctx->bind_compute_state = panfrost_bind_compute_state; 1457ec681f3Smrg pctx->delete_compute_state = panfrost_delete_compute_state; 1467ec681f3Smrg 1477ec681f3Smrg pctx->set_compute_resources = panfrost_set_compute_resources; 1487ec681f3Smrg pctx->set_global_binding = panfrost_set_global_binding; 1497ec681f3Smrg 1507ec681f3Smrg pctx->memory_barrier = panfrost_memory_barrier; 1517ec681f3Smrg} 152