diff options
Diffstat (limited to 'src/gallium')
27 files changed, 883 insertions, 446 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index e1c3bc43a24..452eceb7f4f 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -155,6 +155,7 @@ GALLIVM_SOURCES = \ gallivm/lp_bld_intr.c \ gallivm/lp_bld_logic.c \ gallivm/lp_bld_pack.c \ + gallivm/lp_bld_printf.c \ gallivm/lp_bld_sample.c \ gallivm/lp_bld_sample_soa.c \ gallivm/lp_bld_struct.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 65e1dc8a58d..0a23da47b2a 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -200,6 +200,7 @@ if drawllvm: 'gallivm/lp_bld_logic.c', 'gallivm/lp_bld_init.cpp', 'gallivm/lp_bld_pack.c', + 'gallivm/lp_bld_printf.c', 'gallivm/lp_bld_sample.c', 'gallivm/lp_bld_sample_soa.c', 'gallivm/lp_bld_struct.c', diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.c b/src/gallium/auxiliary/gallivm/lp_bld_printf.c new file mode 100644 index 00000000000..ae4d400af39 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.c @@ -0,0 +1,109 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#include <stdio.h> + +#include "lp_bld_printf.h" + + +static int +lp_get_printf_arg_count(const char *fmt) +{ + int count =0; + const char *p = fmt; + int c; + + while ((c = *p++)) { + if (c != '%') + continue; + switch (*p) { + case '\0': + continue; + case '%': + p++; + continue; + case '.': + if (p[1] == '*' && p[2] == 's') { + count += 2; + p += 3; + continue; + } + default: + count ++; + } + } + return count; +} + +LLVMValueRef +lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len) +{ + LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), len + 1), ""); + LLVMSetGlobalConstant(string, TRUE); + LLVMSetLinkage(string, LLVMInternalLinkage); + LLVMSetInitializer(string, LLVMConstString(str, len + 1, TRUE)); + return string; +} + + +/** + * lp_build_printf. + * + * Build printf call in LLVM IR. The output goes to stdout. + * The additional variable arguments need to have type + * LLVMValueRef. + */ +LLVMValueRef +lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...) +{ + va_list arglist; + int i = 0; + int argcount = lp_get_printf_arg_count(fmt); + LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); + LLVMValueRef params[argcount + 1]; + LLVMValueRef fmtarg = lp_build_const_string_variable(module, fmt, strlen(fmt) + 1); + LLVMValueRef int0 = LLVMConstInt(LLVMInt32Type(), 0, 0); + LLVMValueRef index[2]; + LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf"); + + index[0] = index[1] = int0; + + if (!func_printf) { + LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntType(32), NULL, 0, 1); + func_printf = LLVMAddFunction(module, "printf", printf_type); + } + + params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, ""); + + va_start(arglist, fmt); + for (i = 1; i <= argcount; i++) + params[i] = va_arg(arglist, LLVMValueRef); + va_end(arglist); + + return LLVMBuildCall(builder, func_printf, params, argcount + 1, ""); +} + diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.h b/src/gallium/auxiliary/gallivm/lp_bld_printf.h new file mode 100644 index 00000000000..83bd8f1d557 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef LP_BLD_PRINTF_H +#define LP_BLD_PRINTF_H + + +#include "pipe/p_compiler.h" +#include "lp_bld.h" + +LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len); +LLVMValueRef lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...); + +#endif + diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index f160be878f8..95cd6a0ecf3 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -651,6 +651,19 @@ emit_declaration( unsigned first = decl->Range.First; unsigned last = decl->Range.Last; unsigned idx, i; + LLVMBasicBlockRef current_block = + LLVMGetInsertBlock(bld->base.builder); + LLVMBasicBlockRef first_block = + LLVMGetEntryBasicBlock( + LLVMGetBasicBlockParent(current_block)); + LLVMValueRef first_inst = + LLVMGetFirstInstruction(first_block); + + /* we want alloca's to be the first instruction + * in the function so we need to rewind the builder + * to the very beginning */ + LLVMPositionBuilderBefore(bld->base.builder, + first_inst); for (idx = first; idx <= last; ++idx) { boolean ok; @@ -673,10 +686,15 @@ emit_declaration( ok = TRUE; } - if (!ok) + if (!ok) { + LLVMPositionBuilderAtEnd(bld->base.builder, + current_block); return FALSE; + } } + LLVMPositionBuilderAtEnd(bld->base.builder, + current_block); return TRUE; } diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index f55bc3d805b..57e995c03be 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -121,18 +121,23 @@ PIPE_FORMAT_R9G9B9E5_FLOAT , compressed, 1, 1, x32 , , , , x PIPE_FORMAT_R1_UNORM , compressed, 8, 1, x8 , , , , x001, rgb # Compressed formats -PIPE_FORMAT_DXT1_RGB , compressed, 4, 4, x64 , , , , xyz1, rgb -PIPE_FORMAT_DXT1_RGBA , compressed, 4, 4, x64 , , , , xyzw, rgb -PIPE_FORMAT_DXT3_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb -PIPE_FORMAT_DXT5_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb -PIPE_FORMAT_DXT1_SRGB , compressed, 4, 4, x64 , , , , xyz1, srgb -PIPE_FORMAT_DXT1_SRGBA , compressed, 4, 4, x64 , , , , xyzw, srgb -PIPE_FORMAT_DXT3_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb -PIPE_FORMAT_DXT5_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb -PIPE_FORMAT_RGTC1_UNORM , compressed, 4, 4, x64, , , , x001, rgb -PIPE_FORMAT_RGTC1_SNORM , compressed, 4, 4, x64, , , , x001, rgb -PIPE_FORMAT_RGTC2_UNORM , compressed, 4, 4, x128, , , , xy01, rgb -PIPE_FORMAT_RGTC2_SNORM , compressed, 4, 4, x128, , , , xy01, rgb +# - http://en.wikipedia.org/wiki/S3_Texture_Compression +# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt +# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt +# - http://msdn.microsoft.com/en-us/library/bb694531.aspx +PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb +PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb +PIPE_FORMAT_DXT3_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb +PIPE_FORMAT_DXT5_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb +PIPE_FORMAT_DXT1_SRGB , s3tc, 4, 4, x64 , , , , xyz1, srgb +PIPE_FORMAT_DXT1_SRGBA , s3tc, 4, 4, x64 , , , , xyzw, srgb +PIPE_FORMAT_DXT3_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb +PIPE_FORMAT_DXT5_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb + +PIPE_FORMAT_RGTC1_UNORM , rgtc, 4, 4, x64, , , , x001, rgb +PIPE_FORMAT_RGTC1_SNORM , rgtc, 4, 4, x64, , , , x001, rgb +PIPE_FORMAT_RGTC2_UNORM , rgtc, 4, 4, x128, , , , xy01, rgb +PIPE_FORMAT_RGTC2_SNORM , rgtc, 4, 4, x128, , , , xy01, rgb # Straightforward D3D10-like formats (also used for # vertex buffer element description) diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index c08fdcafcc8..98d4b98ebb5 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -56,15 +56,23 @@ enum util_format_layout { * * This is for formats like YV12 where there is less than one sample per * pixel. - * - * XXX: This could actually b */ UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, /** - * An unspecified compression algorithm. + * S3 Texture Compression formats. + */ + UTIL_FORMAT_LAYOUT_S3TC = 4, + + /** + * Red-Green Texture Compression formats. + */ + UTIL_FORMAT_LAYOUT_RGTC = 5, + + /** + * Everything else that doesn't fit in any of the above layouts. */ - UTIL_FORMAT_LAYOUT_COMPRESSED = 4 + UTIL_FORMAT_LAYOUT_OTHER = 6 }; @@ -210,7 +218,7 @@ util_format_name(enum pipe_format format) } static INLINE boolean -util_format_is_compressed(enum pipe_format format) +util_format_is_s3tc(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -219,7 +227,7 @@ util_format_is_compressed(enum pipe_format format) return FALSE; } - return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE; + return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; } static INLINE boolean diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c index 613ac784207..5825928e28f 100644 --- a/src/gallium/drivers/i965/brw_screen_texture.c +++ b/src/gallium/drivers/i965/brw_screen_texture.c @@ -206,7 +206,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, /* XXX: compressed textures need special treatment here */ tex->cpp = util_format_get_blocksize(tex->base.format); - tex->compressed = util_format_is_compressed(tex->base.format); + tex->compressed = util_format_is_s3tc(tex->base.format); make_empty_list(&tex->views[0]); make_empty_list(&tex->views[1]); @@ -321,7 +321,7 @@ brw_texture_from_handle(struct pipe_screen *screen, templ->depth0 != 1) return NULL; - if (util_format_is_compressed(templ->format)) + if (util_format_is_s3tc(templ->format)) return NULL; tex = CALLOC_STRUCT(brw_texture); diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 74d728ddb39..b37c6754c08 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -44,7 +44,8 @@ CPP_SOURCES = \ PROGS := lp_test_format \ lp_test_blend \ - lp_test_conv + lp_test_conv \ + lp_test_printf include ../../Makefile.template diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c new file mode 100644 index 00000000000..e5e5925012a --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#include <stdlib.h> +#include <stdio.h> + +#include "gallivm/lp_bld.h" +#include "gallivm/lp_bld_printf.h" + +#include <llvm-c/Analysis.h> +#include <llvm-c/ExecutionEngine.h> +#include <llvm-c/Target.h> +#include <llvm-c/Transforms/Scalar.h> + +#include "lp_test.h" + + +struct printf_test_case { +}; + +void +write_tsv_header(FILE *fp) +{ + fprintf(fp, + "result\t" + "format\n"); + + fflush(fp); +} + + + +typedef void (*test_printf_t)(int i); + +static LLVMValueRef +add_printf_test(LLVMModuleRef module) +{ + LLVMTypeRef args[1] = { LLVMIntType(32) }; + LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidType(), args, 1, 0)); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry"); + + LLVMSetFunctionCallConv(func, LLVMCCallConv); + + LLVMPositionBuilderAtEnd(builder, block); + lp_build_printf(builder, "hello, world\n"); + lp_build_printf(builder, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32Type(), 5, 0), + LLVMConstInt(LLVMInt32Type(), 6, 0)); + LLVMBuildRetVoid(builder); + LLVMDisposeBuilder(builder); + return func; +} + + +PIPE_ALIGN_STACK +static boolean +test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) +{ + LLVMModuleRef module = NULL; + LLVMValueRef test = NULL; + LLVMExecutionEngineRef engine = NULL; + LLVMModuleProviderRef provider = NULL; + LLVMPassManagerRef pass = NULL; + char *error = NULL; + test_printf_t test_printf; + float unpacked[4]; + unsigned packed; + boolean success = TRUE; + + module = LLVMModuleCreateWithName("test"); + + test = add_printf_test(module); + + if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) { + LLVMDumpModule(module); + abort(); + } + LLVMDisposeMessage(error); + + provider = LLVMCreateModuleProviderForExistingModule(module); + if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { + fprintf(stderr, "%s\n", error); + LLVMDisposeMessage(error); + abort(); + } + +#if 0 + pass = LLVMCreatePassManager(); + LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); + /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, + * but there are more on SVN. */ + LLVMAddConstantPropagationPass(pass); + LLVMAddInstructionCombiningPass(pass); + LLVMAddPromoteMemoryToRegisterPass(pass); + LLVMAddGVNPass(pass); + LLVMAddCFGSimplificationPass(pass); + LLVMRunPassManager(pass, module); +#else + (void)pass; +#endif + + test_printf = (test_printf_t)LLVMGetPointerToGlobal(engine, test); + + memset(unpacked, 0, sizeof unpacked); + packed = 0; + + + // LLVMDumpModule(module); + + test_printf(0); + + LLVMFreeMachineCodeForFunction(engine, test); + + LLVMDisposeExecutionEngine(engine); + if(pass) + LLVMDisposePassManager(pass); + + return success; +} + + +boolean +test_all(unsigned verbose, FILE *fp) +{ + bool success = TRUE; + + test_printf(verbose, fp, NULL); + + return success; +} + + +boolean +test_some(unsigned verbose, FILE *fp, unsigned long n) +{ + return test_all(verbose, fp); +} diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index bc7e6060636..28cc822b13d 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -159,7 +159,7 @@ static uint32_t r300_translate_texformat(enum pipe_format format) } /* Compressed formats. */ - if (desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED) { + if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { switch (format) { case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c index 41f88eed72c..811c7466956 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ b/src/gallium/drivers/svga/svga_screen_texture.c @@ -330,7 +330,7 @@ svga_texture_create(struct pipe_screen *screen, */ #if 0 if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) && - !util_format_is_compressed(templat->format)) + !util_format_is_s3tc(templat->format)) tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; #endif @@ -969,7 +969,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt, if (min_lod == 0 && max_lod >= pt->last_level) view = FALSE; - if (util_format_is_compressed(pt->format) && view) { + if (util_format_is_s3tc(pt->format) && view) { format = svga_translate_format_render(pt->format); } diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h index 27b7a28c467..bb1cd6d1d82 100644 --- a/src/gallium/include/state_tracker/dri1_api.h +++ b/src/gallium/include/state_tracker/dri1_api.h @@ -7,14 +7,14 @@ #include "state_tracker/drm_api.h" -struct drm_clip_rect; - struct pipe_screen; struct pipe_winsys; struct pipe_buffer; struct pipe_context; struct pipe_texture; +struct drm_clip_rect; + struct dri1_api_version { int major; @@ -31,8 +31,8 @@ struct dri1_api_lock_funcs { void (*lock) (struct pipe_context * pipe); void (*unlock) (struct pipe_context * locked_pipe); - boolean(*is_locked) (struct pipe_context * locked_pipe); - boolean(*is_lock_lost) (struct pipe_context * locked_pipe); + boolean(*is_locked) (struct pipe_context * locked_pipe); + boolean(*is_lock_lost) (struct pipe_context * locked_pipe); void (*clear_lost_lock) (struct pipe_context * locked_pipe); }; diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h new file mode 100644 index 00000000000..c6adebb4ec5 --- /dev/null +++ b/src/gallium/include/state_tracker/drisw_api.h @@ -0,0 +1,35 @@ +#ifndef _DRISW_API_H_ +#define _DRISW_API_H_ + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_format.h" + +#include "state_tracker/drm_api.h" + +struct pipe_screen; +struct pipe_winsys; +struct pipe_buffer; +struct pipe_context; +struct pipe_texture; + +struct dri_drawable; + +/** + * This callback struct is intended for the winsys to call the loader. + */ + +struct drisw_loader_funcs +{ + void (*put_image) (struct dri_drawable *dri_drawable, + void *data, unsigned width, unsigned height); +}; + +struct drisw_create_screen_arg +{ + struct drm_create_screen_arg base; + + struct drisw_loader_funcs *lf; +}; + +#endif diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.c b/src/gallium/state_trackers/dri/common/dri_st_api.c index 40b24b18e9f..7ba7ec383d8 100644 --- a/src/gallium/state_trackers/dri/common/dri_st_api.c +++ b/src/gallium/state_trackers/dri/common/dri_st_api.c @@ -80,7 +80,7 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, } #else if (new_stamp) - drisw_update_drawable_info(drawable->dPriv); + drisw_update_drawable_info(drawable); drisw_allocate_textures(drawable, statt_mask); #endif diff --git a/src/gallium/state_trackers/dri/drm/dri1.c b/src/gallium/state_trackers/dri/drm/dri1.c index aad098bb301..9b5842ba2bf 100644 --- a/src/gallium/state_trackers/dri/drm/dri1.c +++ b/src/gallium/state_trackers/dri/drm/dri1.c @@ -404,6 +404,19 @@ dri1_allocate_textures(struct dri_drawable *drawable, drawable->old_h = height; } +/* + * Backend function for init_screen. + */ + +static const __DRIextension *dri1_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + static void st_dri_lock(struct pipe_context *pipe) { @@ -442,21 +455,6 @@ static struct dri1_api_lock_funcs dri1_lf = { .clear_lost_lock = st_dri_clear_lost_lock }; -/* - * Backend function for init_screen. - */ - -static const __DRIextension *dri1_screen_extensions[] = { - &driReadDrawableExtension, - &driCopySubBufferExtension.base, - &driSwapControlExtension.base, - &driFrameTrackingExtension.base, - &driMediaStreamCounterExtension.base, - NULL -}; - -struct dri1_api *__dri1_api_hooks = NULL; - static INLINE void dri1_copy_version(struct dri1_api_version *dst, const struct __DRIversionRec *src) @@ -466,6 +464,8 @@ dri1_copy_version(struct dri1_api_version *dst, dst->patch_level = src->patch; } +struct dri1_api *__dri1_api_hooks = NULL; + const __DRIconfig ** dri1_init_screen(__DRIscreen * sPriv) { diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index b7eba63bcb9..b8256710972 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.c +++ b/src/gallium/state_trackers/dri/sw/drisw.c @@ -28,37 +28,17 @@ /* TODO: * - * stride: - * - * The driver and the loaders (libGL, xserver/glx) compute the stride from the - * width independently. winsys has a workaround that works for softpipe but may - * explode for other drivers or platforms, rendering- or performance-wise. - * Solving this issue properly requires extending the DRISW loader extension, - * in order to make the stride available to the putImage callback. - * - * drisw_api: - * - * Define drisw_api similarly to dri1_api and use it to call the loader. This - * is predicated on support for calling the loader from the winsys, which has - * to grow for DRI2 as well. - * * xshm / texture_from_pixmap / EGLImage: * * Allow the loaders to use the XSHM extension. It probably requires callbacks - * for createImage/destroyImage similar to DRI2 getBuffers. Probably not worth - * it, given the scope of DRISW, unless it falls naturally from properly - * solving the other issues. - * - * fences: - * - * No fences are used, are they needed for llvmpipe / cell ? + * for createImage/destroyImage similar to DRI2 getBuffers. */ #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_inlines.h" #include "pipe/p_context.h" -#include "state_tracker/drm_api.h" +#include "state_tracker/drisw_api.h" #include "dri_screen.h" #include "dri_context.h" @@ -80,60 +60,47 @@ get_drawable_info(__DRIdrawable *dPriv, int *w, int *h) dPriv->loaderPrivate); } -/* - * Set the width to 'stride / cpp'. PutImage seems to correctly clip the width - * to the actual width of the dst drawable. Even if this is not specified but - * an implementation detail, it is the correct thing to do, so rely on it. XXX - */ static INLINE void -put_image(__DRIdrawable *dPriv, void *data, unsigned width) +put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height) { __DRIscreen *sPriv = dPriv->driScreenPriv; const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, - 0, 0, width, dPriv->h, + 0, 0, width, height, data, dPriv->loaderPrivate); } void -drisw_update_drawable_info(__DRIdrawable *dPriv) +drisw_update_drawable_info(struct dri_drawable *drawable) { + __DRIdrawable *dPriv = drawable->dPriv; + get_drawable_info(dPriv, &dPriv->w, &dPriv->h); } +static void +drisw_put_image(struct dri_drawable *drawable, + void *data, unsigned width, unsigned height) +{ + __DRIdrawable *dPriv = drawable->dPriv; + + put_image(dPriv, data, width, height); +} + static INLINE void drisw_present_texture(__DRIdrawable *dPriv, struct pipe_texture *ptex) { struct dri_drawable *drawable = dri_drawable(dPriv); struct dri_screen *screen = dri_screen(drawable->sPriv); - struct pipe_context *pipe; struct pipe_surface *psurf; - struct pipe_transfer *ptrans; - void *pmap; - unsigned width; - pipe = dri1_get_pipe_context(screen); psurf = dri1_get_pipe_surface(drawable, ptex); - if (!pipe || !psurf) + if (!psurf) return; - ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, dPriv->w, dPriv->h); - - width = ptrans->stride / util_format_get_blocksize(ptex->format); - - pmap = pipe->transfer_map(pipe, ptrans); - - assert(pmap); - - put_image(dPriv, pmap, width); - - pipe->transfer_unmap(pipe, ptrans); - - pipe->tex_transfer_destroy(pipe, ptrans); + screen->pipe_screen->flush_frontbuffer(screen->pipe_screen, psurf, drawable); } static INLINE void @@ -163,38 +130,38 @@ drisw_copy_to_front(__DRIdrawable * dPriv, */ void -drisw_flush_frontbuffer(struct dri_drawable *drawable, - enum st_attachment_type statt) +drisw_swap_buffers(__DRIdrawable *dPriv) { struct dri_context *ctx = dri_get_current(); + struct dri_drawable *drawable = dri_drawable(dPriv); struct pipe_texture *ptex; if (!ctx) return; - ptex = drawable->textures[statt]; + ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; if (ptex) { - drisw_copy_to_front(ctx->dPriv, ptex); + ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + + drisw_copy_to_front(dPriv, ptex); } } void -drisw_swap_buffers(__DRIdrawable *dPriv) +drisw_flush_frontbuffer(struct dri_drawable *drawable, + enum st_attachment_type statt) { struct dri_context *ctx = dri_get_current(); - struct dri_drawable *drawable = dri_drawable(dPriv); struct pipe_texture *ptex; if (!ctx) return; - ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; + ptex = drawable->textures[statt]; if (ptex) { - ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); - - drisw_copy_to_front(dPriv, ptex); + drisw_copy_to_front(ctx->dPriv, ptex); } } @@ -286,12 +253,16 @@ static const __DRIextension *drisw_screen_extensions[] = { NULL }; +static struct drisw_loader_funcs drisw_lf = { + .put_image = drisw_put_image +}; + const __DRIconfig ** drisw_init_screen(__DRIscreen * sPriv) { const __DRIconfig **configs; struct dri_screen *screen; - struct drm_create_screen_arg arg; + struct drisw_create_screen_arg arg; screen = CALLOC_STRUCT(dri_screen); if (!screen) @@ -304,9 +275,10 @@ drisw_init_screen(__DRIscreen * sPriv) sPriv->private = (void *)screen; sPriv->extensions = drisw_screen_extensions; - arg.mode = DRM_CREATE_DRISW; + arg.base.mode = DRM_CREATE_DRISW; + arg.lf = &drisw_lf; - configs = dri_init_screen_helper(screen, &arg, 32); + configs = dri_init_screen_helper(screen, &arg.base, 32); if (!configs) goto fail; diff --git a/src/gallium/state_trackers/dri/sw/drisw.h b/src/gallium/state_trackers/dri/sw/drisw.h index 2c0d5610fac..c0c874f7326 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.h +++ b/src/gallium/state_trackers/dri/sw/drisw.h @@ -39,7 +39,7 @@ const __DRIconfig ** drisw_init_screen(__DRIscreen * sPriv); void -drisw_update_drawable_info(__DRIdrawable *dPriv); +drisw_update_drawable_info(struct dri_drawable *drawable); void drisw_flush_frontbuffer(struct dri_drawable *drawable, diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index d0d141fd249..781f54bf2b9 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -3,8 +3,7 @@ import os.path Import('*') -if 'python' in env['statetrackers'] and 0: - # FIXME: Disable python state tracker until transfers are done by contexts +if 'python' in env['statetrackers']: env = env.Clone() diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index df700bc663c..bccaeead015 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -280,8 +280,11 @@ struct st_context { struct pipe_context *pipe = $self->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_buffer *vbuf; + struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_buffer vbuffer; float *map; unsigned size; + unsigned i; size = num_verts * num_attribs * 4 * sizeof(float); @@ -297,9 +300,31 @@ struct st_context { goto error2; memcpy(map, vertices, size); pipe_buffer_unmap(screen, vbuf); - - util_draw_vertex_buffer(pipe, vbuf, 0, prim, num_verts, num_attribs); - + + cso_save_vertex_elements($self->cso); + + /* tell pipe about the vertex attributes */ + for (i = 0; i < num_attribs; i++) { + velements[i].src_offset = i * 4 * sizeof(float); + velements[i].instance_divisor = 0; + velements[i].vertex_buffer_index = 0; + velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + } + cso_set_vertex_elements($self->cso, num_attribs, velements); + + /* tell pipe about the vertex buffer */ + memset(&vbuffer, 0, sizeof(vbuffer)); + vbuffer.buffer = vbuf; + vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */ + vbuffer.buffer_offset = 0; + vbuffer.max_index = num_verts - 1; + pipe->set_vertex_buffers(pipe, 1, &vbuffer); + + /* draw */ + pipe->draw_arrays(pipe, prim, 0, num_verts); + + cso_restore_vertex_elements($self->cso); + error2: pipe_buffer_reference(&vbuf, NULL); error1: @@ -307,6 +332,13 @@ error1: } void + clear(unsigned buffers, const float *rgba, double depth = 0.0f, + unsigned stencil = 0) + { + $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil); + } + + void flush(unsigned flags = 0) { struct pipe_fence_handle *fence = NULL; $self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence); @@ -362,10 +394,253 @@ error1: pipe_surface_reference(&_dst, NULL); } - void clear(unsigned buffers, const float *rgba, double depth = 0.0f, - unsigned stencil = 0) + %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); + void + surface_read_raw(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + char **STRING, int *LENGTH) { - $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil); + struct pipe_texture *texture = surface->texture; + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + unsigned stride; + + stride = util_format_get_stride(texture->format, w); + *LENGTH = util_format_get_nblocksy(texture->format, h) * stride; + *STRING = (char *) malloc(*LENGTH); + if(!*STRING) + return; + + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(transfer) { + pipe_get_tile_raw(pipe, transfer, 0, 0, w, h, *STRING, stride); + pipe->tex_transfer_destroy(pipe, transfer); + } + } + + %cstring_input_binary(const char *STRING, unsigned LENGTH); + void + surface_write_raw(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + const char *STRING, unsigned LENGTH, unsigned stride = 0) + { + struct pipe_texture *texture = surface->texture; + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + + if(stride == 0) + stride = util_format_get_stride(texture->format, w); + + if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride) + SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size"); + + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_WRITE, + x, y, w, h); + if(!transfer) + SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer"); + + pipe_put_tile_raw(pipe, transfer, 0, 0, w, h, STRING, stride); + pipe->tex_transfer_destroy(pipe, transfer); + + fail: + return; + } + + void + surface_read_rgba(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + float *rgba) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(transfer) { + pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba); + pipe->tex_transfer_destroy(pipe, transfer); + } + } + + void + surface_write_rgba(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + const float *rgba) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_WRITE, + x, y, w, h); + if(transfer) { + pipe_put_tile_rgba(pipe, transfer, 0, 0, w, h, rgba); + pipe->tex_transfer_destroy(pipe, transfer); + } + } + + %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); + void + surface_read_rgba8(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + char **STRING, int *LENGTH) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + float *rgba; + unsigned char *rgba8; + unsigned i, j, k; + + *LENGTH = 0; + *STRING = NULL; + + if (!surface) + return; + + *LENGTH = h*w*4; + *STRING = (char *) malloc(*LENGTH); + if(!*STRING) + return; + + rgba = malloc(h*w*4*sizeof(float)); + if(!rgba) + return; + + rgba8 = (unsigned char *) *STRING; + + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_READ, + x, y, + w, h); + if(transfer) { + pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba); + for(j = 0; j < h; ++j) { + for(i = 0; i < w; ++i) + for(k = 0; k <4; ++k) + rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]); + } + pipe->tex_transfer_destroy(pipe, transfer); + } + + free(rgba); + } + + void + surface_read_z(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + unsigned *z) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(transfer) { + pipe_get_tile_z(pipe, transfer, 0, 0, w, h, z); + pipe->tex_transfer_destroy(pipe, transfer); + } + } + + void + surface_write_z(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + const unsigned *z) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_WRITE, + x, y, w, h); + if(transfer) { + pipe_put_tile_z(pipe, transfer, 0, 0, w, h, z); + pipe->tex_transfer_destroy(pipe, transfer); + } + } + + void + surface_sample_rgba(struct st_surface *surface, + float *rgba) + { + st_sample_surface($self->pipe, surface, rgba); + } + + unsigned + surface_compare_rgba(struct st_surface *surface, + unsigned x, unsigned y, unsigned w, unsigned h, + const float *rgba, float tol = 0.0) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_transfer *transfer; + float *rgba2; + const float *p1; + const float *p2; + unsigned i, j, n; + + rgba2 = MALLOC(h*w*4*sizeof(float)); + if(!rgba2) + return ~0; + + transfer = pipe->get_tex_transfer(pipe, + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_READ, + x, y, w, h); + if(!transfer) { + FREE(rgba2); + return ~0; + } + + pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba2); + pipe->tex_transfer_destroy(pipe, transfer); + + p1 = rgba; + p2 = rgba2; + n = 0; + for(i = h*w; i; --i) { + unsigned differs = 0; + for(j = 4; j; --j) { + float delta = *p2++ - *p1++; + if (delta < -tol || delta > tol) + differs = 1; + } + n += differs; + } + + FREE(rgba2); + + return n; } }; diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index 2dd9e5050ea..923a6285289 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -124,232 +124,6 @@ struct st_surface FREE($self); } - %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); - void get_tile_raw(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH) - { - struct pipe_texture *texture = $self->texture; - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - unsigned stride; - - stride = util_format_get_stride(texture->format, w); - *LENGTH = util_format_get_nblocksy(texture->format, h) * stride; - *STRING = (char *) malloc(*LENGTH); - if(!*STRING) - return; - - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_READ, - x, y, w, h); - if(transfer) { - pipe_get_tile_raw(pipe, transfer, 0, 0, w, h, *STRING, stride); - pipe->tex_transfer_destroy(pipe, transfer); - } - } - - %cstring_input_binary(const char *STRING, unsigned LENGTH); - void put_tile_raw(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, const char *STRING, unsigned LENGTH, unsigned stride = 0) - { - struct pipe_texture *texture = $self->texture; - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - - if(stride == 0) - stride = util_format_get_stride(texture->format, w); - - if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride) - SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size"); - - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_WRITE, - x, y, w, h); - if(!transfer) - SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer"); - - pipe_put_tile_raw(pipe, transfer, 0, 0, w, h, STRING, stride); - pipe->tex_transfer_destroy(pipe, transfer); - - fail: - return; - } - - void get_tile_rgba(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) - { - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_READ, - x, y, w, h); - if(transfer) { - pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba); - pipe->tex_transfer_destroy(pipe, transfer); - } - } - - void - put_tile_rgba(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) - { - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_WRITE, - x, y, w, h); - if(transfer) { - pipe_put_tile_rgba(pipe, transfer, 0, 0, w, h, rgba); - pipe->tex_transfer_destroy(pipe, transfer); - } - } - - %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); - void - get_tile_rgba8(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH) - { - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - float *rgba; - unsigned char *rgba8; - unsigned i, j, k; - - *LENGTH = 0; - *STRING = NULL; - - if (!$self) - return; - - *LENGTH = h*w*4; - *STRING = (char *) malloc(*LENGTH); - if(!*STRING) - return; - - rgba = malloc(h*w*4*sizeof(float)); - if(!rgba) - return; - - rgba8 = (unsigned char *) *STRING; - - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_READ, - x, y, - w, h); - if(transfer) { - pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba); - for(j = 0; j < h; ++j) { - for(i = 0; i < w; ++i) - for(k = 0; k <4; ++k) - rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]); - } - pipe->tex_transfer_destroy(pipe, transfer); - } - - free(rgba); - } - - void get_tile_z(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) - { - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_READ, - x, y, w, h); - if(transfer) { - pipe_get_tile_z(pipe, transfer, 0, 0, w, h, z); - pipe->tex_transfer_destroy(pipe, transfer); - } - } - - void put_tile_z(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) - { - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_WRITE, - x, y, w, h); - if(transfer) { - pipe_put_tile_z(pipe, transfer, 0, 0, w, h, z); - pipe->tex_transfer_destroy(pipe, transfer); - } - } - -/* - void - sample_rgba(float *rgba) { - st_sample_surface($self, rgba); - } -*/ - - unsigned compare_tile_rgba(struct st_context *ctx, unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0) - { - struct pipe_context *pipe = ctx->pipe; - struct pipe_transfer *transfer; - float *rgba2; - const float *p1; - const float *p2; - unsigned i, j, n; - - rgba2 = MALLOC(h*w*4*sizeof(float)); - if(!rgba2) - return ~0; - - transfer = pipe->get_tex_transfer(pipe, - $self->texture, - $self->face, - $self->level, - $self->zslice, - PIPE_TRANSFER_READ, - x, y, w, h); - if(!transfer) { - FREE(rgba2); - return ~0; - } - - pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba2); - pipe->tex_transfer_destroy(pipe, transfer); - - p1 = rgba; - p2 = rgba2; - n = 0; - for(i = h*w; i; --i) { - unsigned differs = 0; - for(j = 4; j; --j) { - float delta = *p2++ - *p1++; - if (delta < -tol || delta > tol) - differs = 1; - } - n += differs; - } - - FREE(rgba2); - - return n; - } }; diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index f9622533fbc..e2c1e060174 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -521,12 +521,13 @@ st_sample_pixel_block(enum pipe_format format, } } -#if 0 + void -st_sample_surface(struct st_surface *surface, float *rgba) +st_sample_surface(struct pipe_context *pipe, + struct st_surface *surface, + float *rgba) { struct pipe_texture *texture = surface->texture; - struct pipe_screen *screen = texture->screen; unsigned width = u_minify(texture->width0, surface->level); unsigned height = u_minify(texture->height0, surface->level); uint rgba_stride = width * 4; @@ -534,18 +535,18 @@ st_sample_surface(struct st_surface *surface, float *rgba) void *raw; transfer = pipe->get_tex_transfer(pipe, - surface->texture, - surface->face, - surface->level, - surface->zslice, - PIPE_TRANSFER_WRITE, - 0, 0, - width, - height); + surface->texture, + surface->face, + surface->level, + surface->zslice, + PIPE_TRANSFER_WRITE, + 0, 0, + width, + height); if (!transfer) return; - raw = screen->transfer_map(screen, transfer); + raw = pipe->transfer_map(pipe, transfer); if (raw) { enum pipe_format format = texture->format; uint x, y; @@ -567,9 +568,8 @@ st_sample_surface(struct st_surface *surface, float *rgba) } } - screen->transfer_unmap(screen, transfer); + pipe->transfer_unmap(pipe, transfer); } - screen->tex_transfer_destroy(transfer); + pipe->tex_transfer_destroy(pipe, transfer); } -#endif diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h index 888114d3021..6fb8417add8 100644 --- a/src/gallium/state_trackers/python/st_sample.h +++ b/src/gallium/state_trackers/python/st_sample.h @@ -32,6 +32,9 @@ #include "pipe/p_format.h" +struct pipe_context; +struct st_surface; + void st_sample_pixel_block(enum pipe_format format, @@ -40,7 +43,9 @@ st_sample_pixel_block(enum pipe_format format, unsigned w, unsigned h); void -st_sample_surface(struct st_surface *surface, float *rgba); +st_sample_surface(struct pipe_context *pipe, + struct st_surface *surface, + float *rgba); #endif /* ST_SAMPLE_H_ */ diff --git a/src/gallium/targets/dri-swrast/swrast_drm_api.c b/src/gallium/targets/dri-swrast/swrast_drm_api.c index 1f24d7650d7..63b935bb07b 100644 --- a/src/gallium/targets/dri-swrast/swrast_drm_api.c +++ b/src/gallium/targets/dri-swrast/swrast_drm_api.c @@ -32,15 +32,7 @@ #include "state_tracker/sw_winsys.h" #include "dri_sw_winsys.h" -/* Copied from targets/libgl-xlib. - * - * TODO: - * This function should be put in targets/common or winsys/sw/common and shared - * with targets/libgl-xlib and winsys/sw/drm. - * - * For targets/common, you get layering violations unless all of drm_api's are - * moved under targets. - */ +/* Copied from targets/libgl-xlib */ #ifdef GALLIUM_SOFTPIPE #include "softpipe/sp_public.h" @@ -98,19 +90,24 @@ swrast_drm_create_screen(struct drm_api *api, { struct sw_winsys *winsys = NULL; struct pipe_screen *screen = NULL; + struct drisw_create_screen_arg *drisw; (void) drmFD; if (arg != NULL) { switch(arg->mode) { case DRM_CREATE_DRISW: + drisw = (struct drisw_create_screen_arg *)arg; break; default: return NULL; } } + else { + return NULL; + } - winsys = dri_create_sw_winsys(); + winsys = dri_create_sw_winsys(drisw->lf); if (winsys == NULL) return NULL; diff --git a/src/gallium/targets/libgl-xlib/xlib.c b/src/gallium/targets/libgl-xlib/xlib.c index 4a8366280d8..48e5bdff429 100644 --- a/src/gallium/targets/libgl-xlib/xlib.c +++ b/src/gallium/targets/libgl-xlib/xlib.c @@ -55,6 +55,14 @@ PUBLIC const struct st_module st_module_OpenGL = { * GALLIUM_CELL, etc. Scons already eliminates those #defines, so * things that are painful for it now are likely to be painful for * other build systems in the future. + * + * Copies (full or partial): + * targets/libgl-xlib + * targets/graw-xlib + * targets/dri-swrast + * winsys/sw/drm + * drivers/sw + * */ #ifdef GALLIUM_SOFTPIPE diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c index 1c1e5612d28..870c6afc124 100644 --- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c @@ -37,128 +37,153 @@ #include "dri_sw_winsys.h" -struct xm_displaytarget +struct dri_sw_displaytarget { + enum pipe_format format; + unsigned width; + unsigned height; + unsigned stride; + void *data; void *mapped; }; +struct dri_sw_winsys +{ + struct sw_winsys base; + + struct drisw_loader_funcs *lf; +}; + +static INLINE struct dri_sw_displaytarget * +dri_sw_displaytarget( struct sw_displaytarget *dt ) +{ + return (struct dri_sw_displaytarget *)dt; +} -/** Cast wrapper */ -static INLINE struct xm_displaytarget * -xm_displaytarget( struct sw_displaytarget *dt ) +static INLINE struct dri_sw_winsys * +dri_sw_winsys( struct sw_winsys *ws ) { - return (struct xm_displaytarget *)dt; + return (struct dri_sw_winsys *)ws; } -/* pipe_screen::is_format_supported */ static boolean -xm_is_displaytarget_format_supported( struct sw_winsys *ws, - unsigned tex_usage, - enum pipe_format format ) +dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format ) { /* TODO: check visuals or other sensible thing here */ return TRUE; } -/* pipe_screen::texture_create DISPLAY_TARGET / SCANOUT / SHARED */ static struct sw_displaytarget * -xm_displaytarget_create(struct sw_winsys *winsys, - unsigned tex_usage, - enum pipe_format format, - unsigned width, unsigned height, - unsigned alignment, - unsigned *stride) +dri_sw_displaytarget_create(struct sw_winsys *winsys, + unsigned tex_usage, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) { - struct xm_displaytarget *xm_dt; - unsigned nblocksy, size, xm_stride, format_stride; + struct dri_sw_displaytarget *dri_sw_dt; + unsigned nblocksy, size, format_stride; - xm_dt = CALLOC_STRUCT(xm_displaytarget); - if(!xm_dt) - goto no_xm_dt; + dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget); + if(!dri_sw_dt) + goto no_dt; + + dri_sw_dt->format = format; + dri_sw_dt->width = width; + dri_sw_dt->height = height; format_stride = util_format_get_stride(format, width); - xm_stride = align(format_stride, alignment); + dri_sw_dt->stride = align(format_stride, alignment); nblocksy = util_format_get_nblocksy(format, height); - size = xm_stride * nblocksy; + size = dri_sw_dt->stride * nblocksy; - xm_dt->data = align_malloc(size, alignment); - if(!xm_dt->data) + dri_sw_dt->data = align_malloc(size, alignment); + if(!dri_sw_dt->data) goto no_data; - *stride = xm_stride; - return (struct sw_displaytarget *)xm_dt; + *stride = dri_sw_dt->stride; + return (struct sw_displaytarget *)dri_sw_dt; no_data: - FREE(xm_dt); -no_xm_dt: + FREE(dri_sw_dt); +no_dt: return NULL; } -/* pipe_screen::texture_destroy */ static void -xm_displaytarget_destroy(struct sw_winsys *ws, - struct sw_displaytarget *dt) +dri_sw_displaytarget_destroy(struct sw_winsys *ws, + struct sw_displaytarget *dt) { - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); + struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); - if (xm_dt->data) { - FREE(xm_dt->data); + if (dri_sw_dt->data) { + FREE(dri_sw_dt->data); } - FREE(xm_dt); + FREE(dri_sw_dt); } -/* pipe_context::transfer_map */ static void * -xm_displaytarget_map(struct sw_winsys *ws, - struct sw_displaytarget *dt, - unsigned flags) +dri_sw_displaytarget_map(struct sw_winsys *ws, + struct sw_displaytarget *dt, + unsigned flags) { - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); - xm_dt->mapped = xm_dt->data; - return xm_dt->mapped; + struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); + dri_sw_dt->mapped = dri_sw_dt->data; + return dri_sw_dt->mapped; } -/* pipe_context::transfer_unmap */ static void -xm_displaytarget_unmap(struct sw_winsys *ws, - struct sw_displaytarget *dt) +dri_sw_displaytarget_unmap(struct sw_winsys *ws, + struct sw_displaytarget *dt) { - struct xm_displaytarget *xm_dt = xm_displaytarget(dt); - xm_dt->mapped = NULL; + struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); + dri_sw_dt->mapped = NULL; } -/* pipe_screen::texture_from_handle */ static struct sw_displaytarget * -xm_displaytarget_from_handle(struct sw_winsys *winsys, - const struct pipe_texture *templ, - struct winsys_handle *whandle, - unsigned *stride) +dri_sw_displaytarget_from_handle(struct sw_winsys *winsys, + const struct pipe_texture *templ, + struct winsys_handle *whandle, + unsigned *stride) { assert(0); return NULL; } -/* pipe_screen::texture_get_handle */ static boolean -xm_displaytarget_get_handle(struct sw_winsys *winsys, - struct sw_displaytarget *dt, - struct winsys_handle *whandle) +dri_sw_displaytarget_get_handle(struct sw_winsys *winsys, + struct sw_displaytarget *dt, + struct winsys_handle *whandle) { assert(0); return FALSE; } -/* pipe_screen::flush_frontbuffer */ static void -xm_displaytarget_display(struct sw_winsys *ws, - struct sw_displaytarget *dt, - void *context_private) +dri_sw_displaytarget_display(struct sw_winsys *ws, + struct sw_displaytarget *dt, + void *context_private) { - assert(0); + struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws); + struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); + struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private; + unsigned width, height; + + /* Set the width to 'stride / cpp'. + * + * PutImage correctly clips to the width of the dst drawable. + */ + width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format); + + height = dri_sw_dt->height; + + dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height); } @@ -169,31 +194,32 @@ dri_destroy_sw_winsys(struct sw_winsys *winsys) } struct sw_winsys * -dri_create_sw_winsys(void) +dri_create_sw_winsys(struct drisw_loader_funcs *lf) { - struct sw_winsys *ws; + struct dri_sw_winsys *ws; - ws = CALLOC_STRUCT(sw_winsys); + ws = CALLOC_STRUCT(dri_sw_winsys); if (!ws) return NULL; - ws->destroy = dri_destroy_sw_winsys; + ws->lf = lf; + ws->base.destroy = dri_destroy_sw_winsys; - ws->is_displaytarget_format_supported = xm_is_displaytarget_format_supported; + ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported; /* screen texture functions */ - ws->displaytarget_create = xm_displaytarget_create; - ws->displaytarget_destroy = xm_displaytarget_destroy; - ws->displaytarget_from_handle = xm_displaytarget_from_handle; - ws->displaytarget_get_handle = xm_displaytarget_get_handle; + ws->base.displaytarget_create = dri_sw_displaytarget_create; + ws->base.displaytarget_destroy = dri_sw_displaytarget_destroy; + ws->base.displaytarget_from_handle = dri_sw_displaytarget_from_handle; + ws->base.displaytarget_get_handle = dri_sw_displaytarget_get_handle; /* texture functions */ - ws->displaytarget_map = xm_displaytarget_map; - ws->displaytarget_unmap = xm_displaytarget_unmap; + ws->base.displaytarget_map = dri_sw_displaytarget_map; + ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap; - ws->displaytarget_display = xm_displaytarget_display; + ws->base.displaytarget_display = dri_sw_displaytarget_display; - return ws; + return &ws->base; } /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.h b/src/gallium/winsys/sw/dri/dri_sw_winsys.h index c2382a68d78..329ac06a05b 100644 --- a/src/gallium/winsys/sw/dri/dri_sw_winsys.h +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.h @@ -29,8 +29,10 @@ #ifndef DRI_SW_WINSYS #define DRI_SW_WINSYS +#include "state_tracker/drisw_api.h" + struct sw_winsys; -struct sw_winsys *dri_create_sw_winsys(void); +struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf); #endif |