/* * 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); }