summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/failover/SConscript2
-rw-r--r--src/gallium/drivers/galahad/SConscript4
-rw-r--r--src/gallium/drivers/i915/SConscript6
-rw-r--r--src/gallium/drivers/i915/i915_reg.h2
-rw-r--r--src/gallium/drivers/i915/i915_resource.h6
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c9
-rw-r--r--src/gallium/drivers/i915/i915_screen.c17
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c8
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c5
-rw-r--r--src/gallium/drivers/i965/SConscript4
-rw-r--r--src/gallium/drivers/i965/brw_screen.c5
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile2
-rw-r--r--src/gallium/drivers/llvmpipe/README65
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_line.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c44
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_soa.py4
-rw-r--r--src/gallium/drivers/noop/Makefile (renamed from src/gallium/drivers/sw/Makefile)5
-rw-r--r--src/gallium/drivers/noop/SConscript15
-rw-r--r--src/gallium/drivers/noop/noop_pipe.c550
-rw-r--r--src/gallium/drivers/noop/noop_public.h30
-rw-r--r--src/gallium/drivers/noop/noop_state.c256
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_shader_state.c3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c17
-rw-r--r--src/gallium/drivers/r300/SConscript2
-rw-r--r--src/gallium/drivers/r300/r300_blit.c4
-rw-r--r--src/gallium/drivers/r300/r300_context.c21
-rw-r--r--src/gallium/drivers/r300/r300_context.h4
-rw-r--r--src/gallium/drivers/r300/r300_emit.c4
-rw-r--r--src/gallium/drivers/r300/r300_hyperz.c32
-rw-r--r--src/gallium/drivers/r300/r300_render.c98
-rw-r--r--src/gallium/drivers/r300/r300_screen.c84
-rw-r--r--src/gallium/drivers/r300/r300_state.c30
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c86
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c5
-rw-r--r--src/gallium/drivers/r600/SConscript4
-rw-r--r--src/gallium/drivers/r600/eg_asm.c9
-rw-r--r--src/gallium/drivers/r600/eg_state_inlines.h43
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c238
-rw-r--r--src/gallium/drivers/r600/evergreend.h6
-rw-r--r--src/gallium/drivers/r600/r600.h9
-rw-r--r--src/gallium/drivers/r600/r600_asm.c117
-rw-r--r--src/gallium/drivers/r600/r600_asm.h21
-rw-r--r--src/gallium/drivers/r600/r600_blit.c7
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c38
-rw-r--r--src/gallium/drivers/r600/r600_opcodes.h9
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c54
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h19
-rw-r--r--src/gallium/drivers/r600/r600_resource.h7
-rw-r--r--src/gallium/drivers/r600/r600_shader.c151
-rw-r--r--src/gallium/drivers/r600/r600_shader.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c190
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c166
-rw-r--r--src/gallium/drivers/r600/r600_state_inlines.h3
-rw-r--r--src/gallium/drivers/r600/r600_texture.c242
-rw-r--r--src/gallium/drivers/r600/r600d.h4
-rw-r--r--src/gallium/drivers/rbug/README16
-rw-r--r--src/gallium/drivers/rbug/SConscript2
-rw-r--r--src/gallium/drivers/softpipe/SConscript2
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c12
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c57
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h2
-rw-r--r--src/gallium/drivers/svga/svga_screen.c13
-rw-r--r--src/gallium/drivers/sw/SConscript38
-rw-r--r--src/gallium/drivers/sw/sw.c58
-rw-r--r--src/gallium/drivers/sw/sw_public.h13
-rw-r--r--src/gallium/drivers/trace/README18
-rw-r--r--src/gallium/drivers/trace/SConscript2
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')