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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 **************************************************************************/ 27 28 29#ifndef LP_STATE_FS_H_ 30#define LP_STATE_FS_H_ 31 32 33#include "util/list.h" 34#include "pipe/p_compiler.h" 35#include "pipe/p_state.h" 36#include "tgsi/tgsi_scan.h" /* for tgsi_shader_info */ 37#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */ 38#include "gallivm/lp_bld_tgsi.h" /* for lp_tgsi_info */ 39#include "lp_bld_interp.h" /* for struct lp_shader_input */ 40#include "util/u_inlines.h" 41#include "lp_jit.h" 42 43struct tgsi_token; 44struct lp_fragment_shader; 45 46 47/** Indexes into jit_function[] array */ 48#define RAST_WHOLE 0 49#define RAST_EDGE_TEST 1 50 51 52enum lp_fs_kind 53{ 54 LP_FS_KIND_GENERAL = 0, 55 LP_FS_KIND_BLIT_RGBA, 56 LP_FS_KIND_BLIT_RGB1, 57 LP_FS_KIND_AERO_MINIFICATION, 58 LP_FS_KIND_LLVM_LINEAR 59}; 60 61 62struct lp_sampler_static_state 63{ 64 /* 65 * These attributes are effectively interleaved for more sane key handling. 66 * However, there might be lots of null space if the amount of samplers and 67 * textures isn't the same. 68 */ 69 struct lp_static_sampler_state sampler_state; 70 struct lp_static_texture_state texture_state; 71}; 72 73 74struct lp_image_static_state 75{ 76 struct lp_static_texture_state image_state; 77}; 78 79struct lp_depth_state 80{ 81 unsigned enabled:1; /**< depth test enabled? */ 82 unsigned writemask:1; /**< allow depth buffer writes? */ 83 unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ 84}; 85 86struct lp_fragment_shader_variant_key 87{ 88 struct lp_depth_state depth; 89 struct pipe_stencil_state stencil[2]; 90 struct pipe_blend_state blend; 91 92 struct { 93 unsigned enabled:1; 94 unsigned func:3; 95 } alpha; 96 97 unsigned nr_cbufs:8; 98 unsigned nr_samplers:8; /* actually derivable from just the shader */ 99 unsigned nr_sampler_views:8; /* actually derivable from just the shader */ 100 unsigned nr_images:8; /* actually derivable from just the shader */ 101 unsigned flatshade:1; 102 unsigned occlusion_count:1; 103 unsigned resource_1d:1; 104 unsigned depth_clamp:1; 105 unsigned multisample:1; 106 unsigned no_ms_sample_mask_out:1; 107 unsigned restrict_depth_values:1; 108 109 enum pipe_format zsbuf_format; 110 enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS]; 111 112 uint8_t cbuf_nr_samples[PIPE_MAX_COLOR_BUFS]; 113 uint8_t zsbuf_nr_samples; 114 uint8_t coverage_samples; 115 uint8_t min_samples; 116 /* followed by variable number of samplers + images */ 117}; 118 119#define LP_FS_MAX_VARIANT_KEY_SIZE \ 120 (sizeof(struct lp_fragment_shader_variant_key) + \ 121 PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct lp_sampler_static_state) +\ 122 PIPE_MAX_SHADER_IMAGES * sizeof(struct lp_image_static_state)) 123 124static inline size_t 125lp_fs_variant_key_size(unsigned nr_samplers, unsigned nr_images) 126{ 127 return (sizeof(struct lp_fragment_shader_variant_key) + 128 nr_samplers * sizeof(struct lp_sampler_static_state) + 129 nr_images * sizeof(struct lp_image_static_state)); 130} 131 132static inline struct lp_sampler_static_state * 133lp_fs_variant_key_samplers(const struct lp_fragment_shader_variant_key *key) 134{ 135 return (struct lp_sampler_static_state *)&(key[1]); 136} 137 138static inline struct lp_sampler_static_state * 139lp_fs_variant_key_sampler_idx(const struct lp_fragment_shader_variant_key *key, int idx) 140{ 141 if (idx >= key->nr_samplers) 142 return NULL; 143 return &lp_fs_variant_key_samplers(key)[idx]; 144} 145 146static inline struct lp_image_static_state * 147lp_fs_variant_key_images(struct lp_fragment_shader_variant_key *key) 148{ 149 return (struct lp_image_static_state *) 150 &(lp_fs_variant_key_samplers(key)[MAX2(key->nr_samplers, 151 key->nr_sampler_views)]); 152} 153 154/** doubly-linked list item */ 155struct lp_fs_variant_list_item 156{ 157 struct list_head list; 158 struct lp_fragment_shader_variant *base; 159}; 160 161 162struct lp_fragment_shader_variant 163{ 164 /* 165 * Whether some primitives can be opaque. 166 */ 167 unsigned potentially_opaque:1; 168 169 unsigned opaque:1; 170 unsigned blit:1; 171 unsigned linear_input_mask:16; 172 struct pipe_reference reference; 173 174 struct gallivm_state *gallivm; 175 176 LLVMTypeRef jit_context_ptr_type; 177 LLVMTypeRef jit_thread_data_ptr_type; 178 LLVMTypeRef jit_linear_context_ptr_type; 179 180 LLVMValueRef function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST] 181 182 lp_jit_frag_func jit_function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST] 183 184 lp_jit_linear_func jit_linear; 185 lp_jit_linear_func jit_linear_blit; 186 187 /* Functions within the linear path: 188 */ 189 LLVMValueRef linear_function; 190 lp_jit_linear_llvm_func jit_linear_llvm; 191 192 /* Bitmask to say what cbufs are unswizzled */ 193 unsigned unswizzled_cbufs; 194 195 /* Total number of LLVM instructions generated */ 196 unsigned nr_instrs; 197 198 struct lp_fs_variant_list_item list_item_global, list_item_local; 199 struct lp_fragment_shader *shader; 200 201 /* For debugging/profiling purposes */ 202 unsigned no; 203 204 /* key is variable-sized, must be last */ 205 struct lp_fragment_shader_variant_key key; 206}; 207 208 209/** Subclass of pipe_shader_state */ 210struct lp_fragment_shader 211{ 212 struct pipe_shader_state base; 213 214 struct pipe_reference reference; 215 struct lp_tgsi_info info; 216 217 /* Analysis results */ 218 enum lp_fs_kind kind; 219 220 struct lp_fs_variant_list_item variants; 221 222 struct draw_fragment_shader *draw_data; 223 224 /* For debugging/profiling purposes */ 225 unsigned variant_key_size; 226 unsigned no; 227 unsigned variants_created; 228 unsigned variants_cached; 229 230 /** Fragment shader input interpolation info */ 231 struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; 232}; 233 234 235void 236llvmpipe_fs_analyse_nir(struct lp_fragment_shader *shader); 237 238void 239llvmpipe_fs_analyse(struct lp_fragment_shader *shader, 240 const struct tgsi_token *tokens); 241 242void 243llvmpipe_fs_variant_fastpath(struct lp_fragment_shader_variant *variant); 244 245void 246llvmpipe_fs_variant_linear_fastpath(struct lp_fragment_shader_variant *variant); 247 248void 249llvmpipe_fs_variant_linear_llvm(struct llvmpipe_context *lp, 250 struct lp_fragment_shader *shader, 251 struct lp_fragment_shader_variant *variant); 252 253void 254lp_debug_fs_variant(struct lp_fragment_shader_variant *variant); 255 256const char * 257lp_debug_fs_kind(enum lp_fs_kind kind); 258 259void 260lp_linear_check_variant(struct lp_fragment_shader_variant *variant); 261 262void 263llvmpipe_destroy_fs(struct llvmpipe_context *llvmpipe, 264 struct lp_fragment_shader *shader); 265 266static inline void 267lp_fs_reference(struct llvmpipe_context *llvmpipe, 268 struct lp_fragment_shader **ptr, 269 struct lp_fragment_shader *shader) 270{ 271 struct lp_fragment_shader *old_ptr = *ptr; 272 if (pipe_reference(old_ptr ? &(*ptr)->reference : NULL, 273 shader ? &shader->reference : NULL)) { 274 llvmpipe_destroy_fs(llvmpipe, old_ptr); 275 } 276 *ptr = shader; 277} 278 279void 280llvmpipe_destroy_shader_variant(struct llvmpipe_context *lp, 281 struct lp_fragment_shader_variant *variant); 282 283static inline void 284lp_fs_variant_reference(struct llvmpipe_context *llvmpipe, 285 struct lp_fragment_shader_variant **ptr, 286 struct lp_fragment_shader_variant *variant) 287{ 288 struct lp_fragment_shader_variant *old_ptr = *ptr; 289 if (pipe_reference(old_ptr ? &(*ptr)->reference : NULL, 290 variant ? &variant->reference : NULL)) { 291 llvmpipe_destroy_shader_variant(llvmpipe, old_ptr); 292 } 293 *ptr = variant; 294} 295 296#endif /* LP_STATE_FS_H_ */ 297