1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2010 Red Hat Inc.
3bf215546Sopenharmony_ci * Copyright © 2014-2017 Broadcom
4bf215546Sopenharmony_ci * Copyright (C) 2019-2020 Collabora, Ltd.
5bf215546Sopenharmony_ci * Copyright 2006 VMware, Inc.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
11bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
12bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
15bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
16bf215546Sopenharmony_ci * Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci#include <stdio.h>
27bf215546Sopenharmony_ci#include <errno.h>
28bf215546Sopenharmony_ci#include "pipe/p_defines.h"
29bf215546Sopenharmony_ci#include "pipe/p_state.h"
30bf215546Sopenharmony_ci#include "pipe/p_context.h"
31bf215546Sopenharmony_ci#include "pipe/p_screen.h"
32bf215546Sopenharmony_ci#include "util/u_memory.h"
33bf215546Sopenharmony_ci#include "util/u_screen.h"
34bf215546Sopenharmony_ci#include "util/u_inlines.h"
35bf215546Sopenharmony_ci#include "util/format/u_format.h"
36bf215546Sopenharmony_ci#include "util/u_upload_mgr.h"
37bf215546Sopenharmony_ci#include "util/half_float.h"
38bf215546Sopenharmony_ci#include "frontend/winsys_handle.h"
39bf215546Sopenharmony_ci#include "frontend/sw_winsys.h"
40bf215546Sopenharmony_ci#include "gallium/auxiliary/util/u_transfer.h"
41bf215546Sopenharmony_ci#include "gallium/auxiliary/util/u_transfer_helper.h"
42bf215546Sopenharmony_ci#include "gallium/auxiliary/util/u_surface.h"
43bf215546Sopenharmony_ci#include "gallium/auxiliary/util/u_framebuffer.h"
44bf215546Sopenharmony_ci#include "agx_public.h"
45bf215546Sopenharmony_ci#include "agx_state.h"
46bf215546Sopenharmony_ci#include "magic.h"
47bf215546Sopenharmony_ci#include "asahi/compiler/agx_compile.h"
48bf215546Sopenharmony_ci#include "asahi/lib/decode.h"
49bf215546Sopenharmony_ci#include "asahi/lib/tiling.h"
50bf215546Sopenharmony_ci#include "asahi/lib/agx_formats.h"
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_cistatic const struct debug_named_value agx_debug_options[] = {
53bf215546Sopenharmony_ci   {"trace",     AGX_DBG_TRACE,    "Trace the command stream"},
54bf215546Sopenharmony_ci   {"deqp",      AGX_DBG_DEQP,     "Hacks for dEQP"},
55bf215546Sopenharmony_ci   {"no16",      AGX_DBG_NO16,     "Disable 16-bit support"},
56bf215546Sopenharmony_ci   DEBUG_NAMED_VALUE_END
57bf215546Sopenharmony_ci};
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_civoid agx_init_state_functions(struct pipe_context *ctx);
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_cistatic struct pipe_query *
62bf215546Sopenharmony_ciagx_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index)
63bf215546Sopenharmony_ci{
64bf215546Sopenharmony_ci   struct agx_query *query = CALLOC_STRUCT(agx_query);
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   return (struct pipe_query *)query;
67bf215546Sopenharmony_ci}
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_cistatic void
70bf215546Sopenharmony_ciagx_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
71bf215546Sopenharmony_ci{
72bf215546Sopenharmony_ci   FREE(query);
73bf215546Sopenharmony_ci}
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_cistatic bool
76bf215546Sopenharmony_ciagx_begin_query(struct pipe_context *ctx, struct pipe_query *query)
77bf215546Sopenharmony_ci{
78bf215546Sopenharmony_ci   return true;
79bf215546Sopenharmony_ci}
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_cistatic bool
82bf215546Sopenharmony_ciagx_end_query(struct pipe_context *ctx, struct pipe_query *query)
83bf215546Sopenharmony_ci{
84bf215546Sopenharmony_ci   return true;
85bf215546Sopenharmony_ci}
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_cistatic bool
88bf215546Sopenharmony_ciagx_get_query_result(struct pipe_context *ctx,
89bf215546Sopenharmony_ci                     struct pipe_query *query,
90bf215546Sopenharmony_ci                     bool wait,
91bf215546Sopenharmony_ci                     union pipe_query_result *vresult)
92bf215546Sopenharmony_ci{
93bf215546Sopenharmony_ci   uint64_t *result = (uint64_t*)vresult;
94bf215546Sopenharmony_ci
95bf215546Sopenharmony_ci   *result = 0;
96bf215546Sopenharmony_ci   return true;
97bf215546Sopenharmony_ci}
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_cistatic void
100bf215546Sopenharmony_ciagx_set_active_query_state(struct pipe_context *pipe, bool enable)
101bf215546Sopenharmony_ci{
102bf215546Sopenharmony_ci}
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci/*
106bf215546Sopenharmony_ci * resource
107bf215546Sopenharmony_ci */
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_cistatic struct pipe_resource *
110bf215546Sopenharmony_ciagx_resource_from_handle(struct pipe_screen *pscreen,
111bf215546Sopenharmony_ci                         const struct pipe_resource *templat,
112bf215546Sopenharmony_ci                         struct winsys_handle *whandle,
113bf215546Sopenharmony_ci                         unsigned usage)
114bf215546Sopenharmony_ci{
115bf215546Sopenharmony_ci   unreachable("Imports todo");
116bf215546Sopenharmony_ci}
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_cistatic bool
119bf215546Sopenharmony_ciagx_resource_get_handle(struct pipe_screen *pscreen,
120bf215546Sopenharmony_ci                        struct pipe_context *ctx,
121bf215546Sopenharmony_ci                        struct pipe_resource *pt,
122bf215546Sopenharmony_ci                        struct winsys_handle *handle,
123bf215546Sopenharmony_ci                        unsigned usage)
124bf215546Sopenharmony_ci{
125bf215546Sopenharmony_ci   unreachable("Handles todo");
126bf215546Sopenharmony_ci}
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci/* Linear textures require specifying their strides explicitly, which only
129bf215546Sopenharmony_ci * works for 2D textures. Rectangle textures are a special case of 2D.
130bf215546Sopenharmony_ci */
131bf215546Sopenharmony_cistatic bool
132bf215546Sopenharmony_ciagx_is_2d(enum pipe_texture_target target)
133bf215546Sopenharmony_ci{
134bf215546Sopenharmony_ci   return (target == PIPE_TEXTURE_2D || target == PIPE_TEXTURE_RECT);
135bf215546Sopenharmony_ci}
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_cistatic uint64_t
138bf215546Sopenharmony_ciagx_select_modifier(const struct agx_resource *pres)
139bf215546Sopenharmony_ci{
140bf215546Sopenharmony_ci   /* Buffers are always linear */
141bf215546Sopenharmony_ci   if (pres->base.target == PIPE_BUFFER)
142bf215546Sopenharmony_ci      return DRM_FORMAT_MOD_LINEAR;
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   /* Optimize streaming textures */
145bf215546Sopenharmony_ci   if (pres->base.usage == PIPE_USAGE_STREAM && agx_is_2d(pres->base.target))
146bf215546Sopenharmony_ci      return DRM_FORMAT_MOD_LINEAR;
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   /* Default to tiled */
149bf215546Sopenharmony_ci   return DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER;
150bf215546Sopenharmony_ci}
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_cistatic struct pipe_resource *
153bf215546Sopenharmony_ciagx_resource_create(struct pipe_screen *screen,
154bf215546Sopenharmony_ci                    const struct pipe_resource *templ)
155bf215546Sopenharmony_ci{
156bf215546Sopenharmony_ci   struct agx_device *dev = agx_device(screen);
157bf215546Sopenharmony_ci   struct agx_resource *nresource;
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci   nresource = CALLOC_STRUCT(agx_resource);
160bf215546Sopenharmony_ci   if (!nresource)
161bf215546Sopenharmony_ci      return NULL;
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci   nresource->base = *templ;
164bf215546Sopenharmony_ci   nresource->base.screen = screen;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci   nresource->modifier = agx_select_modifier(nresource);
167bf215546Sopenharmony_ci   nresource->mipmapped = (templ->last_level > 0);
168bf215546Sopenharmony_ci   nresource->internal_format = nresource->base.format;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci   unsigned offset = 0;
171bf215546Sopenharmony_ci   unsigned blocksize = util_format_get_blocksize(templ->format);
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci   for (unsigned l = 0; l <= templ->last_level; ++l) {
174bf215546Sopenharmony_ci      unsigned width = u_minify(templ->width0, l);
175bf215546Sopenharmony_ci      unsigned height = u_minify(templ->height0, l);
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci      if (nresource->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) {
178bf215546Sopenharmony_ci         unsigned tile = agx_select_tile_size(templ->width0, templ->height0, l, blocksize);
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci         width = ALIGN_POT(width, tile);
181bf215546Sopenharmony_ci         height = ALIGN_POT(height, tile);
182bf215546Sopenharmony_ci      }
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci      /* Align stride to presumed cache line */
185bf215546Sopenharmony_ci      nresource->slices[l].line_stride = util_format_get_stride(templ->format, width);
186bf215546Sopenharmony_ci      if (nresource->modifier == DRM_FORMAT_MOD_LINEAR) {
187bf215546Sopenharmony_ci         nresource->slices[l].line_stride = ALIGN_POT(nresource->slices[l].line_stride, 64);
188bf215546Sopenharmony_ci      }
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci      nresource->slices[l].offset = offset;
191bf215546Sopenharmony_ci      nresource->slices[l].size = ALIGN_POT(nresource->slices[l].line_stride * height, 0x80);
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci      offset += nresource->slices[l].size;
194bf215546Sopenharmony_ci   }
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   /* Arrays and cubemaps have the entire miptree duplicated and page aligned (16K) */
197bf215546Sopenharmony_ci   nresource->array_stride = ALIGN_POT(offset, 0x4000);
198bf215546Sopenharmony_ci   unsigned size = nresource->array_stride * templ->array_size * templ->depth0;
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   pipe_reference_init(&nresource->base.reference, 1);
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   struct sw_winsys *winsys = ((struct agx_screen *) screen)->winsys;
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   if (templ->bind & (PIPE_BIND_DISPLAY_TARGET |
205bf215546Sopenharmony_ci                      PIPE_BIND_SCANOUT |
206bf215546Sopenharmony_ci                      PIPE_BIND_SHARED)) {
207bf215546Sopenharmony_ci      unsigned width0 = templ->width0, height0 = templ->height0;
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci      if (nresource->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) {
210bf215546Sopenharmony_ci         width0 = ALIGN_POT(width0, 64);
211bf215546Sopenharmony_ci         height0 = ALIGN_POT(height0, 64);
212bf215546Sopenharmony_ci      }
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci      nresource->dt = winsys->displaytarget_create(winsys,
215bf215546Sopenharmony_ci                      templ->bind,
216bf215546Sopenharmony_ci                      templ->format,
217bf215546Sopenharmony_ci                      width0,
218bf215546Sopenharmony_ci                      height0,
219bf215546Sopenharmony_ci                      64,
220bf215546Sopenharmony_ci                      NULL /*map_front_private*/,
221bf215546Sopenharmony_ci                      &nresource->dt_stride);
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci      nresource->slices[0].line_stride = nresource->dt_stride;
224bf215546Sopenharmony_ci      assert((nresource->dt_stride & 0xF) == 0);
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci      offset = nresource->slices[0].line_stride * ALIGN_POT(templ->height0, 64);
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci      if (nresource->dt == NULL) {
229bf215546Sopenharmony_ci         FREE(nresource);
230bf215546Sopenharmony_ci         return NULL;
231bf215546Sopenharmony_ci      }
232bf215546Sopenharmony_ci   }
233bf215546Sopenharmony_ci
234bf215546Sopenharmony_ci   nresource->bo = agx_bo_create(dev, size, AGX_MEMORY_TYPE_FRAMEBUFFER);
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci   if (!nresource->bo) {
237bf215546Sopenharmony_ci      FREE(nresource);
238bf215546Sopenharmony_ci      return NULL;
239bf215546Sopenharmony_ci   }
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci   return &nresource->base;
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_cistatic void
245bf215546Sopenharmony_ciagx_resource_destroy(struct pipe_screen *screen,
246bf215546Sopenharmony_ci                     struct pipe_resource *prsrc)
247bf215546Sopenharmony_ci{
248bf215546Sopenharmony_ci   struct agx_resource *rsrc = (struct agx_resource *)prsrc;
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci   if (rsrc->dt) {
251bf215546Sopenharmony_ci      /* display target */
252bf215546Sopenharmony_ci      struct agx_screen *agx_screen = (struct agx_screen*)screen;
253bf215546Sopenharmony_ci      struct sw_winsys *winsys = agx_screen->winsys;
254bf215546Sopenharmony_ci      winsys->displaytarget_destroy(winsys, rsrc->dt);
255bf215546Sopenharmony_ci   }
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci   agx_bo_unreference(rsrc->bo);
258bf215546Sopenharmony_ci   FREE(rsrc);
259bf215546Sopenharmony_ci}
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci/*
263bf215546Sopenharmony_ci * transfer
264bf215546Sopenharmony_ci */
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_cistatic void
267bf215546Sopenharmony_ciagx_transfer_flush_region(struct pipe_context *pipe,
268bf215546Sopenharmony_ci                          struct pipe_transfer *transfer,
269bf215546Sopenharmony_ci                          const struct pipe_box *box)
270bf215546Sopenharmony_ci{
271bf215546Sopenharmony_ci}
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_cistatic void *
274bf215546Sopenharmony_ciagx_transfer_map(struct pipe_context *pctx,
275bf215546Sopenharmony_ci                 struct pipe_resource *resource,
276bf215546Sopenharmony_ci                 unsigned level,
277bf215546Sopenharmony_ci                 unsigned usage,  /* a combination of PIPE_MAP_x */
278bf215546Sopenharmony_ci                 const struct pipe_box *box,
279bf215546Sopenharmony_ci                 struct pipe_transfer **out_transfer)
280bf215546Sopenharmony_ci{
281bf215546Sopenharmony_ci   struct agx_context *ctx = agx_context(pctx);
282bf215546Sopenharmony_ci   struct agx_resource *rsrc = agx_resource(resource);
283bf215546Sopenharmony_ci   unsigned blocksize = util_format_get_blocksize(resource->format);
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci   /* Can't map tiled/compressed directly */
286bf215546Sopenharmony_ci   if ((usage & PIPE_MAP_DIRECTLY) && rsrc->modifier != DRM_FORMAT_MOD_LINEAR)
287bf215546Sopenharmony_ci      return NULL;
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   if (ctx->batch->cbufs[0] && resource == ctx->batch->cbufs[0]->texture)
290bf215546Sopenharmony_ci      pctx->flush(pctx, NULL, 0);
291bf215546Sopenharmony_ci   if (ctx->batch->zsbuf && resource == ctx->batch->zsbuf->texture)
292bf215546Sopenharmony_ci      pctx->flush(pctx, NULL, 0);
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci   struct agx_transfer *transfer = CALLOC_STRUCT(agx_transfer);
295bf215546Sopenharmony_ci   transfer->base.level = level;
296bf215546Sopenharmony_ci   transfer->base.usage = usage;
297bf215546Sopenharmony_ci   transfer->base.box = *box;
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci   pipe_resource_reference(&transfer->base.resource, resource);
300bf215546Sopenharmony_ci   *out_transfer = &transfer->base;
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   if (rsrc->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) {
303bf215546Sopenharmony_ci      transfer->base.stride = box->width * blocksize;
304bf215546Sopenharmony_ci      transfer->base.layer_stride = transfer->base.stride * box->height;
305bf215546Sopenharmony_ci      transfer->map = calloc(transfer->base.layer_stride, box->depth);
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci      if ((usage & PIPE_MAP_READ) && BITSET_TEST(rsrc->data_valid, level)) {
308bf215546Sopenharmony_ci         for (unsigned z = 0; z < box->depth; ++z) {
309bf215546Sopenharmony_ci            uint8_t *map = agx_map_texture_cpu(rsrc, level, box->z + z);
310bf215546Sopenharmony_ci            uint8_t *dst = (uint8_t *) transfer->map +
311bf215546Sopenharmony_ci                           transfer->base.layer_stride * z;
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci            agx_detile(map, dst,
314bf215546Sopenharmony_ci               u_minify(resource->width0, level), blocksize * 8,
315bf215546Sopenharmony_ci               transfer->base.stride / blocksize,
316bf215546Sopenharmony_ci               box->x, box->y, box->x + box->width, box->y + box->height,
317bf215546Sopenharmony_ci               agx_select_tile_shift(resource->width0, resource->height0, level, blocksize));
318bf215546Sopenharmony_ci         }
319bf215546Sopenharmony_ci      }
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci      return transfer->map;
322bf215546Sopenharmony_ci   } else {
323bf215546Sopenharmony_ci      assert (rsrc->modifier == DRM_FORMAT_MOD_LINEAR);
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ci      transfer->base.stride = rsrc->slices[level].line_stride;
326bf215546Sopenharmony_ci      transfer->base.layer_stride = rsrc->array_stride;
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci      /* Be conservative for direct writes */
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci      if ((usage & PIPE_MAP_WRITE) && (usage & PIPE_MAP_DIRECTLY))
331bf215546Sopenharmony_ci         BITSET_SET(rsrc->data_valid, level);
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci      return (uint8_t *) agx_map_texture_cpu(rsrc, level, box->z)
334bf215546Sopenharmony_ci             + transfer->base.box.y * rsrc->slices[level].line_stride
335bf215546Sopenharmony_ci             + transfer->base.box.x * blocksize;
336bf215546Sopenharmony_ci   }
337bf215546Sopenharmony_ci}
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_cistatic void
340bf215546Sopenharmony_ciagx_transfer_unmap(struct pipe_context *pctx,
341bf215546Sopenharmony_ci                   struct pipe_transfer *transfer)
342bf215546Sopenharmony_ci{
343bf215546Sopenharmony_ci   /* Gallium expects writeback here, so we tile */
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci   struct agx_transfer *trans = agx_transfer(transfer);
346bf215546Sopenharmony_ci   struct pipe_resource *prsrc = transfer->resource;
347bf215546Sopenharmony_ci   struct agx_resource *rsrc = (struct agx_resource *) prsrc;
348bf215546Sopenharmony_ci   unsigned blocksize = util_format_get_blocksize(prsrc->format);
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_ci   if (transfer->usage & PIPE_MAP_WRITE)
351bf215546Sopenharmony_ci      BITSET_SET(rsrc->data_valid, transfer->level);
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci   /* Tiling will occur in software from a staging cpu buffer */
354bf215546Sopenharmony_ci   if ((transfer->usage & PIPE_MAP_WRITE) &&
355bf215546Sopenharmony_ci         rsrc->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) {
356bf215546Sopenharmony_ci      assert(trans->map != NULL);
357bf215546Sopenharmony_ci
358bf215546Sopenharmony_ci      for (unsigned z = 0; z < transfer->box.depth; ++z) {
359bf215546Sopenharmony_ci         uint8_t *map = agx_map_texture_cpu(rsrc, transfer->level,
360bf215546Sopenharmony_ci               transfer->box.z + z);
361bf215546Sopenharmony_ci         uint8_t *src = (uint8_t *) trans->map +
362bf215546Sopenharmony_ci                        transfer->layer_stride * z;
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ci         agx_tile(map, src,
365bf215546Sopenharmony_ci            u_minify(transfer->resource->width0, transfer->level),
366bf215546Sopenharmony_ci            blocksize * 8,
367bf215546Sopenharmony_ci            transfer->stride / blocksize,
368bf215546Sopenharmony_ci            transfer->box.x, transfer->box.y,
369bf215546Sopenharmony_ci            transfer->box.x + transfer->box.width,
370bf215546Sopenharmony_ci            transfer->box.y + transfer->box.height,
371bf215546Sopenharmony_ci            agx_select_tile_shift(transfer->resource->width0,
372bf215546Sopenharmony_ci                                  transfer->resource->height0,
373bf215546Sopenharmony_ci                                  transfer->level, blocksize));
374bf215546Sopenharmony_ci      }
375bf215546Sopenharmony_ci   }
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_ci   /* Free the transfer */
378bf215546Sopenharmony_ci   free(trans->map);
379bf215546Sopenharmony_ci   pipe_resource_reference(&transfer->resource, NULL);
380bf215546Sopenharmony_ci   FREE(transfer);
381bf215546Sopenharmony_ci}
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci/*
384bf215546Sopenharmony_ci * clear/copy
385bf215546Sopenharmony_ci */
386bf215546Sopenharmony_cistatic void
387bf215546Sopenharmony_ciagx_clear(struct pipe_context *pctx, unsigned buffers, const struct pipe_scissor_state *scissor_state,
388bf215546Sopenharmony_ci          const union pipe_color_union *color, double depth, unsigned stencil)
389bf215546Sopenharmony_ci{
390bf215546Sopenharmony_ci   struct agx_context *ctx = agx_context(pctx);
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   /* TODO: support partial clears */
393bf215546Sopenharmony_ci   if (ctx->batch->clear | ctx->batch->draw)
394bf215546Sopenharmony_ci      pctx->flush(pctx, NULL, 0);
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_ci   ctx->batch->clear |= buffers;
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci   if (buffers & PIPE_CLEAR_COLOR0)
399bf215546Sopenharmony_ci      memcpy(ctx->batch->clear_color, color->f, sizeof(color->f));
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   if (buffers & PIPE_CLEAR_DEPTH)
402bf215546Sopenharmony_ci      ctx->batch->clear_depth = depth;
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci   if (buffers & PIPE_CLEAR_STENCIL)
405bf215546Sopenharmony_ci      ctx->batch->clear_stencil = stencil;
406bf215546Sopenharmony_ci}
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_cistatic void
410bf215546Sopenharmony_ciagx_flush_resource(struct pipe_context *ctx,
411bf215546Sopenharmony_ci                   struct pipe_resource *resource)
412bf215546Sopenharmony_ci{
413bf215546Sopenharmony_ci}
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci/*
416bf215546Sopenharmony_ci * context
417bf215546Sopenharmony_ci */
418bf215546Sopenharmony_cistatic void
419bf215546Sopenharmony_ciagx_flush(struct pipe_context *pctx,
420bf215546Sopenharmony_ci          struct pipe_fence_handle **fence,
421bf215546Sopenharmony_ci          unsigned flags)
422bf215546Sopenharmony_ci{
423bf215546Sopenharmony_ci   struct agx_context *ctx = agx_context(pctx);
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci   if (fence)
426bf215546Sopenharmony_ci      *fence = NULL;
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ci   /* Nothing to do */
429bf215546Sopenharmony_ci   if (!(ctx->batch->draw | ctx->batch->clear))
430bf215546Sopenharmony_ci      return;
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci   /* Finalize the encoder */
433bf215546Sopenharmony_ci   uint8_t stop[5 + 64] = { 0x00, 0x00, 0x00, 0xc0, 0x00 };
434bf215546Sopenharmony_ci   memcpy(ctx->batch->encoder_current, stop, sizeof(stop));
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci   /* Emit the commandbuffer */
437bf215546Sopenharmony_ci   uint64_t pipeline_clear = 0, pipeline_reload = 0;
438bf215546Sopenharmony_ci   bool clear_pipeline_textures = false;
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ci   struct agx_device *dev = agx_device(pctx->screen);
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci   uint16_t clear_colour[4] = {
443bf215546Sopenharmony_ci      _mesa_float_to_half(ctx->batch->clear_color[0]),
444bf215546Sopenharmony_ci      _mesa_float_to_half(ctx->batch->clear_color[1]),
445bf215546Sopenharmony_ci      _mesa_float_to_half(ctx->batch->clear_color[2]),
446bf215546Sopenharmony_ci      _mesa_float_to_half(ctx->batch->clear_color[3])
447bf215546Sopenharmony_ci   };
448bf215546Sopenharmony_ci
449bf215546Sopenharmony_ci   pipeline_clear = agx_build_clear_pipeline(ctx,
450bf215546Sopenharmony_ci         dev->internal.clear,
451bf215546Sopenharmony_ci         agx_pool_upload(&ctx->batch->pool, clear_colour, sizeof(clear_colour)));
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_ci   if (ctx->batch->cbufs[0]) {
454bf215546Sopenharmony_ci      enum pipe_format fmt = ctx->batch->cbufs[0]->format;
455bf215546Sopenharmony_ci      enum agx_format internal = agx_pixel_format[fmt].internal;
456bf215546Sopenharmony_ci      uint32_t shader = dev->reload.format[internal];
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci      pipeline_reload = agx_build_reload_pipeline(ctx, shader,
459bf215546Sopenharmony_ci                               ctx->batch->cbufs[0]);
460bf215546Sopenharmony_ci   }
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci   if (ctx->batch->cbufs[0] && !(ctx->batch->clear & PIPE_CLEAR_COLOR0)) {
463bf215546Sopenharmony_ci      clear_pipeline_textures = true;
464bf215546Sopenharmony_ci      pipeline_clear = pipeline_reload;
465bf215546Sopenharmony_ci   }
466bf215546Sopenharmony_ci
467bf215546Sopenharmony_ci   uint64_t pipeline_store = 0;
468bf215546Sopenharmony_ci
469bf215546Sopenharmony_ci   if (ctx->batch->cbufs[0]) {
470bf215546Sopenharmony_ci      pipeline_store =
471bf215546Sopenharmony_ci         agx_build_store_pipeline(ctx,
472bf215546Sopenharmony_ci                                  dev->internal.store,
473bf215546Sopenharmony_ci                                  agx_pool_upload(&ctx->batch->pool, ctx->render_target[0], sizeof(ctx->render_target)));
474bf215546Sopenharmony_ci   }
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci   /* Pipelines must 64 aligned */
477bf215546Sopenharmony_ci   for (unsigned i = 0; i < ctx->batch->nr_cbufs; ++i) {
478bf215546Sopenharmony_ci      struct agx_resource *rt = agx_resource(ctx->batch->cbufs[i]->texture);
479bf215546Sopenharmony_ci      BITSET_SET(rt->data_valid, 0);
480bf215546Sopenharmony_ci   }
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_ci   struct agx_resource *zbuf = ctx->batch->zsbuf ?
483bf215546Sopenharmony_ci      agx_resource(ctx->batch->zsbuf->texture) : NULL;
484bf215546Sopenharmony_ci
485bf215546Sopenharmony_ci   if (zbuf) {
486bf215546Sopenharmony_ci      BITSET_SET(zbuf->data_valid, 0);
487bf215546Sopenharmony_ci
488bf215546Sopenharmony_ci      if (zbuf->separate_stencil)
489bf215546Sopenharmony_ci         BITSET_SET(zbuf->separate_stencil->data_valid, 0);
490bf215546Sopenharmony_ci   }
491bf215546Sopenharmony_ci
492bf215546Sopenharmony_ci   /* BO list for a given batch consists of:
493bf215546Sopenharmony_ci    *  - BOs for the batch's framebuffer surfaces
494bf215546Sopenharmony_ci    *  - BOs for the batch's pools
495bf215546Sopenharmony_ci    *  - BOs for the encoder
496bf215546Sopenharmony_ci    *  - BO for internal shaders
497bf215546Sopenharmony_ci    *  - BOs added to the batch explicitly
498bf215546Sopenharmony_ci    */
499bf215546Sopenharmony_ci   struct agx_batch *batch = ctx->batch;
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci   agx_batch_add_bo(batch, batch->encoder);
502bf215546Sopenharmony_ci   agx_batch_add_bo(batch, batch->scissor.bo);
503bf215546Sopenharmony_ci   agx_batch_add_bo(batch, batch->depth_bias.bo);
504bf215546Sopenharmony_ci   agx_batch_add_bo(batch, dev->internal.bo);
505bf215546Sopenharmony_ci   agx_batch_add_bo(batch, dev->reload.bo);
506bf215546Sopenharmony_ci
507bf215546Sopenharmony_ci   for (unsigned i = 0; i < batch->nr_cbufs; ++i) {
508bf215546Sopenharmony_ci      struct pipe_surface *surf = batch->cbufs[i];
509bf215546Sopenharmony_ci      assert(surf != NULL && surf->texture != NULL);
510bf215546Sopenharmony_ci      struct agx_resource *rsrc = agx_resource(surf->texture);
511bf215546Sopenharmony_ci      agx_batch_add_bo(batch, rsrc->bo);
512bf215546Sopenharmony_ci   }
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_ci   if (batch->zsbuf) {
515bf215546Sopenharmony_ci      struct pipe_surface *surf = batch->zsbuf;
516bf215546Sopenharmony_ci      struct agx_resource *rsrc = agx_resource(surf->texture);
517bf215546Sopenharmony_ci      agx_batch_add_bo(batch, rsrc->bo);
518bf215546Sopenharmony_ci
519bf215546Sopenharmony_ci      if (rsrc->separate_stencil)
520bf215546Sopenharmony_ci         agx_batch_add_bo(batch, rsrc->separate_stencil->bo);
521bf215546Sopenharmony_ci   }
522bf215546Sopenharmony_ci
523bf215546Sopenharmony_ci   unsigned handle_count =
524bf215546Sopenharmony_ci      BITSET_COUNT(batch->bo_list) +
525bf215546Sopenharmony_ci      agx_pool_num_bos(&batch->pool) +
526bf215546Sopenharmony_ci      agx_pool_num_bos(&batch->pipeline_pool);
527bf215546Sopenharmony_ci
528bf215546Sopenharmony_ci   uint32_t *handles = calloc(sizeof(uint32_t), handle_count);
529bf215546Sopenharmony_ci   unsigned handle = 0, handle_i = 0;
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci   BITSET_FOREACH_SET(handle, batch->bo_list, sizeof(batch->bo_list) * 8) {
532bf215546Sopenharmony_ci      handles[handle_i++] = handle;
533bf215546Sopenharmony_ci   }
534bf215546Sopenharmony_ci
535bf215546Sopenharmony_ci   agx_pool_get_bo_handles(&batch->pool, handles + handle_i);
536bf215546Sopenharmony_ci   handle_i += agx_pool_num_bos(&batch->pool);
537bf215546Sopenharmony_ci
538bf215546Sopenharmony_ci   agx_pool_get_bo_handles(&batch->pipeline_pool, handles + handle_i);
539bf215546Sopenharmony_ci   handle_i += agx_pool_num_bos(&batch->pipeline_pool);
540bf215546Sopenharmony_ci
541bf215546Sopenharmony_ci   /* Size calculation should've been exact */
542bf215546Sopenharmony_ci   assert(handle_i == handle_count);
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_ci   unsigned cmdbuf_id = agx_get_global_id(dev);
545bf215546Sopenharmony_ci   unsigned encoder_id = agx_get_global_id(dev);
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci   unsigned cmdbuf_size = demo_cmdbuf(dev->cmdbuf.ptr.cpu,
548bf215546Sopenharmony_ci               dev->cmdbuf.size,
549bf215546Sopenharmony_ci               &ctx->batch->pool,
550bf215546Sopenharmony_ci               &ctx->framebuffer,
551bf215546Sopenharmony_ci               ctx->batch->encoder->ptr.gpu,
552bf215546Sopenharmony_ci               encoder_id,
553bf215546Sopenharmony_ci               ctx->batch->scissor.bo->ptr.gpu,
554bf215546Sopenharmony_ci               ctx->batch->depth_bias.bo->ptr.gpu,
555bf215546Sopenharmony_ci               pipeline_clear,
556bf215546Sopenharmony_ci               pipeline_reload,
557bf215546Sopenharmony_ci               pipeline_store,
558bf215546Sopenharmony_ci               clear_pipeline_textures,
559bf215546Sopenharmony_ci               ctx->batch->clear_depth,
560bf215546Sopenharmony_ci               ctx->batch->clear_stencil);
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_ci   /* Generate the mapping table from the BO list */
563bf215546Sopenharmony_ci   demo_mem_map(dev->memmap.ptr.cpu, dev->memmap.size, handles, handle_count,
564bf215546Sopenharmony_ci                cmdbuf_id, encoder_id, cmdbuf_size);
565bf215546Sopenharmony_ci
566bf215546Sopenharmony_ci   free(handles);
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_ci   agx_submit_cmdbuf(dev, dev->cmdbuf.handle, dev->memmap.handle, dev->queue.id);
569bf215546Sopenharmony_ci
570bf215546Sopenharmony_ci   agx_wait_queue(dev->queue);
571bf215546Sopenharmony_ci
572bf215546Sopenharmony_ci   if (dev->debug & AGX_DBG_TRACE) {
573bf215546Sopenharmony_ci      agxdecode_cmdstream(dev->cmdbuf.handle, dev->memmap.handle, true);
574bf215546Sopenharmony_ci      agxdecode_next_frame();
575bf215546Sopenharmony_ci   }
576bf215546Sopenharmony_ci
577bf215546Sopenharmony_ci   memset(batch->bo_list, 0, sizeof(batch->bo_list));
578bf215546Sopenharmony_ci   agx_pool_cleanup(&ctx->batch->pool);
579bf215546Sopenharmony_ci   agx_pool_cleanup(&ctx->batch->pipeline_pool);
580bf215546Sopenharmony_ci   agx_pool_init(&ctx->batch->pool, dev, AGX_MEMORY_TYPE_FRAMEBUFFER, true);
581bf215546Sopenharmony_ci   agx_pool_init(&ctx->batch->pipeline_pool, dev, AGX_MEMORY_TYPE_CMDBUF_32, true);
582bf215546Sopenharmony_ci   ctx->batch->clear = 0;
583bf215546Sopenharmony_ci   ctx->batch->draw = 0;
584bf215546Sopenharmony_ci   ctx->batch->encoder_current = ctx->batch->encoder->ptr.cpu;
585bf215546Sopenharmony_ci   ctx->batch->scissor.count = 0;
586bf215546Sopenharmony_ci   ctx->dirty = ~0;
587bf215546Sopenharmony_ci}
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_cistatic void
590bf215546Sopenharmony_ciagx_destroy_context(struct pipe_context *pctx)
591bf215546Sopenharmony_ci{
592bf215546Sopenharmony_ci   struct agx_context *ctx = agx_context(pctx);
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_ci   if (pctx->stream_uploader)
595bf215546Sopenharmony_ci      u_upload_destroy(pctx->stream_uploader);
596bf215546Sopenharmony_ci
597bf215546Sopenharmony_ci   if (ctx->blitter)
598bf215546Sopenharmony_ci      util_blitter_destroy(ctx->blitter);
599bf215546Sopenharmony_ci
600bf215546Sopenharmony_ci   util_unreference_framebuffer_state(&ctx->framebuffer);
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci   FREE(ctx);
603bf215546Sopenharmony_ci}
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_cistatic void
606bf215546Sopenharmony_ciagx_invalidate_resource(struct pipe_context *ctx,
607bf215546Sopenharmony_ci                        struct pipe_resource *resource)
608bf215546Sopenharmony_ci{
609bf215546Sopenharmony_ci}
610bf215546Sopenharmony_ci
611bf215546Sopenharmony_cistatic struct pipe_context *
612bf215546Sopenharmony_ciagx_create_context(struct pipe_screen *screen,
613bf215546Sopenharmony_ci                   void *priv, unsigned flags)
614bf215546Sopenharmony_ci{
615bf215546Sopenharmony_ci   struct agx_context *ctx = CALLOC_STRUCT(agx_context);
616bf215546Sopenharmony_ci   struct pipe_context *pctx = &ctx->base;
617bf215546Sopenharmony_ci
618bf215546Sopenharmony_ci   if (!ctx)
619bf215546Sopenharmony_ci      return NULL;
620bf215546Sopenharmony_ci
621bf215546Sopenharmony_ci   pctx->screen = screen;
622bf215546Sopenharmony_ci   pctx->priv = priv;
623bf215546Sopenharmony_ci
624bf215546Sopenharmony_ci   ctx->batch = CALLOC_STRUCT(agx_batch);
625bf215546Sopenharmony_ci   agx_pool_init(&ctx->batch->pool,
626bf215546Sopenharmony_ci                 agx_device(screen), AGX_MEMORY_TYPE_FRAMEBUFFER, true);
627bf215546Sopenharmony_ci   agx_pool_init(&ctx->batch->pipeline_pool,
628bf215546Sopenharmony_ci                 agx_device(screen), AGX_MEMORY_TYPE_SHADER, true);
629bf215546Sopenharmony_ci   ctx->batch->encoder = agx_bo_create(agx_device(screen), 0x80000, AGX_MEMORY_TYPE_FRAMEBUFFER);
630bf215546Sopenharmony_ci   ctx->batch->encoder_current = ctx->batch->encoder->ptr.cpu;
631bf215546Sopenharmony_ci   ctx->batch->scissor.bo = agx_bo_create(agx_device(screen), 0x80000, AGX_MEMORY_TYPE_FRAMEBUFFER);
632bf215546Sopenharmony_ci   ctx->batch->depth_bias.bo = agx_bo_create(agx_device(screen), 0x80000, AGX_MEMORY_TYPE_FRAMEBUFFER);
633bf215546Sopenharmony_ci
634bf215546Sopenharmony_ci   /* Upload fixed shaders (TODO: compile them?) */
635bf215546Sopenharmony_ci
636bf215546Sopenharmony_ci   pctx->stream_uploader = u_upload_create_default(pctx);
637bf215546Sopenharmony_ci   if (!pctx->stream_uploader) {
638bf215546Sopenharmony_ci      FREE(pctx);
639bf215546Sopenharmony_ci      return NULL;
640bf215546Sopenharmony_ci   }
641bf215546Sopenharmony_ci   pctx->const_uploader = pctx->stream_uploader;
642bf215546Sopenharmony_ci
643bf215546Sopenharmony_ci   pctx->destroy = agx_destroy_context;
644bf215546Sopenharmony_ci   pctx->flush = agx_flush;
645bf215546Sopenharmony_ci   pctx->clear = agx_clear;
646bf215546Sopenharmony_ci   pctx->resource_copy_region = util_resource_copy_region;
647bf215546Sopenharmony_ci   pctx->blit = agx_blit;
648bf215546Sopenharmony_ci   pctx->flush_resource = agx_flush_resource;
649bf215546Sopenharmony_ci   pctx->create_query = agx_create_query;
650bf215546Sopenharmony_ci   pctx->destroy_query = agx_destroy_query;
651bf215546Sopenharmony_ci   pctx->begin_query = agx_begin_query;
652bf215546Sopenharmony_ci   pctx->end_query = agx_end_query;
653bf215546Sopenharmony_ci   pctx->get_query_result = agx_get_query_result;
654bf215546Sopenharmony_ci   pctx->set_active_query_state = agx_set_active_query_state;
655bf215546Sopenharmony_ci
656bf215546Sopenharmony_ci   pctx->buffer_map = u_transfer_helper_transfer_map;
657bf215546Sopenharmony_ci   pctx->buffer_unmap = u_transfer_helper_transfer_unmap;
658bf215546Sopenharmony_ci   pctx->texture_map = u_transfer_helper_transfer_map;
659bf215546Sopenharmony_ci   pctx->texture_unmap = u_transfer_helper_transfer_unmap;
660bf215546Sopenharmony_ci   pctx->transfer_flush_region = u_transfer_helper_transfer_flush_region;
661bf215546Sopenharmony_ci
662bf215546Sopenharmony_ci   pctx->buffer_subdata = u_default_buffer_subdata;
663bf215546Sopenharmony_ci   pctx->texture_subdata = u_default_texture_subdata;
664bf215546Sopenharmony_ci   pctx->invalidate_resource = agx_invalidate_resource;
665bf215546Sopenharmony_ci   agx_init_state_functions(pctx);
666bf215546Sopenharmony_ci
667bf215546Sopenharmony_ci
668bf215546Sopenharmony_ci   ctx->blitter = util_blitter_create(pctx);
669bf215546Sopenharmony_ci
670bf215546Sopenharmony_ci   return pctx;
671bf215546Sopenharmony_ci}
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_cistatic void
674bf215546Sopenharmony_ciagx_flush_frontbuffer(struct pipe_screen *_screen,
675bf215546Sopenharmony_ci                      struct pipe_context *pctx,
676bf215546Sopenharmony_ci                      struct pipe_resource *prsrc,
677bf215546Sopenharmony_ci                      unsigned level, unsigned layer,
678bf215546Sopenharmony_ci                      void *context_private, struct pipe_box *box)
679bf215546Sopenharmony_ci{
680bf215546Sopenharmony_ci   struct agx_resource *rsrc = (struct agx_resource *) prsrc;
681bf215546Sopenharmony_ci   struct agx_screen *agx_screen = (struct agx_screen*)_screen;
682bf215546Sopenharmony_ci   struct sw_winsys *winsys = agx_screen->winsys;
683bf215546Sopenharmony_ci
684bf215546Sopenharmony_ci   /* Dump the framebuffer */
685bf215546Sopenharmony_ci   assert (rsrc->dt);
686bf215546Sopenharmony_ci   void *map = winsys->displaytarget_map(winsys, rsrc->dt, PIPE_USAGE_DEFAULT);
687bf215546Sopenharmony_ci   assert(map != NULL);
688bf215546Sopenharmony_ci
689bf215546Sopenharmony_ci   if (rsrc->modifier == DRM_FORMAT_MOD_APPLE_64X64_MORTON_ORDER) {
690bf215546Sopenharmony_ci      agx_detile(rsrc->bo->ptr.cpu, map,
691bf215546Sopenharmony_ci                 rsrc->base.width0, 32, rsrc->dt_stride / 4,
692bf215546Sopenharmony_ci                 0, 0, rsrc->base.width0, rsrc->base.height0, 6);
693bf215546Sopenharmony_ci   } else {
694bf215546Sopenharmony_ci      memcpy(map, rsrc->bo->ptr.cpu, rsrc->dt_stride * rsrc->base.height0);
695bf215546Sopenharmony_ci   }
696bf215546Sopenharmony_ci
697bf215546Sopenharmony_ci   winsys->displaytarget_display(winsys, rsrc->dt, context_private, box);
698bf215546Sopenharmony_ci}
699bf215546Sopenharmony_ci
700bf215546Sopenharmony_cistatic const char *
701bf215546Sopenharmony_ciagx_get_vendor(struct pipe_screen* pscreen)
702bf215546Sopenharmony_ci{
703bf215546Sopenharmony_ci   return "Asahi";
704bf215546Sopenharmony_ci}
705bf215546Sopenharmony_ci
706bf215546Sopenharmony_cistatic const char *
707bf215546Sopenharmony_ciagx_get_device_vendor(struct pipe_screen* pscreen)
708bf215546Sopenharmony_ci{
709bf215546Sopenharmony_ci   return "Apple";
710bf215546Sopenharmony_ci}
711bf215546Sopenharmony_ci
712bf215546Sopenharmony_cistatic const char *
713bf215546Sopenharmony_ciagx_get_name(struct pipe_screen* pscreen)
714bf215546Sopenharmony_ci{
715bf215546Sopenharmony_ci   return "Apple M1 (G13G B0)";
716bf215546Sopenharmony_ci}
717bf215546Sopenharmony_ci
718bf215546Sopenharmony_cistatic int
719bf215546Sopenharmony_ciagx_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
720bf215546Sopenharmony_ci{
721bf215546Sopenharmony_ci   bool is_deqp = agx_device(pscreen)->debug & AGX_DBG_DEQP;
722bf215546Sopenharmony_ci
723bf215546Sopenharmony_ci   switch (param) {
724bf215546Sopenharmony_ci   case PIPE_CAP_NPOT_TEXTURES:
725bf215546Sopenharmony_ci   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
726bf215546Sopenharmony_ci   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
727bf215546Sopenharmony_ci   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
728bf215546Sopenharmony_ci   case PIPE_CAP_DEPTH_CLIP_DISABLE:
729bf215546Sopenharmony_ci   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
730bf215546Sopenharmony_ci   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
731bf215546Sopenharmony_ci   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
732bf215546Sopenharmony_ci   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
733bf215546Sopenharmony_ci   case PIPE_CAP_CLIP_HALFZ:
734bf215546Sopenharmony_ci      return 1;
735bf215546Sopenharmony_ci
736bf215546Sopenharmony_ci   case PIPE_CAP_MAX_RENDER_TARGETS:
737bf215546Sopenharmony_ci      return 1;
738bf215546Sopenharmony_ci
739bf215546Sopenharmony_ci   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
740bf215546Sopenharmony_ci      return 0;
741bf215546Sopenharmony_ci
742bf215546Sopenharmony_ci   case PIPE_CAP_OCCLUSION_QUERY:
743bf215546Sopenharmony_ci   case PIPE_CAP_PRIMITIVE_RESTART:
744bf215546Sopenharmony_ci   case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
745bf215546Sopenharmony_ci      return true;
746bf215546Sopenharmony_ci
747bf215546Sopenharmony_ci   case PIPE_CAP_SAMPLER_VIEW_TARGET:
748bf215546Sopenharmony_ci   case PIPE_CAP_TEXTURE_SWIZZLE:
749bf215546Sopenharmony_ci   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
750bf215546Sopenharmony_ci   case PIPE_CAP_INDEP_BLEND_ENABLE:
751bf215546Sopenharmony_ci   case PIPE_CAP_INDEP_BLEND_FUNC:
752bf215546Sopenharmony_ci   case PIPE_CAP_ACCELERATED:
753bf215546Sopenharmony_ci   case PIPE_CAP_UMA:
754bf215546Sopenharmony_ci   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
755bf215546Sopenharmony_ci   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
756bf215546Sopenharmony_ci   case PIPE_CAP_SHADER_ARRAY_COMPONENTS:
757bf215546Sopenharmony_ci   case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED:
758bf215546Sopenharmony_ci   case PIPE_CAP_PACKED_UNIFORMS:
759bf215546Sopenharmony_ci      return 1;
760bf215546Sopenharmony_ci
761bf215546Sopenharmony_ci   case PIPE_CAP_VS_INSTANCEID:
762bf215546Sopenharmony_ci   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
763bf215546Sopenharmony_ci   case PIPE_CAP_TEXTURE_MULTISAMPLE:
764bf215546Sopenharmony_ci   case PIPE_CAP_SURFACE_SAMPLE_COUNT:
765bf215546Sopenharmony_ci   case PIPE_CAP_SAMPLE_SHADING:
766bf215546Sopenharmony_ci      return is_deqp;
767bf215546Sopenharmony_ci
768bf215546Sopenharmony_ci   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
769bf215546Sopenharmony_ci      return 0;
770bf215546Sopenharmony_ci
771bf215546Sopenharmony_ci   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
772bf215546Sopenharmony_ci      return is_deqp ? PIPE_MAX_SO_BUFFERS : 0;
773bf215546Sopenharmony_ci
774bf215546Sopenharmony_ci   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
775bf215546Sopenharmony_ci   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
776bf215546Sopenharmony_ci      return is_deqp ? PIPE_MAX_SO_OUTPUTS : 0;
777bf215546Sopenharmony_ci
778bf215546Sopenharmony_ci   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
779bf215546Sopenharmony_ci   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
780bf215546Sopenharmony_ci      return is_deqp ? 1 : 0;
781bf215546Sopenharmony_ci
782bf215546Sopenharmony_ci   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
783bf215546Sopenharmony_ci      return 256;
784bf215546Sopenharmony_ci
785bf215546Sopenharmony_ci   case PIPE_CAP_GLSL_FEATURE_LEVEL:
786bf215546Sopenharmony_ci   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
787bf215546Sopenharmony_ci      return is_deqp ? 330 : 130;
788bf215546Sopenharmony_ci   case PIPE_CAP_ESSL_FEATURE_LEVEL:
789bf215546Sopenharmony_ci      return is_deqp ? 320 : 120;
790bf215546Sopenharmony_ci
791bf215546Sopenharmony_ci   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
792bf215546Sopenharmony_ci      return 16;
793bf215546Sopenharmony_ci
794bf215546Sopenharmony_ci   case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
795bf215546Sopenharmony_ci      return 65536;
796bf215546Sopenharmony_ci
797bf215546Sopenharmony_ci   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
798bf215546Sopenharmony_ci      return 64;
799bf215546Sopenharmony_ci
800bf215546Sopenharmony_ci   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
801bf215546Sopenharmony_ci      return 1;
802bf215546Sopenharmony_ci
803bf215546Sopenharmony_ci   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
804bf215546Sopenharmony_ci      return 16384;
805bf215546Sopenharmony_ci   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
806bf215546Sopenharmony_ci   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
807bf215546Sopenharmony_ci      return 13;
808bf215546Sopenharmony_ci
809bf215546Sopenharmony_ci   case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT:
810bf215546Sopenharmony_ci      return 0;
811bf215546Sopenharmony_ci
812bf215546Sopenharmony_ci   case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
813bf215546Sopenharmony_ci   case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
814bf215546Sopenharmony_ci   case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER:
815bf215546Sopenharmony_ci   case PIPE_CAP_TGSI_TEXCOORD:
816bf215546Sopenharmony_ci   case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
817bf215546Sopenharmony_ci   case PIPE_CAP_FS_POSITION_IS_SYSVAL:
818bf215546Sopenharmony_ci   case PIPE_CAP_SEAMLESS_CUBE_MAP:
819bf215546Sopenharmony_ci   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
820bf215546Sopenharmony_ci      return true;
821bf215546Sopenharmony_ci   case PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT:
822bf215546Sopenharmony_ci   case PIPE_CAP_FS_POINT_IS_SYSVAL:
823bf215546Sopenharmony_ci      return false;
824bf215546Sopenharmony_ci
825bf215546Sopenharmony_ci   case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
826bf215546Sopenharmony_ci      return 0xffff;
827bf215546Sopenharmony_ci
828bf215546Sopenharmony_ci   case PIPE_CAP_TEXTURE_TRANSFER_MODES:
829bf215546Sopenharmony_ci      return 0;
830bf215546Sopenharmony_ci
831bf215546Sopenharmony_ci   case PIPE_CAP_ENDIANNESS:
832bf215546Sopenharmony_ci      return PIPE_ENDIAN_LITTLE;
833bf215546Sopenharmony_ci
834bf215546Sopenharmony_ci   case PIPE_CAP_VIDEO_MEMORY: {
835bf215546Sopenharmony_ci      uint64_t system_memory;
836bf215546Sopenharmony_ci
837bf215546Sopenharmony_ci      if (!os_get_total_physical_memory(&system_memory))
838bf215546Sopenharmony_ci         return 0;
839bf215546Sopenharmony_ci
840bf215546Sopenharmony_ci      return (int)(system_memory >> 20);
841bf215546Sopenharmony_ci   }
842bf215546Sopenharmony_ci
843bf215546Sopenharmony_ci   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
844bf215546Sopenharmony_ci      return 4;
845bf215546Sopenharmony_ci
846bf215546Sopenharmony_ci   case PIPE_CAP_MAX_VARYINGS:
847bf215546Sopenharmony_ci      return 16;
848bf215546Sopenharmony_ci
849bf215546Sopenharmony_ci   case PIPE_CAP_FLATSHADE:
850bf215546Sopenharmony_ci   case PIPE_CAP_TWO_SIDED_COLOR:
851bf215546Sopenharmony_ci   case PIPE_CAP_ALPHA_TEST:
852bf215546Sopenharmony_ci   case PIPE_CAP_CLIP_PLANES:
853bf215546Sopenharmony_ci   case PIPE_CAP_NIR_IMAGES_AS_DEREF:
854bf215546Sopenharmony_ci      return 0;
855bf215546Sopenharmony_ci
856bf215546Sopenharmony_ci   case PIPE_CAP_SHAREABLE_SHADERS:
857bf215546Sopenharmony_ci      return 1;
858bf215546Sopenharmony_ci
859bf215546Sopenharmony_ci   default:
860bf215546Sopenharmony_ci      return u_pipe_screen_get_param_defaults(pscreen, param);
861bf215546Sopenharmony_ci   }
862bf215546Sopenharmony_ci}
863bf215546Sopenharmony_ci
864bf215546Sopenharmony_cistatic float
865bf215546Sopenharmony_ciagx_get_paramf(struct pipe_screen* pscreen,
866bf215546Sopenharmony_ci               enum pipe_capf param)
867bf215546Sopenharmony_ci{
868bf215546Sopenharmony_ci   switch (param) {
869bf215546Sopenharmony_ci   case PIPE_CAPF_MIN_LINE_WIDTH:
870bf215546Sopenharmony_ci   case PIPE_CAPF_MIN_LINE_WIDTH_AA:
871bf215546Sopenharmony_ci   case PIPE_CAPF_MIN_POINT_SIZE:
872bf215546Sopenharmony_ci   case PIPE_CAPF_MIN_POINT_SIZE_AA:
873bf215546Sopenharmony_ci      return 1;
874bf215546Sopenharmony_ci
875bf215546Sopenharmony_ci   case PIPE_CAPF_POINT_SIZE_GRANULARITY:
876bf215546Sopenharmony_ci   case PIPE_CAPF_LINE_WIDTH_GRANULARITY:
877bf215546Sopenharmony_ci      return 0.1;
878bf215546Sopenharmony_ci
879bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_LINE_WIDTH:
880bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
881bf215546Sopenharmony_ci      return 16.0; /* Off-by-one fixed point 4:4 encoding */
882bf215546Sopenharmony_ci
883bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_POINT_SIZE:
884bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_POINT_SIZE_AA:
885bf215546Sopenharmony_ci      return 511.95f;
886bf215546Sopenharmony_ci
887bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
888bf215546Sopenharmony_ci      return 16.0;
889bf215546Sopenharmony_ci
890bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
891bf215546Sopenharmony_ci      return 16.0; /* arbitrary */
892bf215546Sopenharmony_ci
893bf215546Sopenharmony_ci   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
894bf215546Sopenharmony_ci   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
895bf215546Sopenharmony_ci   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
896bf215546Sopenharmony_ci      return 0.0f;
897bf215546Sopenharmony_ci
898bf215546Sopenharmony_ci   default:
899bf215546Sopenharmony_ci      debug_printf("Unexpected PIPE_CAPF %d query\n", param);
900bf215546Sopenharmony_ci      return 0.0;
901bf215546Sopenharmony_ci   }
902bf215546Sopenharmony_ci}
903bf215546Sopenharmony_ci
904bf215546Sopenharmony_cistatic int
905bf215546Sopenharmony_ciagx_get_shader_param(struct pipe_screen* pscreen,
906bf215546Sopenharmony_ci                     enum pipe_shader_type shader,
907bf215546Sopenharmony_ci                     enum pipe_shader_cap param)
908bf215546Sopenharmony_ci{
909bf215546Sopenharmony_ci   bool is_deqp = agx_device(pscreen)->debug & AGX_DBG_DEQP;
910bf215546Sopenharmony_ci   bool is_no16 = agx_device(pscreen)->debug & AGX_DBG_NO16;
911bf215546Sopenharmony_ci
912bf215546Sopenharmony_ci   if (shader != PIPE_SHADER_VERTEX &&
913bf215546Sopenharmony_ci       shader != PIPE_SHADER_FRAGMENT)
914bf215546Sopenharmony_ci      return 0;
915bf215546Sopenharmony_ci
916bf215546Sopenharmony_ci   /* this is probably not totally correct.. but it's a start: */
917bf215546Sopenharmony_ci   switch (param) {
918bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
919bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
920bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
921bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
922bf215546Sopenharmony_ci      return 16384;
923bf215546Sopenharmony_ci
924bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
925bf215546Sopenharmony_ci      return 1024;
926bf215546Sopenharmony_ci
927bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_INPUTS:
928bf215546Sopenharmony_ci      return 16;
929bf215546Sopenharmony_ci
930bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_OUTPUTS:
931bf215546Sopenharmony_ci      return shader == PIPE_SHADER_FRAGMENT ? 4 : 16;
932bf215546Sopenharmony_ci
933bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_TEMPS:
934bf215546Sopenharmony_ci      return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
935bf215546Sopenharmony_ci
936bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
937bf215546Sopenharmony_ci      return 16 * 1024 * sizeof(float);
938bf215546Sopenharmony_ci
939bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
940bf215546Sopenharmony_ci      return 16;
941bf215546Sopenharmony_ci
942bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_CONT_SUPPORTED:
943bf215546Sopenharmony_ci      return 0;
944bf215546Sopenharmony_ci
945bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
946bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
947bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
948bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_SUBROUTINES:
949bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
950bf215546Sopenharmony_ci      return 0;
951bf215546Sopenharmony_ci
952bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
953bf215546Sopenharmony_ci      return is_deqp;
954bf215546Sopenharmony_ci
955bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INTEGERS:
956bf215546Sopenharmony_ci      return true;
957bf215546Sopenharmony_ci
958bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_FP16:
959bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
960bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_FP16_DERIVATIVES:
961bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
962bf215546Sopenharmony_ci      return !is_no16;
963bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INT16:
964bf215546Sopenharmony_ci      /* GLSL compiler is broken. Flip this on when Panfrost does. */
965bf215546Sopenharmony_ci      return false;
966bf215546Sopenharmony_ci
967bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_INT64_ATOMICS:
968bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_DROUND_SUPPORTED:
969bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED:
970bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_LDEXP_SUPPORTED:
971bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
972bf215546Sopenharmony_ci      return 0;
973bf215546Sopenharmony_ci
974bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
975bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
976bf215546Sopenharmony_ci      return 16; /* XXX: How many? */
977bf215546Sopenharmony_ci
978bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_PREFERRED_IR:
979bf215546Sopenharmony_ci      return PIPE_SHADER_IR_NIR;
980bf215546Sopenharmony_ci
981bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_SUPPORTED_IRS:
982bf215546Sopenharmony_ci      return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED);
983bf215546Sopenharmony_ci
984bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
985bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
986bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
987bf215546Sopenharmony_ci   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
988bf215546Sopenharmony_ci      return 0;
989bf215546Sopenharmony_ci
990bf215546Sopenharmony_ci   default:
991bf215546Sopenharmony_ci      /* Other params are unknown */
992bf215546Sopenharmony_ci      return 0;
993bf215546Sopenharmony_ci   }
994bf215546Sopenharmony_ci
995bf215546Sopenharmony_ci   return 0;
996bf215546Sopenharmony_ci}
997bf215546Sopenharmony_ci
998bf215546Sopenharmony_cistatic int
999bf215546Sopenharmony_ciagx_get_compute_param(struct pipe_screen *pscreen,
1000bf215546Sopenharmony_ci                      enum pipe_shader_ir ir_type,
1001bf215546Sopenharmony_ci                      enum pipe_compute_cap param,
1002bf215546Sopenharmony_ci                      void *ret)
1003bf215546Sopenharmony_ci{
1004bf215546Sopenharmony_ci   return 0;
1005bf215546Sopenharmony_ci}
1006bf215546Sopenharmony_ci
1007bf215546Sopenharmony_cistatic bool
1008bf215546Sopenharmony_ciagx_is_format_supported(struct pipe_screen* pscreen,
1009bf215546Sopenharmony_ci                        enum pipe_format format,
1010bf215546Sopenharmony_ci                        enum pipe_texture_target target,
1011bf215546Sopenharmony_ci                        unsigned sample_count,
1012bf215546Sopenharmony_ci                        unsigned storage_sample_count,
1013bf215546Sopenharmony_ci                        unsigned usage)
1014bf215546Sopenharmony_ci{
1015bf215546Sopenharmony_ci   assert(target == PIPE_BUFFER ||
1016bf215546Sopenharmony_ci          target == PIPE_TEXTURE_1D ||
1017bf215546Sopenharmony_ci          target == PIPE_TEXTURE_1D_ARRAY ||
1018bf215546Sopenharmony_ci          target == PIPE_TEXTURE_2D ||
1019bf215546Sopenharmony_ci          target == PIPE_TEXTURE_2D_ARRAY ||
1020bf215546Sopenharmony_ci          target == PIPE_TEXTURE_RECT ||
1021bf215546Sopenharmony_ci          target == PIPE_TEXTURE_3D ||
1022bf215546Sopenharmony_ci          target == PIPE_TEXTURE_CUBE ||
1023bf215546Sopenharmony_ci          target == PIPE_TEXTURE_CUBE_ARRAY);
1024bf215546Sopenharmony_ci
1025bf215546Sopenharmony_ci   if (sample_count > 1)
1026bf215546Sopenharmony_ci      return false;
1027bf215546Sopenharmony_ci
1028bf215546Sopenharmony_ci   if (MAX2(sample_count, 1) != MAX2(storage_sample_count, 1))
1029bf215546Sopenharmony_ci      return false;
1030bf215546Sopenharmony_ci
1031bf215546Sopenharmony_ci   if (usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) {
1032bf215546Sopenharmony_ci      struct agx_pixel_format_entry ent = agx_pixel_format[format];
1033bf215546Sopenharmony_ci
1034bf215546Sopenharmony_ci      if (!agx_is_valid_pixel_format(format))
1035bf215546Sopenharmony_ci         return false;
1036bf215546Sopenharmony_ci
1037bf215546Sopenharmony_ci      if ((usage & PIPE_BIND_RENDER_TARGET) && !ent.renderable)
1038bf215546Sopenharmony_ci         return false;
1039bf215546Sopenharmony_ci   }
1040bf215546Sopenharmony_ci
1041bf215546Sopenharmony_ci   /* TODO: formats */
1042bf215546Sopenharmony_ci   if (usage & PIPE_BIND_VERTEX_BUFFER) {
1043bf215546Sopenharmony_ci      switch (format) {
1044bf215546Sopenharmony_ci      case PIPE_FORMAT_R16_FLOAT:
1045bf215546Sopenharmony_ci      case PIPE_FORMAT_R16G16_FLOAT:
1046bf215546Sopenharmony_ci      case PIPE_FORMAT_R16G16B16_FLOAT:
1047bf215546Sopenharmony_ci      case PIPE_FORMAT_R16G16B16A16_FLOAT:
1048bf215546Sopenharmony_ci      case PIPE_FORMAT_R32_FLOAT:
1049bf215546Sopenharmony_ci      case PIPE_FORMAT_R32G32_FLOAT:
1050bf215546Sopenharmony_ci      case PIPE_FORMAT_R32G32B32_FLOAT:
1051bf215546Sopenharmony_ci      case PIPE_FORMAT_R32G32B32A32_FLOAT:
1052bf215546Sopenharmony_ci         return true;
1053bf215546Sopenharmony_ci      default:
1054bf215546Sopenharmony_ci         return false;
1055bf215546Sopenharmony_ci      }
1056bf215546Sopenharmony_ci   }
1057bf215546Sopenharmony_ci
1058bf215546Sopenharmony_ci   if (usage & PIPE_BIND_DEPTH_STENCIL) {
1059bf215546Sopenharmony_ci      switch (format) {
1060bf215546Sopenharmony_ci      /* natively supported
1061bf215546Sopenharmony_ci       * TODO: we could also support Z16_UNORM */
1062bf215546Sopenharmony_ci      case PIPE_FORMAT_Z32_FLOAT:
1063bf215546Sopenharmony_ci      case PIPE_FORMAT_S8_UINT:
1064bf215546Sopenharmony_ci
1065bf215546Sopenharmony_ci      /* lowered by u_transfer_helper to one of the above */
1066bf215546Sopenharmony_ci      case PIPE_FORMAT_Z24X8_UNORM:
1067bf215546Sopenharmony_ci      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1068bf215546Sopenharmony_ci      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1069bf215546Sopenharmony_ci         return true;
1070bf215546Sopenharmony_ci
1071bf215546Sopenharmony_ci      default:
1072bf215546Sopenharmony_ci         return false;
1073bf215546Sopenharmony_ci      }
1074bf215546Sopenharmony_ci   }
1075bf215546Sopenharmony_ci
1076bf215546Sopenharmony_ci   /* TODO */
1077bf215546Sopenharmony_ci   return true;
1078bf215546Sopenharmony_ci}
1079bf215546Sopenharmony_ci
1080bf215546Sopenharmony_cistatic uint64_t
1081bf215546Sopenharmony_ciagx_get_timestamp(struct pipe_screen *pscreen)
1082bf215546Sopenharmony_ci{
1083bf215546Sopenharmony_ci   return 0;
1084bf215546Sopenharmony_ci}
1085bf215546Sopenharmony_ci
1086bf215546Sopenharmony_cistatic void
1087bf215546Sopenharmony_ciagx_destroy_screen(struct pipe_screen *screen)
1088bf215546Sopenharmony_ci{
1089bf215546Sopenharmony_ci   u_transfer_helper_destroy(screen->transfer_helper);
1090bf215546Sopenharmony_ci   agx_close_device(agx_device(screen));
1091bf215546Sopenharmony_ci   ralloc_free(screen);
1092bf215546Sopenharmony_ci}
1093bf215546Sopenharmony_ci
1094bf215546Sopenharmony_cistatic void
1095bf215546Sopenharmony_ciagx_fence_reference(struct pipe_screen *screen,
1096bf215546Sopenharmony_ci                    struct pipe_fence_handle **ptr,
1097bf215546Sopenharmony_ci                    struct pipe_fence_handle *fence)
1098bf215546Sopenharmony_ci{
1099bf215546Sopenharmony_ci}
1100bf215546Sopenharmony_ci
1101bf215546Sopenharmony_cistatic bool
1102bf215546Sopenharmony_ciagx_fence_finish(struct pipe_screen *screen,
1103bf215546Sopenharmony_ci                 struct pipe_context *ctx,
1104bf215546Sopenharmony_ci                 struct pipe_fence_handle *fence,
1105bf215546Sopenharmony_ci                 uint64_t timeout)
1106bf215546Sopenharmony_ci{
1107bf215546Sopenharmony_ci   return true;
1108bf215546Sopenharmony_ci}
1109bf215546Sopenharmony_ci
1110bf215546Sopenharmony_cistatic const void *
1111bf215546Sopenharmony_ciagx_get_compiler_options(struct pipe_screen *pscreen,
1112bf215546Sopenharmony_ci                         enum pipe_shader_ir ir,
1113bf215546Sopenharmony_ci                         enum pipe_shader_type shader)
1114bf215546Sopenharmony_ci{
1115bf215546Sopenharmony_ci   return &agx_nir_options;
1116bf215546Sopenharmony_ci}
1117bf215546Sopenharmony_ci
1118bf215546Sopenharmony_cistatic void
1119bf215546Sopenharmony_ciagx_resource_set_stencil(struct pipe_resource *prsrc,
1120bf215546Sopenharmony_ci                         struct pipe_resource *stencil)
1121bf215546Sopenharmony_ci{
1122bf215546Sopenharmony_ci   agx_resource(prsrc)->separate_stencil = agx_resource(stencil);
1123bf215546Sopenharmony_ci}
1124bf215546Sopenharmony_ci
1125bf215546Sopenharmony_cistatic struct pipe_resource *
1126bf215546Sopenharmony_ciagx_resource_get_stencil(struct pipe_resource *prsrc)
1127bf215546Sopenharmony_ci{
1128bf215546Sopenharmony_ci   return (struct pipe_resource *) agx_resource(prsrc)->separate_stencil;
1129bf215546Sopenharmony_ci}
1130bf215546Sopenharmony_ci
1131bf215546Sopenharmony_cistatic enum pipe_format
1132bf215546Sopenharmony_ciagx_resource_get_internal_format(struct pipe_resource *prsrc)
1133bf215546Sopenharmony_ci{
1134bf215546Sopenharmony_ci   return agx_resource(prsrc)->internal_format;
1135bf215546Sopenharmony_ci}
1136bf215546Sopenharmony_ci
1137bf215546Sopenharmony_cistatic const struct u_transfer_vtbl transfer_vtbl = {
1138bf215546Sopenharmony_ci   .resource_create          = agx_resource_create,
1139bf215546Sopenharmony_ci   .resource_destroy         = agx_resource_destroy,
1140bf215546Sopenharmony_ci   .transfer_map             = agx_transfer_map,
1141bf215546Sopenharmony_ci   .transfer_unmap           = agx_transfer_unmap,
1142bf215546Sopenharmony_ci   .transfer_flush_region    = agx_transfer_flush_region,
1143bf215546Sopenharmony_ci   .get_internal_format      = agx_resource_get_internal_format,
1144bf215546Sopenharmony_ci   .set_stencil              = agx_resource_set_stencil,
1145bf215546Sopenharmony_ci   .get_stencil              = agx_resource_get_stencil,
1146bf215546Sopenharmony_ci};
1147bf215546Sopenharmony_ci
1148bf215546Sopenharmony_cistruct pipe_screen *
1149bf215546Sopenharmony_ciagx_screen_create(struct sw_winsys *winsys)
1150bf215546Sopenharmony_ci{
1151bf215546Sopenharmony_ci   struct agx_screen *agx_screen;
1152bf215546Sopenharmony_ci   struct pipe_screen *screen;
1153bf215546Sopenharmony_ci
1154bf215546Sopenharmony_ci   agx_screen = rzalloc(NULL, struct agx_screen);
1155bf215546Sopenharmony_ci   if (!agx_screen)
1156bf215546Sopenharmony_ci      return NULL;
1157bf215546Sopenharmony_ci
1158bf215546Sopenharmony_ci   screen = &agx_screen->pscreen;
1159bf215546Sopenharmony_ci   agx_screen->winsys = winsys;
1160bf215546Sopenharmony_ci
1161bf215546Sopenharmony_ci   /* Set debug before opening */
1162bf215546Sopenharmony_ci   agx_screen->dev.debug =
1163bf215546Sopenharmony_ci      debug_get_flags_option("ASAHI_MESA_DEBUG", agx_debug_options, 0);
1164bf215546Sopenharmony_ci
1165bf215546Sopenharmony_ci   /* Try to open an AGX device */
1166bf215546Sopenharmony_ci   if (!agx_open_device(screen, &agx_screen->dev)) {
1167bf215546Sopenharmony_ci      ralloc_free(agx_screen);
1168bf215546Sopenharmony_ci      return NULL;
1169bf215546Sopenharmony_ci   }
1170bf215546Sopenharmony_ci
1171bf215546Sopenharmony_ci   if (agx_screen->dev.debug & AGX_DBG_DEQP) {
1172bf215546Sopenharmony_ci      /* You're on your own. */
1173bf215546Sopenharmony_ci      static bool warned_about_hacks = false;
1174bf215546Sopenharmony_ci
1175bf215546Sopenharmony_ci      if (!warned_about_hacks) {
1176bf215546Sopenharmony_ci         fprintf(stderr, "\n------------------\n"
1177bf215546Sopenharmony_ci                         "Unsupported debug parameter set. Expect breakage.\n"
1178bf215546Sopenharmony_ci                         "Do not report bugs.\n"
1179bf215546Sopenharmony_ci                         "------------------\n\n");
1180bf215546Sopenharmony_ci         warned_about_hacks = true;
1181bf215546Sopenharmony_ci      }
1182bf215546Sopenharmony_ci   }
1183bf215546Sopenharmony_ci
1184bf215546Sopenharmony_ci   screen->destroy = agx_destroy_screen;
1185bf215546Sopenharmony_ci   screen->get_name = agx_get_name;
1186bf215546Sopenharmony_ci   screen->get_vendor = agx_get_vendor;
1187bf215546Sopenharmony_ci   screen->get_device_vendor = agx_get_device_vendor;
1188bf215546Sopenharmony_ci   screen->get_param = agx_get_param;
1189bf215546Sopenharmony_ci   screen->get_shader_param = agx_get_shader_param;
1190bf215546Sopenharmony_ci   screen->get_compute_param = agx_get_compute_param;
1191bf215546Sopenharmony_ci   screen->get_paramf = agx_get_paramf;
1192bf215546Sopenharmony_ci   screen->is_format_supported = agx_is_format_supported;
1193bf215546Sopenharmony_ci   screen->context_create = agx_create_context;
1194bf215546Sopenharmony_ci   screen->resource_from_handle = agx_resource_from_handle;
1195bf215546Sopenharmony_ci   screen->resource_get_handle = agx_resource_get_handle;
1196bf215546Sopenharmony_ci   screen->flush_frontbuffer = agx_flush_frontbuffer;
1197bf215546Sopenharmony_ci   screen->get_timestamp = agx_get_timestamp;
1198bf215546Sopenharmony_ci   screen->fence_reference = agx_fence_reference;
1199bf215546Sopenharmony_ci   screen->fence_finish = agx_fence_finish;
1200bf215546Sopenharmony_ci   screen->get_compiler_options = agx_get_compiler_options;
1201bf215546Sopenharmony_ci
1202bf215546Sopenharmony_ci   screen->resource_create = u_transfer_helper_resource_create;
1203bf215546Sopenharmony_ci   screen->resource_destroy = u_transfer_helper_resource_destroy;
1204bf215546Sopenharmony_ci   screen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
1205bf215546Sopenharmony_ci                                                      true, true, false, true,
1206bf215546Sopenharmony_ci                                                      true);
1207bf215546Sopenharmony_ci
1208bf215546Sopenharmony_ci   agx_internal_shaders(&agx_screen->dev);
1209bf215546Sopenharmony_ci
1210bf215546Sopenharmony_ci   return screen;
1211bf215546Sopenharmony_ci}
1212