llvmpipe: Separate pixel packing/unpacking from loading/storing.

This commit is contained in:
José Fonseca 2009-07-29 07:58:27 +01:00
parent c4903ee27f
commit 833323b8d0
8 changed files with 185 additions and 44 deletions

View File

@ -9,6 +9,8 @@ C_SOURCES = \
lp_fs_llvm.c \
lp_bld_pack.c \
lp_bld_unpack.c \
lp_bld_load.c \
lp_bld_store.c \
lp_bld_loop.c \
lp_clear.c \
lp_flush.c \

View File

@ -12,6 +12,8 @@ llvmpipe = env.ConvenienceLibrary(
'lp_fs_llvm.c',
'lp_bld_pack.c',
'lp_bld_unpack.c',
'lp_bld_load.c',
'lp_bld_store.c',
'lp_bld_loop.c',
'lp_clear.c',
'lp_context.c',

View File

@ -48,15 +48,14 @@
/**
* Unpack a pixel into its RGBA components.
*
* @param ptr value with the pointer to the packed pixel. Pointer type is
* irrelevant.
* @param packed integer.
*
* @return RGBA in a 4 floats vector.
*/
LLVMValueRef
lp_build_unpack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr);
LLVMValueRef packed);
/**
@ -64,13 +63,38 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
*
* @param rgba 4 float vector with the unpacked components.
*/
void
LLVMValueRef
lp_build_pack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba);
/**
* Load a pixel into its RGBA components.
*
* @param ptr value with the pointer to the packed pixel. Pointer type is
* irrelevant.
*
* @return RGBA in a 4 floats vector.
*/
LLVMValueRef
lp_build_load_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr);
/**
* Store a pixel.
*
* @param rgba 4 float vector with the unpacked components.
*/
void
lp_build_store_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba);
struct lp_build_loop_state
{
LLVMBasicBlockRef block;

View File

@ -0,0 +1,59 @@
/**************************************************************************
*
* 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.h"
LLVMValueRef
lp_build_load_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr)
{
const struct util_format_description *desc;
LLVMTypeRef type;
LLVMValueRef packed;
desc = util_format_description(format);
/* FIXME: Support more formats */
assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
assert(desc->block.width == 1);
assert(desc->block.height == 1);
assert(desc->block.bits <= 32);
type = LLVMIntType(desc->block.bits);
ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
packed = LLVMBuildLoad(builder, ptr, "");
return lp_build_unpack_rgba(builder, format, packed);
}

View File

@ -31,10 +31,9 @@
#include "lp_bld.h"
void
LLVMValueRef
lp_build_pack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba)
{
const struct util_format_description *desc;
@ -121,12 +120,12 @@ lp_build_pack_rgba(LLVMBuilderRef builder,
}
}
if (packed) {
if (!packed)
packed = LLVMGetUndef(LLVMInt32Type());
if (desc->block.bits < 32)
packed = LLVMBuildTrunc(builder, packed, type, "");
if (desc->block.bits < 32)
packed = LLVMBuildTrunc(builder, packed, type, "");
LLVMBuildStore(builder, packed, LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), ""));
}
return packed;
}

View File

