From 76daf893ea0fdbbb53017d0395be7c23b80c256c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 17 Feb 2020 16:58:18 +1000 Subject: [PATCH] draw: add JIT context/functions for tess stages. This adds the initial draw_tess.h with a define needed for the interfaces. TCS input array doesn't need to handle patch inputs so can be smaller. The TCS context has some dummy values to align the textures/images properly. Reviewed-by: Roland Scheidegger Part-of: --- src/gallium/auxiliary/draw/draw_llvm.c | 160 +++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_llvm.h | 113 +++++++++++++++++ src/gallium/auxiliary/draw/draw_tess.h | 40 +++++++ 3 files changed, 313 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_tess.h diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 0701082850f..177b83ee659 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -497,6 +497,166 @@ create_jit_vertex_header(struct gallivm_state *gallivm, int data_elems) return vertex_header; } +/** + * Create LLVM type for struct draw_tcs_jit_context + */ +static LLVMTypeRef +create_tcs_jit_context_type(struct gallivm_state *gallivm, + unsigned vector_length, + LLVMTypeRef texture_type, LLVMTypeRef sampler_type, + LLVMTypeRef image_type, + const char *struct_name) +{ + LLVMTargetDataRef target = gallivm->target; + LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); + LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); + LLVMTypeRef elem_types[DRAW_TCS_JIT_CTX_NUM_FIELDS]; + LLVMTypeRef context_type; + + elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* constants */ + LP_MAX_TGSI_CONST_BUFFERS); + elem_types[1] = LLVMArrayType(int_type, /* num_constants */ + LP_MAX_TGSI_CONST_BUFFERS); + elem_types[2] = LLVMInt32TypeInContext(gallivm->context); + elem_types[3] = LLVMInt32TypeInContext(gallivm->context); + + elem_types[4] = LLVMArrayType(texture_type, + PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */ + elem_types[5] = LLVMArrayType(sampler_type, + PIPE_MAX_SAMPLERS); /* samplers */ + elem_types[6] = LLVMArrayType(image_type, + PIPE_MAX_SHADER_IMAGES); /* images */ + + elem_types[7] = LLVMArrayType(LLVMPointerType(int_type, 0), /* ssbos */ + LP_MAX_TGSI_SHADER_BUFFERS); + elem_types[8] = LLVMArrayType(int_type, /* num_ssbos */ + LP_MAX_TGSI_SHADER_BUFFERS); + + context_type = LLVMStructTypeInContext(gallivm->context, elem_types, + ARRAY_SIZE(elem_types), 0); + + (void) target; /* silence unused var warning for non-debug build */ + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, constants, + target, context_type, DRAW_TCS_JIT_CTX_CONSTANTS); + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, num_constants, + target, context_type, DRAW_TCS_JIT_CTX_NUM_CONSTANTS); + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, textures, + target, context_type, + DRAW_TCS_JIT_CTX_TEXTURES); + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, samplers, + target, context_type, + DRAW_TCS_JIT_CTX_SAMPLERS); + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, ssbos, + target, context_type, DRAW_TCS_JIT_CTX_SSBOS); + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, num_ssbos, + target, context_type, DRAW_TCS_JIT_CTX_NUM_SSBOS); + LP_CHECK_MEMBER_OFFSET(struct draw_tcs_jit_context, images, + target, context_type, DRAW_TCS_JIT_CTX_IMAGES); + LP_CHECK_STRUCT_SIZE(struct draw_tcs_jit_context, + target, context_type); + + return context_type; +} + +static LLVMTypeRef +create_tcs_jit_input_type(struct gallivm_state *gallivm) +{ + LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); + LLVMTypeRef input_array; + + input_array = LLVMArrayType(float_type, TGSI_NUM_CHANNELS); /* num channels */ + input_array = LLVMArrayType(input_array, NUM_TCS_INPUTS); /* num attrs per vertex */ + input_array = LLVMPointerType(input_array, 0); /* num vertices per prim */ + + return input_array; +} + +static LLVMTypeRef +create_tcs_jit_output_type(struct gallivm_state *gallivm) +{ + LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); + LLVMTypeRef output_array; + + output_array = LLVMArrayType(float_type, TGSI_NUM_CHANNELS); /* num channels */ + output_array = LLVMArrayType(output_array, PIPE_MAX_SHADER_INPUTS); /* num attrs per vertex */ + output_array = LLVMPointerType(output_array, 0); /* num vertices per prim */ + + return output_array; +} + +static LLVMTypeRef +create_tes_jit_input_type(struct gallivm_state *gallivm) +{ + LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); + LLVMTypeRef input_array; + + input_array = LLVMArrayType(float_type, TGSI_NUM_CHANNELS); /* num channels */ + input_array = LLVMArrayType(input_array, PIPE_MAX_SHADER_INPUTS); /* num attrs per vertex */ + input_array = LLVMPointerType(input_array, 0); /* num vertices per prim */ + + return input_array; +} + +/** + * Create LLVM type for struct draw_tes_jit_context + */ +static LLVMTypeRef +create_tes_jit_context_type(struct gallivm_state *gallivm, + unsigned vector_length, + LLVMTypeRef texture_type, LLVMTypeRef sampler_type, + LLVMTypeRef image_type, + const char *struct_name) +{ + LLVMTargetDataRef target = gallivm->target; + LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); + LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); + LLVMTypeRef elem_types[DRAW_TCS_JIT_CTX_NUM_FIELDS]; + LLVMTypeRef context_type; + + elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* constants */ + LP_MAX_TGSI_CONST_BUFFERS); + elem_types[1] = LLVMArrayType(int_type, /* num_constants */ + LP_MAX_TGSI_CONST_BUFFERS); + elem_types[2] = LLVMInt32TypeInContext(gallivm->context); + elem_types[3] = LLVMInt32TypeInContext(gallivm->context); + + elem_types[4] = LLVMArrayType(texture_type, + PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */ + elem_types[5] = LLVMArrayType(sampler_type, + PIPE_MAX_SAMPLERS); /* samplers */ + elem_types[6] = LLVMArrayType(image_type, + PIPE_MAX_SHADER_IMAGES); /* images */ + + elem_types[7] = LLVMArrayType(LLVMPointerType(int_type, 0), /* ssbos */ + LP_MAX_TGSI_SHADER_BUFFERS); + elem_types[8] = LLVMArrayType(int_type, /* num_ssbos */ + LP_MAX_TGSI_SHADER_BUFFERS); + + context_type = LLVMStructTypeInContext(gallivm->context, elem_types, + ARRAY_SIZE(elem_types), 0); + + (void) target; /* silence unused var warning for non-debug build */ + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, constants, + target, context_type, DRAW_TCS_JIT_CTX_CONSTANTS); + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, num_constants, + target, context_type, DRAW_TCS_JIT_CTX_NUM_CONSTANTS); + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, textures, + target, context_type, + DRAW_TCS_JIT_CTX_TEXTURES); + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, samplers, + target, context_type, + DRAW_TCS_JIT_CTX_SAMPLERS); + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, ssbos, + target, context_type, DRAW_TCS_JIT_CTX_SSBOS); + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, num_ssbos, + target, context_type, DRAW_TCS_JIT_CTX_NUM_SSBOS); + LP_CHECK_MEMBER_OFFSET(struct draw_tes_jit_context, images, + target, context_type, DRAW_TCS_JIT_CTX_IMAGES); + LP_CHECK_STRUCT_SIZE(struct draw_tes_jit_context, + target, context_type); + + return context_type; +} /** * Create LLVM types for various structures. diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index aa5c374a647..4e7859d5dac 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -32,6 +32,7 @@ #include "draw/draw_vs.h" #include "draw/draw_gs.h" +#include "draw/draw_tess.h" #include "gallivm/lp_bld_sample.h" #include "gallivm/lp_bld_limits.h" @@ -317,6 +318,103 @@ enum { #define draw_gs_jit_context_num_ssbos(_gallivm, _ptr) \ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_GS_JIT_CTX_NUM_SSBOS, "num_ssbos") + +struct draw_tcs_jit_context { + const float *constants[LP_MAX_TGSI_CONST_BUFFERS]; + int num_constants[LP_MAX_TGSI_CONST_BUFFERS]; + + int dummy1; + int dummy2; + /* There two need to be exactly at DRAW_JIT_CTX_TEXTURES and + * DRAW_JIT_CTX_SAMPLERS positions in the struct */ + struct draw_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + struct draw_jit_sampler samplers[PIPE_MAX_SAMPLERS]; + struct draw_jit_image images[PIPE_MAX_SHADER_IMAGES]; + + const uint32_t *ssbos[LP_MAX_TGSI_SHADER_BUFFERS]; + int num_ssbos[LP_MAX_TGSI_SHADER_BUFFERS]; +}; + +enum { + DRAW_TCS_JIT_CTX_CONSTANTS = 0, + DRAW_TCS_JIT_CTX_NUM_CONSTANTS = 1, + DRAW_TCS_JIT_CTX_TEXTURES = DRAW_JIT_CTX_TEXTURES, + DRAW_TCS_JIT_CTX_SAMPLERS = DRAW_JIT_CTX_SAMPLERS, + DRAW_TCS_JIT_CTX_IMAGES = DRAW_JIT_CTX_IMAGES, + DRAW_TCS_JIT_CTX_SSBOS = 7, + DRAW_TCS_JIT_CTX_NUM_SSBOS = 8, + DRAW_TCS_JIT_CTX_NUM_FIELDS = 9, +}; + +#define draw_tcs_jit_context_constants(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_CONSTANTS, "constants") + +#define draw_tcs_jit_context_num_constants(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_NUM_CONSTANTS, "num_constants") + +#define draw_tcs_jit_context_textures(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_TEXTURES, "textures") + +#define draw_tcs_jit_context_samplers(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_SAMPLERS, "samplers") + +#define draw_tcs_jit_context_images(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_IMAGES, "images") + +#define draw_tcs_jit_context_ssbos(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_SSBOS, "ssbos") + +#define draw_tcs_jit_context_num_ssbos(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TCS_JIT_CTX_NUM_SSBOS, "num_ssbos") + +struct draw_tes_jit_context { + const float *constants[LP_MAX_TGSI_CONST_BUFFERS]; + int num_constants[LP_MAX_TGSI_CONST_BUFFERS]; + + int dummy1; + int dummy2; + /* There two need to be exactly at DRAW_JIT_CTX_TEXTURES and + * DRAW_JIT_CTX_SAMPLERS positions in the struct */ + struct draw_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + struct draw_jit_sampler samplers[PIPE_MAX_SAMPLERS]; + struct draw_jit_image images[PIPE_MAX_SHADER_IMAGES]; + + const uint32_t *ssbos[LP_MAX_TGSI_SHADER_BUFFERS]; + int num_ssbos[LP_MAX_TGSI_SHADER_BUFFERS]; +}; + +enum { + DRAW_TES_JIT_CTX_CONSTANTS = 0, + DRAW_TES_JIT_CTX_NUM_CONSTANTS = 1, + DRAW_TES_JIT_CTX_TEXTURES = DRAW_JIT_CTX_TEXTURES, + DRAW_TES_JIT_CTX_SAMPLERS = DRAW_JIT_CTX_SAMPLERS, + DRAW_TES_JIT_CTX_IMAGES = DRAW_JIT_CTX_IMAGES, + DRAW_TES_JIT_CTX_SSBOS = 7, + DRAW_TES_JIT_CTX_NUM_SSBOS = 8, + DRAW_TES_JIT_CTX_NUM_FIELDS = 9, +}; + +#define draw_tes_jit_context_constants(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_CONSTANTS, "constants") + +#define draw_tes_jit_context_num_constants(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_NUM_CONSTANTS, "num_constants") + +#define draw_tes_jit_context_textures(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_TEXTURES, "textures") + +#define draw_tes_jit_context_samplers(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_SAMPLERS, "samplers") + +#define draw_tes_jit_context_images(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_IMAGES, "images") + +#define draw_tes_jit_context_ssbos(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_SSBOS, "ssbos") + +#define draw_tes_jit_context_num_ssbos(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_TES_JIT_CTX_NUM_SSBOS, "num_ssbos") + typedef boolean (*draw_jit_vert_func)(struct draw_jit_context *context, struct vertex_header *io, @@ -341,6 +439,21 @@ typedef int int *prim_ids, unsigned invocation_id); +typedef int +(*draw_tcs_jit_func)(struct draw_tcs_jit_context *context, + float inputs[32][NUM_TCS_INPUTS][TGSI_NUM_CHANNELS], + float outputs[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS], + uint32_t prim_id, uint32_t patch_vertices_in); + +typedef int +(*draw_tes_jit_func)(struct draw_tes_jit_context *context, + float inputs[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS], + struct vertex_header *io, + uint32_t prim_id, uint32_t num_tess_coord, + float *tess_coord_x, float *tess_coord_y, float *tess_outer, + float *tess_inner); + + struct draw_llvm_variant_key { unsigned nr_vertex_elements:8; diff --git a/src/gallium/auxiliary/draw/draw_tess.h b/src/gallium/auxiliary/draw/draw_tess.h new file mode 100644 index 00000000000..304677ca27d --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_tess.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2020 Red Hat. + * All Rights Reserved. + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 DRAW_TESS_H +#define DRAW_TESS_H + +#include "draw_context.h" +#include "draw_private.h" + +struct draw_context; +#ifdef LLVM_AVAILABLE + +#define NUM_PATCH_INPUTS 32 +#define NUM_TCS_INPUTS (PIPE_MAX_SHADER_INPUTS - NUM_PATCH_INPUTS) + +#endif + +#endif -- 2.30.2