From 833323b8d02a08b4f53847a521e14c707efd8beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 29 Jul 2009 07:58:27 +0100 Subject: [PATCH] llvmpipe: Separate pixel packing/unpacking from loading/storing. --- src/gallium/drivers/llvmpipe/Makefile | 2 + src/gallium/drivers/llvmpipe/SConscript | 2 + src/gallium/drivers/llvmpipe/lp_bld.h | 34 +++++++++-- src/gallium/drivers/llvmpipe/lp_bld_load.c | 59 ++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_bld_pack.c | 13 ++--- src/gallium/drivers/llvmpipe/lp_bld_store.c | 58 +++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_bld_test.c | 32 +++++------ src/gallium/drivers/llvmpipe/lp_bld_unpack.c | 29 +++++----- 8 files changed, 185 insertions(+), 44 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_bld_load.c create mode 100644 src/gallium/drivers/llvmpipe/lp_bld_store.c diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 20a8c44a24d..e06bf6668f6 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -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 \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index c6c54d2f00d..bba283f2968 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -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', diff --git a/src/gallium/drivers/llvmpipe/lp_bld.h b/src/gallium/drivers/llvmpipe/lp_bld.h index 368182d6380..44343f644ba 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld.h +++ b/src/gallium/drivers/llvmpipe/lp_bld.h @@ -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; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_load.c b/src/gallium/drivers/llvmpipe/lp_bld_load.c new file mode 100644 index 00000000000..b9734bdbed1 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bld_load.c @@ -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); +} + diff --git a/src/gallium/drivers/llvmpipe/lp_bld_pack.c b/src/gallium/drivers/llvmpipe/lp_bld_pack.c index 2383a07d725..823d67e12db 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_pack.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_pack.c @@ -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; } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_store.c b/src/gallium/drivers/llvmpipe/lp_bld_store.c new file mode 100644 index 00000000000..6273c9ee627 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bld_store.c @@ -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); +} + diff --git a/src/gallium/drivers/llvmpipe/lp_bld_test.c b/src/gallium/drivers/llvmpipe/lp_bld_test.c index 09947dd6bb6..1f093102671 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_test.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_test.c @@ -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); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_unpack.c b/src/gallium/drivers/llvmpipe/lp_bld_unpack.c index cf6f8313282..f1ffe3ecd81 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_unpack.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_unpack.c @@ -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), "");