summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/Makefile8
-rw-r--r--src/gallium/drivers/r300/SConscript2
-rw-r--r--src/gallium/drivers/r300/r300_blit.c130
-rw-r--r--src/gallium/drivers/r300/r300_blit.h (renamed from src/gallium/drivers/r300/r300_clear.h)22
-rw-r--r--src/gallium/drivers/r300/r300_clear.c38
-rw-r--r--src/gallium/drivers/r300/r300_context.c16
-rw-r--r--src/gallium/drivers/r300/r300_context.h20
-rw-r--r--src/gallium/drivers/r300/r300_cs.h16
-rw-r--r--src/gallium/drivers/r300/r300_emit.c164
-rw-r--r--src/gallium/drivers/r300/r300_fs.c102
-rw-r--r--src/gallium/drivers/r300/r300_fs.h32
-rw-r--r--src/gallium/drivers/r300/r300_reg.h6
-rw-r--r--src/gallium/drivers/r300/r300_render.c88
-rw-r--r--src/gallium/drivers/r300/r300_screen.c35
-rw-r--r--src/gallium/drivers/r300/r300_screen.h4
-rw-r--r--src/gallium/drivers/r300/r300_state.c108
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c60
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h75
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c19
-rw-r--r--src/gallium/drivers/r300/r300_texture.c13
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c9
-rw-r--r--src/gallium/drivers/r300/r300_vbo.c86
-rw-r--r--src/gallium/drivers/r300/r300_vbo.h36
-rw-r--r--src/gallium/drivers/r300/r300_vs.c31
-rw-r--r--src/gallium/drivers/r300/r300_vs.h4
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h70
26 files changed, 736 insertions, 458 deletions
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index d13bb7a36b..afddcb161f 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -4,8 +4,8 @@ include $(TOP)/configs/current
LIBNAME = r300
C_SOURCES = \
+ r300_blit.c \
r300_chipset.c \
- r300_clear.c \
r300_context.c \
r300_debug.c \
r300_emit.c \
@@ -17,13 +17,13 @@ C_SOURCES = \
r300_state.c \
r300_state_derived.c \
r300_state_invariant.c \
- r300_vbo.c \
r300_vs.c \
r300_texture.c \
r300_tgsi_to_rc.c
LIBRARY_INCLUDES = \
- -I$(TOP)/src/mesa/drivers/dri/r300/compiler
+ -I$(TOP)/src/mesa/drivers/dri/r300/compiler \
+ -I$(TOP)/src/gallium/winsys/drm/radeon/core
COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a
@@ -35,4 +35,4 @@ include ../../Makefile.template
.PHONY : $(COMPILER_ARCHIVE)
$(COMPILER_ARCHIVE):
- cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make
+ $(MAKE) -C $(TOP)/src/mesa/drivers/dri/r300/compiler
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 97989040d2..0d2de17be9 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -9,8 +9,8 @@ env.Append(CPPPATH = ['#/src/mesa/drivers/dri/r300/compiler', '#/include', '#/sr
r300 = env.ConvenienceLibrary(
target = 'r300',
source = [
+ 'r300_blit.c',
'r300_chipset.c',
- 'r300_clear.c',
'r300_context.c',
'r300_debug.c',
'r300_emit.c',
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
new file mode 100644
index 0000000000..ffe066d536
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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 "r300_blit.h"
+#include "r300_context.h"
+
+#include "util/u_rect.h"
+
+static void r300_blitter_save_states(struct r300_context* r300)
+{
+ util_blitter_save_blend(r300->blitter, r300->blend_state);
+ util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state);
+ util_blitter_save_rasterizer(r300->blitter, r300->rs_state);
+ util_blitter_save_fragment_shader(r300->blitter, r300->fs);
+ util_blitter_save_vertex_shader(r300->blitter, r300->vs);
+}
+
+/* Clear currently bound buffers. */
+void r300_clear(struct pipe_context* pipe,
+ unsigned buffers,
+ const float* rgba,
+ double depth,
+ unsigned stencil)
+{
+ /* XXX Implement fastfill.
+ *
+ * If fastfill is enabled, a few facts should be considered:
+ *
+ * 1) Zbuffer must be micro-tiled and whole microtiles must be
+ * written.
+ *
+ * 2) ZB_DEPTHCLEARVALUE is used to clear a zbuffer and Z Mask must be
+ * equal to 0.
+ *
+ * 3) RB3D_COLOR_CLEAR_VALUE is used to clear a colorbuffer and
+ * RB3D_COLOR_CHANNEL_MASK must be equal to 0.
+ *
+ * 4) ZB_CB_CLEAR can be used to make the ZB units help in clearing
+ * the colorbuffer. The color clear value is supplied through both
+ * RB3D_COLOR_CLEAR_VALUE and ZB_DEPTHCLEARVALUE, and the colorbuffer
+ * must be set in ZB_DEPTHOFFSET and ZB_DEPTHPITCH in addition to
+ * RB3D_COLOROFFSET and RB3D_COLORPITCH. It's obvious that the zbuffer
+ * will not be cleared and multiple render targets cannot be cleared
+ * this way either.
+ *
+ * 5) For 16-bit integer buffering, compression causes a hung with one or
+ * two samples and should not be used.
+ *
+ * 6) Fastfill must not be used if reading of compressed Z data is disabled
+ * and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE),
+ * i.e. it cannot be used to compress the zbuffer.
+ * (what the hell does that mean and how does it fit in clearing
+ * the buffers?)
+ *
+ * - Marek
+ */
+
+ struct r300_context* r300 = r300_context(pipe);
+
+ r300_blitter_save_states(r300);
+
+ util_blitter_clear(r300->blitter,
+ r300->framebuffer_state.width,
+ r300->framebuffer_state.height,
+ r300->framebuffer_state.nr_cbufs,
+ buffers, rgba, depth, stencil);
+}
+
+/* Copy a block of pixels from one surface to another. */
+void r300_surface_copy(struct pipe_context* pipe,
+ struct pipe_surface* dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface* src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
+{
+ struct r300_context* r300 = r300_context(pipe);
+
+ /* Yeah we have to save all those states to ensure this blitter operation
+ * is really transparent. The states will be restored by the blitter once
+ * copying is done. */
+ r300_blitter_save_states(r300);
+ util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+
+ util_blitter_save_fragment_sampler_states(
+ r300->blitter, r300->sampler_count, (void**)r300->sampler_states);
+
+ util_blitter_save_fragment_sampler_textures(
+ r300->blitter, r300->texture_count,
+ (struct pipe_texture**)r300->textures);
+
+ /* Do a copy */
+ util_blitter_copy(r300->blitter,
+ dst, dstx, dsty, src, srcx, srcy, width, height, TRUE);
+}
+
+/* Fill a region of a surface with a constant value. */
+void r300_surface_fill(struct pipe_context* pipe,
+ struct pipe_surface* dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value)
+{
+ struct r300_context* r300 = r300_context(pipe);
+
+ r300_blitter_save_states(r300);
+ util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+
+ util_blitter_fill(r300->blitter,
+ dst, dstx, dsty, width, height, value);
+}
diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_blit.h
index b8fcdf273c..029e4f98e7 100644
--- a/src/gallium/drivers/r300/r300_clear.h
+++ b/src/gallium/drivers/r300/r300_blit.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2008 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,10 +20,11 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#ifndef R300_CLEAR_H
-#define R300_CLEAR_H
+#ifndef R300_BLIT_H
+#define R300_BLIT_H
struct pipe_context;
+struct pipe_surface;
void r300_clear(struct pipe_context* pipe,
unsigned buffers,
@@ -31,4 +32,17 @@ void r300_clear(struct pipe_context* pipe,
double depth,
unsigned stencil);
-#endif /* R300_CLEAR_H */
+void r300_surface_copy(struct pipe_context* pipe,
+ struct pipe_surface* dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface* src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height);
+
+void r300_surface_fill(struct pipe_context* pipe,
+ struct pipe_surface* dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value);
+
+#endif /* R300_BLIT_H */
diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c
deleted file mode 100644
index 02d6d504fc..0000000000
--- a/src/gallium/drivers/r300/r300_clear.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
- *
- * 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 "r300_clear.h"
-#include "r300_context.h"
-
-#include "util/u_clear.h"
-
-/* Clears currently bound buffers. */
-void r300_clear(struct pipe_context* pipe,
- unsigned buffers,
- const float* rgba,
- double depth,
- unsigned stencil)
-{
- /* XXX we can and should do one clear if both color and zs are set */
- util_clear(pipe, &r300_context(pipe)->framebuffer_state,
- buffers, rgba, depth, stencil);
-}
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 769733b6dd..d5c2d63d39 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -28,7 +28,7 @@
#include "util/u_memory.h"
#include "util/u_simple_list.h"
-#include "r300_clear.h"
+#include "r300_blit.h"
#include "r300_context.h"
#include "r300_flush.h"
#include "r300_query.h"
@@ -36,6 +36,7 @@
#include "r300_screen.h"
#include "r300_state_derived.h"
#include "r300_state_invariant.h"
+#include "r300_texture.h"
#include "r300_winsys.h"
static enum pipe_error r300_clear_hash_table(void* key, void* value,
@@ -51,6 +52,8 @@ static void r300_destroy_context(struct pipe_context* context)
struct r300_context* r300 = r300_context(context);
struct r300_query* query, * temp;
+ util_blitter_destroy(r300->blitter);
+
util_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table,
NULL);
util_hash_table_destroy(r300->shader_hash_table);
@@ -105,7 +108,7 @@ static void r300_flush_cb(void *data)
}
struct pipe_context* r300_create_context(struct pipe_screen* screen,
- struct r300_winsys* r300_winsys)
+ struct radeon_winsys* radeon_winsys)
{
struct r300_context* r300 = CALLOC_STRUCT(r300_context);
struct r300_screen* r300screen = r300_screen(screen);
@@ -113,9 +116,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300)
return NULL;
- r300->winsys = r300_winsys;
+ r300->winsys = radeon_winsys;
- r300->context.winsys = (struct pipe_winsys*)r300_winsys;
+ r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
r300->context.screen = screen;
r300_init_debug(r300);
@@ -123,6 +126,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.destroy = r300_destroy_context;
r300->context.clear = r300_clear;
+ r300->context.surface_copy = r300_surface_copy;
+ r300->context.surface_fill = r300_surface_fill;
if (r300screen->caps->has_tcl) {
r300->context.draw_arrays = r300_draw_arrays;
@@ -174,5 +179,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
r300->dirty_state = R300_NEW_KITCHEN_SINK;
r300->dirty_hw++;
+
+ r300->blitter = util_blitter_create(&r300->context);
+
return &r300->context;
}
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 39c0914cff..232530b7dc 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -25,6 +25,8 @@
#include "draw/draw_vertex.h"
+#include "util/u_blitter.h"
+
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
@@ -89,6 +91,8 @@ struct r300_rs_block {
};
struct r300_sampler_state {
+ struct pipe_sampler_state state;
+
uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */
uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */
uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
@@ -98,9 +102,17 @@ struct r300_sampler_state {
unsigned min_lod, max_lod;
};
+struct r300_scissor_regs {
+ uint32_t top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */
+ uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+
+ /* Whether everything is culled by scissoring. */
+ boolean empty_area;
+};
+
struct r300_scissor_state {
- uint32_t scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */
- uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+ struct r300_scissor_regs framebuffer;
+ struct r300_scissor_regs scissor;
};
struct r300_texture_state {
@@ -237,9 +249,11 @@ struct r300_context {
struct pipe_context context;
/* The interface to the windowing system, etc. */
- struct r300_winsys* winsys;
+ struct radeon_winsys* winsys;
/* Draw module. Used mostly for SW TCL. */
struct draw_context* draw;
+ /* Accelerated blit support. */
+ struct blitter_context* blitter;
/* Vertex buffer for rendering. */
struct pipe_buffer* vbo;
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 86ba91db52..d142fee050 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -26,7 +26,8 @@
#include "util/u_math.h"
#include "r300_reg.h"
-#include "r300_winsys.h"
+
+#include "radeon_winsys.h"
/* Yes, I know macros are ugly. However, they are much prettier than the code
* that they neatly hide away, and don't have the cost of function setup,so
@@ -50,11 +51,11 @@
#define CS_LOCALS(context) \
struct r300_context* const cs_context_copy = (context); \
- struct r300_winsys* cs_winsys = cs_context_copy->winsys; \
+ struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \
int cs_count = 0;
#define CHECK_CS(size) \
- cs_winsys->check_cs(cs_winsys, (size))
+ assert(cs_winsys->check_cs(cs_winsys, (size)))
#define BEGIN_CS(size) do { \
CHECK_CS(size); \
@@ -114,6 +115,15 @@
cs_count -= 3; \
} while (0)
+#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
+ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \
+ "domains (%d, %d, %d)\n", \
+ bo, rd, wd, flags); \
+ assert(bo); \
+ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
+ cs_count -= 2; \
+} while (0)
+
#define END_CS do { \
if (VERY_VERBOSE_CS) { \
DBG(cs_context_copy, DBG_CS, "r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 98a39390bf..199ce3a945 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -22,6 +23,7 @@
/* r300_emit: Functions for emitting state. */
+#include "util/u_format.h"
#include "util/u_math.h"
#include "r300_context.h"
@@ -40,9 +42,16 @@ void r300_emit_blend_state(struct r300_context* r300,
CS_LOCALS(r300);
BEGIN_CS(8);
OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
- OUT_CS(blend->blend_control);
- OUT_CS(blend->alpha_blend_control);
- OUT_CS(blend->color_channel_mask);
+ if (r300->framebuffer_state.nr_cbufs) {
+ OUT_CS(blend->blend_control);
+ OUT_CS(blend->alpha_blend_control);
+ OUT_CS(blend->color_channel_mask);
+ } else {
+ OUT_CS(0);
+ OUT_CS(0);
+ OUT_CS(0);
+ /* XXX also disable fastfill here once it's supported */
+ }
OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither);
END_CS;
@@ -149,6 +158,13 @@ static const float * get_shader_constant(
vec[1] = 1.0 / tex->height0;
break;
+ /* Texture compare-fail value. */
+ /* XXX Since Gallium doesn't support GL_ARB_shadow_ambient,
+ * this is always (0,0,0,0). */
+ case RC_STATE_SHADOW_AMBIENT:
+ vec[3] = 0;
+ break;
+
default:
debug_printf("r300: Implementation error: "
"Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
@@ -276,7 +292,7 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
BEGIN_CS(13 +
((code->inst_end + 1) * 6));
- OUT_CS_REG(R500_US_CONFIG, 0);
+ OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
OUT_CS_REG(R500_US_CODE_RANGE,
R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end));
@@ -330,7 +346,13 @@ void r300_emit_fb_state(struct r300_context* r300,
int i;
CS_LOCALS(r300);
- BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);
+ /* Shouldn't fail unless there is a bug in the state tracker. */
+ assert(fb->nr_cbufs <= 4);
+
+ BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) +
+ (fb->zsbuf ? 10 : 0) + 6);
+
+ /* Flush and free renderbuffer caches. */
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
@@ -338,6 +360,10 @@ void r300_emit_fb_state(struct r300_context* r300,
R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
+ /* Set the number of colorbuffers. */
+ OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs));
+
+ /* Set up colorbuffers. */
for (i = 0; i < fb->nr_cbufs; i++) {
surf = fb->cbufs[i];
tex = (struct r300_texture*)surf->texture;
@@ -355,6 +381,12 @@ void r300_emit_fb_state(struct r300_context* r300,
r300_translate_out_fmt(surf->format));
}
+ /* Disable unused colorbuffers. */
+ for (; i < 4; i++) {
+ OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), R300_US_OUT_FMT_UNUSED);
+ }
+
+ /* Set up a zbuffer. */
if (fb->zsbuf) {
surf = fb->zsbuf;
tex = (struct r300_texture*)surf->texture;
@@ -382,8 +414,6 @@ static void r300_emit_query_start(struct r300_context *r300)
if (!query)
return;
- /* XXX This will almost certainly not return good results
- * for overlapping queries. */
BEGIN_CS(4);
if (caps->family == CHIP_FAMILY_RV530) {
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
@@ -565,18 +595,28 @@ void r300_emit_rs_block_state(struct r300_context* r300,
END_CS;
}
-void r300_emit_scissor_state(struct r300_context* r300,
- struct r300_scissor_state* scissor)
+static void r300_emit_scissor_regs(struct r300_context* r300,
+ struct r300_scissor_regs* scissor)
{
CS_LOCALS(r300);
BEGIN_CS(3);
OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
- OUT_CS(scissor->scissor_top_left);
- OUT_CS(scissor->scissor_bottom_right);
+ OUT_CS(scissor->top_left);
+ OUT_CS(scissor->bottom_right);
END_CS;
}
+void r300_emit_scissor_state(struct r300_context* r300,
+ struct r300_scissor_state* scissor)
+{
+ if (r300->rs_state->rs.scissor) {
+ r300_emit_scissor_regs(r300, &scissor->scissor);
+ } else {
+ r300_emit_scissor_regs(r300, &scissor->framebuffer);
+ }
+}
+
void r300_emit_texture(struct r300_context* r300,
struct r300_sampler_state* sampler,
struct r300_texture* tex,
@@ -615,50 +655,68 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
-/* XXX I can't read this and that's not good */
-void r300_emit_aos(struct r300_context* r300, unsigned offset)
+static boolean r300_validate_aos(struct r300_context *r300)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element;
- CS_LOCALS(r300);
int i;
- unsigned aos_count = r300->vertex_element_count;
+ /* Check if formats and strides are aligned to the size of DWORD. */
+ for (i = 0; i < r300->vertex_element_count; i++) {
+ if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
+ util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void r300_emit_aos(struct r300_context* r300, unsigned offset)
+{
+ struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_element *velem = r300->vertex_element;
+ int i;
+ unsigned size1, size2, aos_count = r300->vertex_element_count;
unsigned packet_size = (aos_count * 3 + 1) / 2;
+ CS_LOCALS(r300);
+
+ /* XXX Move this checking to a more approriate place. */
+ if (!r300_validate_aos(r300)) {
+ /* XXX We should fallback using Draw. */
+ assert(0);
+ }
+
BEGIN_CS(2 + packet_size + aos_count * 2);
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(aos_count);
+
for (i = 0; i < aos_count - 1; i += 2) {
- int buf_num1 = velem[i].vertex_buffer_index;
- int buf_num2 = velem[i+1].vertex_buffer_index;
- assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
- assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0);
- OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) |
- (pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22));
- OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset +
- offset * vbuf[buf_num1].stride);
- OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset +
- offset * vbuf[buf_num2].stride);
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ vb2 = &vbuf[velem[i+1].vertex_buffer_index];
+ size1 = util_format_get_blocksize(velem[i].src_format);
+ size2 = util_format_get_blocksize(velem[i+1].src_format);
+
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+ R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+ OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
}
+
if (aos_count & 1) {
- int buf_num = velem[i].vertex_buffer_index;
- assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
- OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6));
- OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset +
- offset * vbuf[buf_num].stride);
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ size1 = util_format_get_blocksize(velem[i].src_format);
+
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
}
- /* XXX bare CS reloc */
for (i = 0; i < aos_count; i++) {
- cs_winsys->write_cs_reloc(cs_winsys,
- vbuf[velem[i].vertex_buffer_index].buffer,
- RADEON_GEM_DOMAIN_GTT,
- 0,
- 0);
- cs_count -= 2;
+ OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
}
END_CS;
}
+
#if 0
void r300_emit_draw_packet(struct r300_context* r300)
{
@@ -833,10 +891,21 @@ void r300_emit_viewport_state(struct r300_context* r300,
void r300_emit_texture_count(struct r300_context* r300)
{
+ uint32_t tx_enable = 0;
+ int i;
CS_LOCALS(r300);
+ /* Notice that texture_count and sampler_count are just sizes
+ * of the respective arrays. We still have to check for the individual
+ * elements. */
+ for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) {
+ if (r300->textures[i]) {
+ tx_enable |= 1 << i;
+ }
+ }
+
BEGIN_CS(2);
- OUT_CS_REG(R300_TX_ENABLE, (1 << r300->texture_count) - 1);
+ OUT_CS_REG(R300_TX_ENABLE, tx_enable);
END_CS;
}
@@ -871,10 +940,17 @@ void r300_emit_dirty_state(struct r300_context* r300)
return;
}
+ /* Check size of CS. */
+ /* Make sure we have at least 8*1024 spare dwords. */
+ /* XXX It would be nice to know the number of dwords we really need to
+ * XXX emit. */
+ if (!r300->winsys->check_cs(r300->winsys, 8*1024)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ }
+
/* Clean out BOs. */
r300->winsys->reset_bos(r300->winsys);
- /* XXX check size */
validate:
/* Color buffers... */
for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
@@ -961,18 +1037,20 @@ validate:
if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
if (r300screen->caps->is_r500) {
- r500_emit_fragment_program_code(r300, &r300->fs->code);
+ r500_emit_fragment_program_code(r300, &r300->fs->shader->code);
} else {
- r300_emit_fragment_program_code(r300, &r300->fs->code);
+ r300_emit_fragment_program_code(r300, &r300->fs->shader->code);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
}
if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
if (r300screen->caps->is_r500) {
- r500_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+ r500_emit_fs_constant_buffer(r300,
+ &r300->fs->shader->code.constants);
} else {
- r300_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+ r300_emit_fs_constant_buffer(r300,
+ &r300->fs->shader->code.constants);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 79b01bb4dc..4e1b61ca40 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -22,6 +22,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
#include "tgsi/tgsi_dump.h"
#include "r300_context.h"
@@ -33,8 +36,8 @@
#include "radeon_compiler.h"
/* Convert info about FS input semantics to r300_shader_semantics. */
-static void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
- struct r300_shader_semantics* fs_inputs)
+void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
+ struct r300_shader_semantics* fs_inputs)
{
int i;
unsigned index;
@@ -66,7 +69,6 @@ static void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
}
}
-
static void find_output_registers(struct r300_fragment_program_compiler * compiler,
struct r300_fragment_shader * fs)
{
@@ -95,7 +97,7 @@ static void allocate_hardware_inputs(
void * mydata)
{
struct r300_shader_semantics* inputs =
- &((struct r300_fragment_shader*)c->UserData)->inputs;
+ (struct r300_shader_semantics*)c->UserData;
int i, reg = 0;
/* Allocate input registers. */
@@ -114,31 +116,45 @@ static void allocate_hardware_inputs(
}
}
-void r300_translate_fragment_shader(struct r300_context* r300,
- struct r300_fragment_shader* fs)
+static void get_compare_state(
+ struct r300_context* r300,
+ struct r300_fragment_program_external_state* state,
+ unsigned shadow_samplers)
+{
+ memset(state, 0, sizeof(*state));
+
+ for (int i = 0; i < r300->sampler_count; i++) {
+ struct r300_sampler_state* s = r300->sampler_states[i];
+
+ if (s && s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ /* XXX Gallium doesn't provide us with any information regarding
+ * this mode, so we are screwed. I'm setting 0 = LUMINANCE. */
+ state->unit[i].depth_texture_mode = 0;
+
+ /* Fortunately, no need to translate this. */
+ state->unit[i].texture_compare_func = s->state.compare_func;
+ }
+ }
+}
+
+static void r300_translate_fragment_shader(
+ struct r300_context* r300,
+ struct r300_fragment_shader_code* shader)
{
+ struct r300_fragment_shader* fs = r300->fs;
struct r300_fragment_program_compiler compiler;
struct tgsi_to_rc ttr;
- /* Initialize. */
- r300_shader_read_fs_inputs(&fs->info, &fs->inputs);
-
/* Setup the compiler. */
memset(&compiler, 0, sizeof(compiler));
rc_init(&compiler.Base);
compiler.Base.Debug = DBG_ON(r300, DBG_FP);
- compiler.code = &fs->code;
+ compiler.code = &shader->code;
+ compiler.state = shader->compare_state;
compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
compiler.AllocateHwInputs = &allocate_hardware_inputs;
- compiler.UserData = fs;
-
- /* XXX: Program compilation depends on texture compare modes,
- * which are sampler state. Therefore, programs need to be recompiled
- * depending on this state as in the classic Mesa driver.
- *
- * This is not yet handled correctly.
- */
+ compiler.UserData = &fs->inputs;
find_output_registers(&compiler, fs);
@@ -153,6 +169,8 @@ void r300_translate_fragment_shader(struct r300_context* r300,
r300_tgsi_to_rc(&ttr, fs->state.tokens);
+ fs->shadow_samplers = compiler.Base.Program.ShadowSamplers;
+
/* Invoke the compiler */
r3xx_compile_fragment_program(&compiler);
if (compiler.Base.Error) {
@@ -164,5 +182,51 @@ void r300_translate_fragment_shader(struct r300_context* r300,
/* And, finally... */
rc_destroy(&compiler.Base);
- fs->translated = TRUE;
+}
+
+boolean r300_pick_fragment_shader(struct r300_context* r300)
+{
+ struct r300_fragment_shader* fs = r300->fs;
+ struct r300_fragment_program_external_state state;
+ struct r300_fragment_shader_code* ptr;
+
+ if (!fs->first) {
+ /* Build the fragment shader for the first time. */
+ fs->first = fs->shader = CALLOC_STRUCT(r300_fragment_shader_code);
+
+ /* BTW shadow samplers will be known after the first translation,
+ * therefore we set ~0, which means it should look at all sampler
+ * states. This choice doesn't have any impact on the correctness. */
+ get_compare_state(r300, &fs->shader->compare_state, ~0);
+ r300_translate_fragment_shader(r300, fs->shader);
+ return TRUE;
+
+ } else if (fs->shadow_samplers) {
+ get_compare_state(r300, &state, fs->shadow_samplers);
+
+ /* Check if the currently-bound shader has been compiled
+ * with the texture-compare state we need. */
+ if (memcmp(&fs->shader->compare_state, &state, sizeof(state)) != 0) {
+ /* Search for the right shader. */
+ ptr = fs->first;
+ while (ptr) {
+ if (memcmp(&ptr->compare_state, &state, sizeof(state)) == 0) {
+ fs->shader = ptr;
+ return TRUE;
+ }
+ ptr = ptr->next;
+ }
+
+ /* Not found, gotta compile a new one. */
+ ptr = CALLOC_STRUCT(r300_fragment_shader_code);
+ ptr->next = fs->first;
+ fs->first = fs->shader = ptr;
+
+ ptr->compare_state = state;
+ r300_translate_fragment_shader(r300, ptr);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h
index 630e2d0c8a..40ce874353 100644
--- a/src/gallium/drivers/r300/r300_fs.h
+++ b/src/gallium/drivers/r300/r300_fs.h
@@ -30,6 +30,13 @@
#include "radeon_code.h"
#include "r300_shader_semantics.h"
+struct r300_fragment_shader_code {
+ struct r300_fragment_program_external_state compare_state;
+ struct rX00_fragment_program_code code;
+
+ struct r300_fragment_shader_code* next;
+};
+
struct r300_fragment_shader {
/* Parent class */
struct pipe_shader_state state;
@@ -37,21 +44,28 @@ struct r300_fragment_shader {
struct tgsi_shader_info info;
struct r300_shader_semantics inputs;
- /* Has this shader been translated yet? */
- boolean translated;
+ /* Bits 0-15: TRUE if it's a shadow sampler, FALSE otherwise. */
+ unsigned shadow_samplers;
- /* Compiled code */
- struct rX00_fragment_program_code code;
+ /* Currently-bound fragment shader. */
+ struct r300_fragment_shader_code* shader;
+
+ /* List of the same shaders compiled with different texture-compare
+ * states. */
+ struct r300_fragment_shader_code* first;
};
+void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
+ struct r300_shader_semantics* fs_inputs);
-void r300_translate_fragment_shader(struct r300_context* r300,
- struct r300_fragment_shader* fs);
+/* Return TRUE if the shader was switched and should be re-emitted. */
+boolean r300_pick_fragment_shader(struct r300_context* r300);
-static inline boolean r300_fragment_shader_writes_depth(struct r300_fragment_shader *fs)
+static INLINE boolean r300_fragment_shader_writes_depth(struct r300_fragment_shader *fs)
{
if (!fs)
- return FALSE;
- return (fs->code.writes_depth) ? TRUE : FALSE;
+ return FALSE;
+ return (fs->shader->code.writes_depth) ? TRUE : FALSE;
}
+
#endif /* R300_FS_H */
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 85b1ea568a..d8d08fbe26 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -2145,6 +2145,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Unpipelined. */
#define R300_RB3D_CCTL 0x4e00
+# define R300_RB3D_CCTL_NUM_MULTIWRITES(x) (MAX2(((x)-1), 0) << 5)
# define R300_RB3D_CCTL_NUM_MULTIWRITES_1_BUFFER (0 << 5)
# define R300_RB3D_CCTL_NUM_MULTIWRITES_2_BUFFERS (1 << 5)
# define R300_RB3D_CCTL_NUM_MULTIWRITES_3_BUFFERS (2 << 5)
@@ -3293,6 +3294,11 @@ enum {
*/
#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00
+# define R300_VBPNTR_SIZE0(x) ((x) >> 2)
+# define R300_VBPNTR_STRIDE0(x) (((x) >> 2) << 8)
+# define R300_VBPNTR_SIZE1(x) (((x) >> 2) << 16)
+# define R300_VBPNTR_STRIDE1(x) (((x) >> 2) << 24)
+
#define R300_PACKET3_INDX_BUFFER 0x00003300
# define R300_INDX_BUFFER_DST_SHIFT 0
# define R300_INDX_BUFFER_SKIP_SHIFT 16
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 4c5fb405c6..2d70ec2ac9 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -37,7 +37,6 @@
#include "r300_reg.h"
#include "r300_render.h"
#include "r300_state_derived.h"
-#include "r300_vbo.h"
/* r300_render: Vertex and index buffer primitive emission. */
#define R300_MAX_VBO_SIZE (1024 * 1024)
@@ -70,14 +69,67 @@ uint32_t r300_translate_primitive(unsigned prim)
}
}
+static boolean r300_nothing_to_draw(struct r300_context *r300)
+{
+ return r300->rs_state->rs.scissor &&
+ r300->scissor_state->scissor.empty_area;
+}
+
+static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
+ unsigned mode)
+{
+ uint32_t color_control = r300->rs_state->color_control;
+
+ /* By default (see r300_state.c:r300_create_rs_state) color_control is
+ * initialized to provoking the first vertex.
+ *
+ * Triangle fans must be reduced to the second vertex, not the first, in
+ * Gallium flatshade-first mode, as per the GL spec.
+ * (http://www.opengl.org/registry/specs/ARB/provoking_vertex.txt)
+ *
+ * Quads never provoke correctly in flatshade-first mode. The first
+ * vertex is never considered as provoking, so only the second, third,
+ * and fourth vertices can be selected, and both "third" and "last" modes
+ * select the fourth vertex. This is probably due to D3D lacking quads.
+ *
+ * Similarly, polygons reduce to the first, not the last, vertex, when in
+ * "last" mode, and all other modes start from the second vertex.
+ *
+ * ~ C.
+ */
+
+ if (r300->rs_state->rs.flatshade_first) {
+ switch (mode) {
+ case PIPE_PRIM_TRIANGLE_FAN:
+ color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND;
+ break;
+ case PIPE_PRIM_QUADS:
+ case PIPE_PRIM_QUAD_STRIP:
+ case PIPE_PRIM_POLYGON:
+ color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+ break;
+ default:
+ color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST;
+ break;
+ }
+ } else {
+ color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+ }
+
+ return color_control;
+}
+
static void r300_emit_draw_arrays(struct r300_context *r300,
unsigned mode,
unsigned count)
{
CS_LOCALS(r300);
- BEGIN_CS(4);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
+ BEGIN_CS(8);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, mode));
+ OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
+ OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300_translate_primitive(mode));
@@ -102,7 +154,10 @@ static void r300_emit_draw_elements(struct r300_context *r300,
assert((start * indexSize) % 4 == 0);
assert(offset_dwords == 0);
- BEGIN_CS(10);
+ BEGIN_CS(14);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, mode));
+ OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) {
@@ -177,13 +232,24 @@ boolean r300_draw_range_elements(struct pipe_context* pipe,
return FALSE;
}
+ if (r300_nothing_to_draw(r300)) {
+ return TRUE;
+ }
+
r300_update_derived_state(r300);
if (!r300_setup_vertex_buffers(r300)) {
return FALSE;
}
- setup_index_buffer(r300, indexBuffer, indexSize);
+ if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ return FALSE;
+ }
+
+ if (!r300->winsys->validate(r300->winsys)) {
+ return FALSE;
+ }
r300_emit_dirty_state(r300);
@@ -218,6 +284,10 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
return FALSE;
}
+ if (r300_nothing_to_draw(r300)) {
+ return TRUE;
+ }
+
r300_update_derived_state(r300);
if (!r300_setup_vertex_buffers(r300)) {
@@ -251,6 +321,10 @@ boolean r300_swtcl_draw_arrays(struct pipe_context* pipe,
return FALSE;
}
+ if (r300_nothing_to_draw(r300)) {
+ return TRUE;
+ }
+
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe->screen,
r300->vertex_buffer[i].buffer,
@@ -292,6 +366,10 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
return FALSE;
}
+ if (r300_nothing_to_draw(r300)) {
+ return TRUE;
+ }
+
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe->screen,
r300->vertex_buffer[i].buffer,
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 390b63007e..2a8667d483 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -21,13 +21,15 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_simple_screen.h"
#include "r300_context.h"
#include "r300_screen.h"
#include "r300_texture.h"
-#include "r300_winsys.h"
+
+#include "radeon_winsys.h"
/* Return the identifier behind whom the brave coders responsible for this
* amalgamation of code, sweat, and duct tape, routinely obscure their names.
@@ -140,6 +142,10 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
return 0;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
+ case PIPE_CAP_SM3:
+ return 1;
+ case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+ return 8;
default:
debug_printf("r300: Implementation error: Bad param %d\n",
param);
@@ -219,12 +225,18 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage,
/* Z buffer or texture */
case PIPE_FORMAT_Z16_UNORM:
+ retval = usage &
+ (PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
+ PIPE_TEXTURE_USAGE_SAMPLER);
+ break;
+
+ /* 24bit Z buffer can only be used as a texture on R500. */
case PIPE_FORMAT_Z24X8_UNORM:
/* Z buffer with stencil or texture */
case PIPE_FORMAT_Z24S8_UNORM:
retval = usage &
(PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
- PIPE_TEXTURE_USAGE_SAMPLER);
+ (is_r500 ? PIPE_TEXTURE_USAGE_SAMPLER : 0));
break;
/* Definitely unsupported formats. */
@@ -311,14 +323,10 @@ r300_get_tex_transfer(struct pipe_screen *screen,
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.format = texture->format;
trans->transfer.x = x;
trans->transfer.y = y;
trans->transfer.width = w;
trans->transfer.height = h;
- trans->transfer.block = texture->block;
- trans->transfer.nblocksx = texture->nblocksx[level];
- trans->transfer.nblocksy = texture->nblocksy[level];
trans->transfer.stride = r300_texture_get_stride(tex, level);
trans->transfer.usage = usage;
@@ -344,6 +352,7 @@ static void* r300_transfer_map(struct pipe_screen* screen,
{
struct r300_texture* tex = (struct r300_texture*)transfer->texture;
char* map;
+ enum pipe_format format = tex->tex.format;
map = pipe_buffer_map(screen, tex->buffer,
pipe_transfer_buffer_flags(transfer));
@@ -353,8 +362,8 @@ static void* r300_transfer_map(struct pipe_screen* screen,
}
return map + r300_transfer(transfer)->offset +
- transfer->y / transfer->block.height * transfer->stride +
- transfer->x / transfer->block.width * transfer->block.size;
+ transfer->y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
}
static void r300_transfer_unmap(struct pipe_screen* screen,
@@ -372,7 +381,7 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
FREE(r300screen);
}
-struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)
+struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
{
struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen);
struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities);
@@ -380,14 +389,14 @@ struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)
if (!r300screen || !caps)
return NULL;
- caps->pci_id = r300_winsys->pci_id;
- caps->num_frag_pipes = r300_winsys->gb_pipes;
- caps->num_z_pipes = r300_winsys->z_pipes;
+ caps->pci_id = radeon_winsys->pci_id;
+ caps->num_frag_pipes = radeon_winsys->gb_pipes;
+ caps->num_z_pipes = radeon_winsys->z_pipes;
r300_parse_chipset(caps);
r300screen->caps = caps;
- r300screen->screen.winsys = (struct pipe_winsys*)r300_winsys;
+ r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys;
r300screen->screen.destroy = r300_destroy_screen;
r300screen->screen.get_name = r300_get_name;
r300screen->screen.get_vendor = r300_get_vendor;
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 1ce5ff3904..2217988add 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -27,7 +27,7 @@
#include "r300_chipset.h"
-struct r300_winsys;
+struct radeon_winsys;
struct r300_screen {
/* Parent class */
@@ -58,6 +58,6 @@ r300_transfer(struct pipe_transfer* transfer)
}
/* Creates a new r300 screen. */
-struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys);
+struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
#endif /* R300_SCREEN_H */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 7505353953..8bcd6c5060 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -151,9 +151,10 @@ static void r300_set_blend_color(struct pipe_context* pipe,
const struct pipe_blend_color* color)
{
struct r300_context* r300 = r300_context(pipe);
+ union util_color uc;
- util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM,
- &r300->blend_color_state->blend_color);
+ util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+ r300->blend_color_state->blend_color = uc.ui;
/* XXX if FP16 blending is enabled, we should use the FP16 format */
r300->blend_color_state->blend_color_red_alpha =
@@ -289,11 +290,37 @@ static void r300_set_edgeflags(struct pipe_context* pipe,
/* XXX and even worse, I have no idea WTF the bitfield is */
}
+static void r300_set_scissor_regs(const struct pipe_scissor_state* state,
+ struct r300_scissor_regs *scissor,
+ boolean is_r500)
+{
+ if (is_r500) {
+ scissor->top_left =
+ (state->minx << R300_SCISSORS_X_SHIFT) |
+ (state->miny << R300_SCISSORS_Y_SHIFT);
+ scissor->bottom_right =
+ ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
+ ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
+ } else {
+ /* Offset of 1440 in non-R500 chipsets. */
+ scissor->top_left =
+ ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
+ ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
+ scissor->bottom_right =
+ (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+ (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
+ }
+
+ scissor->empty_area = state->minx >= state->maxx ||
+ state->miny >= state->maxy;
+}
+
static void
r300_set_framebuffer_state(struct pipe_context* pipe,
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_scissor_state scissor;
if (r300->draw) {
draw_flush(r300->draw);
@@ -301,7 +328,18 @@ static void
r300->framebuffer_state = *state;
+ scissor.minx = scissor.miny = 0;
+ scissor.maxx = state->width;
+ scissor.maxy = state->height;
+ r300_set_scissor_regs(&scissor, &r300->scissor_state->framebuffer,
+ r300_screen(r300->context.screen)->caps->is_r500);
+
+ /* Don't rely on the order of states being set for the first time. */
+ if (!r300->rs_state || !r300->rs_state->rs.scissor) {
+ r300->dirty_state |= R300_NEW_SCISSOR;
+ }
r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
+ r300->dirty_state |= R300_NEW_BLEND;
}
/* Create fragment shader state. */
@@ -317,6 +355,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
fs->state.tokens = tgsi_dup_tokens(shader->tokens);
tgsi_scan_shader(shader->tokens, &fs->info);
+ r300_shader_read_fs_inputs(&fs->info, &fs->inputs);
return (void*)fs;
}
@@ -330,11 +369,10 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
if (fs == NULL) {
r300->fs = NULL;
return;
- } else if (!fs->translated) {
- r300_translate_fragment_shader(r300, fs);
}
r300->fs = fs;
+ r300_pick_fragment_shader(r300);
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
@@ -343,7 +381,14 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
{
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
- rc_constants_destroy(&fs->code.constants);
+ struct r300_fragment_shader_code *tmp, *ptr = fs->first;
+
+ while (ptr) {
+ tmp = ptr;
+ ptr = ptr->next;
+ rc_constants_destroy(&tmp->code.constants);
+ FREE(tmp);
+ }
FREE((void*)fs->state.tokens);
FREE(shader);
}
@@ -382,8 +427,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
if (state->bypass_vs_clip_and_viewport ||
!r300_screen(pipe->screen)->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
- } else {
- rs->rs.bypass_vs_clip_and_viewport = TRUE;
}
rs->point_size = pack_float_16_6x(state->point_size) |
@@ -474,10 +517,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->color_control = R300_SHADE_MODEL_SMOOTH;
}
- if (!state->flatshade_first) {
- rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
- }
-
return (void*)rs;
}
@@ -513,6 +552,9 @@ static void*
struct r300_context* r300 = r300_context(pipe);
struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
int lod_bias;
+ union util_color uc;
+
+ sampler->state = *state;
sampler->filter0 |=
(r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
@@ -534,8 +576,8 @@ static void*
sampler->filter1 |= r300_anisotropy(state->max_anisotropy);
- util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
- &sampler->border_color);
+ util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+ sampler->border_color = uc.ui;
/* R500-specific fixups and optimizations */
if (r300_screen(r300->context.screen)->caps->is_r500) {
@@ -564,6 +606,20 @@ static void r300_bind_sampler_states(struct pipe_context* pipe,
}
r300->sampler_count = count;
+
+ /* Pick a fragment shader based on the texture compare state. */
+ if (r300->fs && (r300->dirty_state & R300_ANY_NEW_SAMPLERS)) {
+ if (r300_pick_fragment_shader(r300)) {
+ r300->dirty_state |= R300_NEW_FRAGMENT_SHADER |
+ R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ }
+ }
+}
+
+static void r300_lacks_vertex_textures(struct pipe_context* pipe,
+ unsigned count,
+ void** states)
+{
}
static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
@@ -584,8 +640,6 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
return;
}
- r300->context.flush(&r300->context, 0, NULL);
-
for (i = 0; i < count; i++) {
if (r300->textures[i] != (struct r300_texture*)texture[i]) {
pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
@@ -617,24 +671,13 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- r300->scissor_state->scissor_top_left =
- (state->minx << R300_SCISSORS_X_SHIFT) |
- (state->miny << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->scissor_bottom_right =
- ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
- ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
- } else {
- /* Offset of 1440 in non-R500 chipsets. */
- r300->scissor_state->scissor_top_left =
- ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
- ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->scissor_bottom_right =
- (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
- (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
- }
+ r300_set_scissor_regs(state, &r300->scissor_state->scissor,
+ r300_screen(r300->context.screen)->caps->is_r500);
- r300->dirty_state |= R300_NEW_SCISSOR;
+ /* Don't rely on the order of states being set for the first time. */
+ if (!r300->rs_state || r300->rs_state->rs.scissor) {
+ r300->dirty_state |= R300_NEW_SCISSOR;
+ }
}
static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -823,6 +866,7 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.create_sampler_state = r300_create_sampler_state;
r300->context.bind_fragment_sampler_states = r300_bind_sampler_states;
+ r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures;
r300->context.delete_sampler_state = r300_delete_sampler_state;
r300->context.set_fragment_sampler_textures = r300_set_sampler_textures;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index cd969d633b..29bc701a86 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -134,6 +134,16 @@ static void r300_vertex_psc(struct r300_context* r300)
uint16_t type, swizzle;
enum pipe_format format;
unsigned i;
+ int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+ int* stream_tab;
+
+ /* If TCL is bypassed, map vertex streams to equivalent VS output
+ * locations. */
+ if (r300->rs_state->enable_vte) {
+ stream_tab = identity;
+ } else {
+ stream_tab = r300->vs->stream_loc_notcl;
+ }
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
@@ -147,10 +157,10 @@ static void r300_vertex_psc(struct r300_context* r300)
format = r300->vertex_element[i].src_format;
type = r300_translate_vertex_data_type(format) |
- (i << R300_DST_VEC_LOC_SHIFT);
+ (stream_tab[i] << R300_DST_VEC_LOC_SHIFT);
swizzle = r300_translate_vertex_data_swizzle(format);
- if (i % 2) {
+ if (i & 1) {
vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
@@ -159,7 +169,6 @@ static void r300_vertex_psc(struct r300_context* r300)
}
}
-
assert(i <= 15);
/* Set the last vector in the PSC. */
@@ -178,7 +187,7 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300)
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
- int* vs_output_tab = r300->vs->output_stream_loc_swtcl;
+ int* vs_output_tab = r300->vs->stream_loc_notcl;
/* For each Draw attribute, route it to the fragment shader according
* to the vs_output_tab. */
@@ -462,6 +471,29 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
r300->dirty_state |= R300_NEW_RS_BLOCK;
}
+static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
+{
+ /* We are interested only in the cases when a new depth or stencil value
+ * can be written and changed. */
+
+ /* We might optionally check for [Z func: never] and inspect the stencil
+ * state in a similar fashion, but it's not terribly important. */
+ return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) ||
+ (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) ||
+ ((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) &&
+ (dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK));
+}
+
+static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa)
+{
+ /* We are interested only in the cases when alpha testing can kill
+ * a fragment. */
+ uint32_t af = dsa->alpha_function;
+
+ return (af & R300_FG_ALPHA_FUNC_ENABLE) &&
+ (af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS;
+}
+
static void r300_update_ztop(struct r300_context* r300)
{
r300->ztop_state.z_buffer_top = R300_ZTOP_ENABLE;
@@ -478,19 +510,25 @@ static void r300_update_ztop(struct r300_context* r300)
* The docs claim that for the first three cases, if no ZS writes happen,
* then ZTOP can be used.
*
+ * (3) will never apply since we do not support chroma-keyed operations.
+ * (4) will need to be re-examined (and this comment updated) if/when
+ * Hyper-Z becomes supported.
+ *
* Additionally, the following conditions require disabled ZTOP:
- * ~) Depth writes in fragment shader
- * ~) Outstanding occlusion queries
+ * 5) Depth writes in fragment shader
+ * 6) Outstanding occlusion queries
*
* ~C.
*/
- if (r300->dsa_state->alpha_function) {
- r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
- } else if (r300->fs->info.uses_kill) {
+
+ /* ZS writes */
+ if (r300_dsa_writes_depth_stencil(r300->dsa_state) &&
+ (r300_dsa_alpha_test_enabled(r300->dsa_state) || /* (1) */
+ r300->fs->info.uses_kill)) { /* (2) */
r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
- } else if (r300_fragment_shader_writes_depth(r300->fs)) {
+ } else if (r300_fragment_shader_writes_depth(r300->fs)) { /* (5) */
r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
- } else if (r300->query_current) {
+ } else if (r300->query_current) { /* (6) */
r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
}
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index e6c1cb54da..dbe42edd91 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -28,6 +28,8 @@
#include "pipe/p_format.h"
+#include "util/u_format.h"
+
#include "r300_reg.h"
/* Some maths. These should probably find their way to u_math, if needed. */
@@ -443,20 +445,22 @@ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
static INLINE unsigned pf_component_count(enum pipe_format format) {
unsigned count = 0;
- if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
- return count;
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
+ count++;
}
-
- if (pf_size_x(format)) {
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) {
+ count++;
+ }
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) {
count++;
}
- if (pf_size_y(format)) {
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) {
count++;
}
- if (pf_size_z(format)) {
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
count++;
}
- if (pf_size_w(format)) {
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
count++;
}
@@ -467,19 +471,23 @@ static INLINE unsigned pf_component_count(enum pipe_format format) {
static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) {
uint32_t result = 0;
+ const struct util_format_description *desc;
unsigned components = pf_component_count(format);
- if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
+ desc = util_format_description(format);
+
+ if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
+ desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) {
debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format),
__FUNCTION__, __LINE__);
assert(0);
}
- switch (pf_type(format)) {
+ switch (desc->channel[0].type) {
/* Half-floats, floats, doubles */
- case PIPE_FORMAT_TYPE_FLOAT:
- switch (pf_size_x(format)) {
- case 4:
+ case UTIL_FORMAT_TYPE_FLOAT:
+ switch (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
+ case 32:
result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
break;
default:
@@ -488,19 +496,15 @@ r300_translate_vertex_data_type(enum pipe_format format) {
assert(0);
}
break;
- /* Normalized unsigned ints */
- case PIPE_FORMAT_TYPE_UNORM:
- /* Normalized signed ints */
- case PIPE_FORMAT_TYPE_SNORM:
- /* Non-normalized unsigned ints */
- case PIPE_FORMAT_TYPE_USCALED:
- /* Non-normalized signed ints */
- case PIPE_FORMAT_TYPE_SSCALED:
- switch (pf_size_x(format)) {
- case 1:
+ /* Unsigned ints */
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ /* Signed ints */
+ case UTIL_FORMAT_TYPE_SIGNED:
+ switch (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
+ case 8:
result = R300_DATA_TYPE_BYTE;
break;
- case 2:
+ case 16:
if (components > 2) {
result = R300_DATA_TYPE_SHORT_4;
} else {
@@ -510,8 +514,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {
default:
debug_printf("r300: Bad format %s in %s:%d\n",
pf_name(format), __FUNCTION__, __LINE__);
- debug_printf("r300: pf_size_x(format) == %d\n",
- pf_size_x(format));
+ debug_printf("r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n",
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0));
assert(0);
}
break;
@@ -521,12 +525,11 @@ r300_translate_vertex_data_type(enum pipe_format format) {
assert(0);
}
- if (pf_type(format) == PIPE_FORMAT_TYPE_SSCALED) {
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
result |= R300_SIGNED;
- } else if (pf_type(format) == PIPE_FORMAT_TYPE_UNORM) {
+ }
+ if (desc->channel[0].normalized) {
result |= R300_NORMALIZE;
- } else if (pf_type(format) == PIPE_FORMAT_TYPE_SNORM) {
- result |= (R300_SIGNED | R300_NORMALIZE);
}
return result;
@@ -534,17 +537,21 @@ r300_translate_vertex_data_type(enum pipe_format format) {
static INLINE uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format) {
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
- if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
+ if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
+ desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) {
debug_printf("r300: Bad format %s in %s:%d\n",
pf_name(format), __FUNCTION__, __LINE__);
return 0;
}
- return ((pf_swizzle_x(format) << R300_SWIZZLE_SELECT_X_SHIFT) |
- (pf_swizzle_y(format) << R300_SWIZZLE_SELECT_Y_SHIFT) |
- (pf_swizzle_z(format) << R300_SWIZZLE_SELECT_Z_SHIFT) |
- (pf_swizzle_w(format) << R300_SWIZZLE_SELECT_W_SHIFT) |
+ return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
+ (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
+ (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
+ (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
(0xf << R300_WRITE_ENA_SHIFT));
}
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 46d1cb39b5..bcd4c030f9 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -43,7 +43,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
CS_LOCALS(r300);
- BEGIN_CS(24 + (caps->has_tcl ? 2: 0));
+ BEGIN_CS(20 + (caps->has_tcl ? 2: 0));
/*** Graphics Backend (GB) ***/
/* Various GB enables */
@@ -70,9 +70,6 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_REG(R300_US_W_FMT, 0x0);
/*** VAP ***/
- /* Max and min vertex index clamp. */
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0x0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, 0xffffff);
/* Sign/normalize control */
OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
/* TCL-only stuff */
@@ -84,15 +81,11 @@ void r300_emit_invariant_state(struct r300_context* r300)
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(56 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));
- /* Flush PVS. */
- OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
+ BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + (caps->is_r500 ? 4 : 0));
- OUT_CS_REG(R300_SE_VTE_CNTL, R300_VPORT_X_SCALE_ENA |
- R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
- R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
- R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT);
if (caps->has_tcl) {
+ /*Flushing PVS is required before the VAP_GB registers can be changed*/
+ OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
OUT_CS_32F(1.0);
OUT_CS_32F(1.0);
@@ -123,19 +116,15 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000);
OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C);
OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525);
- OUT_CS_REG(R300_RB3D_CCTL, 0x00000000);
OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000);
if (caps->is_r500) {
OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000);
OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFFFFFFFF);
}
- OUT_CS_REG(R300_ZB_FORMAT, 0x00000002);
- OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, 0x00000003);
OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000);
OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000);
OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000);
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
- OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F);
/* XXX */
OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 093a21ebe2..9a96206a4d 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -22,6 +22,7 @@
#include "pipe/p_screen.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -105,7 +106,7 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level)
return 0;
}
- return align(pf_get_stride(&tex->tex.block, u_minify(tex->tex.width0, level)), 32);
+ return align(util_format_get_stride(tex->tex.format, u_minify(tex->tex.width0, level)), 32);
}
static void r300_setup_miptree(struct r300_texture* tex)
@@ -115,11 +116,10 @@ static void r300_setup_miptree(struct r300_texture* tex)
int i;
for (i = 0; i <= base->last_level; i++) {
- base->nblocksx[i] = pf_get_nblocksx(&base->block, u_minify(base->width0, i));
- base->nblocksy[i] = pf_get_nblocksy(&base->block, u_minify(base->height0, i));
+ unsigned nblocksy = util_format_get_nblocksy(base->format, u_minify(base->height0, i));
stride = r300_texture_get_stride(tex, i);
- layer_size = stride * base->nblocksy[i];
+ layer_size = stride * nblocksy;
if (base->target == PIPE_TEXTURE_CUBE)
size = layer_size * 6;
@@ -129,7 +129,7 @@ static void r300_setup_miptree(struct r300_texture* tex)
tex->offset[i] = align(tex->size, 32);
tex->size = tex->offset[i] + size;
tex->layer_size[i] = layer_size;
- tex->pitch[i] = stride / base->block.size;
+ tex->pitch[i] = stride / util_format_get_blocksize(base->format);
debug_printf("r300: Texture miptree: Level %d "
"(%dx%dx%d px, pitch %d bytes)\n",
@@ -245,7 +245,7 @@ static struct pipe_texture*
tex->tex.screen = screen;
tex->stride_override = *stride;
- tex->pitch[0] = *stride / base->block.size;
+ tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
r300_setup_flags(tex);
r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500);
@@ -283,7 +283,6 @@ r300_video_surface_create(struct pipe_screen *screen,
template.width0 = util_next_power_of_two(width);
template.height0 = util_next_power_of_two(height);
template.depth0 = 1;
- pf_get_block(template.format, &template.block);
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER |
PIPE_TEXTURE_USAGE_RENDER_TARGET;
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index 9fb2de2403..096cdb20bb 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -212,7 +212,8 @@ static void transform_srcreg(
dst->Negate = src->Register.Negate ? RC_MASK_XYZW : 0;
}
-static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_texture src)
+static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_texture src,
+ uint32_t *shadowSamplers)
{
switch(src.Texture) {
case TGSI_TEXTURE_1D:
@@ -233,14 +234,17 @@ static void transform_texture(struct rc_instruction * dst, struct tgsi_instructi
case TGSI_TEXTURE_SHADOW1D:
dst->U.I.TexSrcTarget = RC_TEXTURE_1D;
dst->U.I.TexShadow = 1;
+ *shadowSamplers |= 1 << dst->U.I.TexSrcUnit;
break;
case TGSI_TEXTURE_SHADOW2D:
dst->U.I.TexSrcTarget = RC_TEXTURE_2D;
dst->U.I.TexShadow = 1;
+ *shadowSamplers |= 1 << dst->U.I.TexSrcUnit;
break;
case TGSI_TEXTURE_SHADOWRECT:
dst->U.I.TexSrcTarget = RC_TEXTURE_RECT;
dst->U.I.TexShadow = 1;
+ *shadowSamplers |= 1 << dst->U.I.TexSrcUnit;
break;
}
}
@@ -269,7 +273,8 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst
/* Texturing. */
if (src->Instruction.Texture)
- transform_texture(dst, src->Texture);
+ transform_texture(dst, src->Texture,
+ &ttr->compiler->Program.ShadowSamplers);
}
static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm)
diff --git a/src/gallium/drivers/r300/r300_vbo.c b/src/gallium/drivers/r300/r300_vbo.c
deleted file mode 100644
index 6ebaf715dc..0000000000
--- a/src/gallium/drivers/r300/r300_vbo.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2009 Maciej Cencora <m.cencora@gmail.com>
- *
- * 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.
- */
-
-/* r300_vbo: Various helpers for emitting vertex buffers. Needs cleanup,
- * refactoring, etc. */
-
-#include "r300_vbo.h"
-
-#include "pipe/p_format.h"
-
-#include "r300_cs.h"
-#include "r300_context.h"
-#include "r300_state_inlines.h"
-#include "r300_reg.h"
-#include "r300_winsys.h"
-
-static INLINE int get_buffer_offset(struct r300_context *r300,
- unsigned int buf_nr,
- unsigned int elem_offset)
-{
- return r300->vertex_buffer[buf_nr].buffer_offset + elem_offset;
-}
-#if 0
-/* XXX not called at all */
-static void setup_vertex_buffers(struct r300_context *r300)
-{
- struct pipe_vertex_element *vert_elem;
- int i;
-
- for (i = 0; i < r300->aos_count; i++)
- {
- vert_elem = &r300->vertex_element[i];
- /* XXX use translate module to convert the data */
- if (!format_is_supported(vert_elem->src_format,
- vert_elem->nr_components)) {
- assert(0);
- /*
- struct pipe_buffer *buf;
- const unsigned int max_index = r300->vertex_buffers[vert_elem->vertex_buffer_index].max_index;
- buf = pipe_buffer_create(r300->context.screen, 4, usage, vert_elem->nr_components * max_index * sizeof(float));
- */
- }
-
- if (get_buffer_offset(r300,
- vert_elem->vertex_buffer_index,
- vert_elem->src_offset) % 4) {
- /* XXX need to align buffer */
- assert(0);
- }
- }
-}
-#endif
-/* XXX these shouldn't be asserts since we can work around bad indexbufs */
-void setup_index_buffer(struct r300_context *r300,
- struct pipe_buffer* indexBuffer,
- unsigned indexSize)
-{
- if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
- RADEON_GEM_DOMAIN_GTT, 0)) {
- assert(0);
- }
-
- if (!r300->winsys->validate(r300->winsys)) {
- assert(0);
- }
-}
diff --git a/src/gallium/drivers/r300/r300_vbo.h b/src/gallium/drivers/r300/r300_vbo.h
deleted file mode 100644
index 7afa75899c..0000000000
--- a/src/gallium/drivers/r300/r300_vbo.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2009 Maciej Cencora <m.cencora@gmail.com>
- *
- * 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 R300_VBO_H
-#define R300_VBO_H
-
-struct r300_context;
-struct pipe_buffer;
-
-void setup_vertex_attributes(struct r300_context *r300);
-
-void setup_index_buffer(struct r300_context *r300,
- struct pipe_buffer* indexBuffer,
- unsigned indexSize);
-
-#endif
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 31248346bc..fa207c939c 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -143,35 +143,33 @@ static void r300_shader_vap_output_fmt(
assert(gen_count <= 8);
}
-/* Set VS output stream locations for SWTCL. */
-static void r300_stream_locations_swtcl(
+/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed
+ * or isn't present. */
+static void r300_stream_locations_notcl(
struct r300_shader_semantics* vs_outputs,
- int* output_stream_loc)
+ int* stream_loc)
{
int i, tabi = 0, gen_count;
- /* XXX Check whether the numbers (0, 1, 2+i, etc.) are correct.
- * These should go to VAP_PROG_STREAM_CNTL/DST_VEC_LOC. */
-
/* Position. */
- output_stream_loc[tabi++] = 0;
+ stream_loc[tabi++] = 0;
/* Point size. */
if (vs_outputs->psize != ATTR_UNUSED) {
- output_stream_loc[tabi++] = 1;
+ stream_loc[tabi++] = 1;
}
/* Colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED) {
- output_stream_loc[tabi++] = 2 + i;
+ stream_loc[tabi++] = 2 + i;
}
}
/* Back-face colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
- output_stream_loc[tabi++] = 4 + i;
+ stream_loc[tabi++] = 4 + i;
}
}
@@ -180,7 +178,7 @@ static void r300_stream_locations_swtcl(
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
assert(tabi < 16);
- output_stream_loc[tabi++] = 6 + gen_count;
+ stream_loc[tabi++] = 6 + gen_count;
gen_count++;
}
}
@@ -188,7 +186,7 @@ static void r300_stream_locations_swtcl(
/* Fog coordinates. */
if (vs_outputs->fog != ATTR_UNUSED) {
assert(tabi < 16);
- output_stream_loc[tabi++] = 6 + gen_count;
+ stream_loc[tabi++] = 6 + gen_count;
gen_count++;
}
@@ -196,7 +194,7 @@ static void r300_stream_locations_swtcl(
assert(gen_count <= 8);
for (; tabi < 16;) {
- output_stream_loc[tabi++] = -1;
+ stream_loc[tabi++] = -1;
}
}
@@ -254,10 +252,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
/* Initialize. */
r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt);
-
- if (!r300_screen(r300->context.screen)->caps->has_tcl) {
- r300_stream_locations_swtcl(&vs->outputs, vs->output_stream_loc_swtcl);
- }
+ r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
/* Setup the compiler */
rc_init(&compiler.Base);
@@ -283,7 +278,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
/* Invoke the compiler */
r3xx_compile_vertex_program(&compiler);
if (compiler.Base.Error) {
- /* XXX Fail gracefully */
+ /* XXX We should fallback using Draw. */
fprintf(stderr, "r300 VP: Compiler error\n");
abort();
}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 283dd5a9e8..67e9db5366 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -38,9 +38,11 @@ struct r300_vertex_shader {
struct tgsi_shader_info info;
struct r300_shader_semantics outputs;
- int output_stream_loc_swtcl[16];
uint hwfmt[4];
+ /* Stream locations for SWTCL or if TCL is bypassed. */
+ int stream_loc_notcl[16];
+
/* Has this shader been translated yet? */
boolean translated;
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 864a6146b2..1ae6de70fe 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -35,76 +35,10 @@ extern "C" {
#include "pipe/p_state.h"
#include "pipe/internal/p_winsys_screen.h"
-struct r300_winsys {
- /* Parent class */
- struct pipe_winsys base;
-
- /* Opaque Radeon-specific winsys object. */
- void* radeon_winsys;
-
- /* PCI ID */
- uint32_t pci_id;
-
- /* GB pipe count */
- uint32_t gb_pipes;
-
- /* Z pipe count (rv530 only) */
- uint32_t z_pipes;
-
- /* GART size. */
- uint32_t gart_size;
-
- /* VRAM size. */
- uint32_t vram_size;
-
- /* Add a pipe_buffer to the list of buffer objects to validate. */
- boolean (*add_buffer)(struct r300_winsys* winsys,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd);
-
- /* Revalidate all currently setup pipe_buffers.
- * Returns TRUE if a flush is required. */
- boolean (*validate)(struct r300_winsys* winsys);
-
- /* Check to see if there's room for commands. */
- boolean (*check_cs)(struct r300_winsys* winsys, int size);
-
- /* Start a command emit. */
- void (*begin_cs)(struct r300_winsys* winsys,
- int size,
- const char* file,
- const char* function,
- int line);
-
- /* Write a dword to the command buffer. */
- void (*write_cs_dword)(struct r300_winsys* winsys, uint32_t dword);
-
- /* Write a relocated dword to the command buffer. */
- void (*write_cs_reloc)(struct r300_winsys* winsys,
- struct pipe_buffer* bo,
- uint32_t rd,
- uint32_t wd,
- uint32_t flags);
-
- /* Finish a command emit. */
- void (*end_cs)(struct r300_winsys* winsys,
- const char* file,
- const char* function,
- int line);
-
- /* Flush the CS. */
- void (*flush_cs)(struct r300_winsys* winsys);
-
- /* winsys flush - callback from winsys when flush required */
- void (*set_flush_cb)(struct r300_winsys *winsys,
- void (*flush_cb)(void *), void *data);
-
- void (*reset_bos)(struct r300_winsys *winsys);
-};
+#include "radeon_winsys.h"
struct pipe_context* r300_create_context(struct pipe_screen* screen,
- struct r300_winsys* r300_winsys);
+ struct radeon_winsys* radeon_winsys);
boolean r300_get_texture_buffer(struct pipe_texture* texture,
struct pipe_buffer** buffer,