Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
  3.  * Copyright 2010 Marek Olšák <maraeo@gmail.com>
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  9.  * license, and/or sell copies of the Software, and to permit persons to whom
  10.  * the Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  19.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22.  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
  23.  
  24. /**
  25.  * This file contains macros for building command buffers in memory.
  26.  *
  27.  * Use NEW_CB for buffers with a varying size and it will also allocate
  28.  * the buffer.
  29.  * Use BEGIN_CB for arrays with a static size.
  30.  *
  31.  * Example:
  32.  *
  33.  *     uint32_t cb[3];
  34.  *     CB_LOCALS;
  35.  *
  36.  *     BEGIN_CB(cb, 3);
  37.  *     OUT_CB_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2);
  38.  *     OUT_CB(blend_color_red_alpha);
  39.  *     OUT_CB(blend_color_green_blue);
  40.  *     END_CB;
  41.  *
  42.  * And later:
  43.  *
  44.  *     CS_LOCALS;
  45.  *     WRITE_CS_TABLE(cb, 3);
  46.  *
  47.  * Or using a little slower variant:
  48.  *
  49.  *     CS_LOCALS;
  50.  *     BEGIN_CS(cb, 3);
  51.  *     OUT_CS_TABLE(cb, 3);
  52.  *     END_CS;
  53.  */
  54.  
  55. #ifndef R300_CB_H
  56. #define R300_CB_H
  57.  
  58. #include "r300_reg.h"
  59.  
  60. /* Yes, I know macros are ugly. However, they are much prettier than the code
  61.  * that they neatly hide away, and don't have the cost of function setup, so
  62.  * we're going to use them. */
  63.  
  64. /**
  65.  * Command buffer setup.
  66.  */
  67.  
  68. #ifdef DEBUG
  69.  
  70. #define CB_LOCALS \
  71.     int cs_count = 0; \
  72.     uint32_t *cs_ptr = NULL; \
  73.     (void) cs_count; (void) cs_ptr
  74.  
  75. #define BEGIN_CB(ptr, size) do { \
  76.     assert(sizeof(*(ptr)) == sizeof(uint32_t)); \
  77.     cs_count = (size); \
  78.     cs_ptr = (ptr); \
  79. } while (0)
  80.  
  81. #define NEW_CB(ptr, size) \
  82.     do { \
  83.     assert(sizeof(*(ptr)) == sizeof(uint32_t)); \
  84.     cs_count = (size); \
  85.     cs_ptr = (ptr) = malloc((size) * sizeof(uint32_t)); \
  86. } while (0)
  87.  
  88. #define END_CB do { \
  89.     if (cs_count != 0) \
  90.         debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \
  91.                      cs_count, __FUNCTION__, __FILE__, __LINE__); \
  92. } while (0)
  93.  
  94. #define CB_USED_DW(x) cs_count -= x
  95.  
  96. #else
  97.  
  98. #define CB_LOCALS \
  99.     uint32_t *cs_ptr = NULL; (void) cs_ptr
  100.  
  101. #define NEW_CB(ptr, size) \
  102.     cs_ptr = (ptr) = malloc((size) * sizeof(uint32_t))
  103.  
  104. #define BEGIN_CB(ptr, size) cs_ptr = (ptr)
  105. #define END_CB
  106. #define CB_USED_DW(x)
  107.  
  108. #endif
  109.  
  110.  
  111. /**
  112.  * Storing pure DWORDs.
  113.  */
  114.  
  115. #define OUT_CB(value) do { \
  116.     *cs_ptr = (value); \
  117.     cs_ptr++; \
  118.     CB_USED_DW(1); \
  119. } while (0)
  120.  
  121. #define OUT_CB_TABLE(values, count) do { \
  122.     memcpy(cs_ptr, values, count * sizeof(uint32_t)); \
  123.     cs_ptr += count; \
  124.     CB_USED_DW(count); \
  125. } while (0)
  126.  
  127. #define OUT_CB_32F(value) \
  128.     OUT_CB(fui(value));
  129.  
  130. #define OUT_CB_REG(register, value) do { \
  131.     assert(register); \
  132.     OUT_CB(CP_PACKET0(register, 0)); \
  133.     OUT_CB(value); \
  134. } while (0)
  135.  
  136. /* Note: This expects count to be the number of registers,
  137.  * not the actual packet0 count! */
  138. #define OUT_CB_REG_SEQ(register, count) do { \
  139.     assert(register); \
  140.     OUT_CB(CP_PACKET0(register, (count) - 1)); \
  141. } while (0)
  142.  
  143. #define OUT_CB_ONE_REG(register, count) do { \
  144.     assert(register); \
  145.     OUT_CB(CP_PACKET0(register, (count) - 1) | RADEON_ONE_REG_WR); \
  146. } while (0)
  147.  
  148. #define OUT_CB_PKT3(op, count) \
  149.     OUT_CB(CP_PACKET3(op, count))
  150.  
  151. #endif /* R300_CB_H */
  152.