draw: limit the number of vertex shader variants kept around
we used to create and cache unltimited number of variant, this change limits the number of variants kept around to a fixed number. the change is based on a similar patch by Roland for llvmpipe fragment shaders.
This commit is contained in:
parent
5cf1921e6d
commit
8ebfcf31eb
|
@ -218,7 +218,8 @@ if env['llvm']:
|
|||
'gallivm/lp_bld_type.c',
|
||||
'draw/draw_llvm.c',
|
||||
'draw/draw_pt_fetch_shade_pipeline_llvm.c',
|
||||
'draw/draw_llvm_translate.c'
|
||||
'draw/draw_llvm_translate.c',
|
||||
'draw/draw_vs_llvm.c'
|
||||
]
|
||||
|
||||
gallium = env.ConvenienceLibrary(
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2010 VMware, Inc.
|
||||
* 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, 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 VMWARE AND/OR ITS 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 "draw_llvm.h"
|
||||
|
||||
#include "draw_context.h"
|
||||
|
@ -219,6 +246,9 @@ draw_llvm_create(struct draw_context *draw)
|
|||
LLVMDumpModule(llvm->module);
|
||||
}
|
||||
|
||||
llvm->nr_variants = 0;
|
||||
make_empty_list(&llvm->vs_variants_list);
|
||||
|
||||
return llvm;
|
||||
}
|
||||
|
||||
|
@ -231,9 +261,13 @@ draw_llvm_destroy(struct draw_llvm *llvm)
|
|||
}
|
||||
|
||||
struct draw_llvm_variant *
|
||||
draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
|
||||
draw_llvm_create_variant(struct draw_llvm *llvm, int num_inputs)
|
||||
{
|
||||
struct draw_llvm_variant *variant = MALLOC(sizeof(struct draw_llvm_variant));
|
||||
struct llvm_vertex_shader *shader =
|
||||
llvm_vertex_shader(llvm->draw->vs.vertex_shader);
|
||||
|
||||
variant->llvm = llvm;
|
||||
|
||||
draw_llvm_make_variant_key(llvm, &variant->key);
|
||||
|
||||
|
@ -242,6 +276,12 @@ draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
|
|||
draw_llvm_generate(llvm, variant);
|
||||
draw_llvm_generate_elts(llvm, variant);
|
||||
|
||||
variant->shader = shader;
|
||||
variant->list_item_global.base = variant;
|
||||
variant->list_item_local.base = variant;
|
||||
/*variant->no = */shader->variants_created++;
|
||||
variant->list_item_global.base = variant;
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
|
@ -897,3 +937,30 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm,
|
|||
&llvm->draw->vs.vertex_shader->state,
|
||||
sizeof(struct pipe_shader_state));
|
||||
}
|
||||
|
||||
void
|
||||
draw_llvm_destroy_variant(struct draw_llvm_variant *variant)
|
||||
{
|
||||
struct draw_llvm *llvm = variant->llvm;
|
||||
struct draw_context *draw = llvm->draw;
|
||||
|
||||
if (variant->function_elts) {
|
||||
if (variant->function_elts)
|
||||
LLVMFreeMachineCodeForFunction(draw->engine,
|
||||
variant->function_elts);
|
||||
LLVMDeleteFunction(variant->function_elts);
|
||||
}
|
||||
|
||||
if (variant->function) {
|
||||
if (variant->function)
|
||||
LLVMFreeMachineCodeForFunction(draw->engine,
|
||||
variant->function);
|
||||
LLVMDeleteFunction(variant->function);
|
||||
}
|
||||
|
||||
remove_from_list(&variant->list_item_local);
|
||||
variant->shader->variants_cached--;
|
||||
remove_from_list(&variant->list_item_global);
|
||||
llvm->nr_variants--;
|
||||
FREE(variant);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,48 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2010 VMware, Inc.
|
||||
* 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, 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 VMWARE AND/OR ITS 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 HAVE_LLVM_H
|
||||
#define HAVE_LLVM_H
|
||||
|
||||
#include "draw/draw_private.h"
|
||||
|
||||
#include "draw/draw_vs.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_simple_list.h"
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Target.h>
|
||||
#include <llvm-c/ExecutionEngine.h>
|
||||
|
||||
struct draw_llvm;
|
||||
struct llvm_vertex_shader;
|
||||
|
||||
struct draw_jit_texture
|
||||
{
|
||||
uint32_t width;
|
||||
|
@ -104,11 +137,50 @@ typedef void
|
|||
unsigned stride,
|
||||
struct pipe_vertex_buffer *vertex_buffers);
|
||||
|
||||
struct draw_llvm_variant_key
|
||||
{
|
||||
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
|
||||
unsigned nr_vertex_elements;
|
||||
struct pipe_shader_state vs;
|
||||
};
|
||||
|
||||
struct draw_llvm_variant_list_item
|
||||
{
|
||||
struct draw_llvm_variant *base;
|
||||
struct draw_llvm_variant_list_item *next, *prev;
|
||||
};
|
||||
|
||||
struct draw_llvm_variant
|
||||
{
|
||||
struct draw_llvm_variant_key key;
|
||||
LLVMValueRef function;
|
||||
LLVMValueRef function_elts;
|
||||
draw_jit_vert_func jit_func;
|
||||
draw_jit_vert_func_elts jit_func_elts;
|
||||
|
||||
struct llvm_vertex_shader *shader;
|
||||
|
||||
struct draw_llvm *llvm;
|
||||
struct draw_llvm_variant_list_item list_item_global;
|
||||
struct draw_llvm_variant_list_item list_item_local;
|
||||
};
|
||||
|
||||
struct llvm_vertex_shader {
|
||||
struct draw_vertex_shader base;
|
||||
|
||||
struct draw_llvm_variant_list_item variants;
|
||||
unsigned variants_created;
|
||||
unsigned variants_cached;
|
||||
};
|
||||
|
||||
struct draw_llvm {
|
||||
struct draw_context *draw;
|
||||
|
||||
struct draw_jit_context jit_context;
|
||||
|
||||
struct draw_llvm_variant_list_item vs_variants_list;
|
||||
int nr_variants;
|
||||
|
||||
LLVMModuleRef module;
|
||||
LLVMExecutionEngineRef engine;
|
||||
LLVMModuleProviderRef provider;
|
||||
|
@ -121,23 +193,12 @@ struct draw_llvm {
|
|||
LLVMTypeRef vb_ptr_type;
|
||||
};
|
||||
|
||||
struct draw_llvm_variant_key
|
||||
static struct llvm_vertex_shader *
|
||||
llvm_vertex_shader(struct draw_vertex_shader *vs)
|
||||
{
|
||||
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
|
||||
unsigned nr_vertex_elements;
|
||||
struct pipe_shader_state vs;
|
||||
};
|
||||
return (struct llvm_vertex_shader *)vs;
|
||||
}
|
||||
|
||||
struct draw_llvm_variant
|
||||
{
|
||||
struct draw_llvm_variant_key key;
|
||||
LLVMValueRef function;
|
||||
LLVMValueRef function_elts;
|
||||
draw_jit_vert_func jit_func;
|
||||
draw_jit_vert_func_elts jit_func_elts;
|
||||
|
||||
struct draw_llvm_variant *next;
|
||||
};
|
||||
|
||||
struct draw_llvm *
|
||||
draw_llvm_create(struct draw_context *draw);
|
||||
|
@ -146,7 +207,10 @@ void
|
|||
draw_llvm_destroy(struct draw_llvm *llvm);
|
||||
|
||||
struct draw_llvm_variant *
|
||||
draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs);
|
||||
draw_llvm_create_variant(struct draw_llvm *llvm, int num_inputs);
|
||||
|
||||
void
|
||||
draw_llvm_destroy_variant(struct draw_llvm_variant *variant);
|
||||
|
||||
void
|
||||
draw_llvm_make_variant_key(struct draw_llvm *llvm,
|
||||
|
@ -156,4 +220,5 @@ LLVMValueRef
|
|||
draw_llvm_translate_from(LLVMBuilderRef builder,
|
||||
LLVMValueRef vbuffer,
|
||||
enum pipe_format from_format);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,6 +81,9 @@ struct vertex_header {
|
|||
#define UNDEFINED_VERTEX_ID 0xffff
|
||||
|
||||
|
||||
/* maximum number of shader variants we can cache */
|
||||
#define DRAW_MAX_SHADER_VARIANTS 1024
|
||||
|
||||
/**
|
||||
* Private context for the drawing module.
|
||||
*/
|
||||
|
|
|
@ -52,9 +52,7 @@ struct llvm_middle_end {
|
|||
unsigned opt;
|
||||
|
||||
struct draw_llvm *llvm;
|
||||
struct draw_llvm_variant *variants;
|
||||
struct draw_llvm_variant *current_variant;
|
||||
int nr_variants;
|
||||
};
|
||||
|
||||
|
||||
|
@ -66,9 +64,11 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
|
|||
{
|
||||
struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
|
||||
struct draw_context *draw = fpme->draw;
|
||||
struct draw_vertex_shader *vs = draw->vs.vertex_shader;
|
||||
struct llvm_vertex_shader *shader =
|
||||
llvm_vertex_shader(draw->vs.vertex_shader);
|
||||
struct draw_llvm_variant_key key;
|
||||
struct draw_llvm_variant *variant = NULL;
|
||||
struct draw_llvm_variant_list_item *li;
|
||||
unsigned i;
|
||||
unsigned instance_id_index = ~0;
|
||||
|
||||
|
@ -80,13 +80,13 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
|
|||
/* Add one to num_outputs because the pipeline occasionally tags on
|
||||
* an additional texcoord, eg for AA lines.
|
||||
*/
|
||||
unsigned nr = MAX2( vs->info.num_inputs,
|
||||
vs->info.num_outputs + 1 );
|
||||
unsigned nr = MAX2( shader->base.info.num_inputs,
|
||||
shader->base.info.num_outputs + 1 );
|
||||
|
||||
/* Scan for instanceID system value.
|
||||
*/
|
||||
for (i = 0; i < vs->info.num_inputs; i++) {
|
||||
if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
|
||||
for (i = 0; i < shader->base.info.num_inputs; i++) {
|
||||
if (shader->base.info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
|
||||
instance_id_index = i;
|
||||
break;
|
||||
}
|
||||
|
@ -130,20 +130,41 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
|
|||
|
||||
draw_llvm_make_variant_key(fpme->llvm, &key);
|
||||
|
||||
variant = fpme->variants;
|
||||
while(variant) {
|
||||
if(memcmp(&variant->key, &key, sizeof key) == 0)
|
||||
li = first_elem(&shader->variants);
|
||||
while(!at_end(&shader->variants, li)) {
|
||||
if(memcmp(&li->base->key, &key, sizeof key) == 0) {
|
||||
variant = li->base;
|
||||
break;
|
||||
|
||||
variant = variant->next;
|
||||
}
|
||||
li = next_elem(li);
|
||||
}
|
||||
|
||||
if (!variant) {
|
||||
variant = draw_llvm_prepare(fpme->llvm, nr);
|
||||
variant->next = fpme->variants;
|
||||
fpme->variants = variant;
|
||||
++fpme->nr_variants;
|
||||
if (variant) {
|
||||
move_to_head(&fpme->llvm->vs_variants_list, &variant->list_item_global);
|
||||
}
|
||||
else {
|
||||
unsigned i;
|
||||
if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) {
|
||||
/*
|
||||
* XXX: should we flush here ?
|
||||
*/
|
||||
for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) {
|
||||
struct draw_llvm_variant_list_item *item =
|
||||
last_elem(&fpme->llvm->vs_variants_list);
|
||||
draw_llvm_destroy_variant(item->base);
|
||||
}
|
||||
}
|
||||
|
||||
variant = draw_llvm_create_variant(fpme->llvm, nr);
|
||||
|
||||
if (variant) {
|
||||
insert_at_head(&shader->variants, &variant->list_item_local);
|
||||
insert_at_head(&fpme->llvm->vs_variants_list, &variant->list_item_global);
|
||||
fpme->llvm->nr_variants++;
|
||||
shader->variants_cached++;
|
||||
}
|
||||
}
|
||||
|
||||
fpme->current_variant = variant;
|
||||
|
||||
/*XXX we only support one constant buffer */
|
||||
|
@ -358,31 +379,7 @@ static void llvm_middle_end_finish( struct draw_pt_middle_end *middle )
|
|||
static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )
|
||||
{
|
||||
struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
|
||||
struct draw_context *draw = fpme->draw;
|
||||
struct draw_llvm_variant *variant = NULL;
|
||||
|
||||
variant = fpme->variants;
|
||||
while(variant) {
|
||||
struct draw_llvm_variant *next = variant->next;
|
||||
|
||||
if (variant->function_elts) {
|
||||
if (variant->function_elts)
|
||||
LLVMFreeMachineCodeForFunction(draw->engine,
|
||||
variant->function_elts);
|
||||
LLVMDeleteFunction(variant->function_elts);
|
||||
}
|
||||
|
||||
if (variant->function) {
|
||||
if (variant->function)
|
||||
LLVMFreeMachineCodeForFunction(draw->engine,
|
||||
variant->function);
|
||||
LLVMDeleteFunction(variant->function);
|
||||
}
|
||||
|
||||
FREE(variant);
|
||||
|
||||
variant = next;
|
||||
}
|
||||
if (fpme->fetch)
|
||||
draw_pt_fetch_destroy( fpme->fetch );
|
||||
|
||||
|
@ -402,7 +399,8 @@ static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )
|
|||
}
|
||||
|
||||
|
||||
struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_context *draw )
|
||||
struct draw_pt_middle_end *
|
||||
draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw)
|
||||
{
|
||||
struct llvm_middle_end *fpme = 0;
|
||||
|
||||
|
@ -442,9 +440,7 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_cont
|
|||
if (!fpme->llvm)
|
||||
goto fail;
|
||||
|
||||
fpme->variants = NULL;
|
||||
fpme->current_variant = NULL;
|
||||
fpme->nr_variants = 0;
|
||||
|
||||
return &fpme->base;
|
||||
|
||||
|
|
|
@ -98,6 +98,11 @@ draw_create_vertex_shader(struct draw_context *draw,
|
|||
vs = draw_create_vs_ppc( draw, shader );
|
||||
#endif
|
||||
}
|
||||
#if HAVE_LLVM
|
||||
else {
|
||||
vs = draw_create_vs_llvm(draw, shader);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!vs) {
|
||||
vs = draw_create_vs_exec( draw, shader );
|
||||
|
|
|
@ -165,7 +165,6 @@ draw_create_vs_ppc(struct draw_context *draw,
|
|||
const struct pipe_shader_state *templ);
|
||||
|
||||
|
||||
|
||||
struct draw_vs_varient_key;
|
||||
struct draw_vertex_shader;
|
||||
|
||||
|
@ -173,6 +172,11 @@ struct draw_vs_varient *
|
|||
draw_vs_create_varient_aos_sse( struct draw_vertex_shader *vs,
|
||||
const struct draw_vs_varient_key *key );
|
||||
|
||||
#if HAVE_LLVM
|
||||
struct draw_vertex_shader *
|
||||
draw_create_vs_llvm(struct draw_context *draw,
|
||||
const struct pipe_shader_state *state);
|
||||
#endif
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2010 VMware, Inc.
|
||||
* 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, 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 VMWARE AND/OR ITS 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 "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "draw_private.h"
|
||||
#include "draw_context.h"
|
||||
#include "draw_vs.h"
|
||||
#include "draw_llvm.h"
|
||||
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
|
||||
static void
|
||||
vs_llvm_prepare(struct draw_vertex_shader *shader,
|
||||
struct draw_context *draw)
|
||||
{
|
||||
/*struct llvm_vertex_shader *evs = llvm_vertex_shader(shader);*/
|
||||
}
|
||||
|
||||
static void
|
||||
vs_llvm_run_linear( struct draw_vertex_shader *shader,
|
||||
const float (*input)[4],
|
||||
float (*output)[4],
|
||||
const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
|
||||
unsigned count,
|
||||
unsigned input_stride,
|
||||
unsigned output_stride )
|
||||
{
|
||||
/* we should never get here since the entire pipeline is
|
||||
* generated in draw_pt_fetch_shade_pipeline_llvm.c */
|
||||
debug_assert(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vs_llvm_delete( struct draw_vertex_shader *dvs )
|
||||
{
|
||||
struct llvm_vertex_shader *shader = llvm_vertex_shader(dvs);
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
struct draw_llvm_variant_list_item *li;
|
||||
struct pipe_context *pipe = dvs->draw->pipe;
|
||||
|
||||
/*
|
||||
* XXX: This might be not neccessary at all.
|
||||
*/
|
||||
pipe->flush(pipe, 0, &fence);
|
||||
if (fence) {
|
||||
pipe->screen->fence_finish(pipe->screen, fence, 0);
|
||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
||||
}
|
||||
|
||||
|
||||
li = first_elem(&shader->variants);
|
||||
while(!at_end(&shader->variants, li)) {
|
||||
struct draw_llvm_variant_list_item *next = next_elem(li);
|
||||
draw_llvm_destroy_variant(li->base);
|
||||
li = next;
|
||||
}
|
||||
|
||||
assert(shader->variants_cached == 0);
|
||||
FREE((void*) dvs->state.tokens);
|
||||
FREE( dvs );
|
||||
}
|
||||
|
||||
|
||||
struct draw_vertex_shader *
|
||||
draw_create_vs_llvm(struct draw_context *draw,
|
||||
const struct pipe_shader_state *state)
|
||||
{
|
||||
struct llvm_vertex_shader *vs = CALLOC_STRUCT( llvm_vertex_shader );
|
||||
|
||||
if (vs == NULL)
|
||||
return NULL;
|
||||
|
||||
/* we make a private copy of the tokens */
|
||||
vs->base.state.tokens = tgsi_dup_tokens(state->tokens);
|
||||
if (!vs->base.state.tokens) {
|
||||
FREE(vs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tgsi_scan_shader(state->tokens, &vs->base.info);
|
||||
|
||||
vs->base.draw = draw;
|
||||
vs->base.prepare = vs_llvm_prepare;
|
||||
vs->base.run_linear = vs_llvm_run_linear;
|
||||
vs->base.delete = vs_llvm_delete;
|
||||
vs->base.create_varient = draw_vs_create_varient_generic;
|
||||
|
||||
make_empty_list(&vs->variants);
|
||||
|
||||
return &vs->base;
|
||||
}
|
Loading…
Reference in New Issue