1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2021 Alyssa Rosenzweig 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci#include <stdio.h> 24bf215546Sopenharmony_ci#include "agx_state.h" 25bf215546Sopenharmony_ci#include "asahi/lib/agx_pack.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci/* Computes the address for a push uniform, adding referenced BOs to the 28bf215546Sopenharmony_ci * current batch as necessary. Note anything uploaded via the batch's pool does 29bf215546Sopenharmony_ci * not require an update to the BO list, since the entire pool will be added 30bf215546Sopenharmony_ci * once at submit time. */ 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cistatic uint64_t 33bf215546Sopenharmony_ciagx_const_buffer_ptr(struct agx_batch *batch, 34bf215546Sopenharmony_ci struct pipe_constant_buffer *cb) 35bf215546Sopenharmony_ci{ 36bf215546Sopenharmony_ci if (cb->buffer) { 37bf215546Sopenharmony_ci struct agx_bo *bo = agx_resource(cb->buffer)->bo; 38bf215546Sopenharmony_ci agx_batch_add_bo(batch, bo); 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci return bo->ptr.gpu + cb->buffer_offset; 41bf215546Sopenharmony_ci } else { 42bf215546Sopenharmony_ci return agx_pool_upload_aligned(&batch->pool, 43bf215546Sopenharmony_ci ((uint8_t *) cb->user_buffer) + cb->buffer_offset, 44bf215546Sopenharmony_ci cb->buffer_size - cb->buffer_offset, 64); 45bf215546Sopenharmony_ci } 46bf215546Sopenharmony_ci} 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistatic uint64_t 49bf215546Sopenharmony_ciagx_push_location_direct(struct agx_context *ctx, struct agx_push push, 50bf215546Sopenharmony_ci enum pipe_shader_type stage) 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci struct agx_batch *batch = ctx->batch; 53bf215546Sopenharmony_ci struct agx_stage *st = &ctx->stage[stage]; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci switch (push.type) { 56bf215546Sopenharmony_ci case AGX_PUSH_UBO_BASES: { 57bf215546Sopenharmony_ci unsigned count = util_last_bit(st->cb_mask); 58bf215546Sopenharmony_ci struct agx_ptr ptr = agx_pool_alloc_aligned(&batch->pool, count * sizeof(uint64_t), 8); 59bf215546Sopenharmony_ci uint64_t *addresses = ptr.cpu; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci for (unsigned i = 0; i < count; ++i) { 62bf215546Sopenharmony_ci struct pipe_constant_buffer *cb = &st->cb[i]; 63bf215546Sopenharmony_ci addresses[i] = agx_const_buffer_ptr(batch, cb); 64bf215546Sopenharmony_ci } 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci return ptr.gpu; 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci case AGX_PUSH_VBO_BASES: { 70bf215546Sopenharmony_ci unsigned count = util_last_bit(ctx->vb_mask); 71bf215546Sopenharmony_ci struct agx_ptr ptr = agx_pool_alloc_aligned(&batch->pool, count * sizeof(uint64_t), 8); 72bf215546Sopenharmony_ci uint64_t *addresses = ptr.cpu; 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci u_foreach_bit(i, ctx->vb_mask) { 75bf215546Sopenharmony_ci struct pipe_vertex_buffer vb = ctx->vertex_buffers[i]; 76bf215546Sopenharmony_ci assert(!vb.is_user_buffer); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci struct agx_bo *bo = agx_resource(vb.buffer.resource)->bo; 79bf215546Sopenharmony_ci agx_batch_add_bo(batch, bo); 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci addresses[i] = bo->ptr.gpu + vb.buffer_offset; 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci return ptr.gpu; 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci case AGX_PUSH_BLEND_CONST: 88bf215546Sopenharmony_ci { 89bf215546Sopenharmony_ci return agx_pool_upload_aligned(&batch->pool, &ctx->blend_color, 90bf215546Sopenharmony_ci sizeof(ctx->blend_color), 8); 91bf215546Sopenharmony_ci } 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci case AGX_PUSH_ARRAY_SIZE_MINUS_1: { 94bf215546Sopenharmony_ci struct agx_stage *st = &ctx->stage[stage]; 95bf215546Sopenharmony_ci unsigned count = st->texture_count; 96bf215546Sopenharmony_ci struct agx_ptr ptr = agx_pool_alloc_aligned(&batch->pool, count * sizeof(uint16_t), 8); 97bf215546Sopenharmony_ci uint16_t *d1 = ptr.cpu; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci for (unsigned i = 0; i < count; ++i) { 100bf215546Sopenharmony_ci unsigned array_size = 1; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci if (st->textures[i]) 103bf215546Sopenharmony_ci array_size = st->textures[i]->base.texture->array_size; 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci d1[i] = array_size - 1; 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci return ptr.gpu; 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci default: 112bf215546Sopenharmony_ci unreachable("todo: push more"); 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ciuint64_t 117bf215546Sopenharmony_ciagx_push_location(struct agx_context *ctx, struct agx_push push, 118bf215546Sopenharmony_ci enum pipe_shader_type stage) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci uint64_t direct = agx_push_location_direct(ctx, push, stage); 121bf215546Sopenharmony_ci struct agx_pool *pool = &ctx->batch->pool; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci if (push.indirect) 124bf215546Sopenharmony_ci return agx_pool_upload(pool, &direct, sizeof(direct)); 125bf215546Sopenharmony_ci else 126bf215546Sopenharmony_ci return direct; 127bf215546Sopenharmony_ci} 128