13464ebd5Sriastradh/* 23464ebd5Sriastradh * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 33464ebd5Sriastradh * Copyright 2010 Marek Olšák <maraeo@gmail.com> 43464ebd5Sriastradh * 53464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 63464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"), 73464ebd5Sriastradh * to deal in the Software without restriction, including without limitation 83464ebd5Sriastradh * on the rights to use, copy, modify, merge, publish, distribute, sub 93464ebd5Sriastradh * license, and/or sell copies of the Software, and to permit persons to whom 103464ebd5Sriastradh * the Software is furnished to do so, subject to the following conditions: 113464ebd5Sriastradh * 123464ebd5Sriastradh * The above copyright notice and this permission notice (including the next 133464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the 143464ebd5Sriastradh * Software. 153464ebd5Sriastradh * 163464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 173464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 183464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 193464ebd5Sriastradh * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 203464ebd5Sriastradh * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 213464ebd5Sriastradh * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 223464ebd5Sriastradh * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 233464ebd5Sriastradh 243464ebd5Sriastradh/** 253464ebd5Sriastradh * This file contains macros for building command buffers in memory. 263464ebd5Sriastradh * 273464ebd5Sriastradh * Use NEW_CB for buffers with a varying size and it will also allocate 283464ebd5Sriastradh * the buffer. 293464ebd5Sriastradh * Use BEGIN_CB for arrays with a static size. 303464ebd5Sriastradh * 313464ebd5Sriastradh * Example: 323464ebd5Sriastradh * 333464ebd5Sriastradh * uint32_t cb[3]; 343464ebd5Sriastradh * CB_LOCALS; 353464ebd5Sriastradh * 363464ebd5Sriastradh * BEGIN_CB(cb, 3); 373464ebd5Sriastradh * OUT_CB_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2); 383464ebd5Sriastradh * OUT_CB(blend_color_red_alpha); 393464ebd5Sriastradh * OUT_CB(blend_color_green_blue); 403464ebd5Sriastradh * END_CB; 413464ebd5Sriastradh * 423464ebd5Sriastradh * And later: 433464ebd5Sriastradh * 443464ebd5Sriastradh * CS_LOCALS; 453464ebd5Sriastradh * WRITE_CS_TABLE(cb, 3); 463464ebd5Sriastradh * 473464ebd5Sriastradh * Or using a little slower variant: 483464ebd5Sriastradh * 493464ebd5Sriastradh * CS_LOCALS; 503464ebd5Sriastradh * BEGIN_CS(cb, 3); 513464ebd5Sriastradh * OUT_CS_TABLE(cb, 3); 523464ebd5Sriastradh * END_CS; 533464ebd5Sriastradh */ 543464ebd5Sriastradh 553464ebd5Sriastradh#ifndef R300_CB_H 563464ebd5Sriastradh#define R300_CB_H 573464ebd5Sriastradh 583464ebd5Sriastradh#include "r300_reg.h" 593464ebd5Sriastradh 603464ebd5Sriastradh/* Yes, I know macros are ugly. However, they are much prettier than the code 613464ebd5Sriastradh * that they neatly hide away, and don't have the cost of function setup, so 623464ebd5Sriastradh * we're going to use them. */ 633464ebd5Sriastradh 643464ebd5Sriastradh/** 653464ebd5Sriastradh * Command buffer setup. 663464ebd5Sriastradh */ 673464ebd5Sriastradh 683464ebd5Sriastradh#ifdef DEBUG 693464ebd5Sriastradh 703464ebd5Sriastradh#define CB_LOCALS \ 713464ebd5Sriastradh int cs_count = 0; \ 723464ebd5Sriastradh uint32_t *cs_ptr = NULL; \ 733464ebd5Sriastradh (void) cs_count; (void) cs_ptr 743464ebd5Sriastradh 753464ebd5Sriastradh#define BEGIN_CB(ptr, size) do { \ 763464ebd5Sriastradh assert(sizeof(*(ptr)) == sizeof(uint32_t)); \ 773464ebd5Sriastradh cs_count = (size); \ 783464ebd5Sriastradh cs_ptr = (ptr); \ 793464ebd5Sriastradh} while (0) 803464ebd5Sriastradh 813464ebd5Sriastradh#define NEW_CB(ptr, size) \ 823464ebd5Sriastradh do { \ 833464ebd5Sriastradh assert(sizeof(*(ptr)) == sizeof(uint32_t)); \ 843464ebd5Sriastradh cs_count = (size); \ 85af69d88dSmrg cs_ptr = (ptr) = malloc((size) * sizeof(uint32_t)); \ 863464ebd5Sriastradh} while (0) 873464ebd5Sriastradh 883464ebd5Sriastradh#define END_CB do { \ 893464ebd5Sriastradh if (cs_count != 0) \ 903464ebd5Sriastradh debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \ 913464ebd5Sriastradh cs_count, __FUNCTION__, __FILE__, __LINE__); \ 923464ebd5Sriastradh} while (0) 933464ebd5Sriastradh 943464ebd5Sriastradh#define CB_USED_DW(x) cs_count -= x 953464ebd5Sriastradh 963464ebd5Sriastradh#else 973464ebd5Sriastradh 983464ebd5Sriastradh#define CB_LOCALS \ 993464ebd5Sriastradh uint32_t *cs_ptr = NULL; (void) cs_ptr 1003464ebd5Sriastradh 1013464ebd5Sriastradh#define NEW_CB(ptr, size) \ 102af69d88dSmrg cs_ptr = (ptr) = malloc((size) * sizeof(uint32_t)) 1033464ebd5Sriastradh 1043464ebd5Sriastradh#define BEGIN_CB(ptr, size) cs_ptr = (ptr) 1053464ebd5Sriastradh#define END_CB 1063464ebd5Sriastradh#define CB_USED_DW(x) 1073464ebd5Sriastradh 1083464ebd5Sriastradh#endif 1093464ebd5Sriastradh 1103464ebd5Sriastradh 1113464ebd5Sriastradh/** 1123464ebd5Sriastradh * Storing pure DWORDs. 1133464ebd5Sriastradh */ 1143464ebd5Sriastradh 1153464ebd5Sriastradh#define OUT_CB(value) do { \ 1163464ebd5Sriastradh *cs_ptr = (value); \ 1173464ebd5Sriastradh cs_ptr++; \ 1183464ebd5Sriastradh CB_USED_DW(1); \ 1193464ebd5Sriastradh} while (0) 1203464ebd5Sriastradh 1213464ebd5Sriastradh#define OUT_CB_TABLE(values, count) do { \ 1223464ebd5Sriastradh memcpy(cs_ptr, values, count * sizeof(uint32_t)); \ 1233464ebd5Sriastradh cs_ptr += count; \ 1243464ebd5Sriastradh CB_USED_DW(count); \ 1253464ebd5Sriastradh} while (0) 1263464ebd5Sriastradh 1273464ebd5Sriastradh#define OUT_CB_32F(value) \ 1283464ebd5Sriastradh OUT_CB(fui(value)); 1293464ebd5Sriastradh 1303464ebd5Sriastradh#define OUT_CB_REG(register, value) do { \ 1313464ebd5Sriastradh assert(register); \ 1323464ebd5Sriastradh OUT_CB(CP_PACKET0(register, 0)); \ 1333464ebd5Sriastradh OUT_CB(value); \ 1343464ebd5Sriastradh} while (0) 1353464ebd5Sriastradh 1363464ebd5Sriastradh/* Note: This expects count to be the number of registers, 1373464ebd5Sriastradh * not the actual packet0 count! */ 1383464ebd5Sriastradh#define OUT_CB_REG_SEQ(register, count) do { \ 1393464ebd5Sriastradh assert(register); \ 1403464ebd5Sriastradh OUT_CB(CP_PACKET0(register, (count) - 1)); \ 1413464ebd5Sriastradh} while (0) 1423464ebd5Sriastradh 1433464ebd5Sriastradh#define OUT_CB_ONE_REG(register, count) do { \ 1443464ebd5Sriastradh assert(register); \ 1453464ebd5Sriastradh OUT_CB(CP_PACKET0(register, (count) - 1) | RADEON_ONE_REG_WR); \ 1463464ebd5Sriastradh} while (0) 1473464ebd5Sriastradh 1483464ebd5Sriastradh#define OUT_CB_PKT3(op, count) \ 1493464ebd5Sriastradh OUT_CB(CP_PACKET3(op, count)) 1503464ebd5Sriastradh 1513464ebd5Sriastradh#endif /* R300_CB_H */ 152