radeon_dma.c revision e9c2c4a76466fc1ccfbf4d5de048414f7126b940
1cf5933a716e7eb6bd5ff49aa62f3e76379ebaf51Chris Lattner/************************************************************************** 2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman 3b576c94c15af9a440f69d9d03c2afead7971118cJohn CriswellCopyright (C) 2004 Nicolai Haehnle. 4b576c94c15af9a440f69d9d03c2afead7971118cJohn CriswellCopyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner 64ee451de366474b9c228b4e5fa573795a715216dChris LattnerThe Weather Channel (TM) funded Tungsten Graphics to develop the 7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukmaninitial release of the Radeon 8500 driver under the XFree86 license. 8b576c94c15af9a440f69d9d03c2afead7971118cJohn CriswellThis notice must be preserved. 9237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner 10befa499d45ffcc32bd9902518aec18589464e47cChris LattnerAll Rights Reserved. 11befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 12befa499d45ffcc32bd9902518aec18589464e47cChris LattnerPermission is hereby granted, free of charge, to any person obtaining a 13237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattnercopy of this software and associated documentation files (the "Software"), 14237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattnerto deal in the Software without restriction, including without limitation 15237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattneron the rights to use, copy, modify, merge, publish, distribute, sub 1686453c52ba02e743d29c08456e51006500041456Chris Lattnerlicense, and/or sell copies of the Software, and to permit persons to whom 17237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattnerthe Software is furnished to do so, subject to the following conditions: 1847b14a4a6a455c7be169cfd312fcbe796f0ad426Misha Brukman 191f67ce4aa3f65619f54c8a3072539da5b0022841Dale JohannesenThe above copyright notice and this permission notice (including the next 20237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattnerparagraph) shall be included in all copies or substantial portions of the 21237ef567f6764f24a47c63121cc0a599ddc8f56dChris LattnerSoftware. 22ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner 236f7426ec2e46bb19cc9f9e75f1c355b35cf12d7dTanya LattnerTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24237ef567f6764f24a47c63121cc0a599ddc8f56dChris LattnerIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid SpencerFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 26551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid SpencerATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 27551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid SpencerDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28befa499d45ffcc32bd9902518aec18589464e47cChris LattnerOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 29a51bcb50b0c74adc741361824ef81dbefb715c53Chris LattnerUSE OR OTHER DEALINGS IN THE SOFTWARE. 30d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 3186453c52ba02e743d29c08456e51006500041456Chris Lattner**************************************************************************/ 3286453c52ba02e743d29c08456e51006500041456Chris Lattner 3386453c52ba02e743d29c08456e51006500041456Chris Lattner#include <errno.h> 34844731a7f1909f55935e3514c9e713a62d67662eDan Gohman#include "radeon_common.h" 35cbfdf9644ce38fd3404469c26ac3c8466c940b6eDale Johannesen#include "main/simple_list.h" 36cbfdf9644ce38fd3404469c26ac3c8466c940b6eDale Johannesen 37237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner#if defined(USE_X86_ASM) 38ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman#define COPY_DWORDS( dst, src, nr ) \ 39ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohmando { \ 40237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner int __tmp; \ 41ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman __asm__ __volatile__( "rep ; movsl" \ 42ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ 43120d053e3ba810b44047fbcb719824bed5673ca9Chris Lattner : "0" (nr), \ 44ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner "D" ((long)dst), \ 45ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner "S" ((long)src) ); \ 46ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner} while (0) 47ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#else 48ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#define COPY_DWORDS( dst, src, nr ) \ 49ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattnerdo { \ 50ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner int j; \ 51ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner for ( j = 0 ; j < nr ; j++ ) \ 52befa499d45ffcc32bd9902518aec18589464e47cChris Lattner dst[j] = ((int *)src)[j]; \ 53befa499d45ffcc32bd9902518aec18589464e47cChris Lattner dst += nr; \ 541f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen} while (0) 55ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner#endif 56ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner 57befa499d45ffcc32bd9902518aec18589464e47cChris Lattnervoid radeonEmitVec4(uint32_t *out, const GLvoid * data, int stride, int count) 5866c75aaa028683c389c55b377ee2411b61081677Bill Wendling{ 5966c75aaa028683c389c55b377ee2411b61081677Bill Wendling int i; 60ff2dad312883e5da91fb9f4e3619b7d095867f3bChris Lattner 61fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman if (RADEON_DEBUG & RADEON_VERTS) 628c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling fprintf(stderr, "%s count %d stride %d out %p data %p\n", 638c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling __FUNCTION__, count, stride, (void *)out, (void *)data); 648c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling 658c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling if (stride == 4) 668c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling COPY_DWORDS(out, data, count); 678c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling else 688c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling for (i = 0; i < count; i++) { 698c1604e7d617622cb391f1c679ddf70ea03baedcBill Wendling out[0] = *(int *)data; 7054970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner out++; 7154970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner data += stride; 72bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola } 73befa499d45ffcc32bd9902518aec18589464e47cChris Lattner} 740a81aac4b46eed130d20714af5a1c01b05d0275eBill Wendling 756f0a7687ab9a0509e847279fae27554ce7da0ba1Duncan Sandsvoid radeonEmitVec8(uint32_t *out, const GLvoid * data, int stride, int count) 76fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman{ 77befa499d45ffcc32bd9902518aec18589464e47cChris Lattner int i; 786f0a7687ab9a0509e847279fae27554ce7da0ba1Duncan Sands 79fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman if (RADEON_DEBUG & RADEON_VERTS) 801f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen fprintf(stderr, "%s count %d stride %d out %p data %p\n", 811f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen __FUNCTION__, count, stride, (void *)out, (void *)data); 82befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 83befa499d45ffcc32bd9902518aec18589464e47cChris Lattner if (stride == 8) 84befa499d45ffcc32bd9902518aec18589464e47cChris Lattner COPY_DWORDS(out, data, count * 2); 85befa499d45ffcc32bd9902518aec18589464e47cChris Lattner else 86befa499d45ffcc32bd9902518aec18589464e47cChris Lattner for (i = 0; i < count; i++) { 87237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner out[0] = *(int *)data; 881a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar out[1] = *(int *)(data + 4); 891a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar out += 2; 901a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar data += stride; 911a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar } 92c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar} 931a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 941a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbarvoid radeonEmitVec12(uint32_t *out, const GLvoid * data, int stride, int count) 95c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar{ 96c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar int i; 97c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar 98c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar if (RADEON_DEBUG & RADEON_VERTS) 99c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar fprintf(stderr, "%s count %d stride %d out %p data %p\n", 100c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar __FUNCTION__, count, stride, (void *)out, (void *)data); 101c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar 102c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar if (stride == 12) { 103c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar COPY_DWORDS(out, data, count * 3); 104c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar } 105c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar else 106c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar for (i = 0; i < count; i++) { 107c5e1ec47c719806fcc882470595960512edc7441Daniel Dunbar out[0] = *(int *)data; 1081a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar out[1] = *(int *)(data + 4); 1091a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar out[2] = *(int *)(data + 8); 1101a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar out += 3; 1111a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar data += stride; 1121a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar } 1131a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar} 1141a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 1151a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbarvoid radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count) 1161a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar{ 1171a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar int i; 1181a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 1191a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar if (RADEON_DEBUG & RADEON_VERTS) 1201a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar fprintf(stderr, "%s count %d stride %d out %p data %p\n", 1211a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar __FUNCTION__, count, stride, (void *)out, (void *)data); 1221a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 1231a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar if (stride == 16) 1241a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar COPY_DWORDS(out, data, count * 4); 1251a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar else 126237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner for (i = 0; i < count; i++) { 127237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner out[0] = *(int *)data; 128237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner out[1] = *(int *)(data + 4); 1291f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen out[2] = *(int *)(data + 8); 130237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner out[3] = *(int *)(data + 12); 131237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner out += 4; 1320a81aac4b46eed130d20714af5a1c01b05d0275eBill Wendling data += stride; 133237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner } 134befa499d45ffcc32bd9902518aec18589464e47cChris Lattner} 135befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 1360a81aac4b46eed130d20714af5a1c01b05d0275eBill Wendlingvoid rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, 137237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner const GLvoid * data, int size, int stride, int count) 138237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner{ 139befa499d45ffcc32bd9902518aec18589464e47cChris Lattner radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 140befa499d45ffcc32bd9902518aec18589464e47cChris Lattner uint32_t *out; 141befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 142befa499d45ffcc32bd9902518aec18589464e47cChris Lattner if (stride == 0) { 143befa499d45ffcc32bd9902518aec18589464e47cChris Lattner radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); 144cf5933a716e7eb6bd5ff49aa62f3e76379ebaf51Chris Lattner count = 1; 145cf5933a716e7eb6bd5ff49aa62f3e76379ebaf51Chris Lattner aos->stride = 0; 146befa499d45ffcc32bd9902518aec18589464e47cChris Lattner } else { 147befa499d45ffcc32bd9902518aec18589464e47cChris Lattner radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); 148befa499d45ffcc32bd9902518aec18589464e47cChris Lattner aos->stride = size; 1491f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen } 1501f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen 1515cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer aos->components = size; 152befa499d45ffcc32bd9902518aec18589464e47cChris Lattner aos->count = count; 153befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 154237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner radeon_bo_map(aos->bo, 1); 1550a81aac4b46eed130d20714af5a1c01b05d0275eBill Wendling out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); 156fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman switch (size) { 157befa499d45ffcc32bd9902518aec18589464e47cChris Lattner case 1: radeonEmitVec4(out, data, stride, count); break; 158befa499d45ffcc32bd9902518aec18589464e47cChris Lattner case 2: radeonEmitVec8(out, data, stride, count); break; 159befa499d45ffcc32bd9902518aec18589464e47cChris Lattner case 3: radeonEmitVec12(out, data, stride, count); break; 160befa499d45ffcc32bd9902518aec18589464e47cChris Lattner case 4: radeonEmitVec16(out, data, stride, count); break; 161befa499d45ffcc32bd9902518aec18589464e47cChris Lattner default: 162befa499d45ffcc32bd9902518aec18589464e47cChris Lattner assert(0); 163befa499d45ffcc32bd9902518aec18589464e47cChris Lattner break; 164fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman } 165befa499d45ffcc32bd9902518aec18589464e47cChris Lattner radeon_bo_unmap(aos->bo); 166befa499d45ffcc32bd9902518aec18589464e47cChris Lattner} 167befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 168befa499d45ffcc32bd9902518aec18589464e47cChris Lattnervoid radeon_init_dma(radeonContextPtr rmesa) 169befa499d45ffcc32bd9902518aec18589464e47cChris Lattner{ 170befa499d45ffcc32bd9902518aec18589464e47cChris Lattner make_empty_list(&rmesa->dma.free); 171befa499d45ffcc32bd9902518aec18589464e47cChris Lattner make_empty_list(&rmesa->dma.wait); 172befa499d45ffcc32bd9902518aec18589464e47cChris Lattner make_empty_list(&rmesa->dma.reserved); 173befa499d45ffcc32bd9902518aec18589464e47cChris Lattner rmesa->dma.minimum_size = MAX_DMA_BUF_SZ; 174befa499d45ffcc32bd9902518aec18589464e47cChris Lattner} 175befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 176cbfdf9644ce38fd3404469c26ac3c8466c940b6eDale Johannesenvoid radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) 17708ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner{ 17808ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner struct radeon_dma_bo *dma_bo = NULL; 17908ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner /* we set minimum sizes to at least requested size 18008ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner aligned to next 16 bytes. */ 18108ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner if (size > rmesa->dma.minimum_size) 18208ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner rmesa->dma.minimum_size = (size + 15) & (~15); 18308ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner 184befa499d45ffcc32bd9902518aec18589464e47cChris Lattner radeon_print(RADEON_DMA, RADEON_NORMAL, "%s size %d minimum_size %d\n", 185befa499d45ffcc32bd9902518aec18589464e47cChris Lattner __FUNCTION__, size, rmesa->dma.minimum_size); 186befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 187befa499d45ffcc32bd9902518aec18589464e47cChris Lattner if (is_empty_list(&rmesa->dma.free) 188befa499d45ffcc32bd9902518aec18589464e47cChris Lattner || last_elem(&rmesa->dma.free)->bo->size < size) { 189befa499d45ffcc32bd9902518aec18589464e47cChris Lattner dma_bo = CALLOC_STRUCT(radeon_dma_bo); 190befa499d45ffcc32bd9902518aec18589464e47cChris Lattner assert(dma_bo); 1911a99dbfe3b70c83d3f3e4648b5868c04697cd77cDaniel Dunbar 192e345566f8eaeeda45e29e3709114a42209a360ccDale Johannesenagain_alloc: 193befa499d45ffcc32bd9902518aec18589464e47cChris Lattner dma_bo->bo = radeon_bo_open(rmesa->radeonScreen->bom, 1941f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen 0, rmesa->dma.minimum_size, 4, 1951f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen RADEON_GEM_DOMAIN_GTT, 0); 1961f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen 1971f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen if (!dma_bo->bo) { 198e345566f8eaeeda45e29e3709114a42209a360ccDale Johannesen rcommonFlushCmdBuf(rmesa, __FUNCTION__); 199e345566f8eaeeda45e29e3709114a42209a360ccDale Johannesen goto again_alloc; 20008ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner } 20108ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner insert_at_head(&rmesa->dma.reserved, dma_bo); 20208ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner } else { 20308ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner /* We push and pop buffers from end of list so we can keep 20408ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner counter on unused buffers for later freeing them from 20508ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner begin of list */ 20608ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner dma_bo = last_elem(&rmesa->dma.free); 20708ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner remove_from_list(dma_bo); 20808ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner insert_at_head(&rmesa->dma.reserved, dma_bo); 20908ff1480ffcb22e946c7bb6c7d66c5d977ae3d6eChris Lattner } 210befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 211befa499d45ffcc32bd9902518aec18589464e47cChris Lattner rmesa->dma.current_used = 0; 212befa499d45ffcc32bd9902518aec18589464e47cChris Lattner rmesa->dma.current_vertexptr = 0; 213befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 214befa499d45ffcc32bd9902518aec18589464e47cChris Lattner if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs, 215775cbdd51a3b33dd5eb343689f65ab5cc8ac7118Chris Lattner first_elem(&rmesa->dma.reserved)->bo, 216237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner RADEON_GEM_DOMAIN_GTT, 0)) 217237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner fprintf(stderr,"failure to revalidate BOs - badness\n"); 218befa499d45ffcc32bd9902518aec18589464e47cChris Lattner 219237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner if (is_empty_list(&rmesa->dma.reserved)) { 220775cbdd51a3b33dd5eb343689f65ab5cc8ac7118Chris Lattner /* Cmd buff have been flushed in radeon_revalidate_bos */ 221237ef567f6764f24a47c63121cc0a599ddc8f56dChris Lattner goto again_alloc; 222d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke } 22368d57e7ae80044401efd889270a12c71b3efb9abChris Lattner radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1); 22468d57e7ae80044401efd889270a12c71b3efb9abChris Lattner} 22568d57e7ae80044401efd889270a12c71b3efb9abChris Lattner 226b7c6bf1e073088635951435acedff793add1cefdDevang Patel/* Allocates a region from rmesa->dma.current. If there isn't enough 227b7c6bf1e073088635951435acedff793add1cefdDevang Patel * space in current, grab a new buffer (and discard what was left of current) 228b7c6bf1e073088635951435acedff793add1cefdDevang Patel */ 229b7c6bf1e073088635951435acedff793add1cefdDevang Patelvoid radeonAllocDmaRegion(radeonContextPtr rmesa, 230b7c6bf1e073088635951435acedff793add1cefdDevang Patel struct radeon_bo **pbo, int *poffset, 231b7c6bf1e073088635951435acedff793add1cefdDevang Patel int bytes, int alignment) 232b7c6bf1e073088635951435acedff793add1cefdDevang Patel{ 2333e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner if (RADEON_DEBUG & RADEON_IOCTL) 2343e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); 2353e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner 2363e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner if (rmesa->dma.flush) 2373e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner rmesa->dma.flush(rmesa->glCtx); 2383e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner 23954970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); 2400c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner 2410c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner alignment--; 24254970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; 24354970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner 244b7c6bf1e073088635951435acedff793add1cefdDevang Patel if (is_empty_list(&rmesa->dma.reserved) 245b7c6bf1e073088635951435acedff793add1cefdDevang Patel || rmesa->dma.current_used + bytes > first_elem(&rmesa->dma.reserved)->bo->size) 246b7c6bf1e073088635951435acedff793add1cefdDevang Patel radeonRefillCurrentDmaRegion(rmesa, bytes); 247bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola 24854970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner *poffset = rmesa->dma.current_used; 2490c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner *pbo = first_elem(&rmesa->dma.reserved)->bo; 25054970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner radeon_bo_ref(*pbo); 2516f0a7687ab9a0509e847279fae27554ce7da0ba1Duncan Sands 252fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman /* Always align to at least 16 bytes */ 2530c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; 2540c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner rmesa->dma.current_vertexptr = rmesa->dma.current_used; 2550c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner 2560c0aa711b8a0550c21f032125c4663ff45864f81Chris Lattner assert(rmesa->dma.current_used <= first_elem(&rmesa->dma.reserved)->bo->size); 257fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman} 25854970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner 25954970c032815edadb1b2988ea33f5a1173e5b29cChris Lattnervoid radeonFreeDmaRegions(radeonContextPtr rmesa) 26054970c032815edadb1b2988ea33f5a1173e5b29cChris Lattner{ 26168d57e7ae80044401efd889270a12c71b3efb9abChris Lattner struct radeon_dma_bo *dma_bo; 26268d57e7ae80044401efd889270a12c71b3efb9abChris Lattner struct radeon_dma_bo *temp; 2633e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner if (RADEON_DEBUG & RADEON_DMA) 2643e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner fprintf(stderr, "%s\n", __FUNCTION__); 2653e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner 2663e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner foreach_s(dma_bo, temp, &rmesa->dma.free) { 2673e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner remove_from_list(dma_bo); 2683e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner radeon_bo_unref(dma_bo->bo); 2693e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner FREE(dma_bo); 2701f67ce4aa3f65619f54c8a3072539da5b0022841Dale Johannesen } 2713e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner 2723e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner foreach_s(dma_bo, temp, &rmesa->dma.wait) { 2733e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner remove_from_list(dma_bo); 2743e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner radeon_bo_unref(dma_bo->bo); 2753e1358a9fa1ebd3f51c94eb69da55d693895fe7cChris Lattner FREE(dma_bo); 27668d57e7ae80044401efd889270a12c71b3efb9abChris Lattner } 27768d57e7ae80044401efd889270a12c71b3efb9abChris Lattner 278 foreach_s(dma_bo, temp, &rmesa->dma.reserved) { 279 remove_from_list(dma_bo); 280 radeon_bo_unref(dma_bo->bo); 281 FREE(dma_bo); 282 } 283} 284 285void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes) 286{ 287 if (is_empty_list(&rmesa->dma.reserved)) 288 return; 289 290 if (RADEON_DEBUG & RADEON_IOCTL) 291 fprintf(stderr, "%s %d\n", __FUNCTION__, return_bytes); 292 rmesa->dma.current_used -= return_bytes; 293 rmesa->dma.current_vertexptr = rmesa->dma.current_used; 294} 295 296static int radeon_bo_is_idle(struct radeon_bo* bo) 297{ 298 uint32_t domain; 299 int ret = radeon_bo_is_busy(bo, &domain); 300 if (ret == -EINVAL) { 301 WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n" 302 "This may cause small performance drop for you.\n"); 303 } 304 return ret != -EBUSY; 305} 306 307void radeonReleaseDmaRegions(radeonContextPtr rmesa) 308{ 309 struct radeon_dma_bo *dma_bo; 310 struct radeon_dma_bo *temp; 311 const int expire_at = ++rmesa->dma.free.expire_counter + DMA_BO_FREE_TIME; 312 const int time = rmesa->dma.free.expire_counter; 313 314 if (RADEON_DEBUG & RADEON_DMA) { 315 size_t free = 0, 316 wait = 0, 317 reserved = 0; 318 foreach(dma_bo, &rmesa->dma.free) 319 ++free; 320 321 foreach(dma_bo, &rmesa->dma.wait) 322 ++wait; 323 324 foreach(dma_bo, &rmesa->dma.reserved) 325 ++reserved; 326 327 fprintf(stderr, "%s: free %zu, wait %zu, reserved %zu, minimum_size: %zu\n", 328 __FUNCTION__, free, wait, reserved, rmesa->dma.minimum_size); 329 } 330 331 if (!rmesa->radeonScreen->driScreen->dri2.enabled) { 332 /* request updated cs processing information from kernel */ 333 legacy_track_pending(rmesa->radeonScreen->bom, 0); 334 } 335 336 /* move waiting bos to free list. 337 wait list provides gpu time to handle data before reuse */ 338 foreach_s(dma_bo, temp, &rmesa->dma.wait) { 339 if (dma_bo->expire_counter == time) { 340 WARN_ONCE("Leaking dma buffer object!\n"); 341 radeon_bo_unref(dma_bo->bo); 342 remove_from_list(dma_bo); 343 FREE(dma_bo); 344 continue; 345 } 346 /* free objects that are too small to be used because of large request */ 347 if (dma_bo->bo->size < rmesa->dma.minimum_size) { 348 radeon_bo_unref(dma_bo->bo); 349 remove_from_list(dma_bo); 350 FREE(dma_bo); 351 continue; 352 } 353 if (!radeon_bo_is_idle(dma_bo->bo)) { 354 if (rmesa->radeonScreen->driScreen->dri2.enabled) 355 break; 356 continue; 357 } 358 remove_from_list(dma_bo); 359 dma_bo->expire_counter = expire_at; 360 insert_at_tail(&rmesa->dma.free, dma_bo); 361 } 362 363 /* move reserved to wait list */ 364 foreach_s(dma_bo, temp, &rmesa->dma.reserved) { 365 radeon_bo_unmap(dma_bo->bo); 366 /* free objects that are too small to be used because of large request */ 367 if (dma_bo->bo->size < rmesa->dma.minimum_size) { 368 radeon_bo_unref(dma_bo->bo); 369 remove_from_list(dma_bo); 370 FREE(dma_bo); 371 continue; 372 } 373 remove_from_list(dma_bo); 374 dma_bo->expire_counter = expire_at; 375 insert_at_tail(&rmesa->dma.wait, dma_bo); 376 } 377 378 /* free bos that have been unused for some time */ 379 foreach_s(dma_bo, temp, &rmesa->dma.free) { 380 if (dma_bo->expire_counter != time) 381 break; 382 remove_from_list(dma_bo); 383 radeon_bo_unref(dma_bo->bo); 384 FREE(dma_bo); 385 } 386 387} 388 389 390/* Flush vertices in the current dma region. 391 */ 392void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) 393{ 394 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 395 struct radeon_dma *dma = &rmesa->dma; 396 397 if (RADEON_DEBUG & RADEON_IOCTL) 398 fprintf(stderr, "%s\n", __FUNCTION__); 399 dma->flush = NULL; 400 401 radeon_bo_unmap(rmesa->swtcl.bo); 402 403 if (!is_empty_list(&dma->reserved)) { 404 GLuint current_offset = dma->current_used; 405 406 assert (dma->current_used + 407 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == 408 dma->current_vertexptr); 409 410 if (dma->current_used != dma->current_vertexptr) { 411 dma->current_used = dma->current_vertexptr; 412 413 rmesa->vtbl.swtcl_flush(ctx, current_offset); 414 } 415 rmesa->swtcl.numverts = 0; 416 } 417 radeon_bo_unref(rmesa->swtcl.bo); 418 rmesa->swtcl.bo = NULL; 419} 420/* Alloc space in the current dma region. 421 */ 422void * 423rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) 424{ 425 GLuint bytes = vsize * nverts; 426 void *head; 427 if (RADEON_DEBUG & RADEON_IOCTL) 428 fprintf(stderr, "%s\n", __FUNCTION__); 429 430 if(is_empty_list(&rmesa->dma.reserved) 431 ||rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) { 432 if (rmesa->dma.flush) { 433 rmesa->dma.flush(rmesa->glCtx); 434 } 435 436 radeonRefillCurrentDmaRegion(rmesa, bytes); 437 438 return NULL; 439 } 440 441 if (!rmesa->dma.flush) { 442 /* if cmdbuf flushed DMA restart */ 443 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; 444 rmesa->dma.flush = rcommon_flush_last_swtcl_prim; 445 } 446 447 ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); 448 ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); 449 ASSERT( rmesa->dma.current_used + 450 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == 451 rmesa->dma.current_vertexptr ); 452 453 if (!rmesa->swtcl.bo) { 454 rmesa->swtcl.bo = first_elem(&rmesa->dma.reserved)->bo; 455 radeon_bo_ref(rmesa->swtcl.bo); 456 radeon_bo_map(rmesa->swtcl.bo, 1); 457 } 458 459 head = (rmesa->swtcl.bo->ptr + rmesa->dma.current_vertexptr); 460 rmesa->dma.current_vertexptr += bytes; 461 rmesa->swtcl.numverts += nverts; 462 return head; 463} 464 465void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs ) 466{ 467 radeonContextPtr radeon = RADEON_CONTEXT( ctx ); 468 int i; 469 if (RADEON_DEBUG & RADEON_IOCTL) 470 fprintf(stderr, "%s\n", __FUNCTION__); 471 472 if (radeon->dma.flush) { 473 radeon->dma.flush(radeon->glCtx); 474 } 475 for (i = 0; i < radeon->tcl.aos_count; i++) { 476 if (radeon->tcl.aos[i].bo) { 477 radeon_bo_unref(radeon->tcl.aos[i].bo); 478 radeon->tcl.aos[i].bo = NULL; 479 480 } 481 } 482} 483