Browse Source

llvmpipe: SoA pixel unpacking specialization.

tags/android-x86-1.6
José Fonseca 16 years ago
parent
commit
866fbacf2b

+ 1
- 0
src/gallium/drivers/llvmpipe/Makefile View File

@@ -15,6 +15,7 @@ C_SOURCES = \
lp_bld_depth.c \
lp_bld_flow.c \
lp_bld_format_aos.c \
lp_bld_format_soa.c \
lp_bld_interp.c \
lp_bld_intr.c \
lp_bld_logic.c \

+ 1
- 0
src/gallium/drivers/llvmpipe/SConscript View File

@@ -23,6 +23,7 @@ llvmpipe = env.ConvenienceLibrary(
'lp_bld_depth.c',
'lp_bld_flow.c',
'lp_bld_format_aos.c',
'lp_bld_format_soa.c',
'lp_bld_interp.c',
'lp_bld_intr.c',
'lp_bld_struct.c',

+ 40
- 22
src/gallium/drivers/llvmpipe/lp_bld_format.h View File

@@ -31,20 +31,14 @@

/**
* @file
* LLVM IR building helpers interfaces.
*
* We use LLVM-C bindings for now. They are not documented, but follow the C++
* interfaces very closely, and appear to be complete enough for code
* genration. See
* http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
* for a standalone example.
* Pixel format helpers.
*/

#include <llvm-c/Core.h>
#include "pipe/p_format.h"

#include "pipe/p_format.h"

struct util_format_description;
union lp_type;


@@ -56,9 +50,9 @@ union lp_type;
* @return RGBA in a 4 floats vector.
*/
LLVMValueRef
lp_build_unpack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed);
lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed);


/**
@@ -67,9 +61,9 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
* @param rgba 4 float vector with the unpacked components.
*/
LLVMValueRef
lp_build_pack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba);
lp_build_pack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba);


/**
@@ -81,9 +75,9 @@ lp_build_pack_rgba(LLVMBuilderRef builder,
* @return RGBA in a 4 floats vector.
*/
LLVMValueRef
lp_build_load_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr);
lp_build_load_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr);


/**
@@ -92,10 +86,34 @@ lp_build_load_rgba(LLVMBuilderRef builder,
* @param rgba 4 float vector with the unpacked components.
*/
void
lp_build_store_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba);
lp_build_store_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba);

LLVMValueRef
lp_build_gather(LLVMBuilderRef builder,
unsigned length,
unsigned src_width,
unsigned dst_width,
LLVMValueRef base_ptr,
LLVMValueRef offsets);


void
lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef packed,
LLVMValueRef *rgba);


void
lp_build_load_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef base_ptr,
LLVMValueRef offsets,
LLVMValueRef *rgba);

#endif /* !LP_BLD_H */

+ 15
- 15
src/gallium/drivers/llvmpipe/lp_bld_format_aos.c View File

@@ -32,9 +32,9 @@


LLVMValueRef
lp_build_unpack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed)
lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef packed)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -152,9 +152,9 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,


LLVMValueRef
lp_build_pack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba)
lp_build_pack_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef rgba)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -250,9 +250,9 @@ lp_build_pack_rgba(LLVMBuilderRef builder,


LLVMValueRef
lp_build_load_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr)
lp_build_load_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -272,15 +272,15 @@ lp_build_load_rgba(LLVMBuilderRef builder,

packed = LLVMBuildLoad(builder, ptr, "");

return lp_build_unpack_rgba(builder, format, packed);
return lp_build_unpack_rgba_aos(builder, format, packed);
}


