aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/frontends/nine/nine_shader.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/frontends/nine/nine_shader.h')
-rw-r--r--src/gallium/frontends/nine/nine_shader.h327
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 = &current->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_ */