1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2013 Advanced Micro Devices, Inc. 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 * Authors: Marek Olšák <maraeo@gmail.com> 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci/** 27bf215546Sopenharmony_ci * This file contains helpers for writing commands to commands streams. 28bf215546Sopenharmony_ci */ 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#ifndef R600_CS_H 31bf215546Sopenharmony_ci#define R600_CS_H 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "r600_pipe_common.h" 34bf215546Sopenharmony_ci#include "r600d_common.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci/** 37bf215546Sopenharmony_ci * Return true if there is enough memory in VRAM and GTT for the buffers 38bf215546Sopenharmony_ci * added so far. 39bf215546Sopenharmony_ci * 40bf215546Sopenharmony_ci * \param vram VRAM memory size not added to the buffer list yet 41bf215546Sopenharmony_ci * \param gtt GTT memory size not added to the buffer list yet 42bf215546Sopenharmony_ci */ 43bf215546Sopenharmony_cistatic inline bool 44bf215546Sopenharmony_ciradeon_cs_memory_below_limit(struct r600_common_screen *screen, 45bf215546Sopenharmony_ci struct radeon_cmdbuf *cs, 46bf215546Sopenharmony_ci uint64_t vram, uint64_t gtt) 47bf215546Sopenharmony_ci{ 48bf215546Sopenharmony_ci vram += (uint64_t)cs->used_vram_kb * 1024; 49bf215546Sopenharmony_ci gtt += (uint64_t)cs->used_gart_kb * 1024; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci /* Anything that goes above the VRAM size should go to GTT. */ 52bf215546Sopenharmony_ci if (vram > (uint64_t)screen->info.vram_size_kb * 1024) 53bf215546Sopenharmony_ci gtt += vram - (uint64_t)screen->info.vram_size_kb * 1024; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci /* Now we just need to check if we have enough GTT. */ 56bf215546Sopenharmony_ci return gtt < (uint64_t)screen->info.gart_size_kb * 1024 * 0.7; 57bf215546Sopenharmony_ci} 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci/** 60bf215546Sopenharmony_ci * Add a buffer to the buffer list for the given command stream (CS). 61bf215546Sopenharmony_ci * 62bf215546Sopenharmony_ci * All buffers used by a CS must be added to the list. This tells the kernel 63bf215546Sopenharmony_ci * driver which buffers are used by GPU commands. Other buffers can 64bf215546Sopenharmony_ci * be swapped out (not accessible) during execution. 65bf215546Sopenharmony_ci * 66bf215546Sopenharmony_ci * The buffer list becomes empty after every context flush and must be 67bf215546Sopenharmony_ci * rebuilt. 68bf215546Sopenharmony_ci */ 69bf215546Sopenharmony_cistatic inline unsigned radeon_add_to_buffer_list(struct r600_common_context *rctx, 70bf215546Sopenharmony_ci struct r600_ring *ring, 71bf215546Sopenharmony_ci struct r600_resource *rbo, 72bf215546Sopenharmony_ci unsigned usage) 73bf215546Sopenharmony_ci{ 74bf215546Sopenharmony_ci assert(usage); 75bf215546Sopenharmony_ci return rctx->ws->cs_add_buffer( 76bf215546Sopenharmony_ci &ring->cs, rbo->buf, 77bf215546Sopenharmony_ci usage | RADEON_USAGE_SYNCHRONIZED, 78bf215546Sopenharmony_ci rbo->domains) * 4; 79bf215546Sopenharmony_ci} 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci/** 82bf215546Sopenharmony_ci * Same as above, but also checks memory usage and flushes the context 83bf215546Sopenharmony_ci * accordingly. 84bf215546Sopenharmony_ci * 85bf215546Sopenharmony_ci * When this SHOULD NOT be used: 86bf215546Sopenharmony_ci * 87bf215546Sopenharmony_ci * - if r600_context_add_resource_size has been called for the buffer 88bf215546Sopenharmony_ci * followed by *_need_cs_space for checking the memory usage 89bf215546Sopenharmony_ci * 90bf215546Sopenharmony_ci * - if r600_need_dma_space has been called for the buffer 91bf215546Sopenharmony_ci * 92bf215546Sopenharmony_ci * - when emitting state packets and draw packets (because preceding packets 93bf215546Sopenharmony_ci * can't be re-emitted at that point) 94bf215546Sopenharmony_ci * 95bf215546Sopenharmony_ci * - if shader resource "enabled_mask" is not up-to-date or there is 96bf215546Sopenharmony_ci * a different constraint disallowing a context flush 97bf215546Sopenharmony_ci */ 98bf215546Sopenharmony_cistatic inline unsigned 99bf215546Sopenharmony_ciradeon_add_to_buffer_list_check_mem(struct r600_common_context *rctx, 100bf215546Sopenharmony_ci struct r600_ring *ring, 101bf215546Sopenharmony_ci struct r600_resource *rbo, 102bf215546Sopenharmony_ci unsigned usage, 103bf215546Sopenharmony_ci bool check_mem) 104bf215546Sopenharmony_ci{ 105bf215546Sopenharmony_ci if (check_mem && 106bf215546Sopenharmony_ci !radeon_cs_memory_below_limit(rctx->screen, &ring->cs, 107bf215546Sopenharmony_ci rctx->vram + rbo->vram_usage, 108bf215546Sopenharmony_ci rctx->gtt + rbo->gart_usage)) 109bf215546Sopenharmony_ci ring->flush(rctx, PIPE_FLUSH_ASYNC, NULL); 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci return radeon_add_to_buffer_list(rctx, ring, rbo, usage); 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_cistatic inline void r600_emit_reloc(struct r600_common_context *rctx, 115bf215546Sopenharmony_ci struct r600_ring *ring, struct r600_resource *rbo, 116bf215546Sopenharmony_ci unsigned usage) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci struct radeon_cmdbuf *cs = &ring->cs; 119bf215546Sopenharmony_ci bool has_vm = ((struct r600_common_screen*)rctx->b.screen)->info.r600_has_virtual_memory; 120bf215546Sopenharmony_ci unsigned reloc = radeon_add_to_buffer_list(rctx, ring, rbo, usage); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci if (!has_vm) { 123bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 124bf215546Sopenharmony_ci radeon_emit(cs, reloc); 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_cistatic inline void radeon_set_config_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 129bf215546Sopenharmony_ci{ 130bf215546Sopenharmony_ci assert(reg < R600_CONTEXT_REG_OFFSET); 131bf215546Sopenharmony_ci assert(cs->current.cdw + 2 + num <= cs->current.max_dw); 132bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_CONFIG_REG, num, 0)); 133bf215546Sopenharmony_ci radeon_emit(cs, (reg - R600_CONFIG_REG_OFFSET) >> 2); 134bf215546Sopenharmony_ci} 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_cistatic inline void radeon_set_config_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 137bf215546Sopenharmony_ci{ 138bf215546Sopenharmony_ci radeon_set_config_reg_seq(cs, reg, 1); 139bf215546Sopenharmony_ci radeon_emit(cs, value); 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_cistatic inline void radeon_set_context_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 143bf215546Sopenharmony_ci{ 144bf215546Sopenharmony_ci assert(reg >= R600_CONTEXT_REG_OFFSET); 145bf215546Sopenharmony_ci assert(cs->current.cdw + 2 + num <= cs->current.max_dw); 146bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, num, 0)); 147bf215546Sopenharmony_ci radeon_emit(cs, (reg - R600_CONTEXT_REG_OFFSET) >> 2); 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_cistatic inline void radeon_set_context_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 151bf215546Sopenharmony_ci{ 152bf215546Sopenharmony_ci radeon_set_context_reg_seq(cs, reg, 1); 153bf215546Sopenharmony_ci radeon_emit(cs, value); 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_cistatic inline void radeon_set_context_reg_idx(struct radeon_cmdbuf *cs, 157bf215546Sopenharmony_ci unsigned reg, unsigned idx, 158bf215546Sopenharmony_ci unsigned value) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci assert(reg >= R600_CONTEXT_REG_OFFSET); 161bf215546Sopenharmony_ci assert(cs->current.cdw + 3 <= cs->current.max_dw); 162bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, 1, 0)); 163bf215546Sopenharmony_ci radeon_emit(cs, (reg - R600_CONTEXT_REG_OFFSET) >> 2 | (idx << 28)); 164bf215546Sopenharmony_ci radeon_emit(cs, value); 165bf215546Sopenharmony_ci} 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_cistatic inline void radeon_set_sh_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 168bf215546Sopenharmony_ci{ 169bf215546Sopenharmony_ci assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END); 170bf215546Sopenharmony_ci assert(cs->current.cdw + 2 + num <= cs->current.max_dw); 171bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_SH_REG, num, 0)); 172bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_SH_REG_OFFSET) >> 2); 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_cistatic inline void radeon_set_sh_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 176bf215546Sopenharmony_ci{ 177bf215546Sopenharmony_ci radeon_set_sh_reg_seq(cs, reg, 1); 178bf215546Sopenharmony_ci radeon_emit(cs, value); 179bf215546Sopenharmony_ci} 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_cistatic inline void radeon_set_uconfig_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 182bf215546Sopenharmony_ci{ 183bf215546Sopenharmony_ci assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END); 184bf215546Sopenharmony_ci assert(cs->current.cdw + 2 + num <= cs->current.max_dw); 185bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, 0)); 186bf215546Sopenharmony_ci radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2); 187bf215546Sopenharmony_ci} 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_cistatic inline void radeon_set_uconfig_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci radeon_set_uconfig_reg_seq(cs, reg, 1); 192bf215546Sopenharmony_ci radeon_emit(cs, value); 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cistatic inline void radeon_set_uconfig_reg_idx(struct radeon_cmdbuf *cs, 196bf215546Sopenharmony_ci unsigned reg, unsigned idx, 197bf215546Sopenharmony_ci unsigned value) 198bf215546Sopenharmony_ci{ 199bf215546Sopenharmony_ci assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END); 200bf215546Sopenharmony_ci assert(cs->current.cdw + 3 <= cs->current.max_dw); 201bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, 1, 0)); 202bf215546Sopenharmony_ci radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2 | (idx << 28)); 203bf215546Sopenharmony_ci radeon_emit(cs, value); 204bf215546Sopenharmony_ci} 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci#endif 207