• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © Microsoft Corporation
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  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #ifndef SPIRV_TO_DXIL_H
25 #define SPIRV_TO_DXIL_H
26 
27 #include "dxil_versions.h"
28 
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 // NB: I've copy and pasted some types into this header so we don't have to
38 // include other headers. This will surely break if any of these types change.
39 
40 // Copy of gl_shader_stage
41 typedef enum {
42    DXIL_SPIRV_SHADER_NONE = -1,
43    DXIL_SPIRV_SHADER_VERTEX = 0,
44    DXIL_SPIRV_SHADER_TESS_CTRL = 1,
45    DXIL_SPIRV_SHADER_TESS_EVAL = 2,
46    DXIL_SPIRV_SHADER_GEOMETRY = 3,
47    DXIL_SPIRV_SHADER_FRAGMENT = 4,
48    DXIL_SPIRV_SHADER_COMPUTE = 5,
49    DXIL_SPIRV_SHADER_KERNEL = 14,
50 } dxil_spirv_shader_stage;
51 
52 // Copy of nir_spirv_const_value
53 typedef union {
54    bool b;
55    float f32;
56    double f64;
57    int8_t i8;
58    uint8_t u8;
59    int16_t i16;
60    uint16_t u16;
61    int32_t i32;
62    uint32_t u32;
63    int64_t i64;
64    uint64_t u64;
65 } dxil_spirv_const_value;
66 
67 // Copy of nir_spirv_specialization
68 struct dxil_spirv_specialization {
69    uint32_t id;
70    dxil_spirv_const_value value;
71    bool defined_on_module;
72 };
73 
74 struct dxil_spirv_metadata {
75    bool requires_runtime_data;
76 };
77 
78 struct dxil_spirv_object {
79    struct dxil_spirv_metadata metadata;
80    struct {
81       void *buffer;
82       size_t size;
83    } binary;
84 };
85 
86 /* This struct describes the layout of data expected in the CB bound to
87  * runtime_data_cbv during compute shader execution */
88 struct dxil_spirv_compute_runtime_data {
89    /* Total number of groups dispatched (i.e. value passed to Dispatch()) */
90    uint32_t group_count_x;
91    uint32_t group_count_y;
92    uint32_t group_count_z;
93    uint32_t padding0;
94    /* Base */
95    uint32_t base_group_x;
96    uint32_t base_group_y;
97    uint32_t base_group_z;
98 };
99 
100 #define DXIL_SPIRV_Y_FLIP_MASK BITFIELD_MASK(DXIL_SPIRV_MAX_VIEWPORT)
101 #define DXIL_SPIRV_Z_FLIP_SHIFT DXIL_SPIRV_MAX_VIEWPORT
102 #define DXIL_SPIRV_Z_FLIP_MASK BITFIELD_RANGE(DXIL_SPIRV_Z_FLIP_SHIFT, DXIL_SPIRV_MAX_VIEWPORT)
103 
104 /* This struct describes the layout of data expected in the CB bound to
105  * runtime_data_cbv during vertex stages */
106 struct dxil_spirv_vertex_runtime_data {
107    uint32_t first_vertex;
108    uint32_t base_instance;
109    bool is_indexed_draw;
110    // The lower 16bits of this mask encode Y-flips (one bit per viewport)
111    // The higher 16bits of this maks encode Z-flips (one bit per viewport)
112    union {
113       uint32_t yz_flip_mask;
114       struct {
115          uint16_t y_flip_mask;
116          uint16_t z_flip_mask;
117       };
118    };
119    uint32_t draw_id;
120    float viewport_width;
121    float viewport_height;
122    uint32_t view_index;
123    /* When depth bias is dynamic, the constant value to add to point
124     * primitives when emulating triangle point fill mode. Slope-scaled
125     * depth bias is currently unsupported. */
126    float depth_bias;
127 };
128 
129 enum dxil_spirv_yz_flip_mode {
130    DXIL_SPIRV_YZ_FLIP_NONE = 0,
131    // Y-flip is unconditional: pos.y = -pos.y
132    // Z-flip is unconditional: pos.z = -pos.z + 1.0f
133    DXIL_SPIRV_Y_FLIP_UNCONDITIONAL = 1 << 0,
134    DXIL_SPIRV_Z_FLIP_UNCONDITIONAL = 1 << 1,
135    DXIL_SPIRV_YZ_FLIP_UNCONDITIONAL = DXIL_SPIRV_Y_FLIP_UNCONDITIONAL | DXIL_SPIRV_Z_FLIP_UNCONDITIONAL,
136    // Y-flip/Z-flip info are passed through a sysval
137    DXIL_SPIRV_Y_FLIP_CONDITIONAL = 1 << 2,
138    DXIL_SPIRV_Z_FLIP_CONDITIONAL = 1 << 3,
139    DXIL_SPIRV_YZ_FLIP_CONDITIONAL = DXIL_SPIRV_Y_FLIP_CONDITIONAL | DXIL_SPIRV_Z_FLIP_CONDITIONAL,
140 };
141 
142 #define DXIL_SPIRV_MAX_VIEWPORT 16
143 
144 struct dxil_spirv_runtime_conf {
145    struct {
146       uint32_t register_space;
147       uint32_t base_shader_register;
148    } runtime_data_cbv;
149 
150    struct {
151       uint32_t register_space;
152       uint32_t base_shader_register;
153    } push_constant_cbv;
154 
155    // Set true if vertex and instance ids have already been converted to
156    // zero-based. Otherwise, runtime_data will be required to lower them.
157    bool zero_based_vertex_instance_id;
158    // Set true if workgroup base is known to be zero
159    bool zero_based_compute_workgroup_id;
160 
161    struct {
162       // mode != DXIL_SPIRV_YZ_FLIP_NONE only valid on vertex/geometry stages.
163       enum dxil_spirv_yz_flip_mode mode;
164 
165       // Y/Z flip masks (one bit per viewport)
166       uint16_t y_mask;
167       uint16_t z_mask;
168    } yz_flip;
169 
170    // The caller supports read-only images to be turned into SRV accesses,
171    // which allows us to run the nir_opt_access() pass
172    bool declared_read_only_images_as_srvs;
173 
174    // The caller supports read-write images to be turned into SRV accesses,
175    // if they are found not to be written
176    bool inferred_read_only_images_as_srvs;
177 
178    // Force sample rate shading on a fragment shader
179    bool force_sample_rate_shading;
180 
181    // View index needs to be lowered to a UBO lookup
182    bool lower_view_index;
183    // View index also needs to be forwarded to RT layer output
184    bool lower_view_index_to_rt_layer;
185 
186    // Affects which features can be used by the shader
187    enum dxil_shader_model shader_model_max;
188 };
189 
190 struct dxil_spirv_debug_options {
191    bool dump_nir;
192 };
193 
194 typedef void (*dxil_spirv_msg_callback)(void *priv, const char *msg);
195 
196 struct dxil_spirv_logger {
197    void *priv;
198    dxil_spirv_msg_callback log;
199 };
200 
201 /**
202  * Compile a SPIR-V module into DXIL.
203  * \param  words  SPIR-V module to compile
204  * \param  word_count  number of words in the SPIR-V module
205  * \param  specializations  specialization constants to compile with the shader
206  * \param  num_specializations  number of specialization constants
207  * \param  stage  shader stage
208  * \param  entry_point_name  name of shader entrypoint
209  * \param  conf  configuration for spriv_to_dxil
210  * \param  out_dxil  will contain the DXIL bytes on success (call spirv_to_dxil_free after use)
211  * \return  true if compilation succeeded
212  */
213 bool
214 spirv_to_dxil(const uint32_t *words, size_t word_count,
215               struct dxil_spirv_specialization *specializations,
216               unsigned int num_specializations, dxil_spirv_shader_stage stage,
217               const char *entry_point_name,
218               enum dxil_validator_version validator_version_max,
219               const struct dxil_spirv_debug_options *debug_options,
220               const struct dxil_spirv_runtime_conf *conf,
221               const struct dxil_spirv_logger *logger,
222               struct dxil_spirv_object *out_dxil);
223 
224 /**
225  * Free the buffer allocated by spirv_to_dxil.
226  */
227 void
228 spirv_to_dxil_free(struct dxil_spirv_object *dxil);
229 
230 uint64_t
231 spirv_to_dxil_get_version(void);
232 
233 #ifdef __cplusplus
234 }
235 #endif
236 
237 #endif
238