llvmpipe: Code generate the texture sampling inside the shader.
Finally a substantial performance improvement: framerates of apps using texturing tripled, and furthermore, enabling/disabling texturing only affects around 15% of the framerate, which means the bottleneck is now somewhere else. Generated texture sampling code is not complete though -- we always sample from the base level -- so final figures will be different.
This commit is contained in:
@@ -46,7 +46,8 @@ C_SOURCES = \
|
|||||||
lp_state_vs.c \
|
lp_state_vs.c \
|
||||||
lp_surface.c \
|
lp_surface.c \
|
||||||
lp_tex_cache.c \
|
lp_tex_cache.c \
|
||||||
lp_tex_sample.c \
|
lp_tex_sample_c.c \
|
||||||
|
lp_tex_sample_llvm.c \
|
||||||
lp_texture.c \
|
lp_texture.c \
|
||||||
lp_tile_cache.c \
|
lp_tile_cache.c \
|
||||||
lp_tile_soa.c
|
lp_tile_soa.c
|
||||||
|
@@ -54,7 +54,8 @@ llvmpipe = env.ConvenienceLibrary(
|
|||||||
'lp_state_vs.c',
|
'lp_state_vs.c',
|
||||||
'lp_surface.c',
|
'lp_surface.c',
|
||||||
'lp_tex_cache.c',
|
'lp_tex_cache.c',
|
||||||
'lp_tex_sample.c',
|
'lp_tex_sample_c.c',
|
||||||
|
'lp_tex_sample_llvm.c',
|
||||||
'lp_texture.c',
|
'lp_texture.c',
|
||||||
'lp_tile_cache.c',
|
'lp_tile_cache.c',
|
||||||
'lp_tile_soa.c',
|
'lp_tile_soa.c',
|
||||||
|
@@ -44,15 +44,47 @@
|
|||||||
static void
|
static void
|
||||||
lp_jit_init_globals(struct llvmpipe_screen *screen)
|
lp_jit_init_globals(struct llvmpipe_screen *screen)
|
||||||
{
|
{
|
||||||
/* struct lp_jit_context */
|
LLVMTypeRef texture_type;
|
||||||
|
|
||||||
|
/* struct lp_jit_texture */
|
||||||
{
|
{
|
||||||
LLVMTypeRef elem_types[4];
|
LLVMTypeRef elem_types[4];
|
||||||
|
|
||||||
|
elem_types[LP_JIT_TEXTURE_WIDTH] = LLVMInt32Type();
|
||||||
|
elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
|
||||||
|
elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
|
||||||
|
elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
|
||||||
|
|
||||||
|
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
|
||||||
|
|
||||||
|
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
|
||||||
|
screen->target, texture_type,
|
||||||
|
LP_JIT_TEXTURE_WIDTH);
|
||||||
|
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, height,
|
||||||
|
screen->target, texture_type,
|
||||||
|
LP_JIT_TEXTURE_HEIGHT);
|
||||||
|
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, stride,
|
||||||
|
screen->target, texture_type,
|
||||||
|
LP_JIT_TEXTURE_STRIDE);
|
||||||
|
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
|
||||||
|
screen->target, texture_type,
|
||||||
|
LP_JIT_TEXTURE_DATA);
|
||||||
|
LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
|
||||||
|
screen->target, texture_type);
|
||||||
|
|
||||||
|
LLVMAddTypeName(screen->module, "texture", texture_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* struct lp_jit_context */
|
||||||
|
{
|
||||||
|
LLVMTypeRef elem_types[5];
|
||||||
LLVMTypeRef context_type;
|
LLVMTypeRef context_type;
|
||||||
|
|
||||||
elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
|
elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
|
||||||
elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
|
elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
|
||||||
elem_types[2] = LLVMFloatType(); /* alpha_ref_value */
|
elem_types[2] = LLVMFloatType(); /* alpha_ref_value */
|
||||||
elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
|
elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
|
||||||
|
elem_types[4] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
|
||||||
|
|
||||||
context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
|
context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
|
||||||
|
|
||||||
@@ -64,6 +96,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
|
|||||||
screen->target, context_type, 2);
|
screen->target, context_type, 2);
|
||||||
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
|
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
|
||||||
screen->target, context_type, 3);
|
screen->target, context_type, 3);
|
||||||
|
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
|
||||||
|
screen->target, context_type,
|
||||||
|
LP_JIT_CONTEXT_TEXTURES_INDEX);
|
||||||
LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
|
LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
|
||||||
screen->target, context_type);
|
screen->target, context_type);
|
||||||
|
|
||||||
|
@@ -38,11 +38,31 @@
|
|||||||
|
|
||||||
#include "lp_bld_struct.h"
|
#include "lp_bld_struct.h"
|
||||||
|
|
||||||
|
#include "pipe/p_state.h"
|
||||||
|
|
||||||
|
|
||||||
struct tgsi_sampler;
|
struct tgsi_sampler;
|
||||||
struct llvmpipe_screen;
|
struct llvmpipe_screen;
|
||||||
|
|
||||||
|
|
||||||
|
struct lp_jit_texture
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t stride;
|
||||||
|
const void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LP_JIT_TEXTURE_WIDTH = 0,
|
||||||
|
LP_JIT_TEXTURE_HEIGHT,
|
||||||
|
LP_JIT_TEXTURE_STRIDE,
|
||||||
|
LP_JIT_TEXTURE_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure is passed directly to the generated fragment shader.
|
* This structure is passed directly to the generated fragment shader.
|
||||||
*
|
*
|
||||||
@@ -65,6 +85,8 @@ struct lp_jit_context
|
|||||||
|
|
||||||
/* TODO: blend constant color */
|
/* TODO: blend constant color */
|
||||||
uint8_t *blend_color;
|
uint8_t *blend_color;
|
||||||
|
|
||||||
|
struct lp_jit_texture textures[PIPE_MAX_SAMPLERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -80,6 +102,11 @@ struct lp_jit_context
|
|||||||
#define lp_jit_context_blend_color(_builder, _ptr) \
|
#define lp_jit_context_blend_color(_builder, _ptr) \
|
||||||
lp_build_struct_get(_builder, _ptr, 3, "blend_color")
|
lp_build_struct_get(_builder, _ptr, 3, "blend_color")
|
||||||
|
|
||||||
|
#define LP_JIT_CONTEXT_TEXTURES_INDEX 4
|
||||||
|
|
||||||
|
#define lp_jit_context_textures(_builder, _ptr) \
|
||||||
|
lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures")
|
||||||
|
|
||||||
|
|
||||||
typedef void
|
typedef void
|
||||||
(*lp_jit_frag_func)(struct lp_jit_context *context,
|
(*lp_jit_frag_func)(struct lp_jit_context *context,
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include "pipe/p_state.h"
|
#include "pipe/p_state.h"
|
||||||
#include "tgsi/tgsi_scan.h"
|
#include "tgsi/tgsi_scan.h"
|
||||||
#include "lp_jit.h"
|
#include "lp_jit.h"
|
||||||
|
#include "lp_bld_sample.h" /* for struct lp_sampler_static_state */
|
||||||
|
|
||||||
|
|
||||||
#define LP_NEW_VIEWPORT 0x1
|
#define LP_NEW_VIEWPORT 0x1
|
||||||
@@ -57,7 +58,8 @@
|
|||||||
|
|
||||||
struct tgsi_sampler;
|
struct tgsi_sampler;
|
||||||
struct vertex_info;
|
struct vertex_info;
|
||||||
|
struct pipe_context;
|
||||||
|
struct llvmpipe_context;
|
||||||
|
|
||||||
struct lp_fragment_shader;
|
struct lp_fragment_shader;
|
||||||
|
|
||||||
@@ -67,6 +69,8 @@ struct lp_fragment_shader_variant_key
|
|||||||
struct pipe_depth_state depth;
|
struct pipe_depth_state depth;
|
||||||
struct pipe_alpha_state alpha;
|
struct pipe_alpha_state alpha;
|
||||||
struct pipe_blend_state blend;
|
struct pipe_blend_state blend;
|
||||||
|
|
||||||
|
struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -250,7 +250,9 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
|
|||||||
|
|
||||||
if (llvmpipe->dirty & (LP_NEW_FS |
|
if (llvmpipe->dirty & (LP_NEW_FS |
|
||||||
LP_NEW_BLEND |
|
LP_NEW_BLEND |
|
||||||
LP_NEW_DEPTH_STENCIL_ALPHA))
|
LP_NEW_DEPTH_STENCIL_ALPHA |
|
||||||
|
LP_NEW_SAMPLER |
|
||||||
|
LP_NEW_TEXTURE))
|
||||||
llvmpipe_update_fs( llvmpipe );
|
llvmpipe_update_fs( llvmpipe );
|
||||||
|
|
||||||
|
|
||||||
|
@@ -486,7 +486,13 @@ generate_fragment(struct llvmpipe_context *lp,
|
|||||||
a0_ptr, dadx_ptr, dady_ptr,
|
a0_ptr, dadx_ptr, dady_ptr,
|
||||||
x0, y0, 2, 0);
|
x0, y0, 2, 0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* C texture sampling */
|
||||||
sampler = lp_c_sampler_soa_create(context_ptr);
|
sampler = lp_c_sampler_soa_create(context_ptr);
|
||||||
|
#else
|
||||||
|
/* code generated texture sampling */
|
||||||
|
sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
for(i = 0; i < num_fs; ++i) {
|
for(i = 0; i < num_fs; ++i) {
|
||||||
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
|
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
|
||||||
@@ -666,8 +672,11 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
make_variant_key(struct llvmpipe_context *lp,
|
make_variant_key(struct llvmpipe_context *lp,
|
||||||
|
struct lp_fragment_shader *shader,
|
||||||
struct lp_fragment_shader_variant_key *key)
|
struct lp_fragment_shader_variant_key *key)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
memset(key, 0, sizeof *key);
|
memset(key, 0, sizeof *key);
|
||||||
|
|
||||||
memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
|
memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
|
||||||
@@ -678,6 +687,10 @@ make_variant_key(struct llvmpipe_context *lp,
|
|||||||
/* alpha.ref_value is passed in jit_context */
|
/* alpha.ref_value is passed in jit_context */
|
||||||
|
|
||||||
memcpy(&key->blend, lp->blend, sizeof key->blend);
|
memcpy(&key->blend, lp->blend, sizeof key->blend);
|
||||||
|
|
||||||
|
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
|
||||||
|
if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
|
||||||
|
lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -688,7 +701,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
|
|||||||
struct lp_fragment_shader_variant_key key;
|
struct lp_fragment_shader_variant_key key;
|
||||||
struct lp_fragment_shader_variant *variant;
|
struct lp_fragment_shader_variant *variant;
|
||||||
|
|
||||||
make_variant_key(lp, &key);
|
make_variant_key(lp, shader, &key);
|
||||||
|
|
||||||
variant = shader->variants;
|
variant = shader->variants;
|
||||||
while(variant) {
|
while(variant) {
|
||||||
|
@@ -98,6 +98,16 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,
|
|||||||
|
|
||||||
pipe_texture_reference(&llvmpipe->texture[i], tex);
|
pipe_texture_reference(&llvmpipe->texture[i], tex);
|
||||||
lp_tex_tile_cache_set_texture(llvmpipe->tex_cache[i], tex);
|
lp_tex_tile_cache_set_texture(llvmpipe->tex_cache[i], tex);
|
||||||
|
|
||||||
|
if(tex) {
|
||||||
|
struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
|
||||||
|
struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i];
|
||||||
|
jit_tex->width = tex->width[0];
|
||||||
|
jit_tex->height = tex->height[0];
|
||||||
|
jit_tex->stride = lp_tex->stride[0];
|
||||||
|
if(!lp_tex->dt)
|
||||||
|
jit_tex->data = lp_tex->data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llvmpipe->num_textures = num;
|
llvmpipe->num_textures = num;
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
|
|
||||||
struct llvmpipe_tex_tile_cache;
|
struct llvmpipe_tex_tile_cache;
|
||||||
|
struct lp_sampler_static_state;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,4 +88,14 @@ struct lp_build_sampler_soa *
|
|||||||
lp_c_sampler_soa_create(LLVMValueRef context_ptr);
|
lp_c_sampler_soa_create(LLVMValueRef context_ptr);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pure-LLVM texture sampling code generator.
|
||||||
|
*
|
||||||
|
* @param context_ptr LLVM value with the pointer to the struct lp_jit_context.
|
||||||
|
*/
|
||||||
|
struct lp_build_sampler_soa *
|
||||||
|
lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *key,
|
||||||
|
LLVMValueRef context_ptr);
|
||||||
|
|
||||||
|
|
||||||
#endif /* LP_TEX_SAMPLE_H */
|
#endif /* LP_TEX_SAMPLE_H */
|
||||||
|
196
src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
Normal file
196
src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2009 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Texture sampling code generation
|
||||||
|
*
|
||||||
|
* This file is nothing more than ugly glue between three largely independent
|
||||||
|
* entities:
|
||||||
|
* - TGSI -> LLVM translation (i.e., lp_build_tgsi_soa)
|
||||||
|
* - texture sampling code generation (i.e., lp_build_sample_soa)
|
||||||
|
* - LLVM pipe driver
|
||||||
|
*
|
||||||
|
* All interesting code is in the functions mentioned above. There is really
|
||||||
|
* nothing to see here.
|
||||||
|
*
|
||||||
|
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pipe/p_defines.h"
|
||||||
|
#include "pipe/p_shader_tokens.h"
|
||||||
|
#include "lp_bld_debug.h"
|
||||||
|
#include "lp_bld_type.h"
|
||||||
|
#include "lp_bld_intr.h"
|
||||||
|
#include "lp_bld_sample.h"
|
||||||
|
#include "lp_bld_tgsi.h"
|
||||||
|
#include "lp_state.h"
|
||||||
|
#include "lp_tex_sample.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This provides the bridge between the sampler state store in lp_jit_context
|
||||||
|
* and lp_jit_texture and the sampler code generator. It provides the
|
||||||
|
* texture layout information required by the texture sampler code generator
|
||||||
|
* in terms of the state stored in lp_jit_context and lp_jit_texture in runtime.
|
||||||
|
*/
|
||||||
|
struct llvmpipe_sampler_dynamic_state
|
||||||
|
{
|
||||||
|
struct lp_sampler_dynamic_state base;
|
||||||
|
|
||||||
|
const struct lp_sampler_static_state *static_state;
|
||||||
|
|
||||||
|
LLVMValueRef context_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the bridge between our sampler and the TGSI translator.
|
||||||
|
*/
|
||||||
|
struct lp_llvm_sampler_soa
|
||||||
|
{
|
||||||
|
struct lp_build_sampler_soa base;
|
||||||
|
|
||||||
|
struct llvmpipe_sampler_dynamic_state dynamic_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the specified member of the lp_jit_texture structure.
|
||||||
|
*
|
||||||
|
* @sa http://llvm.org/docs/GetElementPtr.html
|
||||||
|
*/
|
||||||
|
static LLVMValueRef
|
||||||
|
lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
unsigned unit,
|
||||||
|
unsigned member_index,
|
||||||
|
const char *member_name)
|
||||||
|
{
|
||||||
|
struct llvmpipe_sampler_dynamic_state *state = (struct llvmpipe_sampler_dynamic_state *)base;
|
||||||
|
LLVMValueRef indices[4];
|
||||||
|
LLVMValueRef ptr;
|
||||||
|
LLVMValueRef res;
|
||||||
|
|
||||||
|
assert(unit < PIPE_MAX_SAMPLERS);
|
||||||
|
|
||||||
|
/* context[0] */
|
||||||
|
indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
|
||||||
|
/* context[0].textures */
|
||||||
|
indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CONTEXT_TEXTURES_INDEX, 0);
|
||||||
|
/* context[0].textures[unit] */
|
||||||
|
indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
|
||||||
|
/* context[0].textures[unit].member */
|
||||||
|
indices[3] = LLVMConstInt(LLVMInt32Type(), member_index, 0);
|
||||||
|
|
||||||
|
ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
|
||||||
|
|
||||||
|
res = LLVMBuildLoad(builder, ptr, "");
|
||||||
|
|
||||||
|
lp_build_name(res, "context.texture%u.%s", unit, member_name);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper macro to instantiate the functions that generate the code to fetch
|
||||||
|
* the members of lp_jit_texture to fulfill the sampler code generator requests.
|
||||||
|
*
|
||||||
|
* This complexity is the price we have to pay to keep the texture sampler code
|
||||||
|
* generator a reusable module without dependencies to llvmpipe internals.
|
||||||
|
*/
|
||||||
|
#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
|
||||||
|
static LLVMValueRef \
|
||||||
|
lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
|
||||||
|
LLVMBuilderRef builder, \
|
||||||
|
unsigned unit) \
|
||||||
|
{ \
|
||||||
|
return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH)
|
||||||
|
LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT)
|
||||||
|
LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE)
|
||||||
|
LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
|
||||||
|
{
|
||||||
|
FREE(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base,
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
union lp_type type,
|
||||||
|
unsigned unit,
|
||||||
|
unsigned num_coords,
|
||||||
|
const LLVMValueRef *coords,
|
||||||
|
LLVMValueRef lodbias,
|
||||||
|
LLVMValueRef *texel)
|
||||||
|
{
|
||||||
|
struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
|
||||||
|
|
||||||
|
assert(unit < PIPE_MAX_SAMPLERS);
|
||||||
|
|
||||||
|
lp_build_sample_soa(builder,
|
||||||
|
&sampler->dynamic_state.static_state[unit],
|
||||||
|
&sampler->dynamic_state.base,
|
||||||
|
type,
|
||||||
|
unit,
|
||||||
|
num_coords,
|
||||||
|
coords,
|
||||||
|
lodbias,
|
||||||
|
texel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct lp_build_sampler_soa *
|
||||||
|
lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
|
||||||
|
LLVMValueRef context_ptr)
|
||||||
|
{
|
||||||
|
struct lp_llvm_sampler_soa *sampler;
|
||||||
|
|
||||||
|
sampler = CALLOC_STRUCT(lp_llvm_sampler_soa);
|
||||||
|
if(!sampler)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sampler->base.destroy = lp_llvm_sampler_soa_destroy;
|
||||||
|
sampler->base.emit_fetch_texel = lp_llvm_sampler_soa_emit_fetch_texel;
|
||||||
|
sampler->dynamic_state.base.width = lp_llvm_texture_width;
|
||||||
|
sampler->dynamic_state.base.height = lp_llvm_texture_height;
|
||||||
|
sampler->dynamic_state.base.stride = lp_llvm_texture_stride;
|
||||||
|
sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
|
||||||
|
sampler->dynamic_state.static_state = static_state;
|
||||||
|
sampler->dynamic_state.context_ptr = context_ptr;
|
||||||
|
|
||||||
|
return &sampler->base;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user