diff --git a/Makefile.am b/Makefile.am index 6abe22cc..5e463770 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,6 +65,7 @@ libvkd3d_shader_la_SOURCES = \ include/private/vkd3d_debug.h \ include/private/vkd3d_memory.h \ libs/vkd3d-shader/dxbc.c \ + libs/vkd3d-shader/spirv.c \ libs/vkd3d-shader/vkd3d_shader_main.c \ libs/vkd3d-shader/vkd3d_shader_private.h libvkd3d_shader_la_LIBADD = libvkd3d-common.la diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c new file mode 100644 index 00000000..3dd32aab --- /dev/null +++ b/libs/vkd3d-shader/spirv.c @@ -0,0 +1,148 @@ +/* + * Copyright 2017 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "vkd3d_shader_private.h" + +#include "spirv/1.0/spirv.h" + +static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv) {} +static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv) {} + +struct vkd3d_spirv_builder +{ + uint64_t capability_mask; + SpvExecutionModel execution_model; + + uint32_t current_id; +}; + +static void vkd3d_spirv_enable_capability(struct vkd3d_spirv_builder *builder, + SpvCapability cap) +{ + assert(cap < sizeof(builder->capability_mask) * CHAR_BIT); + builder->capability_mask |= 1ull << cap; +} + +static void vkd3d_spirv_set_execution_model(struct vkd3d_spirv_builder *builder, + SpvExecutionModel model) +{ + builder->execution_model = model; + + switch (model) + { + case SpvExecutionModelVertex: + case SpvExecutionModelFragment: + case SpvExecutionModelGLCompute: + vkd3d_spirv_enable_capability(builder, SpvCapabilityShader); + break; + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + vkd3d_spirv_enable_capability(builder, SpvCapabilityTessellation); + break; + case SpvExecutionModelGeometry: + vkd3d_spirv_enable_capability(builder, SpvCapabilityGeometry); + break; + default: + ERR("Unhandled execution model %#x.\n", model); + } +} + +static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder) +{ + builder->current_id = 1; +} + +static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder, + struct vkd3d_shader_code *spirv) +{ + FIXME("Not implemented!\n"); + + return false; +} + +struct vkd3d_dxbc_compiler +{ + struct vkd3d_spirv_builder spirv_builder; + + uint32_t options; +}; + +struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, + uint32_t compiler_options) +{ + struct vkd3d_dxbc_compiler *compiler; + + if (!(compiler = vkd3d_malloc(sizeof(*compiler)))) + return NULL; + + memset(compiler, 0, sizeof(*compiler)); + vkd3d_spirv_builder_init(&compiler->spirv_builder); + compiler->options = compiler_options; + + switch (shader_version->type) + { + case VKD3D_SHADER_TYPE_VERTEX: + vkd3d_spirv_set_execution_model(&compiler->spirv_builder, SpvExecutionModelVertex); + break; + case VKD3D_SHADER_TYPE_HULL: + vkd3d_spirv_set_execution_model(&compiler->spirv_builder, SpvExecutionModelTessellationControl); + break; + case VKD3D_SHADER_TYPE_DOMAIN: + vkd3d_spirv_set_execution_model(&compiler->spirv_builder, SpvExecutionModelTessellationEvaluation); + break; + case VKD3D_SHADER_TYPE_GEOMETRY: + vkd3d_spirv_set_execution_model(&compiler->spirv_builder, SpvExecutionModelGeometry); + break; + case VKD3D_SHADER_TYPE_PIXEL: + vkd3d_spirv_set_execution_model(&compiler->spirv_builder, SpvExecutionModelFragment); + break; + case VKD3D_SHADER_TYPE_COMPUTE: + vkd3d_spirv_set_execution_model(&compiler->spirv_builder, SpvExecutionModelGLCompute); + break; + default: + ERR("Invalid shader type %#x.\n", shader_version->type); + } + + return compiler; +} + +void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + FIXME("Unhandled instruction %#x.\n", instruction->handler_idx); +} + +bool vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, + struct vkd3d_shader_code *spirv) +{ + if (!vkd3d_spirv_compile_module(&compiler->spirv_builder, spirv)) + return false; + + if (TRACE_ON()) + { + vkd3d_spirv_dump(spirv); + vkd3d_spirv_validate(spirv); + } + + return true; +} + +void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) +{ + vkd3d_free(compiler); +} diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 5e1d2486..c4ebeb16 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -817,4 +817,14 @@ struct vkd3d_shader_signature_element *shader_find_signature_element(const struc const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx) DECLSPEC_HIDDEN; void free_shader_desc(struct vkd3d_shader_desc *desc) DECLSPEC_HIDDEN; +struct vkd3d_dxbc_compiler; + +struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create( + const struct vkd3d_shader_version *shader_version, uint32_t compiler_options) DECLSPEC_HIDDEN; +void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN; +bool vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, + struct vkd3d_shader_code *spirv) DECLSPEC_HIDDEN; +void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) DECLSPEC_HIDDEN; + #endif /* __VKD3D_SHADER_PRIVATE_H */