Home | History | Annotate | Download | only in nine
      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