llvmpipe: Separate pixel packing/unpacking from loading/storing.
This commit is contained in:
parent
c4903ee27f
commit
833323b8d0
|
@ -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 \
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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), "");
|
||||
|
|
Loading…
Reference in New Issue