1 /**************************************************************************** 2 * Copyright (C) 2015 Intel Corporation. All Rights Reserved. 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 ***************************************************************************/ 23 24 #ifndef SWR_STATE_H 25 #define SWR_STATE_H 26 27 #include "pipe/p_defines.h" 28 #include "tgsi/tgsi_scan.h" 29 #include "tgsi/tgsi_parse.h" 30 #include "tgsi/tgsi_dump.h" 31 #include "gallivm/lp_bld_init.h" 32 #include "gallivm/lp_bld_tgsi.h" 33 #include "util/crc32.h" 34 #include "api.h" 35 #include "swr_tex_sample.h" 36 #include "swr_shader.h" 37 #include <unordered_map> 38 #include <memory> 39 40 template <typename T> 41 struct ShaderVariant { 42 struct gallivm_state *gallivm; 43 T shader; 44 45 ShaderVariant(struct gallivm_state *gs, T code) : gallivm(gs), shader(code) {} 46 ~ShaderVariant() { gallivm_destroy(gallivm); } 47 }; 48 49 typedef ShaderVariant<PFN_VERTEX_FUNC> VariantVS; 50 typedef ShaderVariant<PFN_PIXEL_KERNEL> VariantFS; 51 typedef ShaderVariant<PFN_GS_FUNC> VariantGS; 52 53 /* skeleton */ 54 struct swr_vertex_shader { 55 struct pipe_shader_state pipe; 56 struct lp_tgsi_info info; 57 std::unordered_map<swr_jit_vs_key, std::unique_ptr<VariantVS>> map; 58 SWR_STREAMOUT_STATE soState; 59 PFN_SO_FUNC soFunc[PIPE_PRIM_MAX] {0}; 60 }; 61 62 struct swr_fragment_shader { 63 struct pipe_shader_state pipe; 64 struct lp_tgsi_info info; 65 uint32_t constantMask; 66 uint32_t flatConstantMask; 67 uint32_t pointSpriteMask; 68 std::unordered_map<swr_jit_fs_key, std::unique_ptr<VariantFS>> map; 69 }; 70 71 struct swr_geometry_shader { 72 struct pipe_shader_state pipe; 73 struct lp_tgsi_info info; 74 SWR_GS_STATE gsState; 75 76 std::unordered_map<swr_jit_gs_key, std::unique_ptr<VariantGS>> map; 77 }; 78 79 /* Vertex element state */ 80 struct swr_vertex_element_state { 81 FETCH_COMPILE_STATE fsState; 82 PFN_FETCH_FUNC fsFunc {NULL}; 83 uint32_t stream_pitch[PIPE_MAX_ATTRIBS] {0}; 84 uint32_t min_instance_div[PIPE_MAX_ATTRIBS] {0}; 85 uint32_t instanced_bufs {0}; 86 std::unordered_map<swr_jit_fetch_key, PFN_FETCH_FUNC> map; 87 }; 88 89 struct swr_blend_state { 90 struct pipe_blend_state pipe; 91 SWR_BLEND_STATE blendState; 92 RENDER_TARGET_BLEND_COMPILE_STATE compileState[PIPE_MAX_COLOR_BUFS]; 93 }; 94 95 struct swr_poly_stipple { 96 struct pipe_poly_stipple pipe; 97 bool prim_is_poly; 98 }; 99 100 /* 101 * Derived SWR API DrawState 102 * For convenience of making simple changes without re-deriving state. 103 */ 104 struct swr_derived_state { 105 SWR_RASTSTATE rastState; 106 SWR_VIEWPORT vp; 107 SWR_VIEWPORT_MATRICES vpm; 108 }; 109 110 void swr_update_derived(struct pipe_context *, 111 const struct pipe_draw_info * = nullptr); 112 113 /* 114 * Conversion functions: Convert mesa state defines to SWR. 115 */ 116 117 static INLINE SWR_LOGIC_OP 118 swr_convert_logic_op(const UINT op) 119 { 120 switch (op) { 121 case PIPE_LOGICOP_CLEAR: 122 return LOGICOP_CLEAR; 123 case PIPE_LOGICOP_NOR: 124 return LOGICOP_NOR; 125 case PIPE_LOGICOP_AND_INVERTED: 126 return LOGICOP_AND_INVERTED; 127 case PIPE_LOGICOP_COPY_INVERTED: 128 return LOGICOP_COPY_INVERTED; 129 case PIPE_LOGICOP_AND_REVERSE: 130 return LOGICOP_AND_REVERSE; 131 case PIPE_LOGICOP_INVERT: 132 return LOGICOP_INVERT; 133 case PIPE_LOGICOP_XOR: 134 return LOGICOP_XOR; 135 case PIPE_LOGICOP_NAND: 136 return LOGICOP_NAND; 137 case PIPE_LOGICOP_AND: 138 return LOGICOP_AND; 139 case PIPE_LOGICOP_EQUIV: 140 return LOGICOP_EQUIV; 141 case PIPE_LOGICOP_NOOP: 142 return LOGICOP_NOOP; 143 case PIPE_LOGICOP_OR_INVERTED: 144 return LOGICOP_OR_INVERTED; 145 case PIPE_LOGICOP_COPY: 146 return LOGICOP_COPY; 147 case PIPE_LOGICOP_OR_REVERSE: 148 return LOGICOP_OR_REVERSE; 149 case PIPE_LOGICOP_OR: 150 return LOGICOP_OR; 151 case PIPE_LOGICOP_SET: 152 return LOGICOP_SET; 153 default: 154 assert(0 && "Unsupported logic op"); 155 return LOGICOP_NOOP; 156 } 157 } 158 159 static INLINE SWR_STENCILOP 160 swr_convert_stencil_op(const UINT op) 161 { 162 switch (op) { 163 case PIPE_STENCIL_OP_KEEP: 164 return STENCILOP_KEEP; 165 case PIPE_STENCIL_OP_ZERO: 166 return STENCILOP_ZERO; 167 case PIPE_STENCIL_OP_REPLACE: 168 return STENCILOP_REPLACE; 169 case PIPE_STENCIL_OP_INCR: 170 return STENCILOP_INCRSAT; 171 case PIPE_STENCIL_OP_DECR: 172 return STENCILOP_DECRSAT; 173 case PIPE_STENCIL_OP_INCR_WRAP: 174 return STENCILOP_INCR; 175 case PIPE_STENCIL_OP_DECR_WRAP: 176 return STENCILOP_DECR; 177 case PIPE_STENCIL_OP_INVERT: 178 return STENCILOP_INVERT; 179 default: 180 assert(0 && "Unsupported stencil op"); 181 return STENCILOP_KEEP; 182 } 183 } 184 185 static INLINE SWR_FORMAT 186 swr_convert_index_type(const UINT index_size) 187 { 188 switch (index_size) { 189 case sizeof(unsigned char): 190 return R8_UINT; 191 case sizeof(unsigned short): 192 return R16_UINT; 193 case sizeof(unsigned int): 194 return R32_UINT; 195 default: 196 assert(0 && "Unsupported index type"); 197 return R32_UINT; 198 } 199 } 200 201 202 static INLINE SWR_ZFUNCTION 203 swr_convert_depth_func(const UINT pipe_func) 204 { 205 switch (pipe_func) { 206 case PIPE_FUNC_NEVER: 207 return ZFUNC_NEVER; 208 case PIPE_FUNC_LESS: 209 return ZFUNC_LT; 210 case PIPE_FUNC_EQUAL: 211 return ZFUNC_EQ; 212 case PIPE_FUNC_LEQUAL: 213 return ZFUNC_LE; 214 case PIPE_FUNC_GREATER: 215 return ZFUNC_GT; 216 case PIPE_FUNC_NOTEQUAL: 217 return ZFUNC_NE; 218 case PIPE_FUNC_GEQUAL: 219 return ZFUNC_GE; 220 case PIPE_FUNC_ALWAYS: 221 return ZFUNC_ALWAYS; 222 default: 223 assert(0 && "Unsupported depth func"); 224 return ZFUNC_ALWAYS; 225 } 226 } 227 228 229 static INLINE SWR_CULLMODE 230 swr_convert_cull_mode(const UINT cull_face) 231 { 232 switch (cull_face) { 233 case PIPE_FACE_NONE: 234 return SWR_CULLMODE_NONE; 235 case PIPE_FACE_FRONT: 236 return SWR_CULLMODE_FRONT; 237 case PIPE_FACE_BACK: 238 return SWR_CULLMODE_BACK; 239 case PIPE_FACE_FRONT_AND_BACK: 240 return SWR_CULLMODE_BOTH; 241 default: 242 assert(0 && "Invalid cull mode"); 243 return SWR_CULLMODE_NONE; 244 } 245 } 246 247 static INLINE SWR_BLEND_OP 248 swr_convert_blend_func(const UINT blend_func) 249 { 250 switch (blend_func) { 251 case PIPE_BLEND_ADD: 252 return BLENDOP_ADD; 253 case PIPE_BLEND_SUBTRACT: 254 return BLENDOP_SUBTRACT; 255 case PIPE_BLEND_REVERSE_SUBTRACT: 256 return BLENDOP_REVSUBTRACT; 257 case PIPE_BLEND_MIN: 258 return BLENDOP_MIN; 259 case PIPE_BLEND_MAX: 260 return BLENDOP_MAX; 261 default: 262 assert(0 && "Invalid blend func"); 263 return BLENDOP_ADD; 264 } 265 } 266 267 static INLINE SWR_BLEND_FACTOR 268 swr_convert_blend_factor(const UINT blend_factor) 269 { 270 switch (blend_factor) { 271 case PIPE_BLENDFACTOR_ONE: 272 return BLENDFACTOR_ONE; 273 case PIPE_BLENDFACTOR_SRC_COLOR: 274 return BLENDFACTOR_SRC_COLOR; 275 case PIPE_BLENDFACTOR_SRC_ALPHA: 276 return BLENDFACTOR_SRC_ALPHA; 277 case PIPE_BLENDFACTOR_DST_ALPHA: 278 return BLENDFACTOR_DST_ALPHA; 279 case PIPE_BLENDFACTOR_DST_COLOR: 280 return BLENDFACTOR_DST_COLOR; 281 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 282 return BLENDFACTOR_SRC_ALPHA_SATURATE; 283 case PIPE_BLENDFACTOR_CONST_COLOR: 284 return BLENDFACTOR_CONST_COLOR; 285 case PIPE_BLENDFACTOR_CONST_ALPHA: 286 return BLENDFACTOR_CONST_ALPHA; 287 case PIPE_BLENDFACTOR_SRC1_COLOR: 288 return BLENDFACTOR_SRC1_COLOR; 289 case PIPE_BLENDFACTOR_SRC1_ALPHA: 290 return BLENDFACTOR_SRC1_ALPHA; 291 case PIPE_BLENDFACTOR_ZERO: 292 return BLENDFACTOR_ZERO; 293 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 294 return BLENDFACTOR_INV_SRC_COLOR; 295 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 296 return BLENDFACTOR_INV_SRC_ALPHA; 297 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 298 return BLENDFACTOR_INV_DST_ALPHA; 299 case PIPE_BLENDFACTOR_INV_DST_COLOR: 300 return BLENDFACTOR_INV_DST_COLOR; 301 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 302 return BLENDFACTOR_INV_CONST_COLOR; 303 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 304 return BLENDFACTOR_INV_CONST_ALPHA; 305 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 306 return BLENDFACTOR_INV_SRC1_COLOR; 307 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 308 return BLENDFACTOR_INV_SRC1_ALPHA; 309 default: 310 assert(0 && "Invalid blend factor"); 311 return BLENDFACTOR_ONE; 312 } 313 } 314 315 static INLINE enum SWR_SURFACE_TYPE 316 swr_convert_target_type(const enum pipe_texture_target target) 317 { 318 switch (target) { 319 case PIPE_BUFFER: 320 return SURFACE_BUFFER; 321 case PIPE_TEXTURE_1D: 322 case PIPE_TEXTURE_1D_ARRAY: 323 return SURFACE_1D; 324 case PIPE_TEXTURE_2D: 325 case PIPE_TEXTURE_2D_ARRAY: 326 case PIPE_TEXTURE_RECT: 327 return SURFACE_2D; 328 case PIPE_TEXTURE_3D: 329 return SURFACE_3D; 330 case PIPE_TEXTURE_CUBE: 331 case PIPE_TEXTURE_CUBE_ARRAY: 332 return SURFACE_CUBE; 333 default: 334 assert(0); 335 return SURFACE_NULL; 336 } 337 } 338 339 /* 340 * Convert mesa PIPE_PRIM_X to SWR enum PRIMITIVE_TOPOLOGY 341 */ 342 static INLINE enum PRIMITIVE_TOPOLOGY 343 swr_convert_prim_topology(const unsigned mode) 344 { 345 switch (mode) { 346 case PIPE_PRIM_POINTS: 347 return TOP_POINT_LIST; 348 case PIPE_PRIM_LINES: 349 return TOP_LINE_LIST; 350 case PIPE_PRIM_LINE_LOOP: 351 return TOP_LINE_LOOP; 352 case PIPE_PRIM_LINE_STRIP: 353 return TOP_LINE_STRIP; 354 case PIPE_PRIM_TRIANGLES: 355 return TOP_TRIANGLE_LIST; 356 case PIPE_PRIM_TRIANGLE_STRIP: 357 return TOP_TRIANGLE_STRIP; 358 case PIPE_PRIM_TRIANGLE_FAN: 359 return TOP_TRIANGLE_FAN; 360 case PIPE_PRIM_QUADS: 361 return TOP_QUAD_LIST; 362 case PIPE_PRIM_QUAD_STRIP: 363 return TOP_QUAD_STRIP; 364 case PIPE_PRIM_POLYGON: 365 return TOP_TRIANGLE_FAN; /* XXX TOP_POLYGON; */ 366 case PIPE_PRIM_LINES_ADJACENCY: 367 return TOP_LINE_LIST_ADJ; 368 case PIPE_PRIM_LINE_STRIP_ADJACENCY: 369 return TOP_LISTSTRIP_ADJ; 370 case PIPE_PRIM_TRIANGLES_ADJACENCY: 371 return TOP_TRI_LIST_ADJ; 372 case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 373 return TOP_TRI_STRIP_ADJ; 374 default: 375 assert(0 && "Unknown topology"); 376 return TOP_UNKNOWN; 377 } 378 }; 379 380 /* 381 * convert mesa PIPE_POLYGON_MODE_X to SWR enum SWR_FILLMODE 382 */ 383 static INLINE enum SWR_FILLMODE 384 swr_convert_fill_mode(const unsigned mode) 385 { 386 switch(mode) { 387 case PIPE_POLYGON_MODE_FILL: 388 return SWR_FILLMODE_SOLID; 389 case PIPE_POLYGON_MODE_LINE: 390 return SWR_FILLMODE_WIREFRAME; 391 case PIPE_POLYGON_MODE_POINT: 392 return SWR_FILLMODE_POINT; 393 default: 394 assert(0 && "Unknown fillmode"); 395 return SWR_FILLMODE_SOLID; // at least do something sensible 396 } 397 } 398 399 #endif 400