diff options
Diffstat (limited to 'src/gallium/frontends/nine/nine_shader.h')
-rw-r--r-- | src/gallium/frontends/nine/nine_shader.h | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/src/gallium/frontends/nine/nine_shader.h b/src/gallium/frontends/nine/nine_shader.h new file mode 100644 index 00000000000..5abdbe24472 --- /dev/null +++ b/src/gallium/frontends/nine/nine_shader.h @@ -0,0 +1,327 @@ +/* + * Copyright 2011 Joakim Sindholt <[email protected]> + * + * 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 "nine_state.h" +#include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */ +#include "util/u_memory.h" + +struct NineDevice9; +struct NineVertexDeclaration9; +struct ureg_program; + +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_constant_combination; + +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; + uint8_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; + + boolean int_slots_used[NINE_MAX_CONST_I]; + boolean bool_slots_used[NINE_MAX_CONST_B]; + + unsigned const_float_slots; + unsigned const_int_slots; + unsigned const_bool_slots; + + unsigned *const_ranges; + + struct nine_lconstf lconstf; /* out, NOTE: members to be free'd by user */ + uint8_t bumpenvmat_needed; + + struct { + struct nine_shader_constant_combination* c_combination; + boolean (*int_const_added)[NINE_MAX_CONST_I]; + boolean (*bool_const_added)[NINE_MAX_CONST_B]; + } add_constants_defs; + + 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; +}; + +void * +nine_create_shader_with_so_and_destroy(struct ureg_program *p, + struct pipe_context *pipe, + const struct pipe_stream_output_info *so); + +HRESULT +nine_translate_shader(struct NineDevice9 *device, + struct nine_shader_info *, + struct pipe_context *); + + +struct nine_shader_variant +{ + struct nine_shader_variant *next; + void *cso; + unsigned *const_ranges; + unsigned const_used_size; + uint64_t key; +}; + +static inline void * +nine_shader_variant_get(struct nine_shader_variant *list, + unsigned **const_ranges, + unsigned *const_used_size, + uint64_t key) +{ + while (list->key != key && list->next) + list = list->next; + if (list->key == key) { + *const_ranges = list->const_ranges; + *const_used_size = list->const_used_size; + return list->cso; + } + return NULL; +} + +static inline boolean +nine_shader_variant_add(struct nine_shader_variant *list, + uint64_t key, void *cso, + unsigned *const_ranges, + unsigned const_used_size) +{ + 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; + list->next->const_ranges = const_ranges; + list->next->const_used_size = const_used_size; + 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); +} + +struct nine_shader_constant_combination +{ + struct nine_shader_constant_combination *next; + int const_i[NINE_MAX_CONST_I][4]; + BOOL const_b[NINE_MAX_CONST_B]; +}; + +#define NINE_MAX_CONSTANT_COMBINATION_VARIANTS 32 + +static inline uint8_t +nine_shader_constant_combination_key(struct nine_shader_constant_combination **list, + boolean *int_slots_used, + boolean *bool_slots_used, + int *const_i, + BOOL *const_b) +{ + int i; + uint8_t index = 0; + boolean match; + struct nine_shader_constant_combination **next_allocate = list, *current = *list; + + assert(int_slots_used); + assert(bool_slots_used); + assert(const_i); + assert(const_b); + + while (current) { + index++; /* start at 1. 0 is for the variant without constant replacement */ + match = TRUE; + for (i = 0; i < NINE_MAX_CONST_I; ++i) { + if (int_slots_used[i]) + match &= !memcmp(const_i + 4*i, current->const_i[i], sizeof(current->const_i[0])); + } + for (i = 0; i < NINE_MAX_CONST_B; ++i) { + if (bool_slots_used[i]) + match &= const_b[i] == current->const_b[i]; + } + if (match) + return index; + next_allocate = ¤t->next; + current = current->next; + } + + if (index < NINE_MAX_CONSTANT_COMBINATION_VARIANTS) { + *next_allocate = MALLOC_STRUCT(nine_shader_constant_combination); + current = *next_allocate; + index++; + current->next = NULL; + memcpy(current->const_i, const_i, sizeof(current->const_i)); + memcpy(current->const_b, const_b, sizeof(current->const_b)); + return index; + } + + return 0; /* Too many variants, revert to no replacement */ +} + +static inline struct nine_shader_constant_combination * +nine_shader_constant_combination_get(struct nine_shader_constant_combination *list, uint8_t index) +{ + if (index == 0) + return NULL; + while (index) { + assert(list != NULL); + index--; + if (index == 0) + return list; + list = list->next; + } + assert(FALSE); + return NULL; +} + +static inline void +nine_shader_constant_combination_free(struct nine_shader_constant_combination *list) +{ + if (!list) + return; + + while (list->next) { + struct nine_shader_constant_combination *ptr = list->next; + list->next = ptr->next; + FREE(ptr); + } + + FREE(list); +} + +#endif /* _NINE_SHADER_H_ */ |