Bladeren bron

draw: implement vertex texture sampling using llvm

tags/mesa-7.9-rc1
Zack Rusin 15 jaren geleden
bovenliggende
commit
01eebfe1b6

+ 2
- 1
src/gallium/auxiliary/Makefile Bestand weergeven

@@ -171,7 +171,8 @@ GALLIVM_SOURCES = \
draw/draw_llvm.c \
draw/draw_vs_llvm.c \
draw/draw_pt_fetch_shade_pipeline_llvm.c \
draw/draw_llvm_translate.c
draw/draw_llvm_translate.c \
draw/draw_llvm_sample.c

GALLIVM_CPP_SOURCES = \
gallivm/lp_bld_misc.cpp

+ 2
- 1
src/gallium/auxiliary/SConscript Bestand weergeven

@@ -221,7 +221,8 @@ if env['llvm']:
'draw/draw_llvm.c',
'draw/draw_pt_fetch_shade_pipeline_llvm.c',
'draw/draw_llvm_translate.c',
'draw/draw_vs_llvm.c'
'draw/draw_vs_llvm.c',
'draw/draw_llvm_sample.c'
]

gallium = env.ConvenienceLibrary(

+ 56
- 0
src/gallium/auxiliary/draw/draw_context.c Bestand weergeven

@@ -40,6 +40,7 @@

#if HAVE_LLVM
#include "gallivm/lp_bld_init.h"
#include "draw_llvm.h"
#endif

struct draw_context *draw_create( struct pipe_context *pipe )
@@ -52,6 +53,7 @@ struct draw_context *draw_create( struct pipe_context *pipe )
lp_build_init();
assert(lp_build_engine);
draw->engine = lp_build_engine;
draw->llvm = draw_llvm_create(draw);
#endif

if (!draw_init(draw))
@@ -132,6 +134,9 @@ void draw_destroy( struct draw_context *draw )
draw_pt_destroy( draw );
draw_vs_destroy( draw );
draw_gs_destroy( draw );
#ifdef HAVE_LLVM
draw_llvm_destroy( draw->llvm );
#endif

FREE( draw );
}
@@ -601,3 +606,54 @@ draw_set_so_state(struct draw_context *draw,
state,
sizeof(struct pipe_stream_output_state));
}

