1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2013 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the 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 NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Chia-I Wu <olv@lunarg.com>
26 */
27
28#ifndef ILO_FORMAT_H
29#define ILO_FORMAT_H
30
31#include "genhw/genhw.h"
32
33#include "ilo_common.h"
34
35bool
36ilo_format_support_vb(const struct ilo_dev *dev,
37                      enum pipe_format format);
38
39bool
40ilo_format_support_sol(const struct ilo_dev *dev,
41                       enum pipe_format format);
42
43bool
44ilo_format_support_sampler(const struct ilo_dev *dev,
45                           enum pipe_format format);
46
47bool
48ilo_format_support_rt(const struct ilo_dev *dev,
49                      enum pipe_format format);
50
51bool
52ilo_format_support_zs(const struct ilo_dev *dev,
53                      enum pipe_format format);
54
55int
56ilo_format_translate_color(const struct ilo_dev *dev,
57                           enum pipe_format format);
58
59/**
60 * Translate a pipe format to a hardware surface format suitable for
61 * the given purpose.  Return -1 on errors.
62 *
63 * This is an inline function not only for performance reasons.  There are
64 * caveats that the callers should be aware of before calling this function.
65 */
66static inline int
67ilo_format_translate(const struct ilo_dev *dev,
68                     enum pipe_format format, unsigned bind)
69{
70   switch (bind) {
71   case PIPE_BIND_RENDER_TARGET:
72      /*
73       * Some RGBX formats are not supported as render target formats.  But we
74       * can use their RGBA counterparts and force the destination alpha to be
75       * one when blending is enabled.
76       */
77      switch (format) {
78      case PIPE_FORMAT_B8G8R8X8_UNORM:
79         return GEN6_FORMAT_B8G8R8A8_UNORM;
80      default:
81         return ilo_format_translate_color(dev, format);
82      }
83      break;
84   case PIPE_BIND_SAMPLER_VIEW:
85      /*
86       * For depth formats, we want the depth values to be returned as R
87       * values.  But we assume in many places that the depth values are
88       * returned as I values (util_make_fragment_tex_shader_writedepth() is
89       * one such example).  We have to live with that at least for now.
90       *
91       * For ETC1 format, the texture data will be decompressed before being
92       * written to the bo.  See tex_staging_sys_convert_write().
93       */
94      switch (format) {
95      case PIPE_FORMAT_Z16_UNORM:
96         return GEN6_FORMAT_I16_UNORM;
97      case PIPE_FORMAT_Z32_FLOAT:
98         return GEN6_FORMAT_I32_FLOAT;
99      case PIPE_FORMAT_Z24X8_UNORM:
100      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
101         return GEN6_FORMAT_I24X8_UNORM;
102      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
103         return GEN6_FORMAT_I32X32_FLOAT;
104      case PIPE_FORMAT_ETC1_RGB8:
105         return GEN6_FORMAT_R8G8B8X8_UNORM;
106      default:
107         return ilo_format_translate_color(dev, format);
108      }
109      break;
110   case PIPE_BIND_VERTEX_BUFFER:
111      if (ilo_dev_gen(dev) >= ILO_GEN(7.5))
112         return ilo_format_translate_color(dev, format);
113
114      /*
115       * Some 3-component formats are not supported as vertex element formats.
116       * But since we move between vertices using vb->stride, we should be
117       * good to use their 4-component counterparts if we force the W
118       * component to be one.  The only exception is that the vb boundary
119       * check for the last vertex may fail.
120       */
121      switch (format) {
122      case PIPE_FORMAT_R16G16B16_FLOAT:
123         return GEN6_FORMAT_R16G16B16A16_FLOAT;
124      case PIPE_FORMAT_R16G16B16_UINT:
125         return GEN6_FORMAT_R16G16B16A16_UINT;
126      case PIPE_FORMAT_R16G16B16_SINT:
127         return GEN6_FORMAT_R16G16B16A16_SINT;
128      case PIPE_FORMAT_R8G8B8_UINT:
129         return GEN6_FORMAT_R8G8B8A8_UINT;
130      case PIPE_FORMAT_R8G8B8_SINT:
131         return GEN6_FORMAT_R8G8B8A8_SINT;
132      default:
133         return ilo_format_translate_color(dev, format);
134      }
135      break;
136   case PIPE_BIND_STREAM_OUTPUT:
137      return ilo_format_translate_color(dev, format);
138      break;
139   default:
140      assert(!"cannot translate format");
141      break;
142   }
143
144   return -1;
145}
146
147static inline int
148ilo_format_translate_render(const struct ilo_dev *dev,
149                            enum pipe_format format)
150{
151   return ilo_format_translate(dev, format, PIPE_BIND_RENDER_TARGET);
152}
153
154static inline int
155ilo_format_translate_texture(const struct ilo_dev *dev,
156                             enum pipe_format format)
157{
158   return ilo_format_translate(dev, format, PIPE_BIND_SAMPLER_VIEW);
159}
160
161static inline int
162ilo_format_translate_vertex(const struct ilo_dev *dev,
163                            enum pipe_format format)
164{
165   return ilo_format_translate(dev, format, PIPE_BIND_VERTEX_BUFFER);
166}
167
168static inline enum gen_depth_format
169ilo_format_translate_depth(const struct ilo_dev *dev,
170                           enum pipe_format format)
171{
172   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
173      switch (format) {
174      case PIPE_FORMAT_Z32_FLOAT:
175         return GEN6_ZFORMAT_D32_FLOAT;
176      case PIPE_FORMAT_Z24X8_UNORM:
177         return GEN6_ZFORMAT_D24_UNORM_X8_UINT;
178      case PIPE_FORMAT_Z16_UNORM:
179         return GEN6_ZFORMAT_D16_UNORM;
180      default:
181         assert(!"unknown depth format");
182         return GEN6_ZFORMAT_D32_FLOAT;
183      }
184   } else {
185      switch (format) {
186      case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
187         return GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT;
188      case PIPE_FORMAT_Z32_FLOAT:
189         return GEN6_ZFORMAT_D32_FLOAT;
190      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
191         return GEN6_ZFORMAT_D24_UNORM_S8_UINT;
192      case PIPE_FORMAT_Z24X8_UNORM:
193         return GEN6_ZFORMAT_D24_UNORM_X8_UINT;
194      case PIPE_FORMAT_Z16_UNORM:
195         return GEN6_ZFORMAT_D16_UNORM;
196      default:
197         assert(!"unknown depth format");
198         return GEN6_ZFORMAT_D32_FLOAT;
199      }
200   }
201}
202
203#endif /* ILO_FORMAT_H */
204