--- /dev/null
+/*
+ * Copyright 2019 Valve Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ac_shader_args.h"
+#include "nir/nir_builder.h"
+
+void
+ac_add_arg(struct ac_shader_args *info, enum ac_arg_regfile regfile,
+ unsigned size, enum ac_arg_type type, struct ac_arg *arg)
+{
+ assert(info->arg_count < AC_MAX_ARGS);
+
+ unsigned offset;
+ if (regfile == AC_ARG_SGPR) {
+ offset = info->num_sgprs_used;
+ info->num_sgprs_used += size;
+ } else {
+ assert(regfile == AC_ARG_VGPR);
+ offset = info->num_vgprs_used;
+ info->num_vgprs_used += size;
+ }
+
+ info->args[info->arg_count].file = regfile;
+ info->args[info->arg_count].offset = offset;
+ info->args[info->arg_count].size = size;
+ info->args[info->arg_count].type = type;
+
+ if (arg) {
+ arg->arg_index = info->arg_count;
+ arg->used = true;
+ }
+
+ info->arg_count++;
+}
+
--- /dev/null
+/*
+ * Copyright 2019 Valve Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef AC_SHADER_ARGS_H
+#define AC_SHADER_ARGS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define AC_MAX_INLINE_PUSH_CONSTS 8
+
+enum ac_arg_regfile {
+ AC_ARG_SGPR,
+ AC_ARG_VGPR,
+};
+
+enum ac_arg_type {
+ AC_ARG_FLOAT,
+ AC_ARG_INT,
+ AC_ARG_CONST_PTR, /* Pointer to i8 array */
+ AC_ARG_CONST_FLOAT_PTR, /* Pointer to f32 array */
+ AC_ARG_CONST_PTR_PTR, /* Pointer to pointer to i8 array */
+ AC_ARG_CONST_DESC_PTR, /* Pointer to v4i32 array */
+ AC_ARG_CONST_IMAGE_PTR, /* Pointer to v8i32 array */
+};
+
+struct ac_arg {
+ uint8_t arg_index;
+ bool used;
+};
+
+
+#define AC_MAX_ARGS 64
+struct ac_shader_args {
+ /* Info on how to declare arguments */
+ struct {
+ enum ac_arg_type type;
+ enum ac_arg_regfile file;
+ uint8_t offset;
+ uint8_t size;
+ } args[AC_MAX_ARGS];
+
+ uint8_t arg_count;
+ uint8_t sgpr_count;
+ uint8_t num_sgprs_used;
+ uint8_t num_vgprs_used;
+
+ struct ac_arg base_vertex;
+ struct ac_arg start_instance;
+ struct ac_arg draw_id;
+ struct ac_arg vertex_id;
+ struct ac_arg instance_id;
+ struct ac_arg tcs_patch_id;
+ struct ac_arg tcs_rel_ids;
+ struct ac_arg tes_patch_id;
+ struct ac_arg gs_prim_id;
+ struct ac_arg gs_invocation_id;
+
+ /* PS */
+ struct ac_arg frag_pos[4];
+ struct ac_arg front_face;
+ struct ac_arg ancillary;
+ struct ac_arg sample_coverage;
+ struct ac_arg prim_mask;
+ struct ac_arg persp_sample;
+ struct ac_arg persp_center;
+ struct ac_arg persp_centroid;
+ struct ac_arg linear_sample;
+ struct ac_arg linear_center;
+ struct ac_arg linear_centroid;
+
+ /* CS */
+ struct ac_arg local_invocation_ids;
+ struct ac_arg num_work_groups;
+ struct ac_arg workgroup_ids[3];
+ struct ac_arg tg_size;
+
+ /* Vulkan only */
+ struct ac_arg push_constants;
+ struct ac_arg inline_push_consts[AC_MAX_INLINE_PUSH_CONSTS];
+ unsigned num_inline_push_consts;
+ unsigned base_inline_push_consts;
+ struct ac_arg view_index;
+};
+
+void ac_add_arg(struct ac_shader_args *info, enum ac_arg_regfile regfile,
+ unsigned registers, enum ac_arg_type type,
+ struct ac_arg *arg);
+
+#endif
+
'ac_binary.c',
'ac_binary.h',
'ac_exp_param.h',
+ 'ac_shader_args.c',
+ 'ac_shader_args.h',
'ac_shader_util.c',
'ac_shader_util.h',
'ac_gpu_info.c',
args->enabled_channels = mask;
}
+static LLVMTypeRef
+arg_llvm_type(enum ac_arg_type type, unsigned size, struct ac_llvm_context *ctx)
+{
+ if (type == AC_ARG_FLOAT) {
+ return size == 1 ? ctx->f32 : LLVMVectorType(ctx->f32, size);
+ } else if (type == AC_ARG_INT) {
+ return size == 1 ? ctx->i32 : LLVMVectorType(ctx->i32, size);
+ } else {
+ LLVMTypeRef ptr_type;
+ switch (type) {
+ case AC_ARG_CONST_PTR:
+ ptr_type = ctx->i8;
+ break;
+ case AC_ARG_CONST_FLOAT_PTR:
+ ptr_type = ctx->f32;
+ break;
+ case AC_ARG_CONST_PTR_PTR:
+ ptr_type = ac_array_in_const32_addr_space(ctx->i8);
+ break;
+ case AC_ARG_CONST_DESC_PTR:
+ ptr_type = ctx->v4i32;
+ break;
+ case AC_ARG_CONST_IMAGE_PTR:
+ ptr_type = ctx->v8i32;
+ break;
+ default:
+ unreachable("unknown arg type");
+ }
+ if (size == 1) {
+ return ac_array_in_const32_addr_space(ptr_type);
+ } else {
+ assert(size == 2);
+ return ac_array_in_const_addr_space(ptr_type);
+ }
+ }
+}
+
+LLVMValueRef
+ac_build_main(const struct ac_shader_args *args,
+ struct ac_llvm_context *ctx,
+ enum ac_llvm_calling_convention convention,
+ const char *name, LLVMTypeRef ret_type,
+ LLVMModuleRef module)
+{
+ LLVMTypeRef arg_types[AC_MAX_ARGS];
+
+ for (unsigned i = 0; i < args->arg_count; i++) {
+ arg_types[i] = arg_llvm_type(args->args[i].type,
+ args->args[i].size, ctx);
+ }
+
+ LLVMTypeRef main_function_type =
+ LLVMFunctionType(ret_type, arg_types, args->arg_count, 0);
+
+ LLVMValueRef main_function =
+ LLVMAddFunction(module, name, main_function_type);
+ LLVMBasicBlockRef main_function_body =
+ LLVMAppendBasicBlockInContext(ctx->context, main_function, "main_body");
+ LLVMPositionBuilderAtEnd(ctx->builder, main_function_body);
+
+ LLVMSetFunctionCallConv(main_function, convention);
+ for (unsigned i = 0; i < args->arg_count; ++i) {
+ LLVMValueRef P = LLVMGetParam(main_function, i);
+
+ if (args->args[i].file != AC_ARG_SGPR)
+ continue;
+
+ ac_add_function_attr(ctx->context, main_function, i + 1, AC_FUNC_ATTR_INREG);
+
+ if (LLVMGetTypeKind(LLVMTypeOf(P)) == LLVMPointerTypeKind) {
+ ac_add_function_attr(ctx->context, main_function, i + 1, AC_FUNC_ATTR_NOALIAS);
+ ac_add_attr_dereferenceable(P, UINT64_MAX);
+ }
+ }
+
+ ctx->main_function = main_function;
+ return main_function;
+}
+
#include "compiler/nir/nir.h"
#include "amd_family.h"
#include "ac_shader_util.h"
+#include "ac_shader_args.h"
+#include "ac_shader_abi.h"
#ifdef __cplusplus
extern "C" {
LLVMModuleRef module;
LLVMBuilderRef builder;
+ LLVMValueRef main_function;
+
LLVMTypeRef voidt;
LLVMTypeRef i1;
LLVMTypeRef i8;
LLVMValueRef stencil, LLVMValueRef samplemask,
struct ac_export_args *args);
+static inline LLVMValueRef
+ac_get_arg(struct ac_llvm_context *ctx, struct ac_arg arg)
+{
+ assert(arg.used);
+ return LLVMGetParam(ctx->main_function, arg.arg_index);
+}
+
+enum ac_llvm_calling_convention {
+ AC_LLVM_AMDGPU_VS = 87,
+ AC_LLVM_AMDGPU_GS = 88,
+ AC_LLVM_AMDGPU_PS = 89,
+ AC_LLVM_AMDGPU_CS = 90,
+ AC_LLVM_AMDGPU_HS = 93,
+};
+
+LLVMValueRef ac_build_main(const struct ac_shader_args *args,
+ struct ac_llvm_context *ctx,
+ enum ac_llvm_calling_convention convention,
+ const char *name, LLVMTypeRef ret_type,
+ LLVMModuleRef module);
+
#ifdef __cplusplus
}
#endif
#define AC_SHADER_ABI_H
#include <llvm-c/Core.h>
+#include "ac_shader_args.h"
#include "compiler/shader_enums.h"