u_caps.c revision e968975cb57eb854769292f7c6ff773c64a386c3
1/************************************************************************** 2 * 3 * Copyright 2010 Vmware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "pipe/p_screen.h" 29#include "util/u_format.h" 30#include "util/u_debug.h" 31#include "u_caps.h" 32 33/** 34 * Iterates over a list of caps checks as defined in u_caps.h. Should 35 * all checks pass returns TRUE and out is set to the last element of 36 * the list (TERMINATE). Should any check fail returns FALSE and set 37 * out to the index of the start of the first failing check. 38 */ 39boolean 40util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) 41{ 42 int i, tmpi; 43 float tmpf; 44 45 for (i = 0; list[i];) { 46 switch(list[i++]) { 47 case UTIL_CAPS_CHECK_CAP: 48 if (!screen->get_param(screen, list[i++])) { 49 *out = i - 2; 50 return FALSE; 51 } 52 break; 53 case UTIL_CAPS_CHECK_INT: 54 tmpi = screen->get_param(screen, list[i++]); 55 if (tmpi < (int)list[i++]) { 56 *out = i - 3; 57 return FALSE; 58 } 59 break; 60 case UTIL_CAPS_CHECK_FLOAT: 61 tmpf = screen->get_paramf(screen, list[i++]); 62 if (tmpf < (float)list[i++]) { 63 *out = i - 3; 64 return FALSE; 65 } 66 break; 67 case UTIL_CAPS_CHECK_FORMAT: 68 if (!screen->is_format_supported(screen, 69 list[i++], 70 PIPE_TEXTURE_2D, 71 0, 72 PIPE_BIND_SAMPLER_VIEW)) { 73 *out = i - 2; 74 return FALSE; 75 } 76 break; 77 case UTIL_CAPS_CHECK_SHADER: 78 tmpi = screen->get_shader_param(screen, list[i] >> 24, list[i] & ((1 << 24) - 1)); 79 ++i; 80 if (tmpi < (int)list[i++]) { 81 *out = i - 3; 82 return FALSE; 83 } 84 break; 85 case UTIL_CAPS_CHECK_UNIMPLEMENTED: 86 *out = i - 1; 87 return FALSE; 88 default: 89 assert(!"Unsupported check"); 90 return FALSE; 91 } 92 } 93 94 *out = i; 95 return TRUE; 96} 97 98/** 99 * Iterates over a list of caps checks as defined in u_caps.h. 100 * Returns TRUE if all caps checks pass returns FALSE otherwise. 101 */ 102boolean 103util_check_caps(struct pipe_screen *screen, const unsigned *list) 104{ 105 int out; 106 return util_check_caps_out(screen, list, &out); 107} 108 109 110/* 111 * Below follows some demo lists. 112 * 113 * None of these lists are exhausting lists of what is 114 * actually needed to support said API and more here for 115 * as example on how to uses the above functions. Especially 116 * for DX10 and DX11 where Gallium is missing features. 117 */ 118 119/* DX 9_1 */ 120static unsigned caps_dx_9_1[] = { 121 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), 122 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ 123 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ 124 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ 125 UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 2), 126 UTIL_CHECK_TERMINATE 127}; 128 129/* DX 9_2 */ 130static unsigned caps_dx_9_2[] = { 131 UTIL_CHECK_CAP(OCCLUSION_QUERY), 132 UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), 133 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), 134 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ 135 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ 136 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ 137 UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), 138 UTIL_CHECK_TERMINATE 139}; 140 141/* DX 9_3 */ 142static unsigned caps_dx_9_3[] = { 143 UTIL_CHECK_CAP(SM3), 144 //UTIL_CHECK_CAP(INSTANCING), 145 UTIL_CHECK_CAP(OCCLUSION_QUERY), 146 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4), 147 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), /* 4096 */ 148 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ 149 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ 150 UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), 151 UTIL_CHECK_TERMINATE 152}; 153 154/* DX 10 */ 155static unsigned caps_dx_10[] = { 156 UTIL_CHECK_CAP(SM3), 157 //UTIL_CHECK_CAP(INSTANCING), 158 UTIL_CHECK_CAP(OCCLUSION_QUERY), 159 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), 160 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 8192 */ 161 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ 162 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 8192 */ 163 UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), 164 UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ 165 UTIL_CHECK_TERMINATE 166}; 167 168/* DX11 */ 169static unsigned caps_dx_11[] = { 170 UTIL_CHECK_CAP(SM3), 171 //UTIL_CHECK_CAP(INSTANCING), 172 UTIL_CHECK_CAP(OCCLUSION_QUERY), 173 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), 174 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 16384 */ 175 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ 176 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 16384 */ 177 UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), 178 UTIL_CHECK_FORMAT(B8G8R8A8_UNORM), 179 UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ 180 UTIL_CHECK_TERMINATE 181}; 182 183/* OpenGL 2.1 */ 184static unsigned caps_opengl_2_1[] = { 185 UTIL_CHECK_CAP(GLSL), 186 UTIL_CHECK_CAP(OCCLUSION_QUERY), 187 UTIL_CHECK_CAP(TWO_SIDED_STENCIL), 188 UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), 189 UTIL_CHECK_INT(MAX_RENDER_TARGETS, 2), 190 UTIL_CHECK_TERMINATE 191}; 192 193/* OpenGL 3.0 */ 194/* UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), */ 195 196/* Shader Model 3 */ 197static unsigned caps_sm3[] = { 198 UTIL_CHECK_SHADER(FRAGMENT, MAX_INSTRUCTIONS, 512), 199 UTIL_CHECK_SHADER(FRAGMENT, MAX_INPUTS, 10), 200 UTIL_CHECK_SHADER(FRAGMENT, MAX_TEMPS, 32), 201 UTIL_CHECK_SHADER(FRAGMENT, MAX_ADDRS, 1), 202 UTIL_CHECK_SHADER(FRAGMENT, MAX_CONSTS, 224), 203 204 UTIL_CHECK_SHADER(VERTEX, MAX_INSTRUCTIONS, 512), 205 UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16), 206 UTIL_CHECK_SHADER(VERTEX, MAX_TEMPS, 32), 207 UTIL_CHECK_SHADER(VERTEX, MAX_ADDRS, 2), 208 UTIL_CHECK_SHADER(VERTEX, MAX_CONSTS, 256), 209 210 UTIL_CHECK_TERMINATE 211}; 212 213/** 214 * Demo function which checks against theoretical caps needed for different APIs. 215 */ 216void util_caps_demo_print(struct pipe_screen *screen) 217{ 218 struct { 219 char* name; 220 unsigned *list; 221 } list[] = { 222 {"DX 9.1", caps_dx_9_1}, 223 {"DX 9.2", caps_dx_9_2}, 224 {"DX 9.3", caps_dx_9_3}, 225 {"DX 10", caps_dx_10}, 226 {"DX 11", caps_dx_11}, 227 {"OpenGL 2.1", caps_opengl_2_1}, 228/* {"OpenGL 3.0", caps_opengl_3_0},*/ 229 {"SM3", caps_sm3}, 230 {NULL, NULL} 231 }; 232 int i, out = 0; 233 234 for (i = 0; list[i].name; i++) { 235 if (util_check_caps_out(screen, list[i].list, &out)) { 236 debug_printf("%s: %s yes\n", __FUNCTION__, list[i].name); 237 continue; 238 } 239 switch (list[i].list[out]) { 240 case UTIL_CAPS_CHECK_CAP: 241 debug_printf("%s: %s no (cap %u not supported)\n", __FUNCTION__, 242 list[i].name, 243 list[i].list[out + 1]); 244 break; 245 case UTIL_CAPS_CHECK_INT: 246 debug_printf("%s: %s no (cap %u less then %u)\n", __FUNCTION__, 247 list[i].name, 248 list[i].list[out + 1], 249 list[i].list[out + 2]); 250 break; 251 case UTIL_CAPS_CHECK_FLOAT: 252 debug_printf("%s: %s no (cap %u less then %f)\n", __FUNCTION__, 253 list[i].name, 254 list[i].list[out + 1], 255 (double)(int)list[i].list[out + 2]); 256 break; 257 case UTIL_CAPS_CHECK_FORMAT: 258 debug_printf("%s: %s no (format %s not supported)\n", __FUNCTION__, 259 list[i].name, 260 util_format_name(list[i].list[out + 1]) + 12); 261 break; 262 case UTIL_CAPS_CHECK_UNIMPLEMENTED: 263 debug_printf("%s: %s no (not implemented in gallium or state tracker)\n", 264 __FUNCTION__, list[i].name); 265 break; 266 default: 267 assert(!"Unsupported check"); 268 } 269 } 270} 271