Skip to content
Snippets Groups Projects
spirv.c 367 KiB
Newer Older
        case VKD3DSIH_USHR:
            vkd3d_dxbc_compiler_emit_alu_instruction(compiler, instruction);
            break;
        case VKD3DSIH_EXP:
        case VKD3DSIH_FIRSTBIT_HI:
        case VKD3DSIH_FIRSTBIT_LO:
        case VKD3DSIH_FIRSTBIT_SHI:
        case VKD3DSIH_FRC:
        case VKD3DSIH_IMAX:
        case VKD3DSIH_IMIN:
        case VKD3DSIH_LOG:
        case VKD3DSIH_MAX:
        case VKD3DSIH_MIN:
        case VKD3DSIH_ROUND_NE:
        case VKD3DSIH_ROUND_NI:
        case VKD3DSIH_ROUND_PI:
        case VKD3DSIH_ROUND_Z:
        case VKD3DSIH_SQRT:
        case VKD3DSIH_UMAX:
        case VKD3DSIH_UMIN:
            vkd3d_dxbc_compiler_emit_ext_glsl_instruction(compiler, instruction);
            break;
        case VKD3DSIH_DP4:
        case VKD3DSIH_DP3:
        case VKD3DSIH_DP2:
            vkd3d_dxbc_compiler_emit_dot(compiler, instruction);
            break;
        case VKD3DSIH_RCP:
            vkd3d_dxbc_compiler_emit_rcp(compiler, instruction);
            break;
        case VKD3DSIH_SINCOS:
            vkd3d_dxbc_compiler_emit_sincos(compiler, instruction);
            break;
        case VKD3DSIH_IMUL:
            vkd3d_dxbc_compiler_emit_imul(compiler, instruction);
            break;
        case VKD3DSIH_IMAD:
            vkd3d_dxbc_compiler_emit_imad(compiler, instruction);
            break;
        case VKD3DSIH_UDIV:
            vkd3d_dxbc_compiler_emit_udiv(compiler, instruction);
            break;
        case VKD3DSIH_IEQ:
        case VKD3DSIH_IGE:
        case VKD3DSIH_ILT:
        case VKD3DSIH_INE:
        case VKD3DSIH_UGE:
        case VKD3DSIH_ULT:
            vkd3d_dxbc_compiler_emit_comparison_instruction(compiler, instruction);
            break;
        case VKD3DSIH_BFI:
        case VKD3DSIH_IBFE:
        case VKD3DSIH_UBFE:
            vkd3d_dxbc_compiler_emit_bitfield_instruction(compiler, instruction);
            break;
        case VKD3DSIH_F16TOF32:
            vkd3d_dxbc_compiler_emit_f16tof32(compiler, instruction);
            break;
        case VKD3DSIH_F32TOF16:
            vkd3d_dxbc_compiler_emit_f32tof16(compiler, instruction);
            break;
        case VKD3DSIH_BREAKP:
        case VKD3DSIH_CONTINUE:
        case VKD3DSIH_CONTINUEP:
        case VKD3DSIH_ELSE:
        case VKD3DSIH_ENDIF:
        case VKD3DSIH_ENDLOOP:
        case VKD3DSIH_IF:
        case VKD3DSIH_LOOP:
        case VKD3DSIH_RET:
        case VKD3DSIH_RETP:
        case VKD3DSIH_TEXKILL:
            ret = vkd3d_dxbc_compiler_emit_control_flow_instruction(compiler, instruction);
        case VKD3DSIH_DSX:
        case VKD3DSIH_DSX_COARSE:
        case VKD3DSIH_DSX_FINE:
        case VKD3DSIH_DSY:
        case VKD3DSIH_DSY_COARSE:
        case VKD3DSIH_DSY_FINE:
            vkd3d_dxbc_compiler_emit_deriv_instruction(compiler, instruction);
            break;
        case VKD3DSIH_LD2DMS:
        case VKD3DSIH_LD:
            vkd3d_dxbc_compiler_emit_ld(compiler, instruction);
            break;
        case VKD3DSIH_LOD:
            vkd3d_dxbc_compiler_emit_lod(compiler, instruction);
            break;
        case VKD3DSIH_SAMPLE:
        case VKD3DSIH_SAMPLE_B:
        case VKD3DSIH_SAMPLE_GRAD:
        case VKD3DSIH_SAMPLE_LOD:
            vkd3d_dxbc_compiler_emit_sample(compiler, instruction);
            break;
        case VKD3DSIH_SAMPLE_C:
        case VKD3DSIH_SAMPLE_C_LZ:
            vkd3d_dxbc_compiler_emit_sample_c(compiler, instruction);
            break;
        case VKD3DSIH_GATHER4:
        case VKD3DSIH_GATHER4_C:
        case VKD3DSIH_GATHER4_PO:
        case VKD3DSIH_GATHER4_PO_C:
            vkd3d_dxbc_compiler_emit_gather4(compiler, instruction);
            break;
        case VKD3DSIH_LD_RAW:
        case VKD3DSIH_LD_STRUCTURED:
            vkd3d_dxbc_compiler_emit_ld_raw_structured(compiler, instruction);
        case VKD3DSIH_STORE_RAW:
        case VKD3DSIH_STORE_STRUCTURED:
            vkd3d_dxbc_compiler_emit_store_raw_structured(compiler, instruction);
            break;
        case VKD3DSIH_LD_UAV_TYPED:
            vkd3d_dxbc_compiler_emit_ld_uav_typed(compiler, instruction);
        case VKD3DSIH_STORE_UAV_TYPED:
            vkd3d_dxbc_compiler_emit_store_uav_typed(compiler, instruction);
            break;
        case VKD3DSIH_IMM_ATOMIC_ALLOC:
        case VKD3DSIH_IMM_ATOMIC_CONSUME:
            vkd3d_dxbc_compiler_emit_uav_counter_instruction(compiler, instruction);
            break;
        case VKD3DSIH_ATOMIC_IADD:
        case VKD3DSIH_ATOMIC_IMAX:
        case VKD3DSIH_ATOMIC_IMIN:
        case VKD3DSIH_ATOMIC_OR:
        case VKD3DSIH_ATOMIC_UMAX:
        case VKD3DSIH_ATOMIC_UMIN:
        case VKD3DSIH_ATOMIC_XOR:
        case VKD3DSIH_IMM_ATOMIC_AND:
        case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
        case VKD3DSIH_IMM_ATOMIC_EXCH:
        case VKD3DSIH_IMM_ATOMIC_IADD:
        case VKD3DSIH_IMM_ATOMIC_IMAX:
        case VKD3DSIH_IMM_ATOMIC_IMIN:
        case VKD3DSIH_IMM_ATOMIC_OR:
        case VKD3DSIH_IMM_ATOMIC_UMAX:
        case VKD3DSIH_IMM_ATOMIC_UMIN:
        case VKD3DSIH_IMM_ATOMIC_XOR:
            vkd3d_dxbc_compiler_emit_atomic_instruction(compiler, instruction);
            break;
        case VKD3DSIH_BUFINFO:
            vkd3d_dxbc_compiler_emit_bufinfo(compiler, instruction);
            break;
        case VKD3DSIH_RESINFO:
            vkd3d_dxbc_compiler_emit_resinfo(compiler, instruction);
            break;
        case VKD3DSIH_SAMPLE_INFO:
            vkd3d_dxbc_compiler_emit_sample_info(compiler, instruction);
            break;
        case VKD3DSIH_SAMPLE_POS:
            vkd3d_dxbc_compiler_emit_sample_position(compiler, instruction);
            break;
        case VKD3DSIH_EVAL_CENTROID:
        case VKD3DSIH_EVAL_SAMPLE_INDEX:
            vkd3d_dxbc_compiler_emit_eval_attrib(compiler, instruction);
        case VKD3DSIH_SYNC:
            vkd3d_dxbc_compiler_emit_sync(compiler, instruction);
            break;
        case VKD3DSIH_EMIT:
        case VKD3DSIH_EMIT_STREAM:
            vkd3d_dxbc_compiler_emit_emit_stream(compiler, instruction);
            break;
        case VKD3DSIH_CUT:
        case VKD3DSIH_CUT_STREAM:
            vkd3d_dxbc_compiler_emit_cut_stream(compiler, instruction);
            break;
        case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
        case VKD3DSIH_NOP:
        default:
            FIXME("Unhandled instruction %#x.\n", instruction->handler_idx);
    }
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
        const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv)
    const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
    const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info;
    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
    if ((phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler)))
        vkd3d_dxbc_compiler_leave_shader_phase(compiler, phase);
    else
        vkd3d_spirv_build_op_function_end(builder);
    if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
        vkd3d_dxbc_compiler_emit_hull_shader_main(compiler);

    if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN)
    {
        if (info && (ds_info = vkd3d_find_struct(compile_info->next, SPIRV_DOMAIN_SHADER_TARGET_INFO)))
            vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler, ds_info->output_primitive);
            vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler, ds_info->partitioning);
        }
        else if (vkd3d_dxbc_compiler_is_opengl_target(compiler))
        {
            ERR("vkd3d_shader_spirv_domain_shader_target_info is required for "
                    "OpenGL tessellation evaluation shader.\n");
        }
    }

    if (compiler->epilogue_function_id)
    {
        vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue");
        vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler);
        vkd3d_spirv_stream_clear(&builder->debug_stream);

    if (!vkd3d_spirv_compile_module(builder, spirv, vkd3d_dxbc_compiler_get_entry_point_name(compiler)))
        enum vkd3d_shader_spirv_environment environment = vkd3d_dxbc_compiler_get_target_environment(compiler);
        vkd3d_spirv_dump(spirv, environment);
        vkd3d_spirv_validate(spirv, environment);
    if (compiler->failed)
        return VKD3D_ERROR_INVALID_SHADER;

    if (compile_info->target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT)
    {
        struct vkd3d_shader_code text;
        enum vkd3d_shader_spirv_environment environment = vkd3d_dxbc_compiler_get_target_environment(compiler);
        if (vkd3d_spirv_binary_to_text(spirv, environment,
                    get_binary_to_text_options(compiler->formatting), &text) != VKD3D_OK)
}

void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler)
{
    vkd3d_free(compiler->control_flow_info);

    vkd3d_spirv_builder_free(&compiler->spirv_builder);

    rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL);

    vkd3d_free(compiler->shader_phases);
    vkd3d_free(compiler->spec_constants);