void
lp_build_store_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba)
lp_build_store_rgba_aos(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba)
{
const struct util_format_description *desc;
LLVMTypeRef type;
@@ -294,7 +294,7 @@ lp_build_store_rgba(LLVMBuilderRef builder,

type = LLVMIntType(desc->block.bits);

packed = lp_build_pack_rgba(builder, format, rgba);
packed = lp_build_pack_rgba_aos(builder, format, rgba);

ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");


+ 193
- 0
src/gallium/drivers/llvmpipe/lp_bld_format_soa.c View File

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


#include "util/u_format.h"

#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_conv.h"
#include "lp_bld_format.h"


/**
* Gather elements from scatter positions in memory into a single vector.
*
* @param src_width src element width
* @param dst_width result element width (source will be expanded to fit)
* @param length length of the offsets,
* @param base_ptr base pointer, should be a i8 pointer type.
* @param offsets vector with offsets
*/
LLVMValueRef
lp_build_gather(LLVMBuilderRef builder,
unsigned length,
unsigned src_width,
unsigned dst_width,
LLVMValueRef base_ptr,
LLVMValueRef offsets)
{
LLVMTypeRef src_type = LLVMIntType(src_width);
LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
LLVMValueRef res;
unsigned i;

res = LLVMGetUndef(dst_vec_type);
for(i = 0; i < length; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef elem_offset;
LLVMValueRef elem_ptr;
LLVMValueRef elem;

elem_offset = LLVMBuildExtractElement(builder, offsets, index, "");
elem_ptr = LLVMBuildGEP(builder, base_ptr, &elem_offset, 1, "");
elem_ptr = LLVMBuildBitCast(builder, elem_ptr, src_ptr_type, "");
elem = LLVMBuildLoad(builder, elem_ptr, "");

assert(src_width <= dst_width);
if(src_width > dst_width)
elem = LLVMBuildTrunc(builder, elem, dst_elem_type, "");
if(src_width < dst_width)
elem = LLVMBuildZExt(builder, elem, dst_elem_type, "");

res = LLVMBuildInsertElement(builder, res, elem, index, "");
}

return res;
}


void
lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef packed,
LLVMValueRef *rgba)
{
LLVMValueRef inputs[4];
unsigned start;
unsigned chan;

/* FIXME: Support more formats */
assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
assert(format_desc->block.width == 1);
assert(format_desc->block.height == 1);
assert(format_desc->block.bits <= 32);

/* Decode the input vector components */
start = 0;
for (chan = 0; chan < 4; ++chan) {
unsigned width = format_desc->channel[chan].size;
unsigned stop = start + width;
LLVMValueRef input;

input = packed;

switch(format_desc->channel[chan].type) {
case UTIL_FORMAT_TYPE_VOID:
input = NULL;
break;

case UTIL_FORMAT_TYPE_UNSIGNED:
if(type.floating) {
if(start)
input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), "");
if(stop < format_desc->block.bits) {
unsigned mask = ((unsigned long long)1 << width) - 1;
input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), "");
}

if(format_desc->channel[chan].normalized)
input = lp_build_unsigned_norm_to_float(builder, width, type, input);
else
input = LLVMBuildFPToSI(builder, input, lp_build_vec_type(type), "");
}
else {
/* FIXME */
assert(0);
input = lp_build_undef(type);
}
break;

default:
/* fall through */
input = lp_build_undef(type);
break;
}

inputs[chan] = input;

start = stop;
}

for (chan = 0; chan < 4; ++chan) {
enum util_format_swizzle swizzle = format_desc->swizzle[chan];

switch (swizzle) {
case UTIL_FORMAT_SWIZZLE_X:
case UTIL_FORMAT_SWIZZLE_Y:
case UTIL_FORMAT_SWIZZLE_Z:
case UTIL_FORMAT_SWIZZLE_W:
rgba[chan] = inputs[swizzle];
break;
case UTIL_FORMAT_SWIZZLE_0:
rgba[chan] = lp_build_zero(type);
break;
case UTIL_FORMAT_SWIZZLE_1:
rgba[chan] = lp_build_one(type);
break;
case UTIL_FORMAT_SWIZZLE_NONE:
rgba[chan] = lp_build_undef(type);
break;
}
}
}


void
lp_build_load_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
union lp_type type,
LLVMValueRef base_ptr,
LLVMValueRef offsets,
LLVMValueRef *rgba)
{
LLVMValueRef packed;

assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
assert(format_desc->block.width == 1);
assert(format_desc->block.height == 1);
assert(format_desc->block.bits <= 32);

packed = lp_build_gather(builder,
type.length, format_desc->block.bits, type.width,
base_ptr, offsets);

lp_build_unpack_rgba_soa(builder, format_desc, type, packed, rgba);
}

+ 2
- 2
src/gallium/drivers/llvmpipe/lp_test_format.c View File

@@ -119,7 +119,7 @@ add_load_rgba_test(LLVMModuleRef module,

lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), &loop);

rgba = lp_build_load_rgba(builder, format, ptr);
rgba = lp_build_load_rgba_aos(builder, format, ptr);
LLVMBuildStore(builder, rgba, rgba_ptr);

lp_build_loop_end(builder, LLVMConstInt(LLVMInt32Type(), 4, 0), NULL, &loop);
@@ -160,7 +160,7 @@ add_store_rgba_test(LLVMModuleRef module,

rgba = LLVMBuildLoad(builder, rgba_ptr, "");

lp_build_store_rgba(builder, format, ptr, rgba);
lp_build_store_rgba_aos(builder, format, ptr, rgba);

LLVMBuildRetVoid(builder);


Loading…
Cancel
Save