void
draw_set_sampler_views(struct draw_context *draw,
struct pipe_sampler_view **views,
unsigned num)
{
unsigned i;

debug_assert(num <= PIPE_MAX_VERTEX_SAMPLERS);

for (i = 0; i < num; ++i)
draw->sampler_views[i] = views[i];
for (i = num; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
draw->sampler_views[i] = NULL;

draw->num_sampler_views = num;
}

void
draw_set_samplers(struct draw_context *draw,
struct pipe_sampler_state **samplers,
unsigned num)
{
unsigned i;

debug_assert(num <= PIPE_MAX_VERTEX_SAMPLERS);

for (i = 0; i < num; ++i)
draw->samplers[i] = samplers[i];
for (i = num; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
draw->samplers[i] = NULL;

draw->num_samplers = num;
}

void
draw_set_mapped_texture(struct draw_context *draw,
unsigned sampler_idx,
uint32_t width, uint32_t height, uint32_t depth,
uint32_t last_level,
uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
const void *data[DRAW_MAX_TEXTURE_LEVELS])
{
#ifdef HAVE_LLVM
draw_llvm_set_mapped_texture(draw,
sampler_idx,
width, height, depth, last_level,
row_stride, img_stride, data);
#endif
}

+ 18
- 0
src/gallium/auxiliary/draw/draw_context.h Bestand weergeven

@@ -47,6 +47,7 @@ struct draw_vertex_shader;
struct draw_geometry_shader;
struct tgsi_sampler;

#define DRAW_MAX_TEXTURE_LEVELS 13 /* 4K x 4K for now */

struct draw_context *draw_create( struct pipe_context *pipe );

@@ -101,6 +102,23 @@ draw_texture_samplers(struct draw_context *draw,
uint num_samplers,
struct tgsi_sampler **samplers);

void
draw_set_sampler_views(struct draw_context *draw,
struct pipe_sampler_view **views,
unsigned num);
void
draw_set_samplers(struct draw_context *draw,
struct pipe_sampler_state **samplers,
unsigned num);

void
draw_set_mapped_texture(struct draw_context *draw,
unsigned sampler_idx,
uint32_t width, uint32_t height, uint32_t depth,
uint32_t last_level,
uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
const void *data[DRAW_MAX_TEXTURE_LEVELS]);


/*

+ 85
- 13
src/gallium/auxiliary/draw/draw_llvm.c Bestand weergeven

@@ -42,14 +42,13 @@
#include "tgsi/tgsi_dump.h"

#include "util/u_cpu_detect.h"
#include "util/u_string.h"
#include "util/u_pointer.h"
#include "util/u_string.h"

#include <llvm-c/Transforms/Scalar.h>

#define DEBUG_STORE 0


/* generates the draw jit function */
static void
draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var);
@@ -63,12 +62,19 @@ init_globals(struct draw_llvm *llvm)

/* struct draw_jit_texture */
{
LLVMTypeRef elem_types[4];
LLVMTypeRef elem_types[DRAW_JIT_TEXTURE_NUM_FIELDS];

elem_types[DRAW_JIT_TEXTURE_WIDTH] = LLVMInt32Type();
elem_types[DRAW_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
elem_types[DRAW_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
elem_types[DRAW_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
elem_types[DRAW_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] =
LLVMArrayType(LLVMInt32Type(), DRAW_MAX_TEXTURE_LEVELS);
elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
LLVMArrayType(LLVMInt32Type(), DRAW_MAX_TEXTURE_LEVELS);
elem_types[DRAW_JIT_TEXTURE_DATA] =
LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
DRAW_MAX_TEXTURE_LEVELS);

texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);

@@ -78,9 +84,18 @@ init_globals(struct draw_llvm *llvm)
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height,
llvm->target, texture_type,
DRAW_JIT_TEXTURE_HEIGHT);
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, stride,
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth,
llvm->target, texture_type,
DRAW_JIT_TEXTURE_DEPTH);
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level,
llvm->target, texture_type,
DRAW_JIT_TEXTURE_LAST_LEVEL);
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride,
llvm->target, texture_type,
DRAW_JIT_TEXTURE_STRIDE);
DRAW_JIT_TEXTURE_ROW_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride,
llvm->target, texture_type,
DRAW_JIT_TEXTURE_IMG_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data,
llvm->target, texture_type,
DRAW_JIT_TEXTURE_DATA);
@@ -98,7 +113,8 @@ init_globals(struct draw_llvm *llvm)

elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
elem_types[2] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
elem_types[2] = LLVMArrayType(texture_type,
PIPE_MAX_VERTEX_SAMPLERS); /* textures */

context_type = LLVMStructType(elem_types, Elements(elem_types), 0);

@@ -108,7 +124,7 @@ init_globals(struct draw_llvm *llvm)
llvm->target, context_type, 1);
LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,
llvm->target, context_type,
DRAW_JIT_CONTEXT_TEXTURES_INDEX);
DRAW_JIT_CTX_TEXTURES);
LP_CHECK_STRUCT_SIZE(struct draw_jit_context,
llvm->target, context_type);

@@ -290,7 +306,8 @@ generate_vs(struct draw_llvm *llvm,
LLVMBuilderRef builder,
LLVMValueRef (*outputs)[NUM_CHANNELS],
const LLVMValueRef (*inputs)[NUM_CHANNELS],
LLVMValueRef context_ptr)
LLVMValueRef context_ptr,
struct lp_build_sampler_soa *sampler)
{
const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens;
struct lp_type vs_type;
@@ -318,7 +335,7 @@ generate_vs(struct draw_llvm *llvm,
NULL /*pos*/,
inputs,
outputs,
NULL/*sampler*/,
sampler,
&llvm->draw->vs.vertex_shader->info);
}

@@ -641,6 +658,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
const int max_vertices = 4;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
void *code;
struct lp_build_sampler_soa *sampler = 0;

arg_types[0] = llvm->context_ptr_type; /* context */
arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */
@@ -688,6 +706,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)

step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);

