diff options
Diffstat (limited to 'src/gallium/drivers')
72 files changed, 2044 insertions, 999 deletions
diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript index f8e9b1b4911..9347431f4e5 100644 --- a/src/gallium/drivers/failover/SConscript +++ b/src/gallium/drivers/failover/SConscript @@ -10,4 +10,6 @@ failover = env.ConvenienceLibrary( 'fo_context.c', ]) +env.Alias('failover', failover) + Export('failover') diff --git a/src/gallium/drivers/galahad/SConscript b/src/gallium/drivers/galahad/SConscript index b398a3f0615..3f39f99e517 100644 --- a/src/gallium/drivers/galahad/SConscript +++ b/src/gallium/drivers/galahad/SConscript @@ -3,11 +3,13 @@ Import('*') env = env.Clone() galahad = env.ConvenienceLibrary( - target = 'identity', + target = 'galahad', source = [ 'glhd_context.c', 'glhd_objects.c', 'glhd_screen.c', ]) +env.Alias('galahad', galahad) + Export('galahad') diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript index d4bf6fef134..8f5deed64a9 100644 --- a/src/gallium/drivers/i915/SConscript +++ b/src/gallium/drivers/i915/SConscript @@ -2,10 +2,6 @@ Import('*') env = env.Clone() -if msvc: - print 'warning: not building i915g' - Return() - i915 = env.ConvenienceLibrary( target = 'i915', source = [ @@ -34,4 +30,6 @@ i915 = env.ConvenienceLibrary( 'i915_resource_texture.c', ]) +env.Alias('i915', i915) + Export('i915') diff --git a/src/gallium/drivers/i915/i915_reg.h b/src/gallium/drivers/i915/i915_reg.h index 04620fec681..cc28891e4ac 100644 --- a/src/gallium/drivers/i915/i915_reg.h +++ b/src/gallium/drivers/i915/i915_reg.h @@ -973,6 +973,8 @@ #define PCI_CHIP_G33_G 0x29C2 #define PCI_CHIP_Q35_G 0x29B2 #define PCI_CHIP_Q33_G 0x29D2 +#define PCI_CHIP_PINEVIEW_G 0xA001 +#define PCI_CHIP_PINEVIEW_M 0xA011 #endif diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h index 1093e8f41f9..753bd266b12 100644 --- a/src/gallium/drivers/i915/i915_resource.h +++ b/src/gallium/drivers/i915/i915_resource.h @@ -32,6 +32,7 @@ struct i915_screen; #include "util/u_transfer.h" #include "util/u_debug.h" +#include "i915_winsys.h" struct i915_context; @@ -52,13 +53,12 @@ struct i915_buffer { struct i915_texture { struct u_resource b; + /* tiling flags */ + enum i915_winsys_buffer_tile tiling; unsigned stride; unsigned depth_stride; /* per-image on i945? */ unsigned total_nblocksy; - unsigned sw_tiled; /**< tiled with software flags */ - unsigned hw_tiled; /**< tiled with hardware fences */ - unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS]; /* Explicitly store the offset of each image for each cube face or diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index c5c6179b169..d45346b32ad 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -165,7 +165,7 @@ i9x5_scanout_layout(struct i915_texture *tex) if (pt->width0 >= 240) { tex->stride = get_pot_stride(pt->format, pt->width0); tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8); - tex->hw_tiled = I915_TILE_X; + tex->tiling = I915_TILE_X; } else if (pt->width0 == 64 && pt->height0 == 64) { tex->stride = get_pot_stride(pt->format, pt->width0); tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8); @@ -202,7 +202,7 @@ i9x5_display_target_layout(struct i915_texture *tex) tex->stride = get_pot_stride(pt->format, pt->width0); tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8); - tex->hw_tiled = I915_TILE_X; + tex->tiling = I915_TILE_X; #if DEBUG_TEXTURE debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, @@ -790,9 +790,8 @@ i915_texture_create(struct pipe_screen *screen, goto fail; /* setup any hw fences */ - if (tex->hw_tiled) { - assert(tex->sw_tiled == I915_TILE_NONE); - iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled); + if (tex->tiling) { + iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->tiling); } diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index a3e7c5c5772..07183253649 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -83,6 +83,12 @@ i915_get_name(struct pipe_screen *screen) case PCI_CHIP_Q33_G: chipset = "Q33"; break; + case PCI_CHIP_PINEVIEW_G: + chipset = "Pineview G"; + break; + case PCI_CHIP_PINEVIEW_M: + chipset = "Pineview M"; + break; default: chipset = "unknown"; break; @@ -178,6 +184,11 @@ i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_sha return 0; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 0; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: assert(0); return 0; @@ -220,10 +231,6 @@ i915_is_format_supported(struct pipe_screen *screen, static const enum pipe_format tex_supported[] = { PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8X8_UNORM, - PIPE_FORMAT_R8G8B8A8_UNORM, -#if 0 - PIPE_FORMAT_R8G8B8X8_UNORM, -#endif PIPE_FORMAT_B5G6R5_UNORM, PIPE_FORMAT_L8_UNORM, PIPE_FORMAT_A8_UNORM, @@ -346,6 +353,8 @@ i915_screen_create(struct i915_winsys *iws) case PCI_CHIP_G33_G: case PCI_CHIP_Q33_G: case PCI_CHIP_Q35_G: + case PCI_CHIP_PINEVIEW_G: + case PCI_CHIP_PINEVIEW_M: is->is_i945 = TRUE; break; diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index bd059d5716c..49dff1f775c 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -224,10 +224,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) struct i915_texture *tex = i915_texture(cbuf_surface->texture); assert(tex); - if (tex && tex->sw_tiled) { - ctile = BUF_3D_TILED_SURFACE; - } - OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | @@ -246,10 +242,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) struct i915_texture *tex = i915_texture(depth_surface->texture); assert(tex); - if (tex && tex->sw_tiled) { - ztile = BUF_3D_TILED_SURFACE; - } - OUT_BATCH(_3DSTATE_BUF_INFO_CMD); assert(tex); diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 4667e0b78d4..9771274ca11 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -267,11 +267,6 @@ static void update_map(struct i915_context *i915, assert(format); assert(pitch); - if (tex->sw_tiled) { - assert(!((pitch - 1) & pitch)); - tiled = MS3_TILED_SURFACE; - } - /* MS3 state */ state[0] = (((height - 1) << MS3_HEIGHT_SHIFT) diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript index 119f914a16d..019af682f68 100644 --- a/src/gallium/drivers/i965/SConscript +++ b/src/gallium/drivers/i965/SConscript @@ -2,10 +2,6 @@ Import('*') env = env.Clone() -if msvc: - print 'warning: not building i965g' - Return(); - i965 = env.ConvenienceLibrary( target = 'i965', source = [ diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index 864b21fa53c..57160ebb297 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -235,6 +235,11 @@ brw_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shad return 0; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: assert(0); return 0; diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 08da2286b05..669e42e3003 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -69,7 +69,7 @@ lp_test_sincos.o : sse_mathfun.h PROGS_DEPS := ../../auxiliary/libgallium.a lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxiliary/util/u_format_pack.py ../../auxiliary/util/u_format.csv - python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@ + $(PYTHON2) $(PYTHON_FLAGS) lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@ LDFLAGS += $(LLVM_LDFLAGS) LIBS += -L../../auxiliary/ -lgallium libllvmpipe.a $(LLVM_LIBS) $(GL_LIB_DEPS) diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index ec30d4d7084..e9374cc6efa 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -1,53 +1,6 @@ LLVMPIPE -- a fork of softpipe that employs LLVM for code generation. -Status -====== - -Done so far is: - - - the whole fragment pipeline is code generated in a single function - - - input interpolation - - - depth testing - - - texture sampling - - 1D/2D/3D/cube maps supported - - all texture wrap modes supported - - all texture filtering modes supported - - perhaps not all texture formats yet supported - - - fragment shader TGSI translation - - same level of support as the TGSI SSE2 exec machine, with the exception - we don't fallback to TGSI interpretation when an unsupported opcode is - found, but just ignore it - - done in SoA layout - - input interpolation also code generated - - - alpha testing - - - blend (including logic ops) - - both in SoA and AoS layouts, but only the former used for now - - - code is generic - - intermediates can be vectors of floats, ubytes, fixed point, etc, and of - any width and length - - not all operations are implemented for these types yet though - -Most mesa/progs/demos/* work. - -To do (probably by this order): - - - code generate stipple and stencil testing - - - translate TGSI control flow instructions, and all other remaining opcodes - - - integrate with the draw module for VS code generation - - - code generate the triangle setup and rasterization - - Requirements ============ @@ -98,7 +51,7 @@ Building To build everything on Linux invoke scons as: - scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=xlib dri=false + scons build=debug libgl-xlib Alternatively, you can build it with GNU make, if you prefer, by invoking it as @@ -108,19 +61,16 @@ but the rest of these instructions assume that scons is used. For windows is everything the except except the winsys: - scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=gdi dri=false + scons build=debug libgl-gdi Using ===== -On Linux, building will create a drop-in alternative for libGL.so. To use it -set the environment variables: - - export LD_LIBRARY_PATH=$PWD/build/linux-x86_64-debug/lib:$LD_LIBRARY_PATH +On Linux, building will create a drop-in alternative for libGL.so into -or + build/foo/gallium/targets/libgl-xlib/libGL.so - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib:$LD_LIBRARY_PATH +To use it set the LD_LIBRARY_PATH environment variable accordingly. For performance evaluation pass debug=no to scons, and use the corresponding lib directory without the "-debug" suffix. @@ -136,7 +86,7 @@ Profiling To profile llvmpipe you should pass the options - scons debug=no profile=yes <same-as-before> + scons build=profile <same-as-before> This will ensure that frame pointers are used both in C and JIT functions, and that no tail call optimizations are done by gcc. @@ -200,5 +150,4 @@ Development Notes interfaces very closely, and appear to be complete enough for code generation. See http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html - for a stand-alone example. - See the llvm-c/Core.h file for reference. + for a stand-alone example. See the llvm-c/Core.h file for reference. diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 49950153a4f..26b258b9569 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -9,8 +9,6 @@ if not env['llvm']: env = env.Clone() -env.Tool('udis86') - env.Append(CPPPATH = ['.']) env.CodeGenerate( @@ -78,6 +76,8 @@ llvmpipe = env.ConvenienceLibrary( lp_tile_soa_os, ]) +env.Alias('llvmpipe', llvmpipe) + if env['platform'] != 'embedded': env = env.Clone() @@ -92,7 +92,7 @@ if env['platform'] != 'embedded': 'sincos', ] - if not msvc: + if not env['msvc']: tests.append('round') for test in tests: diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d358a983943..decf3bd4499 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -485,8 +485,11 @@ static void lp_rast_end_query(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { - task->query->count[task->thread_index] += task->vis_counter; - task->query = NULL; + assert(task->query); + if (task->query) { + task->query->count[task->thread_index] += task->vis_counter; + task->query = NULL; + } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index 827413bb33e..29c231714e1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -569,7 +569,10 @@ try_setup_line( struct lp_setup_context *setup, return TRUE; } - u_rect_find_intersection(&setup->draw_region, &bbox); + /* Can safely discard negative regions: + */ + bbox.x0 = MAX2(bbox.x0, 0); + bbox.y0 = MAX2(bbox.y0, 0); line = lp_setup_alloc_triangle(scene, key->num_inputs, @@ -680,24 +683,26 @@ try_setup_line( struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 8) { + const struct u_rect *scissor = &setup->scissor; + plane[4].dcdx = -1; plane[4].dcdy = 0; - plane[4].c = 1-bbox.x0; + plane[4].c = 1-scissor->x0; plane[4].eo = 1; plane[5].dcdx = 1; plane[5].dcdy = 0; - plane[5].c = bbox.x1+1; + plane[5].c = scissor->x1+1; plane[5].eo = 0; plane[6].dcdx = 0; plane[6].dcdy = 1; - plane[6].c = 1-bbox.y0; + plane[6].c = 1-scissor->y0; plane[6].eo = 1; plane[7].dcdx = 0; plane[7].dcdy = -1; - plane[7].c = bbox.y1+1; + plane[7].c = scissor->y1+1; plane[7].eo = 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 4ab0b72a574..bfb6bf277bd 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -295,7 +295,12 @@ do_triangle_ccw(struct lp_setup_context *setup, return TRUE; } - u_rect_find_intersection(&setup->draw_region, &bbox); + /* Can safely discard negative regions, but need to keep hold of + * information about when the triangle extends past screen + * boundaries. See trimmed_box in lp_setup_bin_triangle(). + */ + bbox.x0 = MAX2(bbox.x0, 0); + bbox.y0 = MAX2(bbox.y0, 0); tri = lp_setup_alloc_triangle(scene, key->num_inputs, @@ -501,24 +506,26 @@ do_triangle_ccw(struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 7) { + const struct u_rect *scissor = &setup->scissor; + plane[3].dcdx = -1; plane[3].dcdy = 0; - plane[3].c = 1-bbox.x0; + plane[3].c = 1-scissor->x0; plane[3].eo = 1; plane[4].dcdx = 1; plane[4].dcdy = 0; - plane[4].c = bbox.x1+1; + plane[4].c = scissor->x1+1; plane[4].eo = 0; plane[5].dcdx = 0; plane[5].dcdy = 1; - plane[5].c = 1-bbox.y0; + plane[5].c = 1-scissor->y0; plane[5].eo = 1; plane[6].dcdx = 0; plane[6].dcdy = -1; - plane[6].c = bbox.y1+1; + plane[6].c = scissor->y1+1; plane[6].eo = 0; } @@ -559,6 +566,7 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int nr_planes ) { struct lp_scene *scene = setup->scene; + struct u_rect trimmed_box = *bbox; int i; /* What is the largest power-of-two boundary this triangle crosses: @@ -572,6 +580,13 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int sz = floor_pot((bbox->x1 - (bbox->x0 & ~3)) | (bbox->y1 - (bbox->y0 & ~3))); + /* Now apply scissor, etc to the bounding box. Could do this + * earlier, but it confuses the logic for tri-16 and would force + * the rasterizer to also respect scissor, etc, just for the rare + * cases where a small triangle extends beyond the scissor. + */ + u_rect_find_intersection(&setup->draw_region, &trimmed_box); + /* Determine which tile(s) intersect the triangle's bounding box */ if (dx < TILE_SIZE) @@ -626,15 +641,16 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, struct lp_rast_plane *plane = GET_PLANES(tri); int c[MAX_PLANES]; int ei[MAX_PLANES]; + int eo[MAX_PLANES]; int xstep[MAX_PLANES]; int ystep[MAX_PLANES]; int x, y; - int ix0 = bbox->x0 / TILE_SIZE; - int iy0 = bbox->y0 / TILE_SIZE; - int ix1 = bbox->x1 / TILE_SIZE; - int iy1 = bbox->y1 / TILE_SIZE; + int ix0 = trimmed_box.x0 / TILE_SIZE; + int iy0 = trimmed_box.y0 / TILE_SIZE; + int ix1 = trimmed_box.x1 / TILE_SIZE; + int iy1 = trimmed_box.y1 / TILE_SIZE; for (i = 0; i < nr_planes; i++) { c[i] = (plane[i].c + @@ -799,6 +815,16 @@ static void triangle_both( struct lp_setup_context *setup, { float area = calc_area(v0, v1, v2); + if (0) { + assert(!util_is_inf_or_nan(v0[0][0])); + assert(!util_is_inf_or_nan(v0[0][1])); + assert(!util_is_inf_or_nan(v1[0][0])); + assert(!util_is_inf_or_nan(v1[0][1])); + assert(!util_is_inf_or_nan(v2[0][0])); + assert(!util_is_inf_or_nan(v2[0][1])); + assert(!util_is_inf_or_nan(area)); + } + if (area > 0.0f) retry_triangle_ccw( setup, v0, v1, v2, setup->ccw_is_frontface ); else if (area < 0.0f) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 9fbedac165f..48971510f21 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -761,11 +761,6 @@ generate_fragment(struct llvmpipe_screen *screen, } } -#ifdef PIPE_ARCH_X86 - /* Avoid corrupting the FPU stack on 32bit OSes. */ - lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); -#endif - LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -1067,11 +1062,11 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs) draw_flush(llvmpipe->draw); + llvmpipe->fs = (struct lp_fragment_shader *) fs; + draw_bind_fragment_shader(llvmpipe->draw, (llvmpipe->fs ? llvmpipe->fs->draw_data : NULL)); - llvmpipe->fs = fs; - llvmpipe->dirty |= LP_NEW_FS; } diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py index e49f9c62fe7..8df7b236fe0 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -''' +CopyRight = ''' /************************************************************************** * * Copyright 2009 VMware, Inc. @@ -510,7 +510,7 @@ def main(): print '/* This file is autogenerated by lp_tile_soa.py from u_format.csv. Do not edit directly. */' print # This will print the copyright message on the top of this file - print __doc__.strip() + print CopyRight.strip() print print '#include "pipe/p_compiler.h"' print '#include "util/u_format.h"' diff --git a/src/gallium/drivers/sw/Makefile b/src/gallium/drivers/noop/Makefile index 2713a62ee9f..29b8d73de22 100644 --- a/src/gallium/drivers/sw/Makefile +++ b/src/gallium/drivers/noop/Makefile @@ -4,7 +4,10 @@ TOP = ../../../.. include $(TOP)/configs/current +LIBNAME = noop + C_SOURCES = \ - sw.c + noop_pipe.c \ + noop_state.c include ../../Makefile.template diff --git a/src/gallium/drivers/noop/SConscript b/src/gallium/drivers/noop/SConscript new file mode 100644 index 00000000000..a4d0dcaf270 --- /dev/null +++ b/src/gallium/drivers/noop/SConscript @@ -0,0 +1,15 @@ +####################################################################### +# SConscript for noop convenience library + +Import('*') + +env = env.Clone() + +noop = env.ConvenienceLibrary( + target = 'noop', + source = [ + 'noop_pipe.c', + 'noop_state.c' + ] + ) + extra +Export('noop') diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c new file mode 100644 index 00000000000..fb5cdb46093 --- /dev/null +++ b/src/gallium/drivers/noop/noop_pipe.c @@ -0,0 +1,550 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 <errno.h> +#include <pipe/p_defines.h> +#include <pipe/p_state.h> +#include <pipe/p_context.h> +#include <pipe/p_screen.h> +#include <util/u_memory.h> +#include <util/u_inlines.h> +#include <util/u_format.h> +#include "noop_public.h" +#include "state_tracker/sw_winsys.h" + +void noop_init_state_functions(struct pipe_context *ctx); + +/* + * query + */ +struct noop_query { + unsigned query; +}; +static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type) +{ + struct noop_query *query = CALLOC_STRUCT(noop_query); + + return (struct pipe_query *)query; +} + +static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query) +{ + FREE(query); +} + +static void noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) +{ +} + +static void noop_end_query(struct pipe_context *ctx, struct pipe_query *query) +{ +} + +static boolean noop_get_query_result(struct pipe_context *ctx, + struct pipe_query *query, + boolean wait, void *vresult) +{ + uint64_t *result = (uint64_t*)vresult; + + *result = 0; + return TRUE; +} + + +/* + * resource + */ +struct noop_resource { + struct pipe_resource base; + unsigned size; + char *data; + struct sw_displaytarget *dt; +}; + +static unsigned noop_is_resource_referenced(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned face, unsigned level) +{ + return PIPE_UNREFERENCED; +} + +static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, + const struct pipe_resource *templ) +{ + struct noop_resource *nresource; + unsigned stride; + + nresource = CALLOC_STRUCT(noop_resource); + if (nresource == NULL) + return NULL; + + stride = util_format_get_stride(templ->format, templ->width0); + nresource->base = *templ; + nresource->base.screen = screen; + nresource->size = stride * templ->height0 * templ->depth0; + nresource->data = malloc(nresource->size); + pipe_reference_init(&nresource->base.reference, 1); + if (nresource->data == NULL) { + FREE(nresource); + return NULL; + } +#if 0 + if (nresource->base.bind & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { + struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys; + unsigned stride; + + nresource->dt = winsys->displaytarget_create(winsys, nresource->base.bind, + nresource->base.format, + nresource->base.width0, + nresource->base.height0, + 16, &stride); + } +#endif + return &nresource->base; +} + +static struct pipe_resource *noop_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *templ, + struct winsys_handle *whandle) +{ + struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys; + struct noop_resource *nresource; + struct sw_displaytarget *dt; + unsigned stride; + + dt = winsys->displaytarget_from_handle(winsys, templ, whandle, &stride); + if (dt == NULL) { + return NULL; + } + nresource = (struct noop_resource *)noop_resource_create(screen, templ); + nresource->dt = dt; + return &nresource->base; +} + +static boolean noop_resource_get_handle(struct pipe_screen *screen, + struct pipe_resource *resource, + struct winsys_handle *handle) +{ + struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys; + struct noop_resource *nresource = (struct noop_resource *)resource; + + if (nresource->dt == NULL) + return FALSE; + + return winsys->displaytarget_get_handle(winsys, nresource->dt, handle); +} + +static void noop_resource_destroy(struct pipe_screen *screen, + struct pipe_resource *resource) +{ + struct noop_resource *nresource = (struct noop_resource *)resource; + + if (nresource->dt) { + /* display target */ + struct sw_winsys *winsys = (struct sw_winsys *)screen->winsys; + winsys->displaytarget_destroy(winsys, nresource->dt); + } + free(nresource->data); + FREE(resource); +} + +static struct pipe_resource *noop_user_buffer_create(struct pipe_screen *screen, + void *ptr, unsigned bytes, + unsigned bind) +{ + struct pipe_resource templ; + + templ.target = PIPE_BUFFER; + templ.format = PIPE_FORMAT_R8_UNORM; + templ.usage = PIPE_USAGE_IMMUTABLE; + templ.bind = bind; + templ.width0 = bytes; + templ.height0 = 1; + templ.depth0 = 1; + templ.flags = 0; + return noop_resource_create(screen, &templ); +} + + +/* + * transfer + */ +static struct pipe_transfer *noop_get_transfer(struct pipe_context *context, + struct pipe_resource *resource, + struct pipe_subresource sr, + enum pipe_transfer_usage usage, + const struct pipe_box *box) +{ + struct pipe_transfer *transfer; + + transfer = CALLOC_STRUCT(pipe_transfer); + if (transfer == NULL) + return NULL; + pipe_resource_reference(&transfer->resource, resource); + transfer->sr = sr; + transfer->usage = usage; + transfer->box = *box; + transfer->stride = 1; + transfer->slice_stride = 1; + return transfer; +} + +static void *noop_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct noop_resource *nresource = (struct noop_resource *)transfer->resource; + + return nresource->data; +} + +static void noop_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ +} + +static void noop_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ +} + +static void noop_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + pipe_resource_reference(&transfer->resource, NULL); + FREE(transfer); +} + +static void noop_transfer_inline_write(struct pipe_context *pipe, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) +{ +} + + +/* + * clear/copy + */ +static void noop_clear(struct pipe_context *ctx, unsigned buffers, + const float *rgba, double depth, unsigned stencil) +{ +} + +static void noop_clear_render_target(struct pipe_context *ctx, + struct pipe_surface *dst, + const float *rgba, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ +} + +static void noop_clear_depth_stencil(struct pipe_context *ctx, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ +} + +static void noop_resource_copy_region(struct pipe_context *ctx, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, + unsigned width, unsigned height) +{ +} + + +/* + * context + */ +static void noop_flush(struct pipe_context *ctx, unsigned flags, + struct pipe_fence_handle **fence) +{ +} + +static void noop_destroy_context(struct pipe_context *ctx) +{ + FREE(ctx); +} + +static struct pipe_context *noop_create_context(struct pipe_screen *screen, void *priv) +{ + struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); + + if (ctx == NULL) + return NULL; + ctx->winsys = screen->winsys; + ctx->screen = screen; + ctx->priv = priv; + ctx->destroy = noop_destroy_context; + ctx->flush = noop_flush; + ctx->clear = noop_clear; + ctx->clear_render_target = noop_clear_render_target; + ctx->clear_depth_stencil = noop_clear_depth_stencil; + ctx->resource_copy_region = noop_resource_copy_region; + ctx->create_query = noop_create_query; + ctx->destroy_query = noop_destroy_query; + ctx->begin_query = noop_begin_query; + ctx->end_query = noop_end_query; + ctx->get_query_result = noop_get_query_result; + ctx->get_transfer = noop_get_transfer; + ctx->transfer_map = noop_transfer_map; + ctx->transfer_flush_region = noop_transfer_flush_region; + ctx->transfer_unmap = noop_transfer_unmap; + ctx->transfer_destroy = noop_transfer_destroy; + ctx->transfer_inline_write = noop_transfer_inline_write; + ctx->is_resource_referenced = noop_is_resource_referenced; + noop_init_state_functions(ctx); + + return ctx; +} + +/* + * texture + */ +static struct pipe_surface *noop_get_tex_surface(struct pipe_screen *screen, + struct pipe_resource *texture, + unsigned face, unsigned level, + unsigned zslice, unsigned flags) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + if (surface == NULL) + return NULL; + pipe_reference_init(&surface->reference, 1); + pipe_resource_reference(&surface->texture, texture); + surface->format = texture->format; + surface->width = texture->width0; + surface->height = texture->height0; + surface->offset = 0; + surface->usage = flags; + surface->zslice = zslice; + surface->texture = texture; + surface->face = face; + surface->level = level; + + return surface; +} + +static void noop_tex_surface_destroy(struct pipe_surface *surface) +{ + pipe_resource_reference(&surface->texture, NULL); + FREE(surface); +} + + +/* + * pipe_screen + */ +static void noop_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *surface, + void *context_private) +{ +} + +static const char *noop_get_vendor(struct pipe_screen* pscreen) +{ + return "X.Org"; +} + +static const char *noop_get_name(struct pipe_screen* pscreen) +{ + return "NOOP"; +} + +static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) +{ + switch (param) { + /* Supported features (boolean caps). */ + case PIPE_CAP_NPOT_TEXTURES: + case PIPE_CAP_TWO_SIDED_STENCIL: + case PIPE_CAP_GLSL: + case PIPE_CAP_OCCLUSION_QUERY: + case PIPE_CAP_POINT_SPRITE: + case PIPE_CAP_ANISOTROPIC_FILTER: + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + case PIPE_CAP_TEXTURE_SHADOW_MAP: + case PIPE_CAP_TEXTURE_SWIZZLE: + case PIPE_CAP_BLEND_EQUATION_SEPARATE: + + return 1; + case PIPE_CAP_DUAL_SOURCE_BLEND: + + case PIPE_CAP_SM3: + case PIPE_CAP_INDEP_BLEND_ENABLE: + case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: + case PIPE_CAP_DEPTH_CLAMP: + case PIPE_CAP_SHADER_STENCIL_EXPORT: + case PIPE_CAP_TIMER_QUERY: + case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_PRIMITIVE_RESTART: + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + + /* Texturing. */ + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 14; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + return 16; + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 16; + + /* Render targets. */ + case PIPE_CAP_MAX_RENDER_TARGETS: + return 8; + + /* Fragment coordinate conventions. */ + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; + + default: + return 0; + } +} + +static float noop_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + case PIPE_CAP_MAX_LINE_WIDTH_AA: + case PIPE_CAP_MAX_POINT_WIDTH: + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 8192.0f; + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 16.0f; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0f; + default: + return 0.0f; + } +} + +static int noop_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param) +{ + switch(shader) + { + case PIPE_SHADER_FRAGMENT: + case PIPE_SHADER_VERTEX: + case PIPE_SHADER_GEOMETRY: + break; + default: + return 0; + } + + switch (param) { + case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: + case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: + return 16384; + case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: + return 8; + case PIPE_SHADER_CAP_MAX_INPUTS: + return 16; + case PIPE_SHADER_CAP_MAX_TEMPS: + return 256; + case PIPE_SHADER_CAP_MAX_ADDRS: + return 1; + case PIPE_SHADER_CAP_MAX_CONSTS: + return 256; + case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: + return 1; + case PIPE_SHADER_CAP_MAX_PREDS: + return 0; + case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: + return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; + default: + return 0; + } +} + +static boolean noop_is_format_supported(struct pipe_screen* screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned usage, + unsigned geom_flags) +{ + return true; +} + +static void noop_destroy_screen(struct pipe_screen *screen) +{ + FREE(screen); +} + +struct pipe_screen *noop_screen_create(struct sw_winsys *winsys) +{ + struct pipe_screen *screen; + + screen = CALLOC_STRUCT(pipe_screen); + if (screen == NULL) { + return NULL; + } + + screen->winsys = (struct pipe_winsys*)winsys; + screen->destroy = noop_destroy_screen; + screen->get_name = noop_get_name; + screen->get_vendor = noop_get_vendor; + screen->get_param = noop_get_param; + screen->get_shader_param = noop_get_shader_param; + screen->get_paramf = noop_get_paramf; + screen->is_format_supported = noop_is_format_supported; + screen->context_create = noop_create_context; + screen->get_tex_surface = noop_get_tex_surface; + screen->tex_surface_destroy = noop_tex_surface_destroy; + screen->resource_create = noop_resource_create; + screen->resource_from_handle = noop_resource_from_handle; + screen->resource_get_handle = noop_resource_get_handle; + screen->resource_destroy = noop_resource_destroy; + screen->user_buffer_create = noop_user_buffer_create; + screen->flush_frontbuffer = noop_flush_frontbuffer; + + return screen; +} diff --git a/src/gallium/drivers/noop/noop_public.h b/src/gallium/drivers/noop/noop_public.h new file mode 100644 index 00000000000..8ce82bec698 --- /dev/null +++ b/src/gallium/drivers/noop/noop_public.h @@ -0,0 +1,30 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 NOOP_PUBLIC_H +#define NOOP_PUBLIC_H + +struct sw_winsys; + +struct pipe_screen *noop_screen_create(struct sw_winsys *winsys); + +#endif diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c new file mode 100644 index 00000000000..048ed42a9b6 --- /dev/null +++ b/src/gallium/drivers/noop/noop_state.c @@ -0,0 +1,256 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 <errno.h> +#include <pipe/p_defines.h> +#include <pipe/p_state.h> +#include <pipe/p_context.h> +#include <pipe/p_screen.h> +#include <util/u_memory.h> +#include <util/u_inlines.h> + +static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) +{ +} + +static void noop_set_blend_color(struct pipe_context *ctx, + const struct pipe_blend_color *state) +{ +} + +static void *noop_create_blend_state(struct pipe_context *ctx, + const struct pipe_blend_state *state) +{ + struct pipe_blend_state *nstate = CALLOC_STRUCT(pipe_blend_state); + + if (nstate == NULL) { + return NULL; + } + *nstate = *state; + return nstate; +} + +static void *noop_create_dsa_state(struct pipe_context *ctx, + const struct pipe_depth_stencil_alpha_state *state) +{ + struct pipe_depth_stencil_alpha_state *nstate = CALLOC_STRUCT(pipe_depth_stencil_alpha_state); + + if (nstate == NULL) { + return NULL; + } + *nstate = *state; + return nstate; +} + +static void *noop_create_rs_state(struct pipe_context *ctx, + const struct pipe_rasterizer_state *state) +{ + struct pipe_rasterizer_state *nstate = CALLOC_STRUCT(pipe_rasterizer_state); + + if (nstate == NULL) { + return NULL; + } + *nstate = *state; + return nstate; +} + +static void *noop_create_sampler_state(struct pipe_context *ctx, + const struct pipe_sampler_state *state) +{ + struct pipe_sampler_state *nstate = CALLOC_STRUCT(pipe_sampler_state); + + if (nstate == NULL) { + return NULL; + } + *nstate = *state; + return nstate; +} + +static struct pipe_sampler_view *noop_create_sampler_view(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *state) +{ + struct pipe_sampler_view *sampler_view = CALLOC_STRUCT(pipe_sampler_view); + + if (sampler_view == NULL) + return NULL; + /* initialize base object */ + pipe_resource_reference(&sampler_view->texture, texture); + pipe_reference_init(&sampler_view->reference, 1); + sampler_view->context = ctx; + return sampler_view; +} + +static void noop_set_vs_sampler_view(struct pipe_context *ctx, unsigned count, + struct pipe_sampler_view **views) +{ +} + +static void noop_set_ps_sampler_view(struct pipe_context *ctx, unsigned count, + struct pipe_sampler_view **views) +{ +} + +static void noop_bind_sampler(struct pipe_context *ctx, unsigned count, void **states) +{ +} + +static void noop_set_clip_state(struct pipe_context *ctx, + const struct pipe_clip_state *state) +{ +} + +static void noop_set_polygon_stipple(struct pipe_context *ctx, + const struct pipe_poly_stipple *state) +{ +} + +static void noop_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +{ +} + +static void noop_set_scissor_state(struct pipe_context *ctx, + const struct pipe_scissor_state *state) +{ +} + +static void noop_set_stencil_ref(struct pipe_context *ctx, + const struct pipe_stencil_ref *state) +{ +} + +static void noop_set_viewport_state(struct pipe_context *ctx, + const struct pipe_viewport_state *state) +{ +} + +static void noop_set_framebuffer_state(struct pipe_context *ctx, + const struct pipe_framebuffer_state *state) +{ +} + +static void noop_set_constant_buffer(struct pipe_context *ctx, + uint shader, uint index, + struct pipe_resource *buffer) +{ +} + + +static void noop_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *state) +{ + pipe_resource_reference(&state->texture, NULL); + FREE(state); +} + +static void noop_bind_state(struct pipe_context *ctx, void *state) +{ +} + +static void noop_delete_state(struct pipe_context *ctx, void *state) +{ + FREE(state); +} + +static void noop_delete_vertex_element(struct pipe_context *ctx, void *state) +{ + FREE(state); +} + + +static void noop_set_index_buffer(struct pipe_context *ctx, + const struct pipe_index_buffer *ib) +{ +} + +static void noop_set_vertex_buffers(struct pipe_context *ctx, unsigned count, + const struct pipe_vertex_buffer *buffers) +{ +} + +static void *noop_create_vertex_elements(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *state) +{ + struct pipe_vertex_element *nstate = CALLOC_STRUCT(pipe_vertex_element); + + if (nstate == NULL) { + return NULL; + } + *nstate = *state; + return nstate; +} + +static void *noop_create_shader_state(struct pipe_context *ctx, + const struct pipe_shader_state *state) +{ + struct pipe_shader_state *nstate = CALLOC_STRUCT(pipe_shader_state); + + if (nstate == NULL) { + return NULL; + } + *nstate = *state; + return nstate; +} + +void noop_init_state_functions(struct pipe_context *ctx) +{ + ctx->create_blend_state = noop_create_blend_state; + ctx->create_depth_stencil_alpha_state = noop_create_dsa_state; + ctx->create_fs_state = noop_create_shader_state; + ctx->create_rasterizer_state = noop_create_rs_state; + ctx->create_sampler_state = noop_create_sampler_state; + ctx->create_sampler_view = noop_create_sampler_view; + ctx->create_vertex_elements_state = noop_create_vertex_elements; + ctx->create_vs_state = noop_create_shader_state; + ctx->bind_blend_state = noop_bind_state; + ctx->bind_depth_stencil_alpha_state = noop_bind_state; + ctx->bind_fragment_sampler_states = noop_bind_sampler; + ctx->bind_fs_state = noop_bind_state; + ctx->bind_rasterizer_state = noop_bind_state; + ctx->bind_vertex_elements_state = noop_bind_state; + ctx->bind_vertex_sampler_states = noop_bind_sampler; + ctx->bind_vs_state = noop_bind_state; + ctx->delete_blend_state = noop_delete_state; + ctx->delete_depth_stencil_alpha_state = noop_delete_state; + ctx->delete_fs_state = noop_delete_state; + ctx->delete_rasterizer_state = noop_delete_state; + ctx->delete_sampler_state = noop_delete_state; + ctx->delete_vertex_elements_state = noop_delete_vertex_element; + ctx->delete_vs_state = noop_delete_state; + ctx->set_blend_color = noop_set_blend_color; + ctx->set_clip_state = noop_set_clip_state; + ctx->set_constant_buffer = noop_set_constant_buffer; + ctx->set_fragment_sampler_views = noop_set_ps_sampler_view; + ctx->set_framebuffer_state = noop_set_framebuffer_state; + ctx->set_polygon_stipple = noop_set_polygon_stipple; + ctx->set_sample_mask = noop_set_sample_mask; + ctx->set_scissor_state = noop_set_scissor_state; + ctx->set_stencil_ref = noop_set_stencil_ref; + ctx->set_vertex_buffers = noop_set_vertex_buffers; + ctx->set_index_buffer = noop_set_index_buffer; + ctx->set_vertex_sampler_views = noop_set_vs_sampler_view; + ctx->set_viewport_state = noop_set_viewport_state; + ctx->sampler_view_destroy = noop_sampler_view_destroy; + ctx->draw_vbo = noop_draw_vbo; +} diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index c6bd62df1db..51eab3a0b03 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -171,6 +171,11 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, return NV50_CAP_MAX_PROGRAM_TEMPS; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: return 0; } diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 6c41e8f4561..306aa81d985 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -39,6 +39,9 @@ nv50_transfer_constbuf(struct nv50_context *nv50, uint32_t *map; unsigned count, start; + if (buf == NULL) + return; + map = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &transfer); if (!map) return; diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 8024800bd09..d7553e9f399 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -37,7 +37,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_POINT_SPRITE: return 1; case PIPE_CAP_MAX_RENDER_TARGETS: - return screen->use_nv4x ? 4 : 2; + return screen->use_nv4x ? 4 : 1; case PIPE_CAP_OCCLUSION_QUERY: return 1; case PIPE_CAP_TIMER_QUERY: @@ -77,6 +77,10 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLAMP: return 0; // TODO: implement depth clamp + case PIPE_CAP_PRIMITIVE_RESTART: + return 0; // TODO: implement primitive restart + case PIPE_CAP_SHADER_STENCIL_EXPORT: + return 0; default: NOUVEAU_ERR("Warning: unknown PIPE_CAP %d\n", param); return 0; @@ -114,6 +118,11 @@ nvfx_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum return 0; /* we could expose these, but nothing uses them */ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 0; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 0; default: break; } @@ -146,6 +155,12 @@ nvfx_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum return 0; /* we could expose these, but nothing uses them */ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + return 0; + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: break; } diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index bf023daaa56..b49db937994 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -39,5 +39,7 @@ r300 = env.ConvenienceLibrary( 'r300_transfer.c', ] + r300compiler) + r300compiler +env.Alias('r300', r300) + Export('r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 91a374a5838..0ac4e4c6f12 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -176,12 +176,12 @@ static void r300_clear(struct pipe_context* pipe, fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL; uint32_t width = fb->width; uint32_t height = fb->height; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; /* Enable fast Z clear. * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ - if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && has_hyperz) { + if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) { hyperz_dcv = hyperz->zb_depthclearvalue = r300_depth_clear_value(fb->zsbuf->format, depth, stencil); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 624dadd07d7..e8c09b214af 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -79,6 +79,9 @@ static void r300_release_referenced_objects(struct r300_context *r300) NULL); } + /* The dummy VBO. */ + pipe_resource_reference(&r300->dummy_vb, NULL); + /* The SWTCL VBO. */ pipe_resource_reference(&r300->vbo, NULL); @@ -184,7 +187,7 @@ static void r300_setup_atoms(struct r300_context* r300) boolean has_tcl = r300->screen->caps.has_tcl; boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0); - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0; /* Create the actual atom list. @@ -240,7 +243,7 @@ static void r300_setup_atoms(struct r300_context* r300) /* TX. */ R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); - if (has_hyperz) { + if (can_hyperz) { /* HiZ Clear */ if (has_hiz_ram) R300_INIT_ATOM(hiz_clear, 0); @@ -488,6 +491,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, rtempl.target = PIPE_TEXTURE_2D; rtempl.format = PIPE_FORMAT_I8_UNORM; rtempl.bind = PIPE_BIND_SAMPLER_VIEW; + rtempl.usage = PIPE_USAGE_IMMUTABLE; rtempl.width0 = 1; rtempl.height0 = 1; rtempl.depth0 = 1; @@ -501,6 +505,19 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, pipe_resource_reference(&tex, NULL); } + { + struct pipe_resource vb = {}; + vb.target = PIPE_BUFFER; + vb.format = PIPE_FORMAT_R8_UNORM; + vb.bind = PIPE_BIND_VERTEX_BUFFER; + vb.usage = PIPE_USAGE_IMMUTABLE; + vb.width0 = sizeof(float) * 16; + vb.height0 = 1; + vb.depth0 = 1; + + r300->dummy_vb = screen->resource_create(screen, &vb); + } + return &r300->context; fail: diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index b59bc002610..7217c51b951 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -480,6 +480,10 @@ struct r300_context { * dummy texture there. */ struct r300_sampler_view *texkill_sampler; + /* When no vertex buffer is set, this one is used instead to prevent + * hardlocks. */ + struct pipe_resource *dummy_vb; + /* The currently active query. */ struct r300_query *query_current; /* The saved query for blitter operations. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3a1085d2dc5..c187f115da4 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -358,7 +358,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_surface* surf; unsigned i; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); CS_LOCALS(r300); BEGIN_CS(size); @@ -411,7 +411,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); - if (has_hyperz) { + if (can_hyperz) { uint32_t surf_pitch; struct r300_texture *tex; int level = surf->base.level; diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index eb5b0c36f8f..79f7f8abe9b 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -44,10 +44,10 @@ static bool r300_get_sc_hz_max(struct r300_context *r300) { struct r300_dsa_state *dsa_state = r300->dsa_state.state; - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; int ret = R300_SC_HYPERZ_MIN; - if (func >= 4 && func <= 7) + if (func >= R300_ZS_GEQUAL && func <= R300_ZS_ALWAYS) ret = R300_SC_HYPERZ_MAX; return ret; } @@ -55,23 +55,26 @@ static bool r300_get_sc_hz_max(struct r300_context *r300) static bool r300_zfunc_same_direction(int func1, int func2) { /* func1 is less/lessthan */ - if (func1 == 1 || func1 == 2) - if (func2 == 3 || func2 == 4 || func2 == 5) + if ((func1 == R300_ZS_LESS || func1 == R300_ZS_LEQUAL) && + (func2 == R300_ZS_EQUAL || func2 == R300_ZS_GEQUAL || + func2 == R300_ZS_GREATER)) return FALSE; - if (func2 == 1 || func2 == 2) - if (func1 == 4 || func1 == 5) + /* func1 is greater/greaterthan */ + if ((func1 == R300_ZS_GEQUAL || func1 == R300_ZS_GREATER) && + (func2 == R300_ZS_LESS || func2 == R300_ZS_LEQUAL)) return FALSE; + return TRUE; } - + static int r300_get_hiz_min(struct r300_context *r300) { struct r300_dsa_state *dsa_state = r300->dsa_state.state; - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; int ret = R300_HIZ_MIN; - if (func == 1 || func == 2) + if (func == R300_ZS_LESS || func == R300_ZS_LEQUAL) ret = R300_HIZ_MAX; return ret; } @@ -112,13 +115,16 @@ static boolean r300_can_hiz(struct r300_context *r300) } /* depth comparison function - if just cleared save and return okay */ if (z->current_func == -1) { - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; if (func != 0 && func != 7) - z->current_func = dsa_state->z_stencil_control & 0x7; + z->current_func = dsa_state->z_stencil_control & R300_ZS_MASK; } else { /* simple don't change */ - if (!r300_zfunc_same_direction(z->current_func, (dsa_state->z_stencil_control & 0x7))) { - DBG(r300, DBG_HYPERZ, "z func changed direction - disabling hyper-z %d -> %d\n", z->current_func, dsa_state->z_stencil_control); + if (!r300_zfunc_same_direction(z->current_func, + (dsa_state->z_stencil_control & R300_ZS_MASK))) { + DBG(r300, DBG_HYPERZ, + "z func changed direction - disabling hyper-z %d -> %d\n", + z->current_func, dsa_state->z_stencil_control); return FALSE; } } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 2f00c878f5b..60700cf3037 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -535,29 +535,8 @@ static void r300_draw_range_elements(struct pipe_context* pipe, r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); unsigned short_count; int buffer_offset = 0, index_offset = 0; /* for index bias emulation */ - boolean translate = FALSE; unsigned new_offset; - if (r300->skip_rendering) { - return; - } - - if (!u_trim_pipe_prim(mode, &count)) { - return; - } - - /* Index buffer range checking. */ - if ((start + count) * indexSize > indexBuffer->width0) { - fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n"); - return; - } - - /* Set up fallback for incompatible vertex layout if needed. */ - if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { - r300_begin_vertex_translate(r300); - translate = TRUE; - } - if (indexBias && !r500_index_bias_supported(r300)) { r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset); } @@ -603,10 +582,6 @@ done: if (indexBuffer != orgIndexBuffer) { pipe_resource_reference( &indexBuffer, NULL ); } - - if (translate) { - r300_end_vertex_translate(r300); - } } static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, @@ -617,21 +592,6 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, count > 65536 && r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); unsigned short_count; - boolean translate = FALSE; - - if (r300->skip_rendering) { - return; - } - - if (!u_trim_pipe_prim(mode, &count)) { - return; - } - - /* Set up fallback for incompatible vertex layout if needed. */ - if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { - r300_begin_vertex_translate(r300); - translate = TRUE; - } r300_update_derived_state(r300); @@ -642,7 +602,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, start, 0)) - goto done; + return; if (alt_num_verts || count <= 65535) { r300_emit_draw_arrays(r300, mode, count); @@ -659,32 +619,53 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, if (!r300_prepare_for_rendering(r300, PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, start, 0)) - goto done; + return; } } while (count); } } - -done: - if (translate) { - r300_end_vertex_translate(r300); - } } static void r300_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); + unsigned count = info->count; + boolean translate = FALSE; + boolean indexed = info->indexed && r300->index_buffer.buffer; + unsigned start_indexed = 0; - if (!r300->velems->count || !r300->vertex_buffer_count) - return; + if (r300->skip_rendering) { + return; + } - if (info->indexed && r300->index_buffer.buffer) { - unsigned offset; + if (!u_trim_pipe_prim(info->mode, &count)) { + return; + } + /* Index buffer range checking. */ + if (indexed) { assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0); - offset = r300->index_buffer.offset / r300->index_buffer.index_size; + /* Compute start for draw_elements, taking the offset into account. */ + start_indexed = + info->start + + (r300->index_buffer.offset / r300->index_buffer.index_size); + + if ((start_indexed + count) * r300->index_buffer.index_size > + r300->index_buffer.buffer->width0) { + fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n"); + return; + } + } + + /* Set up fallback for incompatible vertex layout if needed. */ + if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { + r300_begin_vertex_translate(r300); + translate = TRUE; + } + + if (indexed) { r300_draw_range_elements(pipe, r300->index_buffer.buffer, r300->index_buffer.index_size, @@ -692,14 +673,17 @@ static void r300_draw_vbo(struct pipe_context* pipe, info->min_index, info->max_index, info->mode, - info->start + offset, - info->count); - } - else { + start_indexed, + count); + } else { r300_draw_arrays(pipe, info->mode, info->start, - info->count); + count); + } + + if (translate) { + r300_end_vertex_translate(r300); } } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index b448924f85e..759d0e66968 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -32,6 +32,8 @@ #include "r300_winsys.h" #include "r300_public.h" +#include "draw/draw_context.h" + /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. * @@ -44,31 +46,31 @@ static const char* r300_get_vendor(struct pipe_screen* pscreen) } static const char* chip_families[] = { - "R300", - "R350", - "R360", - "RV350", - "RV370", - "RV380", - "R420", - "R423", - "R430", - "R480", - "R481", - "RV410", - "RS400", - "RC410", - "RS480", - "RS482", - "RS600", - "RS690", - "RS740", - "RV515", - "R520", - "RV530", - "R580", - "RV560", - "RV570" + "ATI R300", + "ATI R350", + "ATI R360", + "ATI RV350", + "ATI RV370", + "ATI RV380", + "ATI R420", + "ATI R423", + "ATI R430", + "ATI R480", + "ATI R481", + "ATI RV410", + "ATI RS400", + "ATI RC410", + "ATI RS480", + "ATI RS482", + "ATI RS600", + "ATI RS690", + "ATI RS740", + "ATI RV515", + "ATI R520", + "ATI RV530", + "ATI R580", + "ATI RV560", + "ATI RV570" }; static const char* r300_get_name(struct pipe_screen* pscreen) @@ -125,6 +127,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_DEPTH_CLAMP: /* XXX implemented, but breaks Regnum Online */ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: case PIPE_CAP_SHADER_STENCIL_EXPORT: + case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_PRIMITIVE_RESTART: return 0; /* Texturing. */ @@ -154,8 +158,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; default: - fprintf(stderr, "r300: Implementation error: Bad param %d\n", - param); + debug_printf("r300: Warning: Unknown CAP %d in get_param.\n", + param); return 0; } } @@ -205,9 +209,18 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e return is_r500 ? 1 : 0; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 0; } break; case PIPE_SHADER_VERTEX: + if (!r300screen->caps.has_tcl) { + return draw_get_shader_param(shader, param); + } + switch (param) { case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: @@ -232,6 +245,12 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e return is_r500 ? 4 : 0; /* XXX guessed. */ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + return 0; + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: break; } @@ -264,9 +283,16 @@ static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) return 16.0f; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0f; + case PIPE_CAP_GUARD_BAND_LEFT: + case PIPE_CAP_GUARD_BAND_TOP: + case PIPE_CAP_GUARD_BAND_RIGHT: + case PIPE_CAP_GUARD_BAND_BOTTOM: + /* XXX I don't know what these should be but the least we can do is + * silence the potential error message */ + return 0.0f; default: - fprintf(stderr, "r300: Implementation error: Bad paramf %d\n", - param); + debug_printf("r300: Warning: Unknown CAP %d in get_paramf.\n", + param); return 0.0f; } } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f2479a994c8..247c22216e1 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -684,7 +684,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); /* What is marked as dirty depends on the enum r300_fb_state_change. */ r300->gpu_flush.dirty = TRUE; @@ -703,7 +703,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, r300->fb_state.size += 10; else if (state->zsbuf) { r300->fb_state.size += 10; - if (has_hyperz) + if (can_hyperz) r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4; } @@ -717,7 +717,7 @@ static void struct r300_context* r300 = r300_context(pipe); struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; struct pipe_framebuffer_state *old_state = r300->fb_state.state; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; int blocksize; @@ -764,7 +764,7 @@ static void zbuffer_bpp = 24; break; } - if (has_hyperz) { + if (can_hyperz) { struct r300_surface *zs_surf = r300_surface(state->zsbuf); struct r300_texture *tex; int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44; @@ -1448,6 +1448,15 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, struct pipe_vertex_buffer *vbo; unsigned i, max_index = (1 << 24) - 1; boolean any_user_buffer = FALSE; + struct pipe_vertex_buffer dummy_vb = {0}; + + /* There must be at least one vertex buffer set, otherwise it locks up. */ + if (!count) { + dummy_vb.buffer = r300->dummy_vb; + dummy_vb.max_index = r300->dummy_vb->width0 / 4; + buffers = &dummy_vb; + count = 1; + } if (count == r300->vertex_buffer_count && memcmp(r300->vertex_buffer, buffers, @@ -1601,6 +1610,14 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, struct r300_vertex_element_state *velems; unsigned i; enum pipe_format *format; + struct pipe_vertex_element dummy_attrib = {0}; + + /* R300 Programmable Stream Control (PSC) doesn't support 0 vertex elements. */ + if (!count) { + dummy_attrib.src_format = PIPE_FORMAT_R8G8B8A8_UNORM; + attribs = &dummy_attrib; + count = 1; + } assert(count <= PIPE_MAX_ATTRIBS); velems = CALLOC_STRUCT(r300_vertex_element_state); @@ -1667,7 +1684,8 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, * swizzles are already set up. * Also compute the vertex size. */ for (i = 0; i < count; i++) { - /* This is OK because we check for aligned strides too. */ + /* This is OK because we check for aligned strides too + * elsewhere. */ velems->hw_format_size[i] = align(util_format_get_blocksize(velems->hw_format[i]), 4); velems->vertex_size_dwords += velems->hw_format_size[i] / 4; @@ -1789,7 +1807,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, { struct r300_context* r300 = r300_context(pipe); struct r300_constant_buffer *cbuf; - uint32_t *mapped = r300_buffer(buf)->user_buffer; + uint32_t *mapped; switch (shader) { case PIPE_SHADER_VERTEX: diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 904736ef06d..1cff3483b50 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -25,6 +25,7 @@ #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_pack_color.h" #include "r300_context.h" #include "r300_fs.h" @@ -433,6 +434,8 @@ static void r300_update_rs_block(struct r300_context *r300) fp_offset++; col_count++; DBG(r300, DBG_RS, "r300: Rasterized FACE written to FS.\n"); + } else if (fs_inputs->face != ATTR_UNUSED) { + fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n"); } /* Rasterize texture coordinates. */ @@ -484,12 +487,10 @@ static void r300_update_rs_block(struct r300_context *r300) } } - if (DBG_ON(r300, DBG_RS)) { - for (; i < ATTR_GENERIC_COUNT; i++) { - if (fs_inputs->generic[i] != ATTR_UNUSED) { - DBG(r300, DBG_RS, - "r300: FS input generic %i unassigned.\n", i); - } + for (; i < ATTR_GENERIC_COUNT; i++) { + if (fs_inputs->generic[i] != ATTR_UNUSED) { + fprintf(stderr, "r300: ERROR: FS input generic %i unassigned, " + "not enough hardware slots.\n", i); } } @@ -520,7 +521,12 @@ static void r300_update_rs_block(struct r300_context *r300) if (fs_inputs->fog != ATTR_UNUSED) { fp_offset++; - DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n"); + if (tex_count < 8) { + DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n"); + } else { + fprintf(stderr, "r300: ERROR: FS input fog unassigned, " + "not enough hardware slots.\n"); + } } } @@ -543,6 +549,11 @@ static void r300_update_rs_block(struct r300_context *r300) fp_offset++; tex_count++; tex_ptr += 4; + } else { + if (fs_inputs->wpos != ATTR_UNUSED && tex_count >= 8) { + fprintf(stderr, "r300: ERROR: FS input WPOS unassigned, " + "not enough hardware slots.\n"); + } } /* Invalidate the rest of the no-TCL (GA) stream locations. */ @@ -584,53 +595,56 @@ static uint32_t r300_get_border_color(enum pipe_format format, const float border[4]) { const struct util_format_description *desc; - float border_swizzled[4] = { - border[2], - border[1], - border[0], - border[3] - }; - uint32_t r; + float border_swizzled[4] = {0}; + unsigned i; + union util_color uc = {0}; desc = util_format_description(format); - /* We don't use util_pack_format because it does not handle the formats - * we want, e.g. R4G4B4A4 is non-existent in Gallium. */ + /* Apply inverse swizzle of the format. */ + for (i = 0; i < 4; i++) { + switch (desc->swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_X: + border_swizzled[2] = border[i]; + break; + case UTIL_FORMAT_SWIZZLE_Y: + border_swizzled[1] = border[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + border_swizzled[0] = border[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + border_swizzled[3] = border[i]; + break; + } + } + switch (desc->channel[0].size) { case 4: - r = ((float_to_ubyte(border_swizzled[0]) & 0xf0) >> 4) | - ((float_to_ubyte(border_swizzled[1]) & 0xf0) << 0) | - ((float_to_ubyte(border_swizzled[2]) & 0xf0) << 4) | - ((float_to_ubyte(border_swizzled[3]) & 0xf0) << 8); + util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc); break; case 5: if (desc->channel[1].size == 5) { - r = ((float_to_ubyte(border_swizzled[0]) & 0xf8) >> 3) | - ((float_to_ubyte(border_swizzled[1]) & 0xf8) << 2) | - ((float_to_ubyte(border_swizzled[2]) & 0xf8) << 7) | - ((float_to_ubyte(border_swizzled[3]) & 0x80) << 8); + util_pack_color(border_swizzled, PIPE_FORMAT_B5G5R5A1_UNORM, &uc); } else if (desc->channel[1].size == 6) { - r = ((float_to_ubyte(border_swizzled[0]) & 0xf8) >> 3) | - ((float_to_ubyte(border_swizzled[1]) & 0xfc) << 3) | - ((float_to_ubyte(border_swizzled[2]) & 0xf8) << 8); + util_pack_color(border_swizzled, PIPE_FORMAT_B5G6R5_UNORM, &uc); } else { assert(0); - r = 0; } break; default: - /* I think the fat formats (16, 32) are specified - * as the 8-bit ones. I am not sure how compressed formats - * work here. */ - r = ((float_to_ubyte(border_swizzled[0]) & 0xff) << 0) | - ((float_to_ubyte(border_swizzled[1]) & 0xff) << 8) | - ((float_to_ubyte(border_swizzled[2]) & 0xff) << 16) | - ((float_to_ubyte(border_swizzled[3]) & 0xff) << 24); + case 8: + util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); + break; + + case 10: + util_pack_color(border_swizzled, PIPE_FORMAT_B10G10R10A2_UNORM, &uc); + break; } - return r; + return uc.ui; } static void r300_merge_textures_and_samplers(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index a4911b9a2a6..33448bf0def 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -363,10 +363,7 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, break; case TGSI_TOKEN_TYPE_INSTRUCTION: inst = &parser.FullToken.FullInstruction; - /* This hack with the RET opcode woudn't work with - * conditionals. */ - if (inst->Instruction.Opcode == TGSI_OPCODE_END || - inst->Instruction.Opcode == TGSI_OPCODE_RET) { + if (inst->Instruction.Opcode == TGSI_OPCODE_END) { break; } diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index bf0ad8571ba..3fc1fa94c27 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -25,10 +25,14 @@ r600 = env.ConvenienceLibrary( 'r600_resource.c', 'r600_shader.c', 'r600_state.c', + 'r600_state_common.c', 'r600_texture.c', + 'r600_translate.c', 'r700_asm.c', 'evergreen_state.c', 'eg_asm.c', ]) +env.Alias('r600', r600) + Export('r600') diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c index 52b7189e9e5..21d66fa9564 100644 --- a/src/gallium/drivers/r600/eg_asm.c +++ b/src/gallium/drivers/r600/eg_asm.c @@ -36,8 +36,13 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) | - S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache0_mode); + S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache0_mode) | + S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache0_bank) | + S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache1_bank); bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) | + S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache1_mode) | + S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache0_addr) | + S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache1_addr) | S_SQ_CF_ALU_WORD1_BARRIER(1) | S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1); break; @@ -69,6 +74,8 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN: bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1); bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | S_SQ_CF_WORD1_BARRIER(1) | diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index be81c28b43f..698299ec134 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -311,6 +311,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_Z16_UNORM: return V_028C70_SWAP_STD; + case PIPE_FORMAT_L8A8_UNORM: case PIPE_FORMAT_R8G8_UNORM: return V_028C70_SWAP_STD; @@ -400,6 +401,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_Z16_UNORM: return V_028C70_COLOR_16; + case PIPE_FORMAT_L8A8_UNORM: case PIPE_FORMAT_R8G8_UNORM: return V_028C70_COLOR_8_8; @@ -447,8 +449,10 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) return V_028C70_COLOR_16_16; /* 64-bit buffers. */ - case PIPE_FORMAT_R16G16B16A16_SSCALED: + case PIPE_FORMAT_R16G16B16_USCALED: + case PIPE_FORMAT_R16G16B16A16_USCALED: case PIPE_FORMAT_R16G16B16_SSCALED: + case PIPE_FORMAT_R16G16B16A16_SSCALED: case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: return V_028C70_COLOR_16_16_16_16; @@ -460,6 +464,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R32G32_FLOAT: return V_028C70_COLOR_32_32_FLOAT; + case PIPE_FORMAT_R32G32_USCALED: case PIPE_FORMAT_R32G32_SSCALED: return V_028C70_COLOR_32_32; @@ -473,7 +478,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - R600_ERR("unsupported color format %d\n", format); + //R600_ERR("unsupported color format %d\n", format); return ~0; /* Unsupported. */ } } @@ -634,38 +639,4 @@ out_unknown: return ~0; } -static INLINE uint32_t r600_translate_vertex_data_swizzle(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - unsigned i; - uint32_t word3; - - assert(format); - - if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - fprintf(stderr, "r600: Bad format %s in %s:%d\n", - util_format_short_name(format), __FUNCTION__, __LINE__); - return 0; - } - - word3 = 0; - for (i = 0; i < desc->nr_channels; i++) { - switch (i) { - case 0: - word3 |= S_03000C_DST_SEL_X(desc->swizzle[0]); - break; - case 1: - word3 |= S_03000C_DST_SEL_Y(desc->swizzle[1]); - break; - case 2: - word3 |= S_03000C_DST_SEL_Z(desc->swizzle[2]); - break; - case 3: - word3 |= S_03000C_DST_SEL_W(desc->swizzle[3]); - break; - } - } - return word3; -} - #endif diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index f394527edfd..26dad7b65c0 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -137,20 +137,6 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx, return rstate; } -static void evergreen_bind_blend_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; - struct r600_pipe_state *rstate; - - if (state == NULL) - return; - rstate = &blend->rstate; - rctx->states[rstate->id] = rstate; - rctx->cb_target_mask = blend->cb_target_mask; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - static void *evergreen_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { @@ -261,7 +247,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_RASTERIZER; if (state->flatshade_first) prov_vtx = 0; - tmp = 0x00000001; + tmp = S_0286D4_FLAT_SHADE_ENA(1); if (state->sprite_coord_enable) { tmp |= S_0286D4_PNT_SPRITE_ENA(1) | S_0286D4_PNT_SPRITE_OVRD_X(2) | @@ -295,46 +281,23 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, tmp = (unsigned)(state->point_size * 8.0); r600_pipe_state_add_reg(rstate, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A04_PA_SU_POINT_MINMAX, 0x80000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, 0x00000008, 0xFFFFFFFF, NULL); + + tmp = (unsigned)state->line_width * 8; + r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C18_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0x0, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, 0x00000005, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule, 0xFFFFFFFF, NULL); - return rstate; -} - -static void evergreen_bind_rs_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - - if (state == NULL) - return; - - rctx->flatshade = rs->flatshade; - rctx->sprite_coord_enable = rs->sprite_coord_enable; - rctx->rasterizer = rs; - - rctx->states[rs->rstate.id] = &rs->rstate; - r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); -} -static void evergreen_delete_rs_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; + r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, + S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules), + 0xFFFFFFFF, NULL); - if (rctx->rasterizer == rs) { - rctx->rasterizer = NULL; - } - if (rctx->states[rs->rstate.id] == &rs->rstate) { - rctx->states[rs->rstate.id] = NULL; - } - free(rs); + r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule, 0xFFFFFFFF, NULL); + return rstate; } static void *evergreen_create_sampler_state(struct pipe_context *ctx, @@ -360,11 +323,11 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, - S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | - S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)), + S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | + S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, - S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)) | + S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | S_03C008_TYPE(1), 0xFFFFFFFF, NULL); @@ -377,15 +340,6 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, return rstate; } -static void evergreen_sampler_view_destroy(struct pipe_context *ctx, - struct pipe_sampler_view *state) -{ - struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; - - pipe_resource_reference(&state->texture, NULL); - FREE(resource); -} - static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_context *ctx, struct pipe_resource *texture, const struct pipe_sampler_view *state) @@ -477,7 +431,7 @@ static void evergreen_set_vs_sampler_view(struct pipe_context *ctx, unsigned cou for (int i = 0; i < count; i++) { if (resource[i]) { - evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i + PIPE_MAX_ATTRIBS); + evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i); } } } @@ -510,17 +464,6 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou rctx->ps_samplers.n_views = count; } -static void evergreen_bind_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (state == NULL) - return; - rctx->states[rstate->id] = rstate; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - static void evergreen_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -545,31 +488,6 @@ static void evergreen_bind_vs_sampler(struct pipe_context *ctx, unsigned count, } } -static void evergreen_delete_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (rctx->states[rstate->id] == rstate) { - rctx->states[rstate->id] = NULL; - } - for (int i = 0; i < rstate->nregs; i++) { - r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL); - } - free(rstate); -} - -static void evergreen_delete_vertex_element(struct pipe_context *ctx, void *state) -{ - struct r600_vertex_element *v = (struct r600_vertex_element*)state; - - if (v == NULL) - return; - if (--v->refcount) - return; - free(v); -} - static void evergreen_set_clip_state(struct pipe_context *ctx, const struct pipe_clip_state *state) { @@ -583,16 +501,16 @@ static void evergreen_set_clip_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_CLIP; for (int i = 0; i < state->nr; i++) { r600_pipe_state_add_reg(rstate, - R_0285BC_PA_CL_UCP0_X + i * 4, + R_0285BC_PA_CL_UCP0_X + i * 16, fui(state->ucp[i][0]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_0285C0_PA_CL_UCP0_Y + i * 4, + R_0285C0_PA_CL_UCP0_Y + i * 16, fui(state->ucp[i][1]) , 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_0285C4_PA_CL_UCP0_Z + i * 4, + R_0285C4_PA_CL_UCP0_Z + i * 16, fui(state->ucp[i][2]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_0285C8_PA_CL_UCP0_W + i * 4, + R_0285C8_PA_CL_UCP0_W + i * 16, fui(state->ucp[i][3]), 0xFFFFFFFF, NULL); } r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, @@ -605,19 +523,6 @@ static void evergreen_set_clip_state(struct pipe_context *ctx, r600_context_pipe_state_set(&rctx->ctx, rstate); } -static void evergreen_bind_vertex_elements(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_vertex_element *v = (struct r600_vertex_element*)state; - - evergreen_delete_vertex_element(ctx, rctx->vertex_elements); - rctx->vertex_elements = v; - if (v) { - v->refcount++; -// rctx->vs_rebuild = TRUE; - } -} - static void evergreen_set_polygon_stipple(struct pipe_context *ctx, const struct pipe_poly_stipple *state) { @@ -755,7 +660,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state S_028C70_COMP_SWAP(swap) | S_028C70_BLEND_CLAMP(1) | S_028C70_NUMBER_TYPE(ntype); - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) color_info |= S_028C70_SOURCE_FORMAT(1); /* FIXME handle enabling of CB beyond BASE8 which has different offset */ @@ -928,6 +833,13 @@ static void evergreen_set_constant_buffer(struct pipe_context *ctx, uint shader, struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer = (struct r600_resource*)buffer; + /* Note that the state tracker can unbind constant buffers by + * passing NULL here. + */ + if (buffer == NULL) { + return; + } + switch (shader) { case PIPE_SHADER_VERTEX: rctx->vs_const_buffer.nregs = 0; @@ -957,84 +869,31 @@ static void evergreen_set_constant_buffer(struct pipe_context *ctx, uint shader, } } -static void *evergreen_create_shader_state(struct pipe_context *ctx, - const struct pipe_shader_state *state) -{ - struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); - int r; - - r = r600_pipe_shader_create(ctx, shader, state->tokens); - if (r) { - return NULL; - } - return shader; -} - -static void evergreen_bind_ps_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - - /* TODO delete old shader */ - rctx->ps_shader = (struct r600_pipe_shader *)state; -} - -static void evergreen_bind_vs_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - - /* TODO delete old shader */ - rctx->vs_shader = (struct r600_pipe_shader *)state; -} - -static void evergreen_delete_ps_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; - - if (rctx->ps_shader == shader) { - rctx->ps_shader = NULL; - } - /* TODO proper delete */ - free(shader); -} - -static void evergreen_delete_vs_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; - - if (rctx->vs_shader == shader) { - rctx->vs_shader = NULL; - } - /* TODO proper delete */ - free(shader); -} - void evergreen_init_state_functions(struct r600_pipe_context *rctx) { rctx->context.create_blend_state = evergreen_create_blend_state; rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state; - rctx->context.create_fs_state = evergreen_create_shader_state; + rctx->context.create_fs_state = r600_create_shader_state; rctx->context.create_rasterizer_state = evergreen_create_rs_state; rctx->context.create_sampler_state = evergreen_create_sampler_state; rctx->context.create_sampler_view = evergreen_create_sampler_view; rctx->context.create_vertex_elements_state = r600_create_vertex_elements; - rctx->context.create_vs_state = evergreen_create_shader_state; - rctx->context.bind_blend_state = evergreen_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = evergreen_bind_state; + rctx->context.create_vs_state = r600_create_shader_state; + rctx->context.bind_blend_state = r600_bind_blend_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler; - rctx->context.bind_fs_state = evergreen_bind_ps_shader; - rctx->context.bind_rasterizer_state = evergreen_bind_rs_state; - rctx->context.bind_vertex_elements_state = evergreen_bind_vertex_elements; + rctx->context.bind_fs_state = r600_bind_ps_shader; + rctx->context.bind_rasterizer_state = r600_bind_rs_state; + rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements; rctx->context.bind_vertex_sampler_states = evergreen_bind_vs_sampler; - rctx->context.bind_vs_state = evergreen_bind_vs_shader; - rctx->context.delete_blend_state = evergreen_delete_state; - rctx->context.delete_depth_stencil_alpha_state = evergreen_delete_state; - rctx->context.delete_fs_state = evergreen_delete_ps_shader; - rctx->context.delete_rasterizer_state = evergreen_delete_rs_state; - rctx->context.delete_sampler_state = evergreen_delete_state; - rctx->context.delete_vertex_elements_state = evergreen_delete_vertex_element; - rctx->context.delete_vs_state = evergreen_delete_vs_shader; + rctx->context.bind_vs_state = r600_bind_vs_shader; + rctx->context.delete_blend_state = r600_delete_state; + rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; + rctx->context.delete_fs_state = r600_delete_ps_shader; + rctx->context.delete_rasterizer_state = r600_delete_rs_state; + rctx->context.delete_sampler_state = r600_delete_state; + rctx->context.delete_vertex_elements_state = r600_delete_vertex_element; + rctx->context.delete_vs_state = r600_delete_vs_shader; rctx->context.set_blend_color = evergreen_set_blend_color; rctx->context.set_clip_state = evergreen_set_clip_state; rctx->context.set_constant_buffer = evergreen_set_constant_buffer; @@ -1048,7 +907,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx) rctx->context.set_index_buffer = r600_set_index_buffer; rctx->context.set_vertex_sampler_views = evergreen_set_vs_sampler_view; rctx->context.set_viewport_state = evergreen_set_viewport_state; - rctx->context.sampler_view_destroy = evergreen_sampler_view_destroy; + rctx->context.sampler_view_destroy = r600_sampler_view_destroy; } void evergreen_init_config(struct r600_pipe_context *rctx) @@ -1417,7 +1276,10 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) word2 = format | S_030008_STRIDE(vertex_buffer->stride); - word3 = r600_translate_vertex_data_swizzle(rctx->vertex_elements->hw_format[i]); + word3 = S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | + S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) | + S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) | + S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W); r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, rbuffer->size - offset - 1, 0xFFFFFFFF, NULL); @@ -1427,7 +1289,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, 0xC0000000, 0xFFFFFFFF, NULL); - evergreen_vs_resource_set(&rctx->ctx, rstate, i); + evergreen_fs_resource_set(&rctx->ctx, rstate, i); } mask = 0; @@ -1605,8 +1467,8 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader S_0286E0_PERSP_CENTROID_ENA(have_centroid); if (have_linear) spi_baryc_cntl |= S_0286E0_LINEAR_CENTER_ENA(1) | - S_0286E0_LINEAR_CENTROID_ENA(have_centroid); - + S_0286E0_LINEAR_CENTROID_ENA(have_centroid); + r600_pipe_state_add_reg(rstate, R_0286CC_SPI_PS_IN_CONTROL_0, spi_ps_in_control_0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286D0_SPI_PS_IN_CONTROL_1, @@ -1692,7 +1554,7 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo); r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS, - (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo); + (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo_fetch); r600_pipe_state_add_reg(rstate, R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index 8e96f9355e6..a337916c098 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1636,6 +1636,9 @@ #define R_028980_ALU_CONST_CACHE_VS_0 0x00028980 #define R_028A04_PA_SU_POINT_MINMAX 0x00028A04 #define R_028A08_PA_SU_LINE_CNTL 0x00028A08 +#define S_028A08_WIDTH(x) (((x) & 0xFFFF) << 0) +#define G_028A08_WIDTH(x) (((x) >> 0) & 0xFFFF) +#define C_028A08_WIDTH 0xFFFF0000 #define R_028A10_VGT_OUTPUT_PATH_CNTL 0x00028A10 #define R_028A14_VGT_HOS_CNTL 0x00028A14 #define R_028A18_VGT_HOS_MAX_TESS_LEVEL 0x00028A18 @@ -1687,6 +1690,9 @@ #define R_028C00_PA_SC_LINE_CNTL 0x00028C00 #define R_028C04_PA_SC_AA_CONFIG 0x00028C04 #define R_028C08_PA_SU_VTX_CNTL 0x00028C08 +#define S_028C08_PIX_CENTER_HALF(x) (((x) & 0x1) << 0) +#define G_028C08_PIX_CENTER_HALF(x) (((x) >> 0) & 0x1) +#define C_028C08_PIX_CENTER_HALF 0xFFFFFFFE #define R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x00028C0C #define R_028C10_PA_CL_GB_VERT_DISC_ADJ 0x00028C10 #define R_028C14_PA_CL_GB_HORZ_CLIP_ADJ 0x00028C14 diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 62d983269f5..a617a5b8631 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -43,6 +43,7 @@ typedef uint16_t u16; typedef uint8_t u8; struct radeon; +struct winsys_handle; enum radeon_family { CHIP_UNKNOWN, @@ -112,13 +113,16 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon); /* r600_bo.c */ struct r600_bo; struct r600_bo *r600_bo(struct radeon *radeon, - unsigned size, unsigned alignment, unsigned usage); + unsigned size, unsigned alignment, + unsigned binding, unsigned usage); struct r600_bo *r600_bo_handle(struct radeon *radeon, unsigned handle, unsigned *array_mode); void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx); void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo); void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, struct r600_bo *src); +boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo, + unsigned stride, struct winsys_handle *whandle); static INLINE unsigned r600_bo_offset(struct r600_bo *bo) { return 0; @@ -260,6 +264,7 @@ void r600_context_fini(struct r600_context *ctx); void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_state *state); void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); void r600_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void r600_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void r600_context_flush(struct r600_context *ctx); @@ -280,9 +285,11 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon); void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *draw); void evergreen_ps_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); void evergreen_vs_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void evergreen_fs_resource_set(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); +void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid); void evergreen_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); void evergreen_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id); diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index d13da0ef638..ba1471eb785 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -23,6 +23,7 @@ #include <stdio.h> #include <errno.h> #include "util/u_memory.h" +#include "pipe/p_shader_tokens.h" #include "r600_pipe.h" #include "r600_sq.h" #include "r600_opcodes.h" @@ -55,8 +56,8 @@ static inline unsigned int r600_bc_get_num_operands(struct r600_bc_alu *alu) case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: - return 2; - + return 2; + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR: case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: @@ -74,7 +75,7 @@ static inline unsigned int r600_bc_get_num_operands(struct r600_bc_alu *alu) default: R600_ERR( "Need instruction operand number for 0x%x.\n", alu->inst); }; - + return 3; } @@ -137,20 +138,20 @@ int r600_bc_init(struct r600_bc *bc, enum radeon_family family) case CHIP_RV635: case CHIP_RS780: case CHIP_RS880: - bc->chiprev = 0; + bc->chiprev = CHIPREV_R600; break; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: - bc->chiprev = 1; + bc->chiprev = CHIPREV_R700; break; case CHIP_CEDAR: case CHIP_REDWOOD: case CHIP_JUNIPER: case CHIP_CYPRESS: case CHIP_HEMLOCK: - bc->chiprev = 2; + bc->chiprev = CHIPREV_EVERGREEN; break; default: R600_ERR("unknown family %d\n", bc->family); @@ -199,9 +200,9 @@ const unsigned bank_swizzle_vec[8] = {SQ_ALU_VEC_210, //000 SQ_ALU_VEC_012}; //111 const unsigned bank_swizzle_scl[8] = {SQ_ALU_SCL_210, //000 - SQ_ALU_SCL_122, //001 + SQ_ALU_SCL_122, //001 SQ_ALU_SCL_122, //010 - + SQ_ALU_SCL_221, //011 SQ_ALU_SCL_212, //100 SQ_ALU_SCL_122, //101 @@ -592,10 +593,34 @@ int r600_bc_add_cfinst(struct r600_bc *bc, int inst) /* common to all 3 families */ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id) { - bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) | - S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) | - S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) | - S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count); + unsigned fetch_resource_start = 0; + + /* check if we are fetch shader */ + /* fetch shader can also access vertex resource, + * first fetch shader resource is at 160 + */ + if (bc->type == -1) { + switch (bc->chiprev) { + /* r600 */ + case CHIPREV_R600: + /* r700 */ + case CHIPREV_R700: + fetch_resource_start = 160; + break; + /* evergreen */ + case CHIPREV_EVERGREEN: + fetch_resource_start = 0; + break; + default: + fprintf(stderr, "%s:%s:%d unknown chiprev %d\n", + __FILE__, __func__, __LINE__, bc->chiprev); + break; + } + } + bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id + fetch_resource_start) | + S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) | + S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) | + S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count); bc->bytecode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vtx->dst_sel_x) | S_SQ_VTX_WORD1_DST_SEL_Y(vtx->dst_sel_y) | S_SQ_VTX_WORD1_DST_SEL_Z(vtx->dst_sel_z) | @@ -678,8 +703,8 @@ static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsign S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) | S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) | S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle) | - S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(alu->predicate) | - S_SQ_ALU_WORD1_OP2_UPDATE_PRED(alu->predicate); + S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(alu->predicate) | + S_SQ_ALU_WORD1_OP2_UPDATE_PRED(alu->predicate); } if (alu->last) { if (alu->nliteral && !alu->literal_added) { @@ -701,11 +726,16 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) | - S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache0_mode); + S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache0_mode) | + S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache0_bank) | + S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache1_bank); bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) | + S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache1_mode) | + S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache0_addr) | + S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache1_addr) | S_SQ_CF_ALU_WORD1_BARRIER(1) | - S_SQ_CF_ALU_WORD1_USES_WATERFALL(bc->chiprev == 0 ? cf->r6xx_uses_waterfall : 0) | + S_SQ_CF_ALU_WORD1_USES_WATERFALL(bc->chiprev == CHIPREV_R600 ? cf->r6xx_uses_waterfall : 0) | S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1); break; case V_SQ_CF_WORD1_SQ_CF_INST_TEX: @@ -737,6 +767,8 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1); bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | S_SQ_CF_WORD1_BARRIER(1) | @@ -761,7 +793,10 @@ int r600_bc_build(struct r600_bc *bc) int r; if (bc->callstack[0].max > 0) - bc->nstack = ((bc->callstack[0].max + 3) >> 2) + 2; + bc->nstack = ((bc->callstack[0].max + 3) >> 2) + 2; + if (bc->type == TGSI_PROCESSOR_VERTEX && !bc->nstack) { + bc->nstack = 1; + } /* first path compute addr of each CF block */ /* addr start after all the CF instructions */ @@ -790,6 +825,8 @@ int r600_bc_build(struct r600_bc *bc) case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: break; default: R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); @@ -805,7 +842,7 @@ int r600_bc_build(struct r600_bc *bc) return -ENOMEM; LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { addr = cf->addr; - if (bc->chiprev == 2) + if (bc->chiprev == CHIPREV_EVERGREEN) r = eg_bc_cf_build(bc, cf); else r = r600_bc_cf_build(bc, cf); @@ -816,11 +853,11 @@ int r600_bc_build(struct r600_bc *bc) case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { switch(bc->chiprev) { - case 0: + case CHIPREV_R600: r = r600_bc_alu_build(bc, alu, addr); break; - case 1: - case 2: /* eg alu is same encoding as r700 */ + case CHIPREV_R700: + case CHIPREV_EVERGREEN: /* eg alu is same encoding as r700 */ r = r700_bc_alu_build(bc, alu, addr); break; default: @@ -863,6 +900,8 @@ int r600_bc_build(struct r600_bc *bc) case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: case V_SQ_CF_WORD1_SQ_CF_INST_POP: + case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: break; default: R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); @@ -871,3 +910,39 @@ int r600_bc_build(struct r600_bc *bc) } return 0; } + +void r600_bc_clear(struct r600_bc *bc) +{ + struct r600_bc_cf *cf = NULL, *next_cf; + + free(bc->bytecode); + bc->bytecode = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(cf, next_cf, &bc->cf, list) { + struct r600_bc_alu *alu = NULL, *next_alu; + struct r600_bc_tex *tex = NULL, *next_tex; + struct r600_bc_tex *vtx = NULL, *next_vtx; + + LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) { + free(alu); + } + + LIST_INITHEAD(&cf->alu); + + LIST_FOR_EACH_ENTRY_SAFE(tex, next_tex, &cf->tex, list) { + free(tex); + } + + LIST_INITHEAD(&cf->tex); + + LIST_FOR_EACH_ENTRY_SAFE(vtx, next_vtx, &cf->vtx, list) { + free(vtx); + } + + LIST_INITHEAD(&cf->vtx); + + free(cf); + } + + LIST_INITHEAD(&cf->list); +} diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h index bebc7c15b00..f2016af3e72 100644 --- a/src/gallium/drivers/r600/r600_asm.h +++ b/src/gallium/drivers/r600/r600_asm.h @@ -132,6 +132,11 @@ struct r600_bc_cf { unsigned pop_count; unsigned cf_addr; /* control flow addr */ unsigned kcache0_mode; + unsigned kcache1_mode; + unsigned kcache0_addr; + unsigned kcache1_addr; + unsigned kcache0_bank; + unsigned kcache1_bank; unsigned r6xx_uses_waterfall; struct list_head alu; struct list_head tex; @@ -140,12 +145,12 @@ struct r600_bc_cf { struct r600_bc_alu *curr_bs_head; }; -#define FC_NONE 0 -#define FC_IF 1 -#define FC_LOOP 2 -#define FC_REP 3 -#define FC_PUSH_VPM 4 -#define FC_PUSH_WQM 5 +#define FC_NONE 0 +#define FC_IF 1 +#define FC_LOOP 2 +#define FC_REP 3 +#define FC_PUSH_VPM 4 +#define FC_PUSH_WQM 5 struct r600_cf_stack_entry { int type; @@ -161,10 +166,11 @@ struct r600_cf_callstack { int current; int max; }; - + struct r600_bc { enum radeon_family family; int chiprev; /* 0 - r600, 1 - r700, 2 - evergreen */ + int type; struct list_head cf; struct r600_bc_cf *cf_last; unsigned ndw; @@ -185,6 +191,7 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf); /* r600_asm.c */ int r600_bc_init(struct r600_bc *bc, enum radeon_family family); +void r600_bc_clear(struct r600_bc *bc); int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu); int r600_bc_add_literal(struct r600_bc *bc, const u32 *value); int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 50d47060c1a..74cf9687999 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -27,9 +27,9 @@ enum r600_blitter_op /* bitmask */ { - R600_CLEAR = 1, - R600_CLEAR_SURFACE = 2, - R600_COPY = 4 + R600_CLEAR = 1, + R600_CLEAR_SURFACE = 2, + R600_COPY = 4 }; static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op) @@ -189,7 +189,6 @@ static void r600_resource_copy_region(struct pipe_context *ctx, else r600_hw_copy_region(ctx, dst, subdst, dstx, dsty, dstz, src, subsrc, srcx, srcy, srcz, width, height); - } void r600_init_blit_functions(struct r600_pipe_context *rctx) diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 455aa2e81f6..a432271b82d 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -38,32 +38,6 @@ extern struct u_resource_vtbl r600_buffer_vtbl; -u32 r600_domain_from_usage(unsigned usage) -{ - u32 domain = RADEON_GEM_DOMAIN_GTT; - - if (usage & PIPE_BIND_RENDER_TARGET) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_DEPTH_STENCIL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_SAMPLER_VIEW) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - /* also need BIND_BLIT_SOURCE/DESTINATION ? */ - if (usage & PIPE_BIND_VERTEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_INDEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_CONSTANT_BUFFER) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - - return domain; -} struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) @@ -85,8 +59,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, rbuffer->r.base.b.screen = screen; rbuffer->r.base.vtbl = &r600_buffer_vtbl; rbuffer->r.size = rbuffer->r.base.b.width0; - rbuffer->r.domain = r600_domain_from_usage(rbuffer->r.base.b.bind); - bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind); + bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage); if (bo == NULL) { FREE(rbuffer); return NULL; @@ -151,13 +124,14 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, if ((transfer->box.x >= rbuffer->ranges[i].start) && (transfer->box.x < rbuffer->ranges[i].end)) flush = TRUE; - + if (flush) { r600_bo_reference((struct radeon*)pipe->winsys, &rbuffer->r.bo, NULL); rbuffer->num_ranges = 0; rbuffer->r.bo = r600_bo((struct radeon*)pipe->winsys, - rbuffer->r.base.b.width0, 0, - rbuffer->r.base.b.bind); + rbuffer->r.base.b.width0, 0, + rbuffer->r.base.b.bind, + rbuffer->r.base.b.usage); break; } } @@ -206,7 +180,7 @@ static void r600_buffer_transfer_flush_region(struct pipe_context *pipe, return; } } - + rbuffer->ranges[rbuffer->num_ranges].start = offset; rbuffer->ranges[rbuffer->num_ranges].end = offset+length; rbuffer->num_ranges++; diff --git a/src/gallium/drivers/r600/r600_opcodes.h b/src/gallium/drivers/r600/r600_opcodes.h index 4f9b39a7fdc..2ee0c83e5d3 100644 --- a/src/gallium/drivers/r600/r600_opcodes.h +++ b/src/gallium/drivers/r600/r600_opcodes.h @@ -385,8 +385,13 @@ #define EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_EXPORT_COMBINED 0x0000005B #define EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_RAT_COMBINED_CACHELESS 0x0000005C -#define BC_INST(bc, x) ((bc)->chiprev == 2 ? EG_##x : x) -#define CTX_INST(x) (ctx->bc->chiprev == 2 ? EG_##x : x) +#define CHIPREV_R600 0 +#define CHIPREV_R700 1 +#define CHIPREV_EVERGREEN 2 + +#define BC_INST(bc, x) ((bc)->chiprev == CHIPREV_EVERGREEN ? EG_##x : x) + +#define CTX_INST(x) (ctx->bc->chiprev == CHIPREV_EVERGREEN ? EG_##x : x) #endif diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index bea7ef5df84..d7bd4db48ea 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -77,7 +77,12 @@ static void r600_destroy_context(struct pipe_context *context) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)context; + rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush); + r600_context_fini(&rctx->ctx); + + util_blitter_destroy(rctx->blitter); + for (int i = 0; i < R600_PIPE_NSTATES; i++) { free(rctx->states[i]); } @@ -181,7 +186,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void FREE(rctx); return NULL; } - + rctx->vs_resource = CALLOC(R600_RESOURCE_ARRAY_SIZE, sizeof(struct r600_pipe_state)); if (!rctx->vs_resource) { FREE(rctx); @@ -216,24 +221,24 @@ static const char* r600_get_vendor(struct pipe_screen* pscreen) static const char *r600_get_family_name(enum radeon_family family) { switch(family) { - case CHIP_R600: return "R600"; - case CHIP_RV610: return "RV610"; - case CHIP_RV630: return "RV630"; - case CHIP_RV670: return "RV670"; - case CHIP_RV620: return "RV620"; - case CHIP_RV635: return "RV635"; - case CHIP_RS780: return "RS780"; - case CHIP_RS880: return "RS880"; - case CHIP_RV770: return "RV770"; - case CHIP_RV730: return "RV730"; - case CHIP_RV710: return "RV710"; - case CHIP_RV740: return "RV740"; - case CHIP_CEDAR: return "CEDAR"; - case CHIP_REDWOOD: return "REDWOOD"; - case CHIP_JUNIPER: return "JUNIPER"; - case CHIP_CYPRESS: return "CYPRESS"; - case CHIP_HEMLOCK: return "HEMLOCK"; - default: return "unknown"; + case CHIP_R600: return "AMD R600"; + case CHIP_RV610: return "AMD RV610"; + case CHIP_RV630: return "AMD RV630"; + case CHIP_RV670: return "AMD RV670"; + case CHIP_RV620: return "AMD RV620"; + case CHIP_RV635: return "AMD RV635"; + case CHIP_RS780: return "AMD RS780"; + case CHIP_RS880: return "AMD RS880"; + case CHIP_RV770: return "AMD RV770"; + case CHIP_RV730: return "AMD RV730"; + case CHIP_RV710: return "AMD RV710"; + case CHIP_RV740: return "AMD RV740"; + case CHIP_CEDAR: return "AMD CEDAR"; + case CHIP_REDWOOD: return "AMD REDWOOD"; + case CHIP_JUNIPER: return "AMD JUNIPER"; + case CHIP_CYPRESS: return "AMD CYPRESS"; + case CHIP_HEMLOCK: return "AMD HEMLOCK"; + default: return "AMD unknown"; } } @@ -271,6 +276,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* Unsupported features (boolean caps). */ case PIPE_CAP_TIMER_QUERY: case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ return 0; @@ -364,6 +370,11 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e return 0; /* FIXME */ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: return 0; } @@ -395,7 +406,7 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) && - r600_is_colorbuffer_format_supported(format)) { + r600_is_colorbuffer_format_supported(format)) { retval |= usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | @@ -426,6 +437,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen) if (rscreen == NULL) return; + + radeon_decref(rscreen->radeon); + FREE(rscreen); } diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 11410f17c75..ba9fedf0b6c 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -83,7 +83,6 @@ struct r600_pipe_blend { struct r600_vertex_element { unsigned count; - unsigned refcount; struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS]; enum pipe_format hw_format[PIPE_MAX_ATTRIBS]; unsigned hw_format_size[PIPE_MAX_ATTRIBS]; @@ -94,6 +93,7 @@ struct r600_pipe_shader { struct r600_shader shader; struct r600_pipe_state rstate; struct r600_bo *bo; + struct r600_bo *bo_fetch; struct r600_vertex_element vertex_elements; }; @@ -209,6 +209,7 @@ void r600_init_context_resource_functions(struct r600_pipe_context *r600); /* r600_shader.c */ int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *shader); int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens); +void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader); int r600_find_vs_semantic_index(struct r600_shader *vs, struct r600_shader *ps, int id); @@ -242,6 +243,22 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, void *r600_create_vertex_elements(struct pipe_context *ctx, unsigned count, const struct pipe_vertex_element *elements); +void r600_delete_vertex_element(struct pipe_context *ctx, void *state); +void r600_bind_blend_state(struct pipe_context *ctx, void *state); +void r600_bind_rs_state(struct pipe_context *ctx, void *state); +void r600_delete_rs_state(struct pipe_context *ctx, void *state); +void r600_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *state); +void r600_bind_state(struct pipe_context *ctx, void *state); +void r600_delete_state(struct pipe_context *ctx, void *state); +void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); + +void *r600_create_shader_state(struct pipe_context *ctx, + const struct pipe_shader_state *state); +void r600_bind_ps_shader(struct pipe_context *ctx, void *state); +void r600_bind_vs_shader(struct pipe_context *ctx, void *state); +void r600_delete_ps_shader(struct pipe_context *ctx, void *state); +void r600_delete_vs_shader(struct pipe_context *ctx, void *state); /* * common helpers */ diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index d152285815c..7a2d1f44122 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -35,7 +35,7 @@ struct r600_transfer { /* Buffer transfer. */ struct pipe_transfer *buffer_transfer; unsigned offset; - struct pipe_resource *linear_texture; + struct pipe_resource *staging_texture; }; /* This gets further specialized into either buffer or texture @@ -45,8 +45,6 @@ struct r600_transfer { struct r600_resource { struct u_resource base; struct r600_bo *bo; - u32 domain; - u32 flink; u32 size; }; @@ -68,9 +66,6 @@ struct r600_resource_texture { void r600_init_screen_resource_functions(struct pipe_screen *screen); -/* r600_buffer */ -u32 r600_domain_from_usage(unsigned usage); - /* r600_texture */ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ); diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 0dd416c0d83..3e42309bde0 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -80,7 +80,7 @@ static void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shade r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo); r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS, - r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo); + r600_bo_offset(shader->bo_fetch) >> 8, 0xFFFFFFFF, shader->bo_fetch); r600_pipe_state_add_reg(rstate, R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, @@ -217,8 +217,17 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s void *ptr; /* copy new shader */ + if (rshader->processor_type == TGSI_PROCESSOR_VERTEX && shader->bo_fetch == NULL) { + shader->bo_fetch = r600_bo(rctx->radeon, rshader->bc_fetch.ndw * 4, 4096, 0, 0); + if (shader->bo_fetch == NULL) { + return -ENOMEM; + } + ptr = r600_bo_map(rctx->radeon, shader->bo_fetch, 0, NULL); + memcpy(ptr, rshader->bc_fetch.bytecode, rshader->bc_fetch.ndw * 4); + r600_bo_unmap(rctx->radeon, shader->bo_fetch); + } if (shader->bo == NULL) { - shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0); + shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0); if (shader->bo == NULL) { return -ENOMEM; } @@ -257,7 +266,7 @@ static int r600_shader_update(struct pipe_context *ctx, struct r600_pipe_shader const struct util_format_description *desc; enum pipe_format resource_format[160]; unsigned i, nresources = 0; - struct r600_bc *bc = &shader->bc; + struct r600_bc *bc = &shader->bc_fetch; struct r600_bc_cf *cf; struct r600_bc_vtx *vtx; @@ -272,7 +281,7 @@ static int r600_shader_update(struct pipe_context *ctx, struct r600_pipe_shader for (i = 0; i < rctx->vertex_elements->count; i++) { resource_format[nresources++] = rctx->vertex_elements->hw_format[i]; } - r600_bo_reference(rctx->radeon, &rshader->bo, NULL); + r600_bo_reference(rctx->radeon, &rshader->bo_fetch, NULL); LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { switch (cf->inst) { case V_SQ_CF_WORD1_SQ_CF_INST_VTX: @@ -293,7 +302,7 @@ static int r600_shader_update(struct pipe_context *ctx, struct r600_pipe_shader break; } } - return r600_bc_build(&shader->bc); + return r600_bc_build(&shader->bc_fetch); } int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *shader) @@ -334,10 +343,29 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s R600_ERR("building bytecode failed !\n"); return r; } + if (shader->shader.processor_type == TGSI_PROCESSOR_VERTEX) { + r = r600_bc_build(&shader->shader.bc_fetch); + if (r) { + R600_ERR("building bytecode failed !\n"); + return r; + } + } //fprintf(stderr, "______________________________________________________________\n"); return 0; } +void +r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + + r600_bo_reference(rctx->radeon, &shader->bo, NULL); + + r600_bc_clear(&shader->shader.bc); + + /* FIXME: is there more stuff to free? */ +} + /* * tgsi -> r600 shader */ @@ -352,6 +380,7 @@ struct r600_shader_ctx { unsigned temp_reg; struct r600_shader_tgsi_instruction *inst_info; struct r600_bc *bc; + struct r600_bc *bc_fetch; struct r600_shader *shader; u32 value[4]; u32 *literals; @@ -432,7 +461,7 @@ static int evergreen_interp_alu(struct r600_shader_ctx *ctx, int input) if (ctx->shader->input[input].centroid) ij_index++; } - + /* work out gpr and base_chan from index */ gpr = ij_index / 2; base_chan = (2 * (ij_index % 2)) + 1; @@ -465,9 +494,9 @@ static int evergreen_interp_alu(struct r600_shader_ctx *ctx, int input) return r; } return 0; -} - - +} + + static int tgsi_declaration(struct r600_shader_ctx *ctx) { struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration; @@ -499,11 +528,11 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) vtx.dst_sel_z = 2; vtx.dst_sel_w = 3; vtx.use_const_fields = 1; - r = r600_bc_add_vtx(ctx->bc, &vtx); + r = r600_bc_add_vtx(ctx->bc_fetch, &vtx); if (r) return r; } - if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chiprev == 2) { + if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chiprev == CHIPREV_EVERGREEN) { /* turn input into interpolate on EG */ if (ctx->shader->input[i].name != TGSI_SEMANTIC_POSITION) { if (ctx->shader->input[i].interpolate > 0) { @@ -537,7 +566,7 @@ static int r600_get_temp(struct r600_shader_ctx *ctx) return ctx->temp_reg + ctx->max_driver_temp_used++; } -/* +/* * for evergreen we need to scan the shader to find the number of GPRs we need to * reserve for interpolation. * @@ -594,6 +623,7 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s int i, r = 0, pos0; ctx.bc = &shader->bc; + ctx.bc_fetch = &shader->bc_fetch; ctx.shader = shader; r = r600_bc_init(ctx.bc, shader->family); if (r) @@ -603,6 +633,13 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s tgsi_parse_init(&ctx.parse, tokens); ctx.type = ctx.parse.FullHeader.Processor.Processor; shader->processor_type = ctx.type; + if (shader->processor_type == TGSI_PROCESSOR_VERTEX) { + r = r600_bc_init(ctx.bc_fetch, shader->family); + if (r) + return r; + ctx.bc_fetch->type = -1; + } + ctx.bc->type = shader->processor_type; /* register allocations */ /* Values [0,127] correspond to GPR[0..127]. @@ -628,8 +665,13 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s } if (ctx.type == TGSI_PROCESSOR_VERTEX) { ctx.file_offset[TGSI_FILE_INPUT] = 1; + if (ctx.bc->chiprev == CHIPREV_EVERGREEN) { + r600_bc_add_cfinst(ctx.bc, EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS); + } else { + r600_bc_add_cfinst(ctx.bc, V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS); + } } - if (ctx.type == TGSI_PROCESSOR_FRAGMENT && ctx.bc->chiprev == 2) { + if (ctx.type == TGSI_PROCESSOR_FRAGMENT && ctx.bc->chiprev == CHIPREV_EVERGREEN) { ctx.file_offset[TGSI_FILE_INPUT] = evergreen_gpr_count(&ctx); } ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] + @@ -675,7 +717,7 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s /* reserve first tmp for everyone */ r600_get_temp(&ctx); opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode; - if (ctx.bc->chiprev == 2) + if (ctx.bc->chiprev == CHIPREV_EVERGREEN) ctx.inst_info = &eg_shader_tgsi_instruction[opcode]; else ctx.inst_info = &r600_shader_tgsi_instruction[opcode]; @@ -797,6 +839,14 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE); } } + /* add return to fetch shader */ + if (ctx.type == TGSI_PROCESSOR_VERTEX) { + if (ctx.bc->chiprev == CHIPREV_EVERGREEN) { + r600_bc_add_cfinst(ctx.bc_fetch, EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN); + } else { + r600_bc_add_cfinst(ctx.bc_fetch, V_SQ_CF_WORD1_SQ_CF_INST_RETURN); + } + } /* add output to bytecode */ for (i = 0; i < noutput; i++) { r = r600_bc_add_output(ctx.bc, &output[i]); @@ -989,7 +1039,7 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap) r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); if (r) return r; - + alu.inst = ctx->inst_info->r600_opcode; if (!swap) { for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { @@ -1034,7 +1084,7 @@ static int tgsi_op2_swap(struct r600_shader_ctx *ctx) return tgsi_op2_s(ctx, 1); } -/* +/* * r600 - trunc to -PI..PI range * r700 - normalize by dividing by 2PI * see fdo bug 27901 @@ -1046,7 +1096,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, int r; uint32_t lit_vals[4]; struct r600_bc_alu alu; - + memset(lit_vals, 0, 4*4); r = tgsi_split_constant(ctx, r600_src); if (r) @@ -1072,7 +1122,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, alu.src[0] = r600_src[0]; alu.src[0].chan = tgsi_chan(&inst->Src[0], 0); - + alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; alu.src[1].chan = 0; alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; @@ -1087,7 +1137,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT); - + alu.dst.chan = 0; alu.dst.sel = ctx->temp_reg; alu.dst.write = 1; @@ -1099,7 +1149,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, if (r) return r; - if (ctx->bc->chiprev == 0) { + if (ctx->bc->chiprev == CHIPREV_R600) { lit_vals[0] = fui(3.1415926535897f * 2.0f); lit_vals[1] = fui(-3.1415926535897f); } else { @@ -1117,7 +1167,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, alu.src[0].sel = ctx->temp_reg; alu.src[0].chan = 0; - + alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; alu.src[1].chan = 0; alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; @@ -1896,10 +1946,10 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) r = r600_bc_add_alu(ctx->bc, &alu); if (r) return r; - + /* MULADD R0.x, R0.x, PS1, (0x3FC00000, 1.5f).x * MULADD R0.y, R0.y, PS1, (0x3FC00000, 1.5f).x - * muladd has no writemask, have to use another temp + * muladd has no writemask, have to use another temp */ memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD); @@ -1909,7 +1959,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) alu.src[0].chan = 0; alu.src[1].sel = ctx->temp_reg; alu.src[1].chan = 2; - + alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; alu.src[2].chan = 0; @@ -1929,7 +1979,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) alu.src[0].chan = 1; alu.src[1].sel = ctx->temp_reg; alu.src[1].chan = 2; - + alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; alu.src[2].chan = 0; @@ -1968,7 +2018,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) } src_gpr = ctx->temp_reg; } - + opcode = ctx->inst_info->r600_opcode; if (opcode == SQ_TEX_INST_SAMPLE && (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D || inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D)) @@ -1978,8 +2028,6 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) tex.inst = opcode; tex.sampler_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index; tex.resource_id = tex.sampler_id; - if (ctx->shader->processor_type == TGSI_PROCESSOR_VERTEX) - tex.resource_id += PIPE_MAX_ATTRIBS; tex.src_gpr = src_gpr; tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index; tex.dst_sel_x = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7; @@ -2014,7 +2062,6 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) /* add shadow ambient support - gallium doesn't do it yet */ return 0; - } static int tgsi_lrp(struct r600_shader_ctx *ctx) @@ -2144,7 +2191,7 @@ static int tgsi_cmp(struct r600_shader_ctx *ctx) r = r600_bc_add_alu(ctx->bc, &alu); if (r) return r; - } + } if (use_temp) return tgsi_helper_copy(ctx, inst); return 0; @@ -2330,7 +2377,7 @@ static int tgsi_exp(struct r600_shader_ctx *ctx) if (r) return r; } - + /* result.y = tmp - floor(tmp); */ if ((inst->Dst[0].Register.WriteMask >> 1) & 1) { memset(&alu, 0, sizeof(struct r600_bc_alu)); @@ -2609,16 +2656,25 @@ static int tgsi_log(struct r600_shader_ctx *ctx) return tgsi_helper_copy(ctx, inst); } -/* r6/7 only for now */ static int tgsi_eg_arl(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; struct r600_bc_alu alu; int r; - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + alu.inst = EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR; + break; + case TGSI_OPCODE_ARR: + alu.inst = EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT; + break; + default: + assert(0); + return -1; + } + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); if (r) return r; @@ -2651,7 +2707,18 @@ static int tgsi_r600_arl(struct r600_shader_ctx *ctx) int r; memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR; + break; + case TGSI_OPCODE_ARR: + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA; + break; + default: + assert(0); + return -1; + } + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); if (r) @@ -2680,8 +2747,8 @@ static int tgsi_opdst(struct r600_shader_ctx *ctx) r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); if (r) return r; - - if (i == 0 || i == 3) { + + if (i == 0 || i == 3) { alu.src[0].sel = V_SQ_ALU_SRC_1; } else { r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); @@ -2727,7 +2794,7 @@ static int emit_logic_pred(struct r600_shader_ctx *ctx, int opcode) alu.src[0].chan = tgsi_chan(&inst->Src[0], 0); alu.src[1].sel = V_SQ_ALU_SRC_0; alu.src[1].chan = 0; - + alu.last = 1; r = r600_bc_add_alu_type(ctx->bc, &alu, CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE)); @@ -2781,7 +2848,7 @@ static inline void callstack_check_depth(struct r600_shader_ctx *ctx, unsigned r ctx->bc->callstack[ctx->bc->call_sp].current + diff; } return; - } + } switch (reason) { case FC_PUSH_VPM: ctx->bc->callstack[ctx->bc->call_sp].current++; @@ -2855,7 +2922,7 @@ static int emit_setret_in_loop_flag(struct r600_shader_ctx *ctx, unsigned flag_v static void emit_testflag(struct r600_shader_ctx *ctx) { - + } static void emit_return_on_flag(struct r600_shader_ctx *ctx, unsigned ifidx) @@ -3058,7 +3125,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_UP4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_X2D, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_ARA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_r600_arl}, {TGSI_OPCODE_BRA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_CAL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_RET, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, @@ -3216,7 +3283,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = { {TGSI_OPCODE_UP4UB, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_X2D, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_ARA, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_ARR, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARR, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_eg_arl}, {TGSI_OPCODE_BRA, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_CAL, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_RET, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index f8bc5951395..cd108da4915 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -46,6 +46,7 @@ struct r600_shader { struct r600_shader_io output[32]; enum radeon_family family; boolean uses_kill; + struct r600_bc bc_fetch; }; int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index df2c05ea139..bf4ca057d28 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -109,7 +109,7 @@ static void r600_draw_common(struct r600_drawl *draw) r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6, 0xC0000000, 0xFFFFFFFF, NULL); - r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, i); + r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); } mask = 0; @@ -296,7 +296,7 @@ static void *r600_create_blend_state(struct pipe_context *ctx, unsigned eqRGB = state->rt[i].rgb_func; unsigned srcRGB = state->rt[i].rgb_src_factor; unsigned dstRGB = state->rt[i].rgb_dst_factor; - + unsigned eqA = state->rt[i].alpha_func; unsigned srcA = state->rt[i].alpha_src_factor; unsigned dstA = state->rt[i].alpha_dst_factor; @@ -324,20 +324,6 @@ static void *r600_create_blend_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_blend_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; - struct r600_pipe_state *rstate; - - if (state == NULL) - return; - rstate = &blend->rstate; - rctx->states[rstate->id] = rstate; - rctx->cb_target_mask = blend->cb_target_mask; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - static void *r600_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { @@ -448,7 +434,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_RASTERIZER; if (state->flatshade_first) prov_vtx = 0; - tmp = 0x00000001; + tmp = S_0286D4_FLAT_SHADE_ENA(1); if (state->sprite_coord_enable) { tmp |= S_0286D4_PNT_SPRITE_ENA(1) | S_0286D4_PNT_SPRITE_OVRD_X(2) | @@ -483,12 +469,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A04_PA_SU_POINT_MINMAX, 0x80000000, 0xFFFFFFFF, NULL); - tmp = (unsigned)(state->line_width * 8.0); + tmp = (unsigned)state->line_width * 8; r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A0C_PA_SC_LINE_STIPPLE, 0x00000005, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MPASS_PS_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL); + + r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, + S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); @@ -499,36 +490,6 @@ static void *r600_create_rs_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_rs_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - - if (state == NULL) - return; - - rctx->flatshade = rs->flatshade; - rctx->sprite_coord_enable = rs->sprite_coord_enable; - rctx->rasterizer = rs; - - rctx->states[rs->rstate.id] = &rs->rstate; - r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); -} - -static void r600_delete_rs_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; - - if (rctx->rasterizer == rs) { - rctx->rasterizer = NULL; - } - if (rctx->states[rs->rstate.id] == &rs->rstate) { - rctx->states[rs->rstate.id] = NULL; - } - free(rs); -} - static void *r600_create_sampler_state(struct pipe_context *ctx, const struct pipe_sampler_state *state) { @@ -565,16 +526,6 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, return rstate; } - -static void r600_sampler_view_destroy(struct pipe_context *ctx, - struct pipe_sampler_view *state) -{ - struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; - - pipe_resource_reference(&state->texture, NULL); - FREE(resource); -} - static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, struct pipe_resource *texture, const struct pipe_sampler_view *state) @@ -671,7 +622,7 @@ static void r600_set_vs_sampler_view(struct pipe_context *ctx, unsigned count, for (int i = 0; i < count; i++) { if (resource[i]) { - r600_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i + PIPE_MAX_ATTRIBS); + r600_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i); } } } @@ -705,17 +656,6 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count, rctx->ps_samplers.n_views = count; } -static void r600_bind_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (state == NULL) - return; - rctx->states[rstate->id] = rstate; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - static void r600_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -739,31 +679,6 @@ static void r600_bind_vs_sampler(struct pipe_context *ctx, unsigned count, void } } -static void r600_delete_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (rctx->states[rstate->id] == rstate) { - rctx->states[rstate->id] = NULL; - } - for (int i = 0; i < rstate->nregs; i++) { - r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL); - } - free(rstate); -} - -static void r600_delete_vertex_element(struct pipe_context *ctx, void *state) -{ - struct r600_vertex_element *v = (struct r600_vertex_element*)state; - - if (v == NULL) - return; - if (--v->refcount) - return; - free(v); -} - static void r600_set_clip_state(struct pipe_context *ctx, const struct pipe_clip_state *state) { @@ -777,16 +692,16 @@ static void r600_set_clip_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_CLIP; for (int i = 0; i < state->nr; i++) { r600_pipe_state_add_reg(rstate, - R_028E20_PA_CL_UCP0_X + i * 4, + R_028E20_PA_CL_UCP0_X + i * 16, fui(state->ucp[i][0]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_028E24_PA_CL_UCP0_Y + i * 4, + R_028E24_PA_CL_UCP0_Y + i * 16, fui(state->ucp[i][1]) , 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_028E28_PA_CL_UCP0_Z + i * 4, + R_028E28_PA_CL_UCP0_Z + i * 16, fui(state->ucp[i][2]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_028E2C_PA_CL_UCP0_W + i * 4, + R_028E2C_PA_CL_UCP0_W + i * 16, fui(state->ucp[i][3]), 0xFFFFFFFF, NULL); } r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, @@ -799,19 +714,6 @@ static void r600_set_clip_state(struct pipe_context *ctx, r600_context_pipe_state_set(&rctx->ctx, rstate); } -static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_vertex_element *v = (struct r600_vertex_element*)state; - - r600_delete_vertex_element(ctx, rctx->vertex_elements); - rctx->vertex_elements = v; - if (v) { - v->refcount++; -// rctx->vs_rebuild = TRUE; - } -} - static void r600_set_polygon_stipple(struct pipe_context *ctx, const struct pipe_poly_stipple *state) { @@ -950,7 +852,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta S_0280A0_ARRAY_MODE(rtex->array_mode[level]) | S_0280A0_BLEND_CLAMP(1) | S_0280A0_NUMBER_TYPE(ntype); - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) color_info |= S_0280A0_SOURCE_FORMAT(1); r600_pipe_state_add_reg(rstate, @@ -1031,7 +933,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_FRAMEBUFFER; util_copy_framebuffer_state(&rctx->framebuffer, state); - + rctx->pframebuffer = &rctx->framebuffer; /* build states */ @@ -1121,6 +1023,13 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer = (struct r600_resource*)buffer; + /* Note that the state tracker can unbind constant buffers by + * passing NULL here. + */ + if (buffer == NULL) { + return; + } + switch (shader) { case PIPE_SHADER_VERTEX: rctx->vs_const_buffer.nregs = 0; @@ -1150,59 +1059,6 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint } } -static void *r600_create_shader_state(struct pipe_context *ctx, - const struct pipe_shader_state *state) -{ - struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); - int r; - - r = r600_pipe_shader_create(ctx, shader, state->tokens); - if (r) { - return NULL; - } - return shader; -} - -static void r600_bind_ps_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - - /* TODO delete old shader */ - rctx->ps_shader = (struct r600_pipe_shader *)state; -} - -static void r600_bind_vs_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - - /* TODO delete old shader */ - rctx->vs_shader = (struct r600_pipe_shader *)state; -} - -static void r600_delete_ps_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; - - if (rctx->ps_shader == shader) { - rctx->ps_shader = NULL; - } - /* TODO proper delete */ - free(shader); -} - -static void r600_delete_vs_shader(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; - - if (rctx->vs_shader == shader) { - rctx->vs_shader = NULL; - } - /* TODO proper delete */ - free(shader); -} - void r600_init_state_functions(struct r600_pipe_context *rctx) { rctx->context.create_blend_state = r600_create_blend_state; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 722ce32263e..55bc5d0d22b 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -30,6 +30,105 @@ #include "r600_pipe.h" /* common state between evergreen and r600 */ +void r600_bind_blend_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; + struct r600_pipe_state *rstate; + + if (state == NULL) + return; + rstate = &blend->rstate; + rctx->states[rstate->id] = rstate; + rctx->cb_target_mask = blend->cb_target_mask; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + +void r600_bind_rs_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + + if (state == NULL) + return; + + rctx->flatshade = rs->flatshade; + rctx->sprite_coord_enable = rs->sprite_coord_enable; + rctx->rasterizer = rs; + + rctx->states[rs->rstate.id] = &rs->rstate; + r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); +} + +void r600_delete_rs_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; + + if (rctx->rasterizer == rs) { + rctx->rasterizer = NULL; + } + if (rctx->states[rs->rstate.id] == &rs->rstate) { + rctx->states[rs->rstate.id] = NULL; + } + free(rs); +} + +void r600_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *state) +{ + struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; + + pipe_resource_reference(&state->texture, NULL); + FREE(resource); +} + +void r600_bind_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; + + if (state == NULL) + return; + rctx->states[rstate->id] = rstate; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + +void r600_delete_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; + + if (rctx->states[rstate->id] == rstate) { + rctx->states[rstate->id] = NULL; + } + for (int i = 0; i < rstate->nregs; i++) { + r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL); + } + free(rstate); +} + +void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_vertex_element *v = (struct r600_vertex_element*)state; + + rctx->vertex_elements = v; + if (v) { +// rctx->vs_rebuild = TRUE; + } +} + +void r600_delete_vertex_element(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + + FREE(state); + + if (rctx->vertex_elements == state) + rctx->vertex_elements = NULL; +} + void r600_set_index_buffer(struct pipe_context *ctx, const struct pipe_index_buffer *ib) @@ -103,10 +202,10 @@ void *r600_create_vertex_elements(struct pipe_context *ctx, format = &v->hw_format[i]; switch (*format) { - FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); - FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); - FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); - FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); + FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); + FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); + FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); + FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); default:; } v->incompatible_layout = @@ -114,10 +213,63 @@ void *r600_create_vertex_elements(struct pipe_context *ctx, v->elements[i].src_format != v->hw_format[i] || v->elements[i].src_offset % 4 != 0; - v->hw_format_size[i] = - align(util_format_get_blocksize(v->hw_format[i]), 4); + v->hw_format_size[i] = align(util_format_get_blocksize(v->hw_format[i]), 4); } - v->refcount = 1; return v; } + +void *r600_create_shader_state(struct pipe_context *ctx, + const struct pipe_shader_state *state) +{ + struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); + int r; + + r = r600_pipe_shader_create(ctx, shader, state->tokens); + if (r) { + return NULL; + } + return shader; +} + +void r600_bind_ps_shader(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + + /* TODO delete old shader */ + rctx->ps_shader = (struct r600_pipe_shader *)state; +} + +void r600_bind_vs_shader(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + + /* TODO delete old shader */ + rctx->vs_shader = (struct r600_pipe_shader *)state; +} + +void r600_delete_ps_shader(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; + + if (rctx->ps_shader == shader) { + rctx->ps_shader = NULL; + } + + r600_pipe_shader_destroy(ctx, shader); + free(shader); +} + +void r600_delete_vs_shader(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; + + if (rctx->vs_shader == shader) { + rctx->vs_shader = NULL; + } + + r600_pipe_shader_destroy(ctx, shader); + free(shader); +} diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 1c1978f8abb..781612af570 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -282,6 +282,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) switch (format) { /* 8-bit buffers. */ case PIPE_FORMAT_A8_UNORM: + return V_0280A0_SWAP_ALT_REV; case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_R8_UNORM: @@ -472,7 +473,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); + //R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 4ebd5b754b3..8ecd434a43a 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -31,6 +31,7 @@ #include <util/u_inlines.h> #include <util/u_memory.h> #include "state_tracker/drm_driver.h" +#include "pipebuffer/pb_buffer.h" #include "r600_pipe.h" #include "r600_resource.h" #include "r600_state_inlines.h" @@ -39,8 +40,8 @@ extern struct u_resource_vtbl r600_texture_vtbl; -/* Copy from a tiled texture to a detiled one. */ -static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) +/* Copy from a full GPU texture to a transfer's staging one. */ +static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; @@ -48,15 +49,15 @@ static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_t subdst.face = 0; subdst.level = 0; - ctx->resource_copy_region(ctx, rtransfer->linear_texture, + ctx->resource_copy_region(ctx, rtransfer->staging_texture, subdst, 0, 0, 0, texture, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, transfer->box.width, transfer->box.height); } -/* Copy from a detiled texture to a tiled one. */ -static void r600_copy_into_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) +/* Copy from a transfer's staging texture to a full GPU one. */ +static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; @@ -66,7 +67,7 @@ static void r600_copy_into_tiled_texture(struct pipe_context *ctx, struct r600_t subsrc.level = 0; ctx->resource_copy_region(ctx, texture, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, - rtransfer->linear_texture, subsrc, + rtransfer->staging_texture, subsrc, 0, 0, 0, transfer->box.width, transfer->box.height); @@ -108,11 +109,11 @@ static unsigned r600_get_pixel_alignment(struct pipe_screen *screen, case V_038000_ARRAY_2D_TILED_THIN1: p_align = MAX2(rscreen->tiling_info->num_banks, (((rscreen->tiling_info->group_bytes / 8 / pixsize)) * - rscreen->tiling_info->num_banks)); + rscreen->tiling_info->num_banks)) * 8; break; - case 0: + case V_038000_ARRAY_LINEAR_GENERAL: default: - p_align = 64; + p_align = rscreen->tiling_info->group_bytes / pixsize; break; } return p_align; @@ -138,6 +139,29 @@ static unsigned r600_get_height_alignment(struct pipe_screen *screen, return h_align; } +static unsigned r600_get_base_alignment(struct pipe_screen *screen, + enum pipe_format format, + unsigned array_mode) +{ + struct r600_screen* rscreen = (struct r600_screen *)screen; + unsigned pixsize = util_format_get_blocksize(format); + int p_align = r600_get_pixel_alignment(screen, format, array_mode); + int h_align = r600_get_height_alignment(screen, array_mode); + int b_align; + + switch (array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + b_align = MAX2(rscreen->tiling_info->num_banks * rscreen->tiling_info->num_channels * 8 * 8 * pixsize, + p_align * pixsize * h_align); + break; + case V_038000_ARRAY_1D_TILED_THIN1: + default: + b_align = rscreen->tiling_info->group_bytes; + break; + } + return b_align; +} + static unsigned mip_minify(unsigned size, unsigned level) { unsigned val; @@ -151,11 +175,12 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen, struct r600_resource_texture *rtex, unsigned level) { + struct r600_screen* rscreen = (struct r600_screen *)screen; struct pipe_resource *ptex = &rtex->resource.base.b; struct radeon *radeon = (struct radeon *)screen->winsys; enum chip_class chipc = r600_get_family_class(radeon); unsigned width, stride, tile_width; - + if (rtex->pitch_override) return rtex->pitch_override; @@ -166,8 +191,7 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen, width = align(width, tile_width); } stride = util_format_get_stride(ptex->format, width); - if (chipc == EVERGREEN) - stride = align(stride, 512); + return stride; } @@ -252,6 +276,9 @@ static void r600_setup_miptree(struct pipe_screen *screen, } else size = layer_size * u_minify(ptex->depth0, i); + /* align base image and start of miptree */ + if ((i == 0) || (i == 1)) + offset = align(offset, r600_get_base_alignment(screen, ptex->format, array_mode)); rtex->offset[i] = offset; rtex->layer_size[i] = layer_size; rtex->pitch_in_bytes[i] = pitch; @@ -283,7 +310,6 @@ r600_texture_create_object(struct pipe_screen *screen, pipe_reference_init(&resource->base.b.reference, 1); resource->base.b.screen = screen; resource->bo = bo; - resource->domain = r600_domain_from_usage(resource->base.b.bind); rtex->pitch_override = pitch_in_bytes_override; if (array_mode) @@ -293,7 +319,10 @@ r600_texture_create_object(struct pipe_screen *screen, resource->size = rtex->size; if (!resource->bo) { - resource->bo = r600_bo(radeon, rtex->size, 4096, 0); + struct pipe_resource *ptex = &rtex->resource.base.b; + int base_align = r600_get_base_alignment(screen, ptex->format, array_mode); + + resource->bo = r600_bo(radeon, rtex->size, base_align, base->bind, base->usage); if (!resource->bo) { FREE(rtex); return NULL; @@ -306,8 +335,14 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ) { unsigned array_mode = 0; + static int force_tiling = -1; - if (debug_get_bool_option("R600_FORCE_TILING", FALSE)) { + /* Would like some magic "get_bool_option_once" routine. + */ + if (force_tiling == -1) + force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE); + + if (force_tiling) { if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && !(templ->bind & PIPE_BIND_SCANOUT)) { array_mode = V_038000_ARRAY_2D_TILED_THIN1; @@ -335,6 +370,18 @@ static void r600_texture_destroy(struct pipe_screen *screen, FREE(rtex); } +static boolean r600_texture_get_handle(struct pipe_screen* screen, + struct pipe_resource *ptex, + struct winsys_handle *whandle) +{ + struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; + struct r600_resource *resource = &rtex->resource; + struct radeon *radeon = (struct radeon *)screen->winsys; + + return r600_bo_get_winsys_handle(radeon, resource->bo, + rtex->pitch_in_bytes[0], whandle); +} + static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, struct pipe_resource *texture, unsigned face, unsigned level, @@ -434,10 +481,59 @@ int r600_texture_depth_flush(struct pipe_context *ctx, } out: + /* XXX: only do this if the depth texture has actually changed: + */ r600_blit_uncompress_depth_ptr(ctx, rtex); return 0; } +/* Needs adjustment for pixelformat: + */ +static INLINE unsigned u_box_volume( const struct pipe_box *box ) +{ + return box->width * box->depth * box->height; +}; + + +/* Figure out whether u_blitter will fallback to a transfer operation. + * If so, don't use a staging resource. + */ +static boolean permit_hardware_blit(struct pipe_screen *screen, + struct pipe_resource *res) +{ + unsigned bind; + + if (util_format_is_depth_or_stencil(res->format)) + bind = PIPE_BIND_DEPTH_STENCIL; + else + bind = PIPE_BIND_RENDER_TARGET; + + /* See r600_resource_copy_region: there is something wrong + * with depth resource copies at the moment so avoid them for + * now. + */ + if (util_format_get_component_bits(res->format, + UTIL_FORMAT_COLORSPACE_ZS, + 0) != 0) + return FALSE; + + if (!screen->is_format_supported(screen, + res->format, + res->target, + res->nr_samples, + bind, 0)) + return FALSE; + + if (!screen->is_format_supported(screen, + res->format, + res->target, + res->nr_samples, + PIPE_BIND_SAMPLER_VIEW, 0)) + return FALSE; + + return TRUE; +} + struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource *texture, struct pipe_subresource sr, @@ -448,6 +544,36 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource resource; struct r600_transfer *trans; int r; + boolean use_staging_texture = FALSE; + + /* We cannot map a tiled texture directly because the data is + * in a different order, therefore we do detiling using a blit. + * + * Also, use a temporary in GTT memory for read transfers, as + * the CPU is much happier reading out of cached system memory + * than uncached VRAM. + */ + if (rtex->tiled) + use_staging_texture = TRUE; + + if ((usage & PIPE_TRANSFER_READ) && + u_box_volume(box) > 1024) + use_staging_texture = TRUE; + + /* XXX: Use a staging texture for uploads if the underlying BO + * is busy. No interface for checking that currently? so do + * it eagerly whenever the transfer doesn't require a readback + * and might block. + */ + if ((usage & PIPE_TRANSFER_WRITE) && + !(usage & (PIPE_TRANSFER_READ | + PIPE_TRANSFER_DONTBLOCK | + PIPE_TRANSFER_UNSYNCHRONIZED))) + use_staging_texture = TRUE; + + if (!permit_hardware_blit(ctx->screen, texture) || + (texture->flags & R600_RESOURCE_FLAG_TRANSFER)) + use_staging_texture = FALSE; trans = CALLOC_STRUCT(r600_transfer); if (trans == NULL) @@ -457,6 +583,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.usage = usage; trans->transfer.box = *box; if (rtex->depth) { + /* XXX: only readback the rectangle which is being mapped? + */ + /* XXX: when discard is true, no need to read back from depth texture + */ r = r600_texture_depth_flush(ctx, texture); if (r < 0) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); @@ -464,7 +594,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, FREE(trans); return NULL; } - } else if (rtex->tiled) { + } else if (use_staging_texture) { resource.target = PIPE_TEXTURE_2D; resource.format = texture->format; resource.width0 = box->width; @@ -472,7 +602,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.depth0 = 1; resource.last_level = 0; resource.nr_samples = 0; - resource.usage = PIPE_USAGE_DYNAMIC; + resource.usage = PIPE_USAGE_STAGING; resource.bind = 0; resource.flags = R600_RESOURCE_FLAG_TRANSFER; /* For texture reading, the temporary (detiled) texture is used as @@ -486,8 +616,8 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.bind |= PIPE_BIND_SAMPLER_VIEW; } /* Create the temporary texture. */ - trans->linear_texture = ctx->screen->resource_create(ctx->screen, &resource); - if (trans->linear_texture == NULL) { + trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource); + if (trans->staging_texture == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); pipe_resource_reference(&trans->transfer.resource, NULL); FREE(trans); @@ -495,11 +625,9 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, } trans->transfer.stride = - ((struct r600_resource_texture *)trans->linear_texture)->pitch_in_bytes[0]; + ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0]; if (usage & PIPE_TRANSFER_READ) { - /* We cannot map a tiled texture directly because the data is - * in a different order, therefore we do detiling using a blit. */ - r600_copy_from_tiled_texture(ctx, trans); + r600_copy_to_staging_texture(ctx, trans); /* Always referenced in the blit. */ ctx->flush(ctx, 0, NULL); } @@ -516,11 +644,11 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; - if (rtransfer->linear_texture) { + if (rtransfer->staging_texture) { if (transfer->usage & PIPE_TRANSFER_WRITE) { - r600_copy_into_tiled_texture(ctx, rtransfer); + r600_copy_from_staging_texture(ctx, rtransfer); } - pipe_resource_reference(&rtransfer->linear_texture, NULL); + pipe_resource_reference(&rtransfer->staging_texture, NULL); } if (rtex->flushed_depth_texture) { pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); @@ -537,10 +665,11 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, enum pipe_format format = transfer->resource->format; struct radeon *radeon = (struct radeon *)ctx->screen->winsys; unsigned offset = 0; + unsigned usage = 0; char *map; - if (rtransfer->linear_texture) { - bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; + if (rtransfer->staging_texture) { + bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; @@ -553,7 +682,30 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, transfer->box.y / util_format_get_blockheight(format) * transfer->stride + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } - map = r600_bo_map(radeon, bo, 0, ctx); + + if (transfer->usage & PIPE_TRANSFER_WRITE) { + usage |= PB_USAGE_CPU_WRITE; + + if (transfer->usage & PIPE_TRANSFER_DISCARD) { + } + + if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) { + } + } + + if (transfer->usage & PIPE_TRANSFER_READ) { + usage |= PB_USAGE_CPU_READ; + } + + if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { + usage |= PB_USAGE_DONTBLOCK; + } + + if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) { + usage |= PB_USAGE_UNSYNCHRONIZED; + } + + map = r600_bo_map(radeon, bo, usage, ctx); if (!map) { return NULL; } @@ -568,8 +720,8 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct radeon *radeon = (struct radeon *)ctx->screen->winsys; struct r600_bo *bo; - if (rtransfer->linear_texture) { - bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; + if (rtransfer->staging_texture) { + bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; @@ -584,7 +736,7 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct u_resource_vtbl r600_texture_vtbl = { - u_default_resource_get_handle, /* get_handle */ + r600_texture_get_handle, /* get_handle */ r600_texture_destroy, /* resource_destroy */ r600_texture_is_referenced, /* is_resource_referenced */ r600_texture_get_transfer, /* get_transfer */ @@ -689,7 +841,7 @@ uint32_t r600_translate_texformat(enum pipe_format format, result = FMT_24_8; goto out_word4; case PIPE_FORMAT_S8_USCALED: - result = V_0280A0_COLOR_8; + result = FMT_8; word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); goto out_word4; default: @@ -718,7 +870,29 @@ uint32_t r600_translate_texformat(enum pipe_format format, /* S3TC formats. TODO */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { - goto out_unknown; + static int r600_enable_s3tc = -1; + + if (r600_enable_s3tc == -1) + r600_enable_s3tc = + debug_get_bool_option("R600_ENABLE_S3TC", FALSE); + + if (!r600_enable_s3tc) + goto out_unknown; + + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + result = FMT_BC1; + goto out_word4; + case PIPE_FORMAT_DXT3_RGBA: + result = FMT_BC2; + goto out_word4; + case PIPE_FORMAT_DXT5_RGBA: + result = FMT_BC3; + goto out_word4; + default: + goto out_unknown; + } } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index a3cb5b86004..ae19bfb8285 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -2100,6 +2100,10 @@ #define G_028C00_LAST_PIXEL(x) (((x) >> 10) & 0x1) #define C_028C00_LAST_PIXEL 0xFFFFFBFF #define R_028C04_PA_SC_AA_CONFIG 0x028C04 +#define R_028C08_PA_SU_VTX_CNTL 0x028C08 +#define S_028C08_PIX_CENTER_HALF(x) (((x) & 0x1) << 0) +#define G_028C08_PIX_CENTER_HALF(x) (((x) >> 0) & 0x1) +#define C_028C08_PIX_CENTER_HALF 0xFFFFFFFE #define R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX 0x028C1C #define R_028C48_PA_SC_AA_MASK 0x028C48 #define R_028810_PA_CL_CLIP_CNTL 0x028810 diff --git a/src/gallium/drivers/rbug/README b/src/gallium/drivers/rbug/README index b6d3a5cf351..9d7bd4e7695 100644 --- a/src/gallium/drivers/rbug/README +++ b/src/gallium/drivers/rbug/README @@ -7,24 +7,10 @@ This directory contains a Gallium3D remote debugger pipe driver. It provides remote debugging functionality. -= Build Instructions = - -To build, invoke scons on the top dir as - - scons dri=no statetrackers=mesa winsys=xlib - - = Usage = -To use do - - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib - -ensure the right libGL.so is being picked by doing - - ldd progs/trivial/tri +Do - export XMESA_TRACE=y GALLIUM_RBUG=true progs/trivial/tri which should open gallium remote debugging session. While the program is running diff --git a/src/gallium/drivers/rbug/SConscript b/src/gallium/drivers/rbug/SConscript index 3da6ac104a4..169c2718dc3 100644 --- a/src/gallium/drivers/rbug/SConscript +++ b/src/gallium/drivers/rbug/SConscript @@ -11,4 +11,6 @@ rbug = env.ConvenienceLibrary( 'rbug_screen.c', ]) +env.Alias('rbug', rbug) + Export('rbug') diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index d5f4d28aeff..ea10e8a9f98 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -37,4 +37,6 @@ softpipe = env.ConvenienceLibrary( 'sp_tile_cache.c', ]) +env.Alias('softpipe', softpipe) + Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index c8f5f89568a..89b2a91fc1f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -860,6 +860,7 @@ choose_depth_test(struct quad_stage *qs, /* look for special cases */ if (!alpha && !depth && + !occlusion && !stencil) { qs->run = depth_noop; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index a2bfa1bd8d5..5f171d314a3 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -64,7 +64,12 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return PIPE_MAX_SAMPLERS; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: +#ifdef HAVE_LLVM + /* Softpipe doesn't yet know how to tell draw/llvm about textures */ + return 0; +#else return PIPE_MAX_VERTEX_SAMPLERS; +#endif case PIPE_CAP_MAX_COMBINED_SAMPLERS: return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: @@ -209,13 +214,6 @@ softpipe_is_format_supported( struct pipe_screen *screen, if (format_desc->block.width != 1 || format_desc->block.height != 1) return FALSE; - - /* - * TODO: Unfortunately we cannot render into anything more than 32 bits - * because we encode color clear values into a 32bit word. - */ - if (format_desc->block.bits > 32) - return FALSE; } if (bind & PIPE_BIND_DEPTH_STENCIL) { diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 088e48f81fe..2eac4c7a82b 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -44,6 +44,9 @@ #include "sp_tex_tile_cache.h" +/** Set to one to help debug texture sampling */ +#define DEBUG_TEX 0 + /* * Return fractional part of 'f'. Used for computing interpolation weights. @@ -774,6 +777,18 @@ pot_level_size(unsigned base_pot, unsigned level) } +static void +print_sample(const char *function, float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + debug_printf("%s %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n", + function, + rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0], + rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1], + rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2], + rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]); +} + + /* Some image-filter fastpaths: */ static INLINE void @@ -832,6 +847,10 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, tx[2][c], tx[3][c]); } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -872,6 +891,10 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, rgba[c][j] = out[c]; } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -921,6 +944,10 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, rgba[c][j] = out[c]; } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -957,6 +984,10 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, rgba[c][j] = out[c]; } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -997,6 +1028,10 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, rgba[c][j] = out[c]; } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -1045,6 +1080,10 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, rgba[c][j] = out[c]; } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -1357,6 +1396,10 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, } } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -1402,13 +1445,9 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); } -#if 0 - printf("RGBA %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n", - rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0], - rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1], - rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2], - rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]); -#endif + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } @@ -1510,6 +1549,10 @@ mip_filter_linear_2d_linear_repeat_POT( } } } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 031c7c1ea5c..4151a47c323 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -86,7 +86,7 @@ struct softpipe_tile_cache struct softpipe_cached_tile *entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; float clear_color[4]; /**< for color bufs */ - uint clear_val; /**< for z+stencil, or packed color clear value */ + uint clear_val; /**< for z+stencil */ boolean depth_stencil; /**< Is the surface a depth/stencil format? */ struct softpipe_cached_tile *tile; /**< scratch tile for clears */ diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index b5fae94f783..af99c419010 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -231,6 +231,12 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en return svgascreen->use_ps30 ? 1 : 0; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + return svgascreen->use_ps30 ? 1 : 0; + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 0; } break; case PIPE_SHADER_VERTEX: @@ -263,6 +269,13 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en return svgascreen->use_vs30 ? 1 : 0; case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + return svgascreen->use_vs30 ? 1 : 0; + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + return 0; + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; default: break; } diff --git a/src/gallium/drivers/sw/SConscript b/src/gallium/drivers/sw/SConscript deleted file mode 100644 index e9ebf751ddd..00000000000 --- a/src/gallium/drivers/sw/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -####################################################################### -# SConscript for swrast convenience library -# -# This is a meta-driver which consists of any and all of the software -# rasterizers into a single driver. A software rasterizer is defined -# as any driver which takes an sw_winsys pointer as the only argument -# to create_screen. - -Import('*') - -env = env.Clone() - -# To avoid targets having to check extensively or add drivers on a whim, append -# all referenced extra drivers to the exported symbol. -extra = [] -if True: - env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') - env.Prepend(LIBS = [softpipe]) - extra.append(softpipe) - -if env['llvm']: - env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') - env.Prepend(LIBS = [llvmpipe]) - extra.append(llvmpipe) - -if 'cell' in env['drivers']: - env.Append(CPPDEFINES = 'GALLIUM_CELL') - env.Prepend(LIBS = [cell]) - extra.append(cell) - -sw = env.ConvenienceLibrary( - target = 'sw', - source = [ - 'sw.c', - ] - ) + extra -Export('sw') diff --git a/src/gallium/drivers/sw/sw.c b/src/gallium/drivers/sw/sw.c deleted file mode 100644 index 6b873ecc1b0..00000000000 --- a/src/gallium/drivers/sw/sw.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "pipe/p_compiler.h" -#include "util/u_debug.h" -#include "target-helpers/wrap_screen.h" -#include "sw_public.h" - - -/* Helper function to choose and instantiate one of the software rasterizers: - * cell, llvmpipe, softpipe. - */ - -#ifdef GALLIUM_SOFTPIPE -#include "softpipe/sp_public.h" -#endif - -#ifdef GALLIUM_LLVMPIPE -#include "llvmpipe/lp_public.h" -#endif - -#ifdef GALLIUM_CELL -#include "cell/ppu/cell_public.h" -#endif - -struct pipe_screen * -swrast_create_screen(struct sw_winsys *winsys) -{ - const char *default_driver; - const char *driver; - struct pipe_screen *screen = NULL; - -#if defined(GALLIUM_CELL) - default_driver = "cell"; -#elif defined(GALLIUM_LLVMPIPE) - default_driver = "llvmpipe"; -#elif defined(GALLIUM_SOFTPIPE) - default_driver = "softpipe"; -#else - default_driver = ""; -#endif - - driver = debug_get_option("GALLIUM_DRIVER", default_driver); - -#if defined(GALLIUM_CELL) - if (screen == NULL && strcmp(driver, "cell") == 0) - screen = cell_create_screen( winsys ); -#endif - -#if defined(GALLIUM_LLVMPIPE) - if (screen == NULL && strcmp(driver, "llvmpipe") == 0) - screen = llvmpipe_create_screen( winsys ); -#endif - -#if defined(GALLIUM_SOFTPIPE) - if (screen == NULL) - screen = softpipe_create_screen( winsys ); -#endif - - return screen; -} diff --git a/src/gallium/drivers/sw/sw_public.h b/src/gallium/drivers/sw/sw_public.h deleted file mode 100644 index 7085c5c85a0..00000000000 --- a/src/gallium/drivers/sw/sw_public.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SW_PUBLIC_H -#define SW_PUBLIC_H - -/* A convenience library, primarily to isolate the logic required to - * figure out which if any software rasterizers have been built and - * select between them. - */ -struct sw_winsys; - -struct pipe_screen * -swrast_create_screen(struct sw_winsys *winsys); - -#endif diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index cdcd8d2b4be..c210cba032a 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -7,23 +7,8 @@ This directory contains a Gallium3D trace debugger pipe driver. It can traces all incoming calls. -= Build Instructions = - -To build, invoke scons on the top dir as - - scons dri=no statetrackers=mesa winsys=xlib - - = Usage = -To use do - - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib - -ensure the right libGL.so is being picked by doing - - ldd progs/trivial/tri - == Tracing == For tracing then do @@ -40,6 +25,7 @@ For remote debugging see: src/gallium/drivers/rbug/README + = Integrating = You can integrate the trace pipe driver either inside the state tracker or the @@ -60,5 +46,5 @@ are automatically wrapped by trace_screen. -- -Jose Fonseca <[email protected]> +Jose Fonseca <[email protected]> Jakob Bornecrantz <[email protected]> diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 06b0c4863a4..1384fe33d72 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -12,4 +12,6 @@ trace = env.ConvenienceLibrary( 'tr_texture.c', ]) +env.Alias('trace', trace) + Export('trace') |