Path: blob/21.2-virgl/src/microsoft/spirv_to_dxil/spirv_to_dxil.c
4564 views
/*1* Copyright © Microsoft Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "spirv_to_dxil.h"24#include "nir_to_dxil.h"25#include "dxil_nir.h"26#include "shader_enums.h"27#include "spirv/nir_spirv.h"28#include "util/blob.h"2930bool31spirv_to_dxil(const uint32_t *words, size_t word_count,32struct dxil_spirv_specialization *specializations,33unsigned int num_specializations, dxil_spirv_shader_stage stage,34const char *entry_point_name, void **buffer, size_t *size)35{36if (stage == MESA_SHADER_NONE || stage == MESA_SHADER_KERNEL)37return false;3839struct spirv_to_nir_options spirv_opts = {40.ubo_addr_format = nir_address_format_32bit_index_offset,41.ssbo_addr_format = nir_address_format_32bit_index_offset,42// use_deref_buffer_array_length + nir_lower_explicit_io force43// get_ssbo_size to take in the return from load_vulkan_descriptor44// instead of vulkan_resource_index. This makes it much easier to45// get the DXIL handle for the SSBO.46.use_deref_buffer_array_length = true47};4849glsl_type_singleton_init_or_ref();5051struct nir_shader_compiler_options nir_options = *dxil_get_nir_compiler_options();52// We will manually handle base_vertex53nir_options.lower_base_vertex = false;5455nir_shader *nir = spirv_to_nir(56words, word_count, (struct nir_spirv_specialization *)specializations,57num_specializations, (gl_shader_stage)stage, entry_point_name,58&spirv_opts, &nir_options);59if (!nir) {60glsl_type_singleton_decref();61return false;62}6364nir_validate_shader(nir,65"Validate before feeding NIR to the DXIL compiler");6667NIR_PASS_V(nir, nir_lower_system_values);6869// vertex_id and instance_id should have already been transformed to base70// zero before spirv_to_dxil was called. Also, WebGPU does not support71// base/firstVertex/Instance.72gl_system_value system_values[] = {73SYSTEM_VALUE_FIRST_VERTEX,74SYSTEM_VALUE_BASE_VERTEX,75SYSTEM_VALUE_BASE_INSTANCE76};77NIR_PASS_V(nir, dxil_nir_lower_system_values_to_zero, system_values, ARRAY_SIZE(system_values));7879NIR_PASS_V(nir, nir_split_per_member_structs);8081NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ubo | nir_var_mem_ssbo,82nir_address_format_32bit_index_offset);8384nir_variable_mode nir_var_function_temp =85nir_var_shader_in | nir_var_shader_out;86NIR_PASS_V(nir, nir_lower_variable_initializers,87nir_var_function_temp);88NIR_PASS_V(nir, nir_opt_deref);89NIR_PASS_V(nir, nir_lower_returns);90NIR_PASS_V(nir, nir_inline_functions);91NIR_PASS_V(nir, nir_lower_variable_initializers,92~nir_var_function_temp);9394// Pick off the single entrypoint that we want.95nir_function *entrypoint;96foreach_list_typed_safe(nir_function, func, node, &nir->functions) {97if (func->is_entrypoint)98entrypoint = func;99else100exec_node_remove(&func->node);101}102assert(exec_list_length(&nir->functions) == 1);103104NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);105NIR_PASS_V(nir, nir_lower_io_to_temporaries, entrypoint->impl, true, true);106NIR_PASS_V(nir, nir_lower_global_vars_to_local);107NIR_PASS_V(nir, nir_split_var_copies);108NIR_PASS_V(nir, nir_lower_var_copies);109NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);110111NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);112NIR_PASS_V(nir, nir_opt_dce);113NIR_PASS_V(nir, dxil_nir_lower_double_math);114115{116bool progress;117do118{119progress = false;120NIR_PASS(progress, nir, nir_copy_prop);121NIR_PASS(progress, nir, nir_opt_copy_prop_vars);122NIR_PASS(progress, nir, nir_opt_deref);123NIR_PASS(progress, nir, nir_opt_dce);124NIR_PASS(progress, nir, nir_opt_undef);125NIR_PASS(progress, nir, nir_opt_constant_folding);126NIR_PASS(progress, nir, nir_opt_cse);127NIR_PASS(progress, nir, nir_lower_vars_to_ssa);128NIR_PASS(progress, nir, nir_opt_algebraic);129} while (progress);130}131132NIR_PASS_V(nir, nir_lower_readonly_images_to_tex, true);133NIR_PASS_V(nir, dxil_nir_split_clip_cull_distance);134NIR_PASS_V(nir, dxil_nir_lower_loads_stores_to_dxil);135NIR_PASS_V(nir, dxil_nir_create_bare_samplers);136137nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));138139nir->info.inputs_read =140dxil_reassign_driver_locations(nir, nir_var_shader_in, 0);141142if (stage != MESA_SHADER_FRAGMENT) {143nir->info.outputs_written =144dxil_reassign_driver_locations(nir, nir_var_shader_out, 0);145} else {146dxil_sort_ps_outputs(nir);147}148149struct nir_to_dxil_options opts = {.vulkan_environment = true};150151struct blob dxil_blob;152if (!nir_to_dxil(nir, &opts, &dxil_blob)) {153if (dxil_blob.allocated)154blob_finish(&dxil_blob);155glsl_type_singleton_decref();156return false;157}158159blob_finish_get_buffer(&dxil_blob, buffer, size);160161glsl_type_singleton_decref();162return true;163}164165void166spirv_to_dxil_free(void* buffer)167{168free(buffer);169}170171172