/* code generated texture sampling */
sampler = draw_llvm_sampler_soa_create(variant->key.sampler,
context_ptr);

#if DEBUG_STORE
lp_build_printf(builder, "start = %d, end = %d, step = %d\n",
start, end, step);
@@ -729,7 +751,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
builder,
outputs,
ptr_aos,
context_ptr);
context_ptr,
sampler);

convert_to_aos(builder, io, outputs,
draw->vs.vertex_shader->info.num_outputs,
@@ -737,6 +760,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
}
lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop);

sampler->destroy(sampler);

LLVMBuildRetVoid(builder);

LLVMDisposeBuilder(builder);
@@ -787,6 +812,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef fetch_max;
void *code;
struct lp_build_sampler_soa *sampler = 0;

arg_types[0] = llvm->context_ptr_type; /* context */
arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */
@@ -833,6 +859,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian

step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);

/* code generated texture sampling */
sampler = draw_llvm_sampler_soa_create(variant->key.sampler,
context_ptr);

fetch_max = LLVMBuildSub(builder, fetch_count,
LLVMConstInt(LLVMInt32Type(), 1, 0),
"fetch_max");
@@ -884,7 +914,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
builder,
outputs,
ptr_aos,
context_ptr);
context_ptr,
sampler);

convert_to_aos(builder, io, outputs,
draw->vs.vertex_shader->info.num_outputs,
@@ -892,6 +923,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
}
lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop);

sampler->destroy(sampler);

LLVMBuildRetVoid(builder);

LLVMDisposeBuilder(builder);
@@ -925,6 +958,8 @@ void
draw_llvm_make_variant_key(struct draw_llvm *llvm,
struct draw_llvm_variant_key *key)
{
unsigned i;

memset(key, 0, sizeof(struct draw_llvm_variant_key));

key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements;
@@ -936,6 +971,43 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm,
memcpy(&key->vs,
&llvm->draw->vs.vertex_shader->state,
sizeof(struct pipe_shader_state));

for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) {
struct draw_vertex_shader *shader = llvm->draw->vs.vertex_shader;
if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
lp_sampler_static_state(&key->sampler[i],
llvm->draw->sampler_views[i],
llvm->draw->samplers[i]);
}
}

void
draw_llvm_set_mapped_texture(struct draw_context *draw,
unsigned sampler_idx,
uint32_t width, uint32_t height, uint32_t depth,
uint32_t last_level,
uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
const void *data[DRAW_MAX_TEXTURE_LEVELS])
{
unsigned j;
struct draw_jit_texture *jit_tex;

assert(sampler_idx <= PIPE_MAX_VERTEX_SAMPLERS);


jit_tex = &draw->llvm->jit_context.textures[sampler_idx];

jit_tex->width = width;
jit_tex->height = height;
jit_tex->depth = depth;
jit_tex->last_level = last_level;

for (j = 0; j <= last_level; j++) {
jit_tex->data[j] = data[j];
jit_tex->row_stride[j] = row_stride[j];
jit_tex->img_stride[j] = img_stride[j];
}
}

void

+ 33
- 9
src/gallium/auxiliary/draw/draw_llvm.h Bestand weergeven

@@ -25,12 +25,13 @@
*
**************************************************************************/

#ifndef HAVE_LLVM_H
#define HAVE_LLVM_H
#ifndef DRAW_LLVM_H
#define DRAW_LLVM_H

#include "draw/draw_private.h"

#include "draw/draw_vs.h"
#include "gallivm/lp_bld_sample.h"

#include "pipe/p_context.h"
#include "util/u_simple_list.h"
@@ -40,6 +41,8 @@
#include <llvm-c/Target.h>
#include <llvm-c/ExecutionEngine.h>

#define DRAW_MAX_TEXTURE_LEVELS 13 /* 4K x 4K for now */

struct draw_llvm;
struct llvm_vertex_shader;

@@ -47,15 +50,22 @@ struct draw_jit_texture
{
uint32_t width;
uint32_t height;
uint32_t stride;
const void *data;
uint32_t depth;
uint32_t last_level;
uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
const void *data[DRAW_MAX_TEXTURE_LEVELS];
};

