1/************************************************************************** 2 3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4Copyright © 2002 David Dawes 5 6All Rights Reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a 9copy of this software and associated documentation files (the 10"Software"), to deal in the Software without restriction, including 11without limitation the rights to use, copy, modify, merge, publish, 12distribute, sub license, and/or sell copies of the Software, and to 13permit persons to whom the Software is furnished to do so, subject to 14the following conditions: 15 16The above copyright notice and this permission notice (including the 17next paragraph) shall be included in all copies or substantial portions 18of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 28**************************************************************************/ 29 30#ifndef _INTEL_BATCHBUFFER_H 31#define _INTEL_BATCHBUFFER_H 32 33#define BATCH_RESERVED 16 34 35void intel_batch_init(ScrnInfoPtr pScrn); 36void intel_batch_teardown(ScrnInfoPtr pScrn); 37void intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed); 38void intel_batch_wait_last(ScrnInfoPtr pScrn); 39 40static inline int 41intel_batch_space(I830Ptr pI830) 42{ 43 return (pI830->batch_bo->size - BATCH_RESERVED) - (pI830->batch_used); 44} 45 46static inline void 47intel_batch_require_space(ScrnInfoPtr pScrn, I830Ptr pI830, GLuint sz) 48{ 49 assert(sz < pI830->batch_bo->size - 8); 50 if (intel_batch_space(pI830) < sz) 51 intel_batch_flush(pScrn, FALSE); 52} 53 54static inline void 55intel_batch_start_atomic(ScrnInfoPtr pScrn, unsigned int sz) 56{ 57 I830Ptr pI830 = I830PTR(pScrn); 58 59 assert(!pI830->in_batch_atomic); 60 intel_batch_require_space(pScrn, pI830, sz * 4); 61 62 pI830->in_batch_atomic = TRUE; 63 pI830->batch_atomic_limit = pI830->batch_used + sz * 4; 64} 65 66static inline void 67intel_batch_end_atomic(ScrnInfoPtr pScrn) 68{ 69 I830Ptr pI830 = I830PTR(pScrn); 70 71 assert(pI830->in_batch_atomic); 72 assert(pI830->batch_used <= pI830->batch_atomic_limit); 73 pI830->in_batch_atomic = FALSE; 74} 75 76static inline void 77intel_batch_emit_dword(I830Ptr pI830, uint32_t dword) 78{ 79 assert(pI830->batch_ptr != NULL); 80 assert(intel_batch_space(pI830) >= 4); 81 *(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = dword; 82 pI830->batch_used += 4; 83} 84 85static inline void 86intel_batch_emit_reloc (I830Ptr pI830, 87 dri_bo *bo, 88 uint32_t read_domains, 89 uint32_t write_domains, 90 uint32_t delta) 91{ 92 assert(intel_batch_space(pI830) >= 4); 93 *(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = bo->offset + delta; 94 dri_bo_emit_reloc(pI830->batch_bo, read_domains, write_domains, delta, 95 pI830->batch_used, bo); 96 pI830->batch_used += 4; 97} 98 99static inline void 100intel_batch_emit_reloc_pixmap(I830Ptr pI830, PixmapPtr pPixmap, 101 uint32_t read_domains, uint32_t write_domain, 102 uint32_t delta) 103{ 104 dri_bo *bo = i830_get_pixmap_bo(pPixmap); 105 uint32_t offset; 106 assert(pI830->batch_ptr != NULL); 107 assert(intel_batch_space(pI830) >= 4); 108 if (bo) { 109 intel_batch_emit_reloc(pI830, bo, read_domains, write_domain, delta); 110 return; 111 } 112 offset = intel_get_pixmap_offset(pPixmap); 113 *(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = offset + delta; 114 pI830->batch_used += 4; 115} 116 117#define OUT_BATCH(dword) intel_batch_emit_dword(pI830, dword) 118 119#define OUT_RELOC(bo, read_domains, write_domains, delta) \ 120 intel_batch_emit_reloc (pI830, bo, read_domains, write_domains, delta) 121 122#define OUT_RELOC_PIXMAP(pPixmap, reads, write, delta) \ 123 intel_batch_emit_reloc_pixmap(pI830, pPixmap, reads, write, delta) 124 125union intfloat { 126 float f; 127 unsigned int ui; 128}; 129 130#define OUT_BATCH_F(x) do { \ 131 union intfloat tmp; \ 132 tmp.f = (float)(x); \ 133 OUT_BATCH(tmp.ui); \ 134} while(0) 135 136#define BEGIN_BATCH(n) \ 137do { \ 138 if (pI830->batch_emitting != 0) \ 139 FatalError("%s: BEGIN_BATCH called without closing " \ 140 "ADVANCE_BATCH\n", __FUNCTION__); \ 141 intel_batch_require_space(pScrn, pI830, (n) * 4); \ 142 pI830->batch_emitting = (n) * 4; \ 143 pI830->batch_emit_start = pI830->batch_used; \ 144} while (0) 145 146#define ADVANCE_BATCH() do { \ 147 if (pI830->batch_emitting == 0) \ 148 FatalError("%s: ADVANCE_BATCH called with no matching " \ 149 "BEGIN_BATCH\n", __FUNCTION__); \ 150 if (pI830->batch_used > pI830->batch_emit_start + pI830->batch_emitting) \ 151 FatalError("%s: ADVANCE_BATCH: exceeded allocation %d/%d\n ", \ 152 __FUNCTION__, \ 153 pI830->batch_used - pI830->batch_emit_start, \ 154 pI830->batch_emitting); \ 155 if (pI830->batch_used < pI830->batch_emit_start + pI830->batch_emitting) \ 156 FatalError("%s: ADVANCE_BATCH: under-used allocation %d/%d\n ", \ 157 __FUNCTION__, \ 158 pI830->batch_used - pI830->batch_emit_start, \ 159 pI830->batch_emitting); \ 160 if ((pI830->batch_emitting > 8) && (I810_DEBUG & DEBUG_ALWAYS_SYNC)) { \ 161 /* Note: not actually syncing, just flushing each batch. */ \ 162 intel_batch_flush(pScrn, FALSE); \ 163 } \ 164 pI830->batch_emitting = 0; \ 165} while (0) 166 167#endif /* _INTEL_BATCHBUFFER_H */ 168