draw: add main tessellation code
This is the bulk of the llvm shader builders and tessellation execution code. TCS uses a coroutine launcher like compute shaders to handle barriers. It executes 4-wide with one input vertex per lane. Tessellation happens before the TES is run. TES is just a 4-wide launcher, one per primitive is executed, with one lane per tessellation coordinate input. Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3841>
This commit is contained in:
parent
76daf893ea
commit
0d02a7b8ca
|
@ -50,6 +50,8 @@ C_SOURCES := \
|
|||
draw/draw_pt_vsplit_tmp.h \
|
||||
draw/draw_so_emit_tmp.h \
|
||||
draw/draw_split_tmp.h \
|
||||
draw/draw_tess.c \
|
||||
draw/draw_tess.h \
|
||||
draw/draw_vbuf.h \
|
||||
draw/draw_vertex.c \
|
||||
draw/draw_vertex.h \
|
||||
|
|
|
@ -746,6 +746,37 @@ draw_total_gs_outputs(const struct draw_context *draw)
|
|||
return info->num_outputs + draw->extra_shader_outputs.num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return total number of the tess ctrl shader outputs.
|
||||
*/
|
||||
uint
|
||||
draw_total_tcs_outputs(const struct draw_context *draw)
|
||||
{
|
||||
const struct tgsi_shader_info *info;
|
||||
|
||||
if (!draw->tcs.tess_ctrl_shader)
|
||||
return 0;
|
||||
|
||||
info = &draw->tcs.tess_ctrl_shader->info;
|
||||
|
||||
return info->num_outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return total number of the tess eval shader outputs.
|
||||
*/
|
||||
uint
|
||||
draw_total_tes_outputs(const struct draw_context *draw)
|
||||
{
|
||||
const struct tgsi_shader_info *info;
|
||||
|
||||
if (!draw->tes.tess_eval_shader)
|
||||
return 0;
|
||||
|
||||
info = &draw->tes.tess_eval_shader->info;
|
||||
|
||||
return info->num_outputs + draw->extra_shader_outputs.num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide TGSI sampler objects for vertex/geometry shaders that use
|
||||
|
|
|
@ -152,6 +152,12 @@ draw_total_vs_outputs(const struct draw_context *draw);
|
|||
uint
|
||||
draw_total_gs_outputs(const struct draw_context *draw);
|
||||
|
||||
uint
|
||||
draw_total_tcs_outputs(const struct draw_context *draw);
|
||||
|
||||
uint
|
||||
draw_total_tes_outputs(const struct draw_context *draw);
|
||||
|
||||
void
|
||||
draw_texture_sampler(struct draw_context *draw,
|
||||
enum pipe_shader_type shader_type,
|
||||
|
@ -242,6 +248,23 @@ void draw_bind_geometry_shader(struct draw_context *draw,
|
|||
void draw_delete_geometry_shader(struct draw_context *draw,
|
||||
struct draw_geometry_shader *dvs);
|
||||
|
||||
/*
|
||||
* Tess shader functions
|
||||
*/
|
||||
struct draw_tess_ctrl_shader *
|
||||
draw_create_tess_ctrl_shader(struct draw_context *draw,
|
||||
const struct pipe_shader_state *shader);
|
||||
void draw_bind_tess_ctrl_shader(struct draw_context *draw,
|
||||
struct draw_tess_ctrl_shader *dvs);
|
||||
void draw_delete_tess_ctrl_shader(struct draw_context *draw,
|
||||
struct draw_tess_ctrl_shader *dvs);
|
||||
struct draw_tess_eval_shader *
|
||||
draw_create_tess_eval_shader(struct draw_context *draw,
|
||||
const struct pipe_shader_state *shader);
|
||||
void draw_bind_tess_eval_shader(struct draw_context *draw,
|
||||
struct draw_tess_eval_shader *dvs);
|
||||
void draw_delete_tess_eval_shader(struct draw_context *draw,
|
||||
struct draw_tess_eval_shader *dvs);
|
||||
|
||||
/*
|
||||
* Vertex data functions
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -44,6 +44,8 @@
|
|||
struct draw_llvm;
|
||||
struct llvm_vertex_shader;
|
||||
struct llvm_geometry_shader;
|
||||
struct llvm_tess_ctrl_shader;
|
||||
struct llvm_tess_eval_shader;
|
||||
|
||||
struct draw_jit_texture
|
||||
{
|
||||
|
@ -467,7 +469,7 @@ struct draw_llvm_variant_key
|
|||
unsigned clip_halfz:1;
|
||||
unsigned bypass_viewport:1;
|
||||
unsigned need_edgeflags:1;
|
||||
unsigned has_gs:1;
|
||||
unsigned has_gs_or_tes:1;
|
||||
unsigned num_outputs:8;
|
||||
unsigned ucp_enable:PIPE_MAX_CLIP_PLANES;
|
||||
/* note padding here - must use memset */
|
||||
|
@ -495,6 +497,24 @@ struct draw_gs_llvm_variant_key
|
|||
/* Followed by variable number of images.*/
|
||||
};
|
||||
|
||||
struct draw_tcs_llvm_variant_key
|
||||
{
|
||||
unsigned nr_samplers:8;
|
||||
unsigned nr_sampler_views:8;
|
||||
unsigned nr_images:8;
|
||||
struct draw_sampler_static_state samplers[1];
|
||||
/* Followed by variable number of images.*/
|
||||
};
|
||||
|
||||
struct draw_tes_llvm_variant_key
|
||||
{
|
||||
unsigned nr_samplers:8;
|
||||
unsigned nr_sampler_views:8;
|
||||
unsigned nr_images:8;
|
||||
struct draw_sampler_static_state samplers[1];
|
||||
/* Followed by variable number of images.*/
|
||||
};
|
||||
|
||||
#define DRAW_LLVM_MAX_VARIANT_KEY_SIZE \
|
||||
(sizeof(struct draw_llvm_variant_key) + \
|
||||
PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state) + \
|
||||
|
@ -506,6 +526,16 @@ struct draw_gs_llvm_variant_key
|
|||
PIPE_MAX_SHADER_IMAGES * sizeof(struct draw_image_static_state) + \
|
||||
PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state))
|
||||
|
||||
#define DRAW_TCS_LLVM_MAX_VARIANT_KEY_SIZE \
|
||||
(sizeof(struct draw_tcs_llvm_variant_key) + \
|
||||
PIPE_MAX_SHADER_IMAGES * sizeof(struct draw_image_static_state) + \
|
||||
PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state))
|
||||
|
||||
#define DRAW_TES_LLVM_MAX_VARIANT_KEY_SIZE \
|
||||
(sizeof(struct draw_tes_llvm_variant_key) + \
|
||||
PIPE_MAX_SHADER_IMAGES * sizeof(struct draw_image_static_state) + \
|
||||
PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state))
|
||||
|
||||
|
||||
static inline size_t
|
||||
draw_llvm_variant_key_size(unsigned nr_vertex_elements,
|
||||
|
@ -526,6 +556,21 @@ draw_gs_llvm_variant_key_size(unsigned nr_samplers, unsigned nr_images)
|
|||
(nr_samplers - 1) * sizeof(struct draw_sampler_static_state));
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
draw_tcs_llvm_variant_key_size(unsigned nr_samplers, unsigned nr_images)
|
||||
{
|
||||
return (sizeof(struct draw_tcs_llvm_variant_key) +
|
||||
(nr_images) * sizeof(struct draw_sampler_static_state) +
|
||||
(nr_samplers - 1) * sizeof(struct draw_sampler_static_state));
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
draw_tes_llvm_variant_key_size(unsigned nr_samplers, unsigned nr_images)
|
||||
{
|
||||
return (sizeof(struct draw_tes_llvm_variant_key) +
|
||||
(nr_images) * sizeof(struct draw_sampler_static_state) +
|
||||
(nr_samplers - 1) * sizeof(struct draw_sampler_static_state));
|
||||
}
|
||||
|
||||
static inline struct draw_sampler_static_state *
|
||||
draw_llvm_variant_key_samplers(struct draw_llvm_variant_key *key)
|
||||
|
@ -550,6 +595,20 @@ draw_gs_llvm_variant_key_images(struct draw_gs_llvm_variant_key *key)
|
|||
&key->samplers[key->nr_samplers];
|
||||
}
|
||||
|
||||
static inline struct draw_image_static_state *
|
||||
draw_tcs_llvm_variant_key_images(struct draw_tcs_llvm_variant_key *key)
|
||||
{
|
||||
return (struct draw_image_static_state *)
|
||||
&key->samplers[key->nr_samplers];
|
||||
}
|
||||
|
||||
static inline struct draw_image_static_state *
|
||||
draw_tes_llvm_variant_key_images(struct draw_tes_llvm_variant_key *key)
|
||||
{
|
||||
return (struct draw_image_static_state *)
|
||||
&key->samplers[key->nr_samplers];
|
||||
}
|
||||
|
||||
struct draw_llvm_variant_list_item
|
||||
{
|
||||
struct draw_llvm_variant *base;
|
||||
|
@ -562,6 +621,17 @@ struct draw_gs_llvm_variant_list_item
|
|||
struct draw_gs_llvm_variant_list_item *next, *prev;
|
||||
};
|
||||
|
||||
struct draw_tcs_llvm_variant_list_item
|
||||
{
|
||||
struct draw_tcs_llvm_variant *base;
|
||||
struct draw_tcs_llvm_variant_list_item *next, *prev;
|
||||
};
|
||||
|
||||
struct draw_tes_llvm_variant_list_item
|
||||
{
|
||||
struct draw_tes_llvm_variant *base;
|
||||
struct draw_tes_llvm_variant_list_item *next, *prev;
|
||||
};
|
||||
|
||||
struct draw_llvm_variant
|
||||
{
|
||||
|
@ -612,6 +682,57 @@ struct draw_gs_llvm_variant
|
|||
struct draw_gs_llvm_variant_key key;
|
||||
};
|
||||
|
||||
struct draw_tcs_llvm_variant
|
||||
{
|
||||
struct gallivm_state *gallivm;
|
||||
|
||||
/* LLVM JIT builder types */
|
||||
LLVMTypeRef context_ptr_type;
|
||||
LLVMTypeRef input_array_type;
|
||||
LLVMTypeRef output_array_type;
|
||||
|
||||
LLVMValueRef context_ptr;
|
||||
LLVMValueRef io_ptr;
|
||||
LLVMValueRef num_prims;
|
||||
LLVMValueRef function;
|
||||
draw_tcs_jit_func jit_func;
|
||||
|
||||
struct llvm_tess_ctrl_shader *shader;
|
||||
|
||||
struct draw_llvm *llvm;
|
||||
struct draw_tcs_llvm_variant_list_item list_item_global;
|
||||
struct draw_tcs_llvm_variant_list_item list_item_local;
|
||||
|
||||
/* key is variable-sized, must be last */
|
||||
struct draw_tcs_llvm_variant_key key;
|
||||
};
|
||||
|
||||
struct draw_tes_llvm_variant
|
||||
{
|
||||
struct gallivm_state *gallivm;
|
||||
|
||||
/* LLVM JIT builder types */
|
||||
LLVMTypeRef context_ptr_type;
|
||||
LLVMTypeRef vertex_header_ptr_type;
|
||||
LLVMTypeRef input_array_type;
|
||||
LLVMTypeRef patch_input_array_type;
|
||||
|
||||
LLVMValueRef context_ptr;
|
||||
LLVMValueRef io_ptr;
|
||||
LLVMValueRef num_prims;
|
||||
LLVMValueRef function;
|
||||
draw_tes_jit_func jit_func;
|
||||
|
||||
struct llvm_tess_eval_shader *shader;
|
||||
|
||||
struct draw_llvm *llvm;
|
||||
struct draw_tes_llvm_variant_list_item list_item_global;
|
||||
struct draw_tes_llvm_variant_list_item list_item_local;
|
||||
|
||||
/* key is variable-sized, must be last */
|
||||
struct draw_tes_llvm_variant_key key;
|
||||
};
|
||||
|
||||
struct llvm_vertex_shader {
|
||||
struct draw_vertex_shader base;
|
||||
|
||||
|
@ -630,6 +751,23 @@ struct llvm_geometry_shader {
|
|||
unsigned variants_cached;
|
||||
};
|
||||
|
||||
struct llvm_tess_ctrl_shader {
|
||||
struct draw_tess_ctrl_shader base;
|
||||
|
||||
unsigned variant_key_size;
|
||||
struct draw_tcs_llvm_variant_list_item variants;
|
||||
unsigned variants_created;
|
||||
unsigned variants_cached;
|
||||
};
|
||||
|
||||
struct llvm_tess_eval_shader {
|
||||
struct draw_tess_eval_shader base;
|
||||
|
||||
unsigned variant_key_size;
|
||||
struct draw_tes_llvm_variant_list_item variants;
|
||||
unsigned variants_created;
|
||||
unsigned variants_cached;
|
||||
};
|
||||
|
||||
struct draw_llvm {
|
||||
struct draw_context *draw;
|
||||
|
@ -639,12 +777,20 @@ struct draw_llvm {
|
|||
|
||||
struct draw_jit_context jit_context;
|
||||
struct draw_gs_jit_context gs_jit_context;
|
||||
struct draw_tcs_jit_context tcs_jit_context;
|
||||
struct draw_tes_jit_context tes_jit_context;
|
||||
|
||||
struct draw_llvm_variant_list_item vs_variants_list;
|
||||
int nr_variants;
|
||||
|
||||
struct draw_gs_llvm_variant_list_item gs_variants_list;
|
||||
int nr_gs_variants;
|
||||
|
||||
struct draw_tcs_llvm_variant_list_item tcs_variants_list;
|
||||
int nr_tcs_variants;
|
||||
|
||||
struct draw_tes_llvm_variant_list_item tes_variants_list;
|
||||
int nr_tes_variants;
|
||||
};
|
||||
|
||||
|
||||
|
@ -660,8 +806,17 @@ llvm_geometry_shader(struct draw_geometry_shader *gs)
|
|||
return (struct llvm_geometry_shader *)gs;
|
||||
}
|
||||
|
||||
static inline struct llvm_tess_ctrl_shader *
|
||||
llvm_tess_ctrl_shader(struct draw_tess_ctrl_shader *tcs)
|
||||
{
|
||||
return (struct llvm_tess_ctrl_shader *)tcs;
|
||||
}
|
||||
|
||||
|
||||
static inline struct llvm_tess_eval_shader *
|
||||
llvm_tess_eval_shader(struct draw_tess_eval_shader *tes)
|
||||
{
|
||||
return (struct llvm_tess_eval_shader *)tes;
|
||||
}
|
||||
|
||||
struct draw_llvm *
|
||||
draw_llvm_create(struct draw_context *draw, LLVMContextRef llvm_context);
|
||||
|
@ -698,6 +853,34 @@ draw_gs_llvm_make_variant_key(struct draw_llvm *llvm, char *store);
|
|||
void
|
||||
draw_gs_llvm_dump_variant_key(struct draw_gs_llvm_variant_key *key);
|
||||
|
||||
struct draw_tcs_llvm_variant *
|
||||
draw_tcs_llvm_create_variant(struct draw_llvm *llvm,
|
||||
unsigned num_vertex_header_attribs,
|
||||
const struct draw_tcs_llvm_variant_key *key);
|
||||
|
||||
void
|
||||
draw_tcs_llvm_destroy_variant(struct draw_tcs_llvm_variant *variant);
|
||||
|
||||
struct draw_tcs_llvm_variant_key *
|
||||
draw_tcs_llvm_make_variant_key(struct draw_llvm *llvm, char *store);
|
||||
|
||||
void
|
||||
draw_tcs_llvm_dump_variant_key(struct draw_tcs_llvm_variant_key *key);
|
||||
|
||||
struct draw_tes_llvm_variant *
|
||||
draw_tes_llvm_create_variant(struct draw_llvm *llvm,
|
||||
unsigned num_vertex_header_attribs,
|
||||
const struct draw_tes_llvm_variant_key *key);
|
||||
|
||||
void
|
||||
draw_tes_llvm_destroy_variant(struct draw_tes_llvm_variant *variant);
|
||||
|
||||
struct draw_tes_llvm_variant_key *
|
||||
draw_tes_llvm_make_variant_key(struct draw_llvm *llvm, char *store);
|
||||
|
||||
void
|
||||
draw_tes_llvm_dump_variant_key(struct draw_tes_llvm_variant_key *key);
|
||||
|
||||
struct lp_build_sampler_soa *
|
||||
draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state);
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ struct draw_context
|
|||
unsigned prim;
|
||||
unsigned opt; /**< bitmask of PT_x flags */
|
||||
unsigned eltSize; /* saved eltSize for flushing */
|
||||
|
||||
ubyte vertices_per_patch;
|
||||
boolean rebind_parameters;
|
||||
|
||||
struct {
|
||||
|
@ -206,12 +206,20 @@ struct draw_context
|
|||
unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
const void *tcs_constants[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
unsigned tcs_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
const void *tes_constants[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
unsigned tes_constants_size[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
|
||||
/** shader buffers (for vertex/geometry shader) */
|
||||
const void *vs_ssbos[PIPE_MAX_SHADER_BUFFERS];
|
||||
unsigned vs_ssbos_size[PIPE_MAX_SHADER_BUFFERS];
|
||||
const void *gs_ssbos[PIPE_MAX_SHADER_BUFFERS];
|
||||
unsigned gs_ssbos_size[PIPE_MAX_SHADER_BUFFERS];
|
||||
const void *tcs_ssbos[PIPE_MAX_SHADER_BUFFERS];
|
||||
unsigned tcs_ssbos_size[PIPE_MAX_SHADER_BUFFERS];
|
||||
const void *tes_ssbos[PIPE_MAX_SHADER_BUFFERS];
|
||||
unsigned tes_ssbos_size[PIPE_MAX_SHADER_BUFFERS];
|
||||
|
||||
/* pointer to planes */
|
||||
float (*planes)[DRAW_TOTAL_CLIP_PLANES][4];
|
||||
|
@ -303,6 +311,34 @@ struct draw_context
|
|||
|
||||
} gs;
|
||||
|
||||
/* Tessellation state */
|
||||
struct {
|
||||
struct draw_tess_ctrl_shader *tess_ctrl_shader;
|
||||
|
||||
/** Fields for TGSI interpreter / execution */
|
||||
struct {
|
||||
struct tgsi_exec_machine *machine;
|
||||
|
||||
struct tgsi_sampler *sampler;
|
||||
struct tgsi_image *image;
|
||||
struct tgsi_buffer *buffer;
|
||||
} tgsi;
|
||||
} tcs;
|
||||
|
||||
struct {
|
||||
struct draw_tess_eval_shader *tess_eval_shader;
|
||||
uint position_output;
|
||||
|
||||
/** Fields for TGSI interpreter / execution */
|
||||
struct {
|
||||
struct tgsi_exec_machine *machine;
|
||||
|
||||
struct tgsi_sampler *sampler;
|
||||
struct tgsi_image *image;
|
||||
struct tgsi_buffer *buffer;
|
||||
} tgsi;
|
||||
} tes;
|
||||
|
||||
/** Fragment shader state */
|
||||
struct {
|
||||
struct draw_fragment_shader *fragment_shader;
|
||||
|
@ -349,6 +385,8 @@ struct draw_context
|
|||
struct pipe_query_data_pipeline_statistics statistics;
|
||||
boolean collect_statistics;
|
||||
|
||||
float default_outer_tess_level[4];
|
||||
float default_inner_tess_level[2];
|
||||
bool collect_primgen;
|
||||
|
||||
struct draw_assembler *ia;
|
||||
|
|
|
@ -0,0 +1,630 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
#include "draw_tess.h"
|
||||
#ifdef LLVM_AVAILABLE
|
||||
#include "draw_llvm.h"
|
||||
#endif
|
||||
|
||||
#include "tessellator/p_tessellator.h"
|
||||
#include "nir/nir_to_tgsi_info.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
static inline int
|
||||
draw_tes_get_input_index(int semantic, int index,
|
||||
const struct tgsi_shader_info *input_info)
|
||||
{
|
||||
int i;
|
||||
const ubyte *input_semantic_names = input_info->output_semantic_name;
|
||||
const ubyte *input_semantic_indices = input_info->output_semantic_index;
|
||||
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
|
||||
if (input_semantic_names[i] == semantic &&
|
||||
input_semantic_indices[i] == index)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
#define DEBUG_INPUTS 0
|
||||
static void
|
||||
llvm_fetch_tcs_input(struct draw_tess_ctrl_shader *shader,
|
||||
const struct draw_prim_info *input_prim_info,
|
||||
unsigned prim_id,
|
||||
unsigned num_vertices)
|
||||
{
|
||||
const float (*input_ptr)[4];
|
||||
float (*input_data)[32][NUM_TCS_INPUTS][TGSI_NUM_CHANNELS] = &shader->tcs_input->data;
|
||||
unsigned slot, i;
|
||||
int vs_slot;
|
||||
unsigned input_vertex_stride = shader->input_vertex_stride;
|
||||
|
||||
input_ptr = shader->input;
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
const float (*input)[4];
|
||||
int vertex_idx = prim_id * num_vertices + i;
|
||||
if (input_prim_info->linear == FALSE)
|
||||
vertex_idx = input_prim_info->elts[vertex_idx];
|
||||
#if DEBUG_INPUTS
|
||||
debug_printf("%d) tcs vertex index = %d (prim idx = %d)\n",
|
||||
i, prim_id, 0);
|
||||
#endif
|
||||
input = (const float (*)[4])((const char *)input_ptr + (vertex_idx * input_vertex_stride));
|
||||
for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
|
||||
vs_slot = draw_tes_get_input_index(
|
||||
shader->info.input_semantic_name[slot],
|
||||
shader->info.input_semantic_index[slot],
|
||||
shader->input_info);
|
||||
if (vs_slot < 0) {
|
||||
debug_printf("VS/TCS signature mismatch!\n");
|
||||
(*input_data)[i][slot][0] = 0;
|
||||
(*input_data)[i][slot][1] = 0;
|
||||
(*input_data)[i][slot][2] = 0;
|
||||
(*input_data)[i][slot][3] = 0;
|
||||
} else {
|
||||
(*input_data)[i][slot][0] = input[vs_slot][0];
|
||||
(*input_data)[i][slot][1] = input[vs_slot][1];
|
||||
(*input_data)[i][slot][2] = input[vs_slot][2];
|
||||
(*input_data)[i][slot][3] = input[vs_slot][3];
|
||||
#if DEBUG_INPUTS
|
||||
debug_printf("\t\t%p = %f %f %f %f\n", &(*input_data)[i][slot][0],
|
||||
(*input_data)[i][slot][0],
|
||||
(*input_data)[i][slot][1],
|
||||
(*input_data)[i][slot][2],
|
||||
(*input_data)[i][slot][3]);
|
||||
#endif
|
||||
++vs_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DEBUG_OUTPUTS 0
|
||||
static void
|
||||
llvm_store_tcs_output(struct draw_tess_ctrl_shader *shader,
|
||||
unsigned prim_id,
|
||||
struct draw_vertex_info *output_verts,
|
||||
unsigned vert_start)
|
||||
{
|
||||
float (*output_ptr)[4];
|
||||
float (*output_data)[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS] = &shader->tcs_output->data;
|
||||
unsigned slot, i;
|
||||
unsigned num_vertices = shader->vertices_out;
|
||||
|
||||
char *output = (char *)output_verts->verts->data;
|
||||
output += vert_start * output_verts->stride;
|
||||
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
|
||||
#if DEBUG_OUTPUTS
|
||||
debug_printf("%d) tcs store vertex index = %d (prim idx = %d)\n",
|
||||
i, prim_id, 0);
|
||||
#endif
|
||||
output_ptr = (float(*)[4])(output + (i * output_verts->stride));
|
||||
|
||||
for (slot = 0; slot < shader->info.num_outputs; ++slot) {
|
||||
output_ptr[slot][0] = (*output_data)[i][slot][0];
|
||||
output_ptr[slot][1] = (*output_data)[i][slot][1];
|
||||
output_ptr[slot][2] = (*output_data)[i][slot][2];
|
||||
output_ptr[slot][3] = (*output_data)[i][slot][3];
|
||||
#if DEBUG_OUTPUTS
|
||||
debug_printf("\t\t%p = %f %f %f %f\n",
|
||||
&output_ptr[slot][0],
|
||||
output_ptr[slot][0],
|
||||
output_ptr[slot][1],
|
||||
output_ptr[slot][2],
|
||||
output_ptr[slot][3]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
llvm_tcs_run(struct draw_tess_ctrl_shader *shader, uint32_t prim_id)
|
||||
{
|
||||
shader->current_variant->jit_func(shader->jit_context, shader->tcs_input->data, shader->tcs_output->data, prim_id,
|
||||
shader->draw->pt.vertices_per_patch);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Execute tess ctrl shader.
|
||||
*/
|
||||
int draw_tess_ctrl_shader_run(struct draw_tess_ctrl_shader *shader,
|
||||
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
const struct draw_vertex_info *input_verts,
|
||||
const struct draw_prim_info *input_prim,
|
||||
const struct tgsi_shader_info *input_info,
|
||||
struct draw_vertex_info *output_verts,
|
||||
struct draw_prim_info *output_prims )
|
||||
{
|
||||
const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
|
||||
unsigned num_outputs = draw_total_tcs_outputs(shader->draw);
|
||||
unsigned input_stride = input_verts->vertex_size;
|
||||
unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
|
||||
unsigned num_patches = input_prim->count / shader->draw->pt.vertices_per_patch;
|
||||
|
||||
output_verts->vertex_size = vertex_size;
|
||||
output_verts->stride = output_verts->vertex_size;
|
||||
output_verts->verts = NULL;
|
||||
output_verts->count = 0;
|
||||
shader->input = input;
|
||||
shader->input_vertex_stride = input_stride;
|
||||
shader->input_info = input_info;
|
||||
|
||||
output_prims->linear = TRUE;
|
||||
output_prims->start = 0;
|
||||
output_prims->elts = NULL;
|
||||
output_prims->count = 0;
|
||||
output_prims->prim = PIPE_PRIM_PATCHES;
|
||||
output_prims->flags = 0;
|
||||
output_prims->primitive_lengths = NULL;
|
||||
output_prims->primitive_count = 0;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
for (unsigned i = 0; i < num_patches; i++) {
|
||||
uint32_t vert_start = output_verts->count;
|
||||
|
||||
output_verts->count += shader->vertices_out;
|
||||
|
||||
llvm_fetch_tcs_input(shader, input_prim, i, shader->draw->pt.vertices_per_patch);
|
||||
|
||||
llvm_tcs_run(shader, i);
|
||||
|
||||
uint32_t old_verts = util_align_npot(vert_start, 16);
|
||||
uint32_t new_verts = util_align_npot(output_verts->count, 16);
|
||||
uint32_t old_size = output_verts->vertex_size * old_verts;
|
||||
uint32_t new_size = output_verts->vertex_size * new_verts;
|
||||
output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
|
||||
|
||||
llvm_store_tcs_output(shader, i, output_verts, vert_start);
|
||||
}
|
||||
#endif
|
||||
|
||||
output_prims->primitive_count = num_patches;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
#define DEBUG_INPUTS 0
|
||||
static void
|
||||
llvm_fetch_tes_input(struct draw_tess_eval_shader *shader,
|
||||
const struct draw_prim_info *input_prim_info,
|
||||
unsigned prim_id,
|
||||
unsigned num_vertices)
|
||||
{
|
||||
const float (*input_ptr)[4];
|
||||
float (*input_data)[32][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS] = &shader->tes_input->data;
|
||||
unsigned slot, i;
|
||||
int vs_slot;
|
||||
unsigned input_vertex_stride = shader->input_vertex_stride;
|
||||
|
||||
input_ptr = shader->input;
|
||||
for (i = 0; i < num_vertices; i++) {
|
||||
const float (*input)[4];
|
||||
int vertex_idx = prim_id * num_vertices + i;
|
||||
|
||||
if (input_prim_info->linear == FALSE)
|
||||
vertex_idx = input_prim_info->elts[vertex_idx];
|
||||
#if DEBUG_INPUTS
|
||||
debug_printf("%d) tes vertex index = %d (prim idx = %d)\n",
|
||||
i, prim_id, 0);
|
||||
#endif
|
||||
input = (const float (*)[4])((const char *)input_ptr + (vertex_idx * input_vertex_stride));
|
||||
for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
|
||||
vs_slot = draw_tes_get_input_index(
|
||||
shader->info.input_semantic_name[slot],
|
||||
shader->info.input_semantic_index[slot],
|
||||
shader->input_info);
|
||||
if (vs_slot < 0) {
|
||||
debug_printf("TCS/TES signature mismatch!\n");
|
||||
(*input_data)[i][slot][0] = 0;
|
||||
(*input_data)[i][slot][1] = 0;
|
||||
(*input_data)[i][slot][2] = 0;
|
||||
(*input_data)[i][slot][3] = 0;
|
||||
} else {
|
||||
(*input_data)[i][slot][0] = input[vs_slot][0];
|
||||
(*input_data)[i][slot][1] = input[vs_slot][1];
|
||||
(*input_data)[i][slot][2] = input[vs_slot][2];
|
||||
(*input_data)[i][slot][3] = input[vs_slot][3];
|
||||
#if DEBUG_INPUTS
|
||||
debug_printf("\t\t%p = %f %f %f %f\n",
|
||||
&input[vs_slot][0],
|
||||
(*input_data)[i][slot][0],
|
||||
(*input_data)[i][slot][1],
|
||||
(*input_data)[i][slot][2],
|
||||
(*input_data)[i][slot][3]);
|
||||
#endif
|
||||
++vs_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
llvm_fetch_tess_factors(struct draw_tess_eval_shader *shader,
|
||||
unsigned patch_id,
|
||||
unsigned num_vertices,
|
||||
struct pipe_tessellation_factors *factors)
|
||||
{
|
||||
int outer_slot = draw_tes_get_input_index(
|
||||
TGSI_SEMANTIC_TESSOUTER, 0, shader->input_info);
|
||||
int inner_slot = draw_tes_get_input_index(
|
||||
TGSI_SEMANTIC_TESSINNER, 0, shader->input_info);
|
||||
const float (*input_ptr)[4];
|
||||
const float (*input)[4];
|
||||
input_ptr = shader->input;
|
||||
input = (const float (*)[4])((const char *)input_ptr + ((patch_id * num_vertices) * shader->input_vertex_stride));
|
||||
|
||||
if (outer_slot != -1) {
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
factors->outer_tf[i] = input[outer_slot][i];
|
||||
} else {
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
factors->outer_tf[i] = shader->draw->default_outer_tess_level[i];
|
||||
}
|
||||
if (inner_slot != -1) {
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
factors->inner_tf[i] = input[inner_slot][i];
|
||||
} else {
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
factors->inner_tf[i] = shader->draw->default_inner_tess_level[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
llvm_tes_run(struct draw_tess_eval_shader *shader,
|
||||
uint32_t prim_id,
|
||||
struct pipe_tessellator_data *tess_data,
|
||||
struct pipe_tessellation_factors *tess_factors,
|
||||
struct vertex_header *output)
|
||||
{
|
||||
shader->current_variant->jit_func(shader->jit_context, shader->tes_input->data, output, prim_id,
|
||||
tess_data->num_domain_points, tess_data->domain_points_u, tess_data->domain_points_v,
|
||||
tess_factors->outer_tf, tess_factors->inner_tf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Execute tess eval shader.
|
||||
*/
|
||||
int draw_tess_eval_shader_run(struct draw_tess_eval_shader *shader,
|
||||
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
unsigned num_input_vertices_per_patch,
|
||||
const struct draw_vertex_info *input_verts,
|
||||
const struct draw_prim_info *input_prim,
|
||||
const struct tgsi_shader_info *input_info,
|
||||
struct draw_vertex_info *output_verts,
|
||||
struct draw_prim_info *output_prims,
|
||||
ushort **elts_out)
|
||||
{
|
||||
const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
|
||||
unsigned num_outputs = draw_total_tes_outputs(shader->draw);
|
||||
unsigned input_stride = input_verts->vertex_size;
|
||||
unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
|
||||
ushort *elts = NULL;
|
||||
output_verts->vertex_size = vertex_size;
|
||||
output_verts->stride = output_verts->vertex_size;
|
||||
output_verts->count = 0;
|
||||
output_verts->verts = NULL;
|
||||
|
||||
output_prims->linear = FALSE;
|
||||
output_prims->start = 0;
|
||||
output_prims->elts = NULL;
|
||||
output_prims->count = 0;
|
||||
output_prims->prim = get_tes_output_prim(shader);
|
||||
output_prims->flags = 0;
|
||||
output_prims->primitive_lengths = NULL;
|
||||
output_prims->primitive_count = 0;
|
||||
|
||||
shader->input = input;
|
||||
shader->input_vertex_stride = input_stride;
|
||||
shader->input_info = input_info;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
struct pipe_tessellation_factors factors;
|
||||
struct pipe_tessellator_data data = { 0 };
|
||||
struct pipe_tessellator *ptess = p_tess_init(shader->prim_mode,
|
||||
shader->spacing,
|
||||
!shader->vertex_order_cw,
|
||||
shader->point_mode);
|
||||
for (unsigned i = 0; i < input_prim->primitive_count; i++) {
|
||||
uint32_t vert_start = output_verts->count;
|
||||
uint32_t prim_start = output_prims->primitive_count;
|
||||
uint32_t elt_start = output_prims->count;
|
||||
|
||||
llvm_fetch_tess_factors(shader, i, num_input_vertices_per_patch, &factors);
|
||||
|
||||
/* tessellate with the factors for this primitive */
|
||||
p_tessellate(ptess, &factors, &data);
|
||||
|
||||
if (data.num_domain_points == 0)
|
||||
continue;
|
||||
|
||||
uint32_t old_verts = vert_start;
|
||||
uint32_t new_verts = vert_start + util_align_npot(data.num_domain_points, 4);
|
||||
uint32_t old_size = output_verts->vertex_size * old_verts;
|
||||
uint32_t new_size = output_verts->vertex_size * new_verts;
|
||||
output_verts->verts = REALLOC(output_verts->verts, old_size, new_size);
|
||||
|
||||
output_verts->count += data.num_domain_points;
|
||||
|
||||
output_prims->count += data.num_indices;
|
||||
elts = REALLOC(elts, elt_start * sizeof(uint16_t),
|
||||
output_prims->count * sizeof(uint16_t));
|
||||
|
||||
for (unsigned i = 0; i < data.num_indices; i++)
|
||||
elts[elt_start + i] = vert_start + data.indices[i];
|
||||
|
||||
llvm_fetch_tes_input(shader, input_prim, i, num_input_vertices_per_patch);
|
||||
/* run once per primitive? */
|
||||
char *output = (char *)output_verts->verts;
|
||||
output += vert_start * vertex_size;
|
||||
llvm_tes_run(shader, i, &data, &factors, (struct vertex_header *)output);
|
||||
|
||||
uint32_t prim_len = u_prim_vertex_count(output_prims->prim)->min;
|
||||
output_prims->primitive_count += data.num_indices / prim_len;
|
||||
output_prims->primitive_lengths = REALLOC(output_prims->primitive_lengths, prim_start * sizeof(uint32_t),
|
||||
output_prims->primitive_count * sizeof(uint32_t));
|
||||
for (unsigned i = prim_start; i < output_prims->primitive_count; i++) {
|
||||
output_prims->primitive_lengths[i] = prim_len;
|
||||
}
|
||||
}
|
||||
p_tess_destroy(ptess);
|
||||
#endif
|
||||
|
||||
*elts_out = elts;
|
||||
output_prims->elts = elts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct draw_tess_ctrl_shader *
|
||||
draw_create_tess_ctrl_shader(struct draw_context *draw,
|
||||
const struct pipe_shader_state *state)
|
||||
{
|
||||
#ifdef LLVM_AVAILABLE
|
||||
boolean use_llvm = draw->llvm != NULL;
|
||||
struct llvm_tess_ctrl_shader *llvm_tcs = NULL;
|
||||
#endif
|
||||
struct draw_tess_ctrl_shader *tcs;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
if (use_llvm) {
|
||||
llvm_tcs = CALLOC_STRUCT(llvm_tess_ctrl_shader);
|
||||
|
||||
if (!llvm_tcs)
|
||||
return NULL;
|
||||
|
||||
tcs = &llvm_tcs->base;
|
||||
|
||||
make_empty_list(&llvm_tcs->variants);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
tcs = CALLOC_STRUCT(draw_tess_ctrl_shader);
|
||||
}
|
||||
|
||||
if (!tcs)
|
||||
return NULL;
|
||||
|
||||
tcs->draw = draw;
|
||||
tcs->state = *state;
|
||||
|
||||
nir_tgsi_scan_shader(state->ir.nir, &tcs->info, true);
|
||||
|
||||
tcs->vector_length = 4;
|
||||
tcs->vertices_out = tcs->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
|
||||
#ifdef LLVM_AVAILABLE
|
||||
if (use_llvm) {
|
||||
|
||||
tcs->tcs_input = align_malloc(sizeof(struct draw_tcs_inputs), 16);
|
||||
memset(tcs->tcs_input, 0, sizeof(struct draw_tcs_inputs));
|
||||
|
||||
tcs->tcs_output = align_malloc(sizeof(struct draw_tcs_outputs), 16);
|
||||
memset(tcs->tcs_output, 0, sizeof(struct draw_tcs_outputs));
|
||||
|
||||
tcs->jit_context = &draw->llvm->tcs_jit_context;
|
||||
llvm_tcs->variant_key_size =
|
||||
draw_tcs_llvm_variant_key_size(
|
||||
MAX2(tcs->info.file_max[TGSI_FILE_SAMPLER]+1,
|
||||
tcs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1),
|
||||
tcs->info.file_max[TGSI_FILE_IMAGE]+1);
|
||||
}
|
||||
#endif
|
||||
return tcs;
|
||||
}
|
||||
|
||||
void draw_bind_tess_ctrl_shader(struct draw_context *draw,
|
||||
struct draw_tess_ctrl_shader *dtcs)
|
||||
{
|
||||
draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
|
||||
if (dtcs) {
|
||||
draw->tcs.tess_ctrl_shader = dtcs;
|
||||
} else {
|
||||
draw->tcs.tess_ctrl_shader = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_delete_tess_ctrl_shader(struct draw_context *draw,
|
||||
struct draw_tess_ctrl_shader *dtcs)
|
||||
{
|
||||
if (!dtcs)
|
||||
return;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
if (draw->llvm) {
|
||||
struct llvm_tess_ctrl_shader *shader = llvm_tess_ctrl_shader(dtcs);
|
||||
|
||||
struct draw_tcs_llvm_variant_list_item *li;
|
||||
|
||||
li = first_elem(&shader->variants);
|
||||
while(!at_end(&shader->variants, li)) {
|
||||
struct draw_tcs_llvm_variant_list_item *next = next_elem(li);
|
||||
draw_tcs_llvm_destroy_variant(li->base);
|
||||
li = next;
|
||||
}
|
||||
|
||||
assert(shader->variants_cached == 0);
|
||||
}
|
||||
#endif
|
||||
FREE(dtcs);
|
||||
}
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
void draw_tcs_set_current_variant(struct draw_tess_ctrl_shader *shader,
|
||||
struct draw_tcs_llvm_variant *variant)
|
||||
{
|
||||
shader->current_variant = variant;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct draw_tess_eval_shader *
|
||||
draw_create_tess_eval_shader(struct draw_context *draw,
|
||||
const struct pipe_shader_state *state)
|
||||
{
|
||||
#ifdef LLVM_AVAILABLE
|
||||
boolean use_llvm = draw->llvm != NULL;
|
||||
struct llvm_tess_eval_shader *llvm_tes = NULL;
|
||||
#endif
|
||||
struct draw_tess_eval_shader *tes;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
if (use_llvm) {
|
||||
llvm_tes = CALLOC_STRUCT(llvm_tess_eval_shader);
|
||||
|
||||
if (!llvm_tes)
|
||||
return NULL;
|
||||
|
||||
tes = &llvm_tes->base;
|
||||
make_empty_list(&llvm_tes->variants);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
tes = CALLOC_STRUCT(draw_tess_eval_shader);
|
||||
}
|
||||
|
||||
if (!tes)
|
||||
return NULL;
|
||||
|
||||
tes->draw = draw;
|
||||
tes->state = *state;
|
||||
|
||||
nir_tgsi_scan_shader(state->ir.nir, &tes->info, true);
|
||||
|
||||
tes->prim_mode = tes->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
|
||||
tes->spacing = tes->info.properties[TGSI_PROPERTY_TES_SPACING];
|
||||
tes->vertex_order_cw = tes->info.properties[TGSI_PROPERTY_TES_VERTEX_ORDER_CW];
|
||||
tes->point_mode = tes->info.properties[TGSI_PROPERTY_TES_POINT_MODE];
|
||||
|
||||
tes->vector_length = 4;
|
||||
|
||||
tes->position_output = -1;
|
||||
for (unsigned i = 0; i < tes->info.num_outputs; i++) {
|
||||
if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
|
||||
tes->info.output_semantic_index[i] == 0)
|
||||
tes->position_output = i;
|
||||
if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
|
||||
tes->viewport_index_output = i;
|
||||
if (tes->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
|
||||
debug_assert(tes->info.output_semantic_index[i] <
|
||||
PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
|
||||
tes->ccdistance_output[tes->info.output_semantic_index[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
if (use_llvm) {
|
||||
|
||||
tes->tes_input = align_malloc(sizeof(struct draw_tes_inputs), 16);
|
||||
memset(tes->tes_input, 0, sizeof(struct draw_tes_inputs));
|
||||
|
||||
tes->jit_context = &draw->llvm->tes_jit_context;
|
||||
llvm_tes->variant_key_size =
|
||||
draw_tes_llvm_variant_key_size(
|
||||
MAX2(tes->info.file_max[TGSI_FILE_SAMPLER]+1,
|
||||
tes->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1),
|
||||
tes->info.file_max[TGSI_FILE_IMAGE]+1);
|
||||
}
|
||||
#endif
|
||||
return tes;
|
||||
}
|
||||
|
||||
void draw_bind_tess_eval_shader(struct draw_context *draw,
|
||||
struct draw_tess_eval_shader *dtes)
|
||||
{
|
||||
draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
|
||||
if (dtes) {
|
||||
draw->tes.tess_eval_shader = dtes;
|
||||
draw->tes.position_output = dtes->position_output;
|
||||
} else {
|
||||
draw->tes.tess_eval_shader = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_delete_tess_eval_shader(struct draw_context *draw,
|
||||
struct draw_tess_eval_shader *dtes)
|
||||
{
|
||||
if (!dtes)
|
||||
return;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
if (draw->llvm) {
|
||||
struct llvm_tess_eval_shader *shader = llvm_tess_eval_shader(dtes);
|
||||
struct draw_tes_llvm_variant_list_item *li;
|
||||
|
||||
li = first_elem(&shader->variants);
|
||||
while(!at_end(&shader->variants, li)) {
|
||||
struct draw_tes_llvm_variant_list_item *next = next_elem(li);
|
||||
draw_tes_llvm_destroy_variant(li->base);
|
||||
li = next;
|
||||
}
|
||||
|
||||
assert(shader->variants_cached == 0);
|
||||
align_free(dtes->tes_input);
|
||||
}
|
||||
#endif
|
||||
FREE(dtes);
|
||||
}
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
void draw_tes_set_current_variant(struct draw_tess_eval_shader *shader,
|
||||
struct draw_tes_llvm_variant *variant)
|
||||
{
|
||||
shader->current_variant = variant;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum pipe_prim_type get_tes_output_prim(struct draw_tess_eval_shader *shader)
|
||||
{
|
||||
if (shader->point_mode)
|
||||
return PIPE_PRIM_POINTS;
|
||||
else if (shader->prim_mode == PIPE_PRIM_LINES)
|
||||
return PIPE_PRIM_LINES;
|
||||
else
|
||||
return PIPE_PRIM_TRIANGLES;
|
||||
}
|
|
@ -35,6 +35,96 @@ struct draw_context;
|
|||
#define NUM_PATCH_INPUTS 32
|
||||
#define NUM_TCS_INPUTS (PIPE_MAX_SHADER_INPUTS - NUM_PATCH_INPUTS)
|
||||
|
||||
struct draw_tcs_inputs {
|
||||
/* num vertices per prim */
|
||||
float data[32][NUM_TCS_INPUTS][4];
|
||||
};
|
||||
|
||||
struct draw_tcs_outputs {
|
||||
/* num vertices per prim */
|
||||
float data[32][PIPE_MAX_SHADER_INPUTS][4];
|
||||
};
|
||||
|
||||
struct draw_tes_inputs {
|
||||
/* num vertices per prim */
|
||||
float data[32][PIPE_MAX_SHADER_INPUTS][4];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct draw_tess_ctrl_shader {
|
||||
struct draw_context *draw;
|
||||
|
||||
struct pipe_shader_state state;
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
unsigned vector_length;
|
||||
unsigned vertices_out;
|
||||
|
||||
unsigned input_vertex_stride;
|
||||
const float (*input)[4];
|
||||
const struct tgsi_shader_info *input_info;
|
||||
#ifdef LLVM_AVAILABLE
|
||||
struct draw_tcs_inputs *tcs_input;
|
||||
struct draw_tcs_outputs *tcs_output;
|
||||
struct draw_tcs_jit_context *jit_context;
|
||||
struct draw_tcs_llvm_variant *current_variant;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct draw_tess_eval_shader {
|
||||
struct draw_context *draw;
|
||||
struct pipe_shader_state state;
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
unsigned prim_mode;
|
||||
unsigned spacing;
|
||||
unsigned vertex_order_cw;
|
||||
unsigned point_mode;
|
||||
|
||||
unsigned position_output;
|
||||
unsigned viewport_index_output;
|
||||
unsigned ccdistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];
|
||||
unsigned vector_length;
|
||||
|
||||
unsigned input_vertex_stride;
|
||||
const float (*input)[4];
|
||||
const struct tgsi_shader_info *input_info;
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
struct draw_tes_inputs *tes_input;
|
||||
struct draw_tes_jit_context *jit_context;
|
||||
struct draw_tes_llvm_variant *current_variant;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum pipe_prim_type get_tes_output_prim(struct draw_tess_eval_shader *shader);
|
||||
|
||||
int draw_tess_ctrl_shader_run(struct draw_tess_ctrl_shader *shader,
|
||||
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
const struct draw_vertex_info *input_verts,
|
||||
const struct draw_prim_info *input_prim,
|
||||
const struct tgsi_shader_info *input_info,
|
||||
struct draw_vertex_info *output_verts,
|
||||
struct draw_prim_info *output_prims );
|
||||
|
||||
int draw_tess_eval_shader_run(struct draw_tess_eval_shader *shader,
|
||||
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
unsigned num_input_vertices_per_patch,
|
||||
const struct draw_vertex_info *input_verts,
|
||||
const struct draw_prim_info *input_prim,
|
||||
const struct tgsi_shader_info *input_info,
|
||||
struct draw_vertex_info *output_verts,
|
||||
struct draw_prim_info *output_prims,
|
||||
ushort **elts_out);
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
void draw_tcs_set_current_variant(struct draw_tess_ctrl_shader *shader,
|
||||
struct draw_tcs_llvm_variant *variant);
|
||||
void draw_tes_set_current_variant(struct draw_tess_eval_shader *shader,
|
||||
struct draw_tes_llvm_variant *variant);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,6 +70,8 @@ files_libgallium = files(
|
|||
'draw/draw_pt_vsplit_tmp.h',
|
||||
'draw/draw_so_emit_tmp.h',
|
||||
'draw/draw_split_tmp.h',
|
||||
'draw/draw_tess.c',
|
||||
'draw/draw_tess.h',
|
||||
'draw/draw_vbuf.h',
|
||||
'draw/draw_vertex.c',
|
||||
'draw/draw_vertex.h',
|
||||
|
|
Loading…
Reference in New Issue