enum {
DRAW_JIT_TEXTURE_WIDTH = 0,
DRAW_JIT_TEXTURE_HEIGHT,
DRAW_JIT_TEXTURE_STRIDE,
DRAW_JIT_TEXTURE_DATA
DRAW_JIT_TEXTURE_DEPTH,
DRAW_JIT_TEXTURE_LAST_LEVEL,
DRAW_JIT_TEXTURE_ROW_STRIDE,
DRAW_JIT_TEXTURE_IMG_STRIDE,
DRAW_JIT_TEXTURE_DATA,
DRAW_JIT_TEXTURE_NUM_FIELDS /* number of fields above */
};

enum {
@@ -81,7 +91,7 @@ struct draw_jit_context
const float *gs_constants;


struct draw_jit_texture textures[PIPE_MAX_SAMPLERS];
struct draw_jit_texture textures[PIPE_MAX_VERTEX_SAMPLERS];
};


@@ -91,10 +101,10 @@ struct draw_jit_context
#define draw_jit_context_gs_constants(_builder, _ptr) \
lp_build_struct_get(_builder, _ptr, 1, "gs_constants")

#define DRAW_JIT_CONTEXT_TEXTURES_INDEX 2
#define DRAW_JIT_CTX_TEXTURES 2

#define draw_jit_context_textures(_builder, _ptr) \
lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CONTEXT_TEXTURES_INDEX, "textures")
lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")



@@ -142,6 +152,7 @@ struct draw_llvm_variant_key
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_elements;
struct pipe_shader_state vs;
struct lp_sampler_static_state sampler[PIPE_MAX_VERTEX_SAMPLERS];
};

struct draw_llvm_variant_list_item
@@ -221,4 +232,17 @@ draw_llvm_translate_from(LLVMBuilderRef builder,
LLVMValueRef vbuffer,
enum pipe_format from_format);

struct lp_build_sampler_soa *
draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
LLVMValueRef context_ptr);

void
draw_llvm_set_mapped_texture(struct draw_context *draw,
unsigned sampler_idx,
uint32_t width, uint32_t height, uint32_t depth,
uint32_t last_level,
uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
const void *data[DRAW_MAX_TEXTURE_LEVELS]);

#endif

+ 216
- 0
src/gallium/auxiliary/draw/draw_llvm_sample.c Bestand weergeven

@@ -0,0 +1,216 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/

/**
* Texture sampling code generation
* @author Jose Fonseca <jfonseca@vmware.com>
*/

#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "gallivm/lp_bld_debug.h"
#include "gallivm/lp_bld_type.h"
#include "gallivm/lp_bld_sample.h"
#include "gallivm/lp_bld_tgsi.h"


#include "util/u_cpu_detect.h"
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_pointer.h"
#include "util/u_string.h"

#include "draw_llvm.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 draw_llvm_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 draw_llvm_sampler_soa
{
struct lp_build_sampler_soa base;

struct draw_llvm_sampler_dynamic_state dynamic_state;
};


/**
* Fetch the specified member of the lp_jit_texture structure.
* \param emit_load if TRUE, emit the LLVM load instruction to actually
* fetch the field's value. Otherwise, just emit the
* GEP code to address the field.
*
* @sa http://llvm.org/docs/GetElementPtr.html
*/
static LLVMValueRef
draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
LLVMBuilderRef builder,
unsigned unit,
unsigned member_index,
const char *member_name,
boolean emit_load)
{
struct draw_llvm_sampler_dynamic_state *state =
(struct draw_llvm_sampler_dynamic_state *)base;
LLVMValueRef indices[4];
LLVMValueRef ptr;
LLVMValueRef res;

debug_assert(unit < PIPE_MAX_VERTEX_SAMPLERS);

/* context[0] */
indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
/* context[0].textures */
indices[1] = LLVMConstInt(LLVMInt32Type(), DRAW_JIT_CTX_TEXTURES, 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), "");

if (emit_load)
res = LLVMBuildLoad(builder, ptr, "");
else
res = 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 DRAW_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \
static LLVMValueRef \
draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
LLVMBuilderRef builder, \
unsigned unit) \
{ \
return draw_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
}