@ -0,0 +1,58 @@
/**************************************************************************
*
* 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.h"
void
lp_build_store_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr,
LLVMValueRef rgba)
{
const struct util_format_description *desc;
LLVMTypeRef type;
LLVMValueRef packed;
desc = util_format_description(format);
assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
assert(desc->block.width == 1);
assert(desc->block.height == 1);
type = LLVMIntType(desc->block.bits);
packed = lp_build_pack_rgba(builder, format, rgba);
ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
LLVMBuildStore(builder, packed, ptr);
}

View File

@ -89,14 +89,14 @@ struct pixel_test_case test_cases[] =
static LLVMValueRef
add_unpack_rgba_test(LLVMModuleRef module,
enum pipe_format format)
add_load_rgba_test(LLVMModuleRef module,
enum pipe_format format)
{
LLVMTypeRef args[] = {
LLVMPointerType(LLVMInt8Type(), 0),
LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0)
};
LLVMValueRef func = LLVMAddFunction(module, "unpack", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
LLVMValueRef func = LLVMAddFunction(module, "load", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
LLVMSetFunctionCallConv(func, LLVMCCallConv);
LLVMValueRef ptr = LLVMGetParam(func, 0);
LLVMValueRef rgba_ptr = LLVMGetParam(func, 1);
@ -111,7 +111,7 @@ add_unpack_rgba_test(LLVMModuleRef module,
lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), &loop);
rgba = lp_build_unpack_rgba(builder, format, ptr);
rgba = lp_build_load_rgba(builder, format, ptr);
LLVMBuildStore(builder, rgba, rgba_ptr);
lp_build_loop_end(builder, LLVMConstInt(LLVMInt32Type(), 4, 0), NULL, &loop);
@ -124,14 +124,14 @@ add_unpack_rgba_test(LLVMModuleRef module,
static LLVMValueRef
add_pack_rgba_test(LLVMModuleRef module,
enum pipe_format format)
add_store_rgba_test(LLVMModuleRef module,
enum pipe_format format)
{
LLVMTypeRef args[] = {
LLVMPointerType(LLVMInt8Type(), 0),
LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0)
};
LLVMValueRef func = LLVMAddFunction(module, "pack", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
LLVMValueRef func = LLVMAddFunction(module, "store", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
LLVMSetFunctionCallConv(func, LLVMCCallConv);
LLVMValueRef ptr = LLVMGetParam(func, 0);
LLVMValueRef rgba_ptr = LLVMGetParam(func, 1);
@ -144,7 +144,7 @@ add_pack_rgba_test(LLVMModuleRef module,
rgba = LLVMBuildLoad(builder, rgba_ptr, "");
lp_build_pack_rgba(builder, format, ptr, rgba);
lp_build_store_rgba(builder, format, ptr, rgba);
LLVMBuildRetVoid(builder);
@ -164,8 +164,8 @@ test_format(const struct pixel_test_case *test)
LLVMModuleRef module = LLVMModuleCreateWithName("test");
LLVMValueRef unpack = add_unpack_rgba_test(module, test->format);
LLVMValueRef pack = add_pack_rgba_test(module, test->format);
LLVMValueRef load = add_load_rgba_test(module, test->format);
LLVMValueRef store = add_store_rgba_test(module, test->format);
LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);
@ -200,19 +200,19 @@ test_format(const struct pixel_test_case *test)
unsigned packed = 0;
{
typedef void (*unpack_ptr_t)(const void *, float *);
unpack_ptr_t unpack_ptr = (unpack_ptr_t)LLVMGetPointerToGlobal(engine, unpack);
typedef void (*load_ptr_t)(const void *, float *);
load_ptr_t load_ptr = (load_ptr_t)LLVMGetPointerToGlobal(engine, load);
unpack_ptr(&test->packed, unpacked);
load_ptr(&test->packed, unpacked);
}
{
typedef void (*pack_ptr_t)(void *, const float *);
pack_ptr_t pack_ptr = (pack_ptr_t)LLVMGetPointerToGlobal(engine, pack);
typedef void (*store_ptr_t)(void *, const float *);
store_ptr_t store_ptr = (store_ptr_t)LLVMGetPointerToGlobal(engine, store);
pack_ptr(&packed, unpacked);
store_ptr(&packed, unpacked);
}

View File

@ -34,11 +34,10 @@
LLVMValueRef
lp_build_unpack_rgba(LLVMBuilderRef builder,
enum pipe_format format,
LLVMValueRef ptr)
LLVMValueRef packed)
{
const struct util_format_description *desc;
LLVMTypeRef type;
LLVMValueRef deferred;
unsigned shift = 0;
unsigned i;
@ -52,24 +51,22 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
type = LLVMIntType(desc->block.bits);
deferred = LLVMBuildLoad(builder, LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), ""), "");
/* Do the intermediate integer computations with 32bit integers since it
* matches floating point size */
if (desc->block.bits < 32)
deferred = LLVMBuildZExt(builder, deferred, LLVMInt32Type(), "");
packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), "");
/* Broadcast the packed value to all four channels */
deferred = LLVMBuildInsertElement(builder,
LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
deferred,
LLVMConstNull(LLVMInt32Type()),
"");
deferred = LLVMBuildShuffleVector(builder,
deferred,
LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
"");
packed = LLVMBuildInsertElement(builder,
LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
packed,
LLVMConstNull(LLVMInt32Type()),
"");
packed = LLVMBuildShuffleVector(builder,
packed,
LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
"");
LLVMValueRef shifted, casted, scaled, masked, swizzled;
LLVMValueRef shifts[4];
@ -108,7 +105,7 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
shift += bits;
}
shifted = LLVMBuildLShr(builder, deferred, LLVMConstVector(shifts, 4), "");
shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), "");
masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), "");
// UIToFP can't be expressed in SSE2
casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");