Path: blob/21.2-virgl/src/gallium/drivers/asahi/magic.c
4570 views
/*1* Copyright 2021 Alyssa Rosenzweig2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*/22#23#include <stdint.h>24#include "agx_state.h"25#include "magic.h"2627/* The structures managed in this file appear to be software defined (either in28* the macOS kernel driver or in the AGX firmware) */2930/* Odd pattern */31static uint64_t32demo_unk6(struct agx_pool *pool)33{34struct agx_ptr ptr = agx_pool_alloc_aligned(pool, 0x4000 * sizeof(uint64_t), 64);35uint64_t *buf = ptr.cpu;36memset(buf, 0, sizeof(*buf));3738for (unsigned i = 1; i < 0x3ff; ++i)39buf[i] = (i + 1);4041return ptr.gpu;42}4344static uint64_t45demo_zero(struct agx_pool *pool, unsigned count)46{47struct agx_ptr ptr = agx_pool_alloc_aligned(pool, count, 64);48memset(ptr.cpu, 0, count);49return ptr.gpu;50}5152unsigned53demo_cmdbuf(uint64_t *buf, size_t size,54struct agx_pool *pool,55uint64_t encoder_ptr,56uint64_t encoder_id,57uint64_t scissor_ptr,58unsigned width, unsigned height,59uint32_t pipeline_null,60uint32_t pipeline_clear,61uint32_t pipeline_store,62uint64_t rt0,63bool clear_pipeline_textures)64{65uint32_t *map = (uint32_t *) buf;66memset(map, 0, 474 * 4);6768map[54] = 0x6b0003;69map[55] = 0x3a0012;70map[56] = 1;7172map[106] = 1;73map[108] = 0x1c;74map[112] = 0xffffffff;75map[113] = 0xffffffff;76map[114] = 0xffffffff;7778uint64_t unk_buffer = demo_zero(pool, 0x1000);79uint64_t unk_buffer_2 = demo_zero(pool, 0x8000);8081// This is a pipeline bind82map[156] = 0xffff8002 | (clear_pipeline_textures ? 0x210 : 0);83map[158] = pipeline_clear | 0x4;84map[163] = 0x12;85map[164] = pipeline_store | 0x4;86map[166] = scissor_ptr & 0xFFFFFFFF;87map[167] = scissor_ptr >> 32;88map[168] = unk_buffer & 0xFFFFFFFF;89map[169] = unk_buffer >> 32;9091map[220] = 4;92map[222] = 0xc000;93map[224] = width;94map[225] = height;95map[226] = unk_buffer_2 & 0xFFFFFFFF;96map[227] = unk_buffer_2 >> 32;9798float depth_clear = 1.0;99uint8_t stencil_clear = 0;100101map[278] = fui(depth_clear);102map[279] = (0x3 << 8) | stencil_clear;103map[282] = 0x1000000;104map[284] = 0xffffffff;105map[285] = 0xffffffff;106map[286] = 0xffffffff;107108map[298] = 0xffff8212;109map[300] = pipeline_null | 0x4;110map[305] = 0x12;111map[306] = pipeline_store | 0x4;112map[352] = 1;113map[360] = 0x1c;114map[362] = encoder_id;115map[365] = 0xffffffff;116map[366] = 1;117118uint64_t unk6 = demo_unk6(pool);119map[370] = unk6 & 0xFFFFFFFF;120map[371] = unk6 >> 32;121122map[374] = width;123map[375] = height;124map[376] = 1;125map[377] = 8;126map[378] = 8;127128map[393] = 8;129map[394] = 32;130map[395] = 32;131map[396] = 1;132133unsigned offset_unk = (458 * 4);134unsigned offset_attachments = (470 * 4);135unsigned nr_attachments = 1;136137map[473] = nr_attachments;138139/* A single attachment follows, depth/stencil have their own attachments */140agx_pack((map + (offset_attachments / 4) + 4), IOGPU_ATTACHMENT, cfg) {141cfg.address = rt0;142cfg.type = AGX_IOGPU_ATTACHMENT_TYPE_COLOUR;143cfg.unk_1 = 0x80000000;144cfg.unk_2 = 0x5;145cfg.bytes_per_pixel = 4;146cfg.percent = 100;147}148149unsigned total_size = offset_attachments + (AGX_IOGPU_ATTACHMENT_LENGTH * nr_attachments) + 16;150151agx_pack(map, IOGPU_HEADER, cfg) {152cfg.total_size = total_size;153cfg.attachment_offset_1 = offset_attachments;154cfg.attachment_offset_2 = offset_attachments;155cfg.attachment_length = nr_attachments * AGX_IOGPU_ATTACHMENT_LENGTH;156cfg.unknown_offset = offset_unk;157cfg.encoder = encoder_ptr;158}159160return total_size;161}162163static struct agx_map_header164demo_map_header(uint64_t cmdbuf_id, uint64_t encoder_id, unsigned cmdbuf_size, unsigned count)165{166return (struct agx_map_header) {167.cmdbuf_id = cmdbuf_id,168.unk2 = 0x1,169.unk3 = 0x528, // 1320170.encoder_id = encoder_id,171.unk6 = 0x0,172.cmdbuf_size = cmdbuf_size,173174/* +1 for the sentinel ending */175.nr_entries = count + 1,176.nr_handles = count + 1,177.indices = {0x0b},178};179}180181void182demo_mem_map(void *map, size_t size, unsigned *handles, unsigned count,183uint64_t cmdbuf_id, uint64_t encoder_id, unsigned cmdbuf_size)184{185struct agx_map_header *header = map;186struct agx_map_entry *entries = (struct agx_map_entry *) (((uint8_t *) map) + 0x40);187struct agx_map_entry *end = (struct agx_map_entry *) (((uint8_t *) map) + size);188189/* Header precedes the entry */190*header = demo_map_header(cmdbuf_id, encoder_id, cmdbuf_size, count);191192/* Add an entry for each BO mapped */193for (unsigned i = 0; i < count; ++i) {194assert((entries + i) < end);195entries[i] = (struct agx_map_entry) {196.unkAAA = 0x20,197.unkBBB = 0x1,198.unka = 0x1ffff,199.indices = {handles[i]}200};201}202203/* Final entry is a sentinel */204assert((entries + count) < end);205entries[count] = (struct agx_map_entry) {206.unkAAA = 0x40,207.unkBBB = 0x1,208.unka = 0x1ffff,209};210}211212213