DRAW_LLVM_TEXTURE_MEMBER(width, DRAW_JIT_TEXTURE_WIDTH, TRUE)
DRAW_LLVM_TEXTURE_MEMBER(height, DRAW_JIT_TEXTURE_HEIGHT, TRUE)
DRAW_LLVM_TEXTURE_MEMBER(depth, DRAW_JIT_TEXTURE_DEPTH, TRUE)
DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE)
DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE)
DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE)
DRAW_LLVM_TEXTURE_MEMBER(data_ptr, DRAW_JIT_TEXTURE_DATA, FALSE)


static void
draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
{
FREE(sampler);
}


/**
* Fetch filtered values from texture.
* The 'texel' parameter returns four vectors corresponding to R, G, B, A.
*/
static void
draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
LLVMBuilderRef builder,
struct lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
const LLVMValueRef *ddx,
const LLVMValueRef *ddy,
LLVMValueRef lod_bias, /* optional */
LLVMValueRef explicit_lod, /* optional */
LLVMValueRef *texel)
{
struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;

assert(unit < PIPE_MAX_VERTEX_SAMPLERS);

lp_build_sample_soa(builder,
&sampler->dynamic_state.static_state[unit],
&sampler->dynamic_state.base,
type,
unit,
num_coords, coords,
ddx, ddy,
lod_bias, explicit_lod,
texel);
}


struct lp_build_sampler_soa *
draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
LLVMValueRef context_ptr)
{
struct draw_llvm_sampler_soa *sampler;

sampler = CALLOC_STRUCT(draw_llvm_sampler_soa);
if(!sampler)
return NULL;

sampler->base.destroy = draw_llvm_sampler_soa_destroy;
sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel;
sampler->dynamic_state.base.width = draw_llvm_texture_width;
sampler->dynamic_state.base.height = draw_llvm_texture_height;
sampler->dynamic_state.base.depth = draw_llvm_texture_depth;
sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level;
sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride;
sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
sampler->dynamic_state.base.data_ptr = draw_llvm_texture_data_ptr;
sampler->dynamic_state.static_state = static_state;
sampler->dynamic_state.context_ptr = context_ptr;

return &sampler->base;
}


+ 7
- 0
src/gallium/auxiliary/draw/draw_private.h Bestand weergeven

@@ -48,6 +48,7 @@

#ifdef HAVE_LLVM
#include <llvm-c/ExecutionEngine.h>
struct draw_llvm;
#endif


@@ -262,9 +263,15 @@ struct draw_context
unsigned instance_id;

#ifdef HAVE_LLVM
struct draw_llvm *llvm;
LLVMExecutionEngineRef engine;
#endif

struct pipe_sampler_view *sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
unsigned num_sampler_views;
const struct pipe_sampler_state *samplers[PIPE_MAX_VERTEX_SAMPLERS];
unsigned num_samplers;

void *driver_private;
};


+ 1
- 4
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c Bestand weergeven

@@ -392,9 +392,6 @@ static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )
if (fpme->post_vs)
draw_pt_post_vs_destroy( fpme->post_vs );

if (fpme->llvm)
draw_llvm_destroy( fpme->llvm );

FREE(middle);
}

@@ -436,7 +433,7 @@ draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw)
if (!fpme->so_emit)
goto fail;

fpme->llvm = draw_llvm_create(draw);
fpme->llvm = draw->llvm;
if (!fpme->llvm)
goto fail;


+ 1
- 1
src/gallium/drivers/llvmpipe/lp_screen.c Bestand weergeven

@@ -86,7 +86,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return PIPE_MAX_SAMPLERS;
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
return 0;
return PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:

+ 72
- 1
src/gallium/drivers/llvmpipe/lp_setup.c Bestand weergeven

@@ -641,7 +641,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
/*
* XXX: Where should this be unmapped?
*/

struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
struct sw_winsys *winsys = screen->winsys;
jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
@@ -657,6 +656,75 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
}


/**
* Called during state validation when LP_NEW_SAMPLER_VIEW is set.
*/
void
lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup,
unsigned num,
struct pipe_sampler_view **views)
{
unsigned i;
uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
const void *data[DRAW_MAX_TEXTURE_LEVELS];
struct lp_scene *scene;
struct llvmpipe_context *lp;

LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);

