1 /* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23 /** 24 * This file contains macros for immediate command submission. 25 */ 26 27 #ifndef R300_CS_H 28 #define R300_CS_H 29 30 #include "r300_reg.h" 31 #include "r300_context.h" 32 33 /* Yes, I know macros are ugly. However, they are much prettier than the code 34 * that they neatly hide away, and don't have the cost of function setup,so 35 * we're going to use them. */ 36 37 /** 38 * Command submission setup. 39 */ 40 41 #define CS_LOCALS(context) \ 42 struct radeon_winsys_cs *cs_copy = (context)->cs; \ 43 struct radeon_winsys *cs_winsys = (context)->rws; \ 44 int cs_count = 0; (void) cs_count; (void) cs_winsys; 45 46 #ifdef DEBUG 47 48 #define BEGIN_CS(size) do { \ 49 assert(size <= (RADEON_MAX_CMDBUF_DWORDS - cs_copy->cdw)); \ 50 cs_count = size; \ 51 } while (0) 52 53 #define END_CS do { \ 54 if (cs_count != 0) \ 55 debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \ 56 cs_count, __FUNCTION__, __FILE__, __LINE__); \ 57 cs_count = 0; \ 58 } while (0) 59 60 #define CS_USED_DW(x) cs_count -= (x) 61 62 #else 63 64 #define BEGIN_CS(size) 65 #define END_CS 66 #define CS_USED_DW(x) 67 68 #endif 69 70 /** 71 * Writing pure DWORDs. 72 */ 73 74 #define OUT_CS(value) do { \ 75 cs_copy->buf[cs_copy->cdw++] = (value); \ 76 CS_USED_DW(1); \ 77 } while (0) 78 79 #define OUT_CS_32F(value) \ 80 OUT_CS(fui(value)) 81 82 #define OUT_CS_REG(register, value) do { \ 83 OUT_CS(CP_PACKET0(register, 0)); \ 84 OUT_CS(value); \ 85 } while (0) 86 87 /* Note: This expects count to be the number of registers, 88 * not the actual packet0 count! */ 89 #define OUT_CS_REG_SEQ(register, count) \ 90 OUT_CS(CP_PACKET0((register), ((count) - 1))) 91 92 #define OUT_CS_ONE_REG(register, count) \ 93 OUT_CS(CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR) 94 95 #define OUT_CS_PKT3(op, count) \ 96 OUT_CS(CP_PACKET3(op, count)) 97 98 #define OUT_CS_TABLE(values, count) do { \ 99 memcpy(cs_copy->buf + cs_copy->cdw, values, count * 4); \ 100 cs_copy->cdw += count; \ 101 CS_USED_DW(count); \ 102 } while (0) 103 104 105 /** 106 * Writing relocations. 107 */ 108 109 #define OUT_CS_RELOC(r) do { \ 110 assert((r)); \ 111 assert((r)->cs_buf); \ 112 cs_winsys->cs_write_reloc(cs_copy, (r)->cs_buf); \ 113 CS_USED_DW(2); \ 114 } while (0) 115 116 117 /** 118 * Command buffer emission. 119 */ 120 121 #define WRITE_CS_TABLE(values, count) do { \ 122 assert(cs_count == 0); \ 123 memcpy(cs_copy->buf + cs_copy->cdw, (values), (count) * 4); \ 124 cs_copy->cdw += (count); \ 125 } while (0) 126 127 #endif /* R300_CS_H */ 128