1 /* 2 * Copyright 2011 Joakim Sindholt <opensource (at) zhasha.com> 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 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23 #ifndef _NINE_SHADER_H_ 24 #define _NINE_SHADER_H_ 25 26 #include "d3d9types.h" 27 #include "d3d9caps.h" 28 #include "nine_defines.h" 29 #include "nine_helpers.h" 30 #include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */ 31 #include "util/u_memory.h" 32 33 struct NineDevice9; 34 struct NineVertexDeclaration9; 35 36 struct nine_lconstf /* NOTE: both pointers should be FREE'd by the user */ 37 { 38 struct nine_range *ranges; /* single MALLOC, but next-pointers valid */ 39 float *data; 40 }; 41 42 struct nine_shader_info 43 { 44 unsigned type; /* in, PIPE_SHADER_x */ 45 46 uint8_t version; /* (major << 4) | minor */ 47 48 const DWORD *byte_code; /* in, pointer to shader tokens */ 49 DWORD byte_size; /* out, size of data at byte_code */ 50 51 void *cso; /* out, pipe cso for bind_vs,fs_state */ 52 53 uint16_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */ 54 uint8_t num_inputs; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */ 55 56 boolean position_t; /* out, true if VP writes pre-transformed position */ 57 boolean point_size; /* out, true if VP writes point size */ 58 float point_size_min; 59 float point_size_max; 60 61 uint32_t sampler_ps1xtypes; /* 2 bits per sampler */ 62 uint16_t sampler_mask; /* out, which samplers are being used */ 63 uint16_t sampler_mask_shadow; /* in, which samplers use depth compare */ 64 uint8_t rt_mask; /* out, which render targets are being written */ 65 66 uint8_t fog_enable; 67 uint8_t fog_mode; 68 uint8_t force_color_in_centroid; 69 uint16_t projected; /* ps 1.1 to 1.3 */ 70 71 unsigned const_i_base; /* in vec4 (16 byte) units */ 72 unsigned const_b_base; /* in vec4 (16 byte) units */ 73 unsigned const_used_size; 74 75 unsigned const_float_slots; 76 unsigned const_int_slots; 77 unsigned const_bool_slots; 78 79 struct nine_lconstf lconstf; /* out, NOTE: members to be free'd by user */ 80 uint8_t bumpenvmat_needed; 81 82 boolean swvp_on; 83 84 boolean process_vertices; 85 struct NineVertexDeclaration9 *vdecl_out; 86 struct pipe_stream_output_info so; 87 }; 88 89 struct nine_vs_output_info 90 { 91 BYTE output_semantic; 92 int output_semantic_index; 93 int mask; 94 int output_index; 95 }; 96 97 static inline void 98 nine_info_mark_const_f_used(struct nine_shader_info *info, int idx) 99 { 100 if (info->const_float_slots < (idx + 1)) 101 info->const_float_slots = idx + 1; 102 } 103 static inline void 104 nine_info_mark_const_i_used(struct nine_shader_info *info, int idx) 105 { 106 if (info->const_int_slots < (idx + 1)) 107 info->const_int_slots = idx + 1; 108 } 109 static inline void 110 nine_info_mark_const_b_used(struct nine_shader_info *info, int idx) 111 { 112 if (info->const_bool_slots < (idx + 1)) 113 info->const_bool_slots = idx + 1; 114 } 115 116 HRESULT 117 nine_translate_shader(struct NineDevice9 *device, 118 struct nine_shader_info *, 119 struct pipe_context *); 120 121 122 struct nine_shader_variant 123 { 124 struct nine_shader_variant *next; 125 void *cso; 126 uint64_t key; 127 }; 128 129 static inline void * 130 nine_shader_variant_get(struct nine_shader_variant *list, uint64_t key) 131 { 132 while (list->key != key && list->next) 133 list = list->next; 134 if (list->key == key) 135 return list->cso; 136 return NULL; 137 } 138 139 static inline boolean 140 nine_shader_variant_add(struct nine_shader_variant *list, 141 uint64_t key, void *cso) 142 { 143 while (list->next) { 144 assert(list->key != key); 145 list = list->next; 146 } 147 list->next = MALLOC_STRUCT(nine_shader_variant); 148 if (!list->next) 149 return FALSE; 150 list->next->next = NULL; 151 list->next->key = key; 152 list->next->cso = cso; 153 return TRUE; 154 } 155 156 static inline void 157 nine_shader_variants_free(struct nine_shader_variant *list) 158 { 159 while (list->next) { 160 struct nine_shader_variant *ptr = list->next; 161 list->next = ptr->next; 162 FREE(ptr); 163 } 164 } 165 166 struct nine_shader_variant_so 167 { 168 struct nine_shader_variant_so *next; 169 struct NineVertexDeclaration9 *vdecl; 170 struct pipe_stream_output_info so; 171 void *cso; 172 }; 173 174 static inline void * 175 nine_shader_variant_so_get(struct nine_shader_variant_so *list, 176 struct NineVertexDeclaration9 *vdecl, 177 struct pipe_stream_output_info *so) 178 { 179 while (list->vdecl != vdecl && list->next) 180 list = list->next; 181 if (list->vdecl == vdecl) { 182 *so = list->so; 183 return list->cso; 184 } 185 return NULL; 186 } 187 188 static inline boolean 189 nine_shader_variant_so_add(struct nine_shader_variant_so *list, 190 struct NineVertexDeclaration9 *vdecl, 191 struct pipe_stream_output_info *so, void *cso) 192 { 193 if (list->vdecl == NULL) { /* first shader */ 194 list->next = NULL; 195 nine_bind(&list->vdecl, vdecl); 196 list->so = *so; 197 list->cso = cso; 198 return TRUE; 199 } 200 while (list->next) { 201 assert(list->vdecl != vdecl); 202 list = list->next; 203 } 204 list->next = MALLOC_STRUCT(nine_shader_variant_so); 205 if (!list->next) 206 return FALSE; 207 list->next->next = NULL; 208 nine_bind(&list->vdecl, vdecl); 209 list->next->so = *so; 210 list->next->cso = cso; 211 return TRUE; 212 } 213 214 static inline void 215 nine_shader_variants_so_free(struct nine_shader_variant_so *list) 216 { 217 while (list->next) { 218 struct nine_shader_variant_so *ptr = list->next; 219 list->next = ptr->next; 220 nine_bind(&ptr->vdecl, NULL); 221 FREE(ptr); 222 } 223 if (list->vdecl) 224 nine_bind(&list->vdecl, NULL); 225 } 226 227 #endif /* _NINE_SHADER_H_ */ 228