| /* |
| * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * on the rights to use, copy, modify, merge, publish, distribute, sub |
| * license, and/or sell copies of the Software, and to permit persons to whom |
| * the Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, |
| * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
| * USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
| |
| #ifndef _NINE_SHADER_H_ |
| #define _NINE_SHADER_H_ |
| |
| #include "d3d9types.h" |
| #include "d3d9caps.h" |
| #include "nine_defines.h" |
| #include "nine_helpers.h" |
| #include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */ |
| #include "util/u_memory.h" |
| |
| struct NineDevice9; |
| struct NineVertexDeclaration9; |
| |
| struct nine_lconstf /* NOTE: both pointers should be FREE'd by the user */ |
| { |
| struct nine_range *ranges; /* single MALLOC, but next-pointers valid */ |
| float *data; |
| }; |
| |
| struct nine_shader_info |
| { |
| unsigned type; /* in, PIPE_SHADER_x */ |
| |
| uint8_t version; /* (major << 4) | minor */ |
| |
| const DWORD *byte_code; /* in, pointer to shader tokens */ |
| DWORD byte_size; /* out, size of data at byte_code */ |
| |
| void *cso; /* out, pipe cso for bind_vs,fs_state */ |
| |
| uint16_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */ |
| uint8_t num_inputs; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */ |
| |
| boolean position_t; /* out, true if VP writes pre-transformed position */ |
| boolean point_size; /* out, true if VP writes point size */ |
| float point_size_min; |
| float point_size_max; |
| |
| uint32_t sampler_ps1xtypes; /* 2 bits per sampler */ |
| uint16_t sampler_mask; /* out, which samplers are being used */ |
| uint16_t sampler_mask_shadow; /* in, which samplers use depth compare */ |
| uint8_t rt_mask; /* out, which render targets are being written */ |
| |
| uint8_t fog_enable; |
| uint8_t fog_mode; |
| uint8_t force_color_in_centroid; |
| uint16_t projected; /* ps 1.1 to 1.3 */ |
| |
| unsigned const_i_base; /* in vec4 (16 byte) units */ |
| unsigned const_b_base; /* in vec4 (16 byte) units */ |
| unsigned const_used_size; |
| |
| unsigned const_float_slots; |
| unsigned const_int_slots; |
| unsigned const_bool_slots; |
| |
| struct nine_lconstf lconstf; /* out, NOTE: members to be free'd by user */ |
| uint8_t bumpenvmat_needed; |
| |
| boolean swvp_on; |
| |
| boolean process_vertices; |
| struct NineVertexDeclaration9 *vdecl_out; |
| struct pipe_stream_output_info so; |
| }; |
| |
| struct nine_vs_output_info |
| { |
| BYTE output_semantic; |
| int output_semantic_index; |
| int mask; |
| int output_index; |
| }; |
| |
| static inline void |
| nine_info_mark_const_f_used(struct nine_shader_info *info, int idx) |
| { |
| if (info->const_float_slots < (idx + 1)) |
| info->const_float_slots = idx + 1; |
| } |
| static inline void |
| nine_info_mark_const_i_used(struct nine_shader_info *info, int idx) |
| { |
| if (info->const_int_slots < (idx + 1)) |
| info->const_int_slots = idx + 1; |
| } |
| static inline void |
| nine_info_mark_const_b_used(struct nine_shader_info *info, int idx) |
| { |
| if (info->const_bool_slots < (idx + 1)) |
| info->const_bool_slots = idx + 1; |
| } |
| |
| HRESULT |
| nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *); |
| |
| |
| struct nine_shader_variant |
| { |
| struct nine_shader_variant *next; |
| void *cso; |
| uint64_t key; |
| }; |
| |
| static inline void * |
| nine_shader_variant_get(struct nine_shader_variant *list, uint64_t key) |
| { |
| while (list->key != key && list->next) |
| list = list->next; |
| if (list->key == key) |
| return list->cso; |
| return NULL; |
| } |
| |
| static inline boolean |
| nine_shader_variant_add(struct nine_shader_variant *list, |
| uint64_t key, void *cso) |
| { |
| while (list->next) { |
| assert(list->key != key); |
| list = list->next; |
| } |
| list->next = MALLOC_STRUCT(nine_shader_variant); |
| if (!list->next) |
| return FALSE; |
| list->next->next = NULL; |
| list->next->key = key; |
| list->next->cso = cso; |
| return TRUE; |
| } |
| |
| static inline void |
| nine_shader_variants_free(struct nine_shader_variant *list) |
| { |
| while (list->next) { |
| struct nine_shader_variant *ptr = list->next; |
| list->next = ptr->next; |
| FREE(ptr); |
| } |
| } |
| |
| struct nine_shader_variant_so |
| { |
| struct nine_shader_variant_so *next; |
| struct NineVertexDeclaration9 *vdecl; |
| struct pipe_stream_output_info so; |
| void *cso; |
| }; |
| |
| static inline void * |
| nine_shader_variant_so_get(struct nine_shader_variant_so *list, |
| struct NineVertexDeclaration9 *vdecl, |
| struct pipe_stream_output_info *so) |
| { |
| while (list->vdecl != vdecl && list->next) |
| list = list->next; |
| if (list->vdecl == vdecl) { |
| *so = list->so; |
| return list->cso; |
| } |
| return NULL; |
| } |
| |
| static inline boolean |
| nine_shader_variant_so_add(struct nine_shader_variant_so *list, |
| struct NineVertexDeclaration9 *vdecl, |
| struct pipe_stream_output_info *so, void *cso) |
| { |
| if (list->vdecl == NULL) { /* first shader */ |
| list->next = NULL; |
| nine_bind(&list->vdecl, vdecl); |
| list->so = *so; |
| list->cso = cso; |
| return TRUE; |
| } |
| while (list->next) { |
| assert(list->vdecl != vdecl); |
| list = list->next; |
| } |
| list->next = MALLOC_STRUCT(nine_shader_variant_so); |
| if (!list->next) |
| return FALSE; |
| list->next->next = NULL; |
| nine_bind(&list->vdecl, vdecl); |
| list->next->so = *so; |
| list->next->cso = cso; |
| return TRUE; |
| } |
| |
| static inline void |
| nine_shader_variants_so_free(struct nine_shader_variant_so *list) |
| { |
| while (list->next) { |
| struct nine_shader_variant_so *ptr = list->next; |
| list->next = ptr->next; |
| nine_bind(&ptr->vdecl, NULL); |
| FREE(ptr); |
| } |
| if (list->vdecl) |
| nine_bind(&list->vdecl, NULL); |
| } |
| |
| #endif /* _NINE_SHADER_H_ */ |