assert(num <= PIPE_MAX_VERTEX_SAMPLERS);

scene = lp_setup_get_current_scene(setup);
lp = llvmpipe_context(scene->pipe);

for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
struct pipe_sampler_view *view = i < num ? views[i] : NULL;

if (view) {
struct pipe_resource *tex = view->texture;
struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);

/* We're referencing the texture's internal data, so save a
* reference to it.
*/
pipe_resource_reference(&setup->vs.current_tex[i], tex);

if (!lp_tex->dt) {
/* regular texture - setup array of mipmap level pointers */
int j;
for (j = 0; j <= tex->last_level; j++) {
data[j] =
llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
LP_TEX_LAYOUT_LINEAR);
row_stride[j] = lp_tex->row_stride[j];
img_stride[j] = lp_tex->img_stride[j];
}
}
else {
/* display target texture/surface */
/*
* XXX: Where should this be unmapped?
*/
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
struct sw_winsys *winsys = screen->winsys;
data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
PIPE_TRANSFER_READ);
row_stride[0] = lp_tex->row_stride[0];
img_stride[0] = lp_tex->img_stride[0];
assert(data[0]);
}
draw_set_mapped_texture(lp->draw,
i,
tex->width0, tex->height0, tex->depth0,
tex->last_level,
row_stride, img_stride, data);
}
}
}



/**
* Is the given texture referenced by any scene?
* Note: we have to check all scenes including any scenes currently
@@ -850,6 +918,9 @@ lp_setup_destroy( struct lp_setup_context *setup )

util_unreference_framebuffer_state(&setup->fb);

for (i = 0; i < Elements(setup->vs.current_tex); i++) {
pipe_resource_reference(&setup->vs.current_tex[i], NULL);
}
for (i = 0; i < Elements(setup->fs.current_tex); i++) {
pipe_resource_reference(&setup->fs.current_tex[i], NULL);
}

+ 5
- 0
src/gallium/drivers/llvmpipe/lp_setup.h Bestand weergeven

@@ -133,6 +133,11 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
unsigned num,
struct pipe_sampler_view **views);

void
lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup,
unsigned num,
struct pipe_sampler_view **views);

unsigned
lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
const struct pipe_resource *texture );

+ 4
- 0
src/gallium/drivers/llvmpipe/lp_setup_context.h Bestand weergeven

@@ -116,6 +116,10 @@ struct lp_setup_context
struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS];
} fs;

struct {
struct pipe_resource *current_tex[PIPE_MAX_VERTEX_SAMPLERS];
} vs;

/** fragment shader constants */
struct {
struct pipe_resource *current;

+ 6
- 2
src/gallium/drivers/llvmpipe/lp_state_derived.c Bestand weergeven

@@ -188,10 +188,14 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
lp_setup_set_fs_constants(llvmpipe->setup,
llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);

if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
lp_setup_set_fragment_sampler_views(llvmpipe->setup,
if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) {
lp_setup_set_fragment_sampler_views(llvmpipe->setup,
llvmpipe->num_fragment_sampler_views,
llvmpipe->fragment_sampler_views);
lp_setup_set_vertex_sampler_views(llvmpipe->setup,
llvmpipe->num_vertex_sampler_views,
llvmpipe->vertex_sampler_views);
}

llvmpipe->dirty = 0;
}

+ 8
- 0
src/gallium/drivers/llvmpipe/lp_state_sampler.c Bestand weergeven

@@ -100,6 +100,10 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,

llvmpipe->num_vertex_samplers = num_samplers;

draw_set_samplers(llvmpipe->draw,
llvmpipe->vertex_samplers,
llvmpipe->num_vertex_samplers);

llvmpipe->dirty |= LP_NEW_SAMPLER;
}

@@ -166,6 +170,10 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,

llvmpipe->num_vertex_sampler_views = num;

draw_set_sampler_views(llvmpipe->draw,
llvmpipe->vertex_sampler_views,
llvmpipe->num_vertex_sampler_views);

llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
}


Laden…
Annuleren
Opslaan