summaryrefslogtreecommitdiffstats
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/r300_blit.c308
-rw-r--r--src/gallium/drivers/r300/r300_cb.h54
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c2
-rw-r--r--src/gallium/drivers/r300/r300_chipset.h13
-rw-r--r--src/gallium/drivers/r300/r300_context.c136
-rw-r--r--src/gallium/drivers/r300/r300_context.h150
-rw-r--r--src/gallium/drivers/r300/r300_cs.h51
-rw-r--r--src/gallium/drivers/r300/r300_debug.c3
-rw-r--r--src/gallium/drivers/r300/r300_emit.c293
-rw-r--r--src/gallium/drivers/r300/r300_flush.c49
-rw-r--r--src/gallium/drivers/r300/r300_fs.c126
-rw-r--r--src/gallium/drivers/r300/r300_hyperz.c128
-rw-r--r--src/gallium/drivers/r300/r300_hyperz.h2
-rw-r--r--src/gallium/drivers/r300/r300_query.c23
-rw-r--r--src/gallium/drivers/r300/r300_reg.h9
-rw-r--r--src/gallium/drivers/r300/r300_render.c444
-rw-r--r--src/gallium/drivers/r300/r300_render_translate.c237
-rw-r--r--src/gallium/drivers/r300/r300_resource.c20
-rw-r--r--src/gallium/drivers/r300/r300_screen.c49
-rw-r--r--src/gallium/drivers/r300/r300_screen.h4
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c180
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h37
-rw-r--r--src/gallium/drivers/r300/r300_state.c306
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c130
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h22
-rw-r--r--src/gallium/drivers/r300/r300_texture.c229
-rw-r--r--src/gallium/drivers/r300/r300_texture.h13
-rw-r--r--src/gallium/drivers/r300/r300_texture_desc.c343
-rw-r--r--src/gallium/drivers/r300/r300_texture_desc.h14
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c9
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.h3
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c61
-rw-r--r--src/gallium/drivers/r300/r300_vs.c7
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h110
34 files changed, 1625 insertions, 1940 deletions
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index a43e83c0d36..4f86db39926 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -55,11 +55,12 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o
util_blitter_save_viewport(r300->blitter, &r300->viewport);
util_blitter_save_clip(r300->blitter, (struct pipe_clip_state*)r300->clip_state.state);
util_blitter_save_vertex_elements(r300->blitter, r300->velems);
- util_blitter_save_vertex_buffers(r300->blitter, r300->vertex_buffer_count,
- r300->vertex_buffer);
+ util_blitter_save_vertex_buffers(r300->blitter, r300->vbuf_mgr->nr_vertex_buffers,
+ r300->vbuf_mgr->vertex_buffer);
- if (op & (R300_CLEAR_SURFACE | R300_COPY))
+ if (op & (R300_CLEAR_SURFACE | R300_COPY)) {
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
+ }
if (op & R300_COPY) {
struct r300_textures_state* state =
@@ -108,6 +109,14 @@ static boolean r300_cbzb_clear_allowed(struct r300_context *r300,
return r300_surface(fb->cbufs[0])->cbzb_allowed;
}
+static boolean r300_fast_zclear_allowed(struct r300_context *r300)
+{
+ struct pipe_framebuffer_state *fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
+
+ return r300_resource(fb->zsbuf->texture)->tex.zmask_dwords[fb->zsbuf->u.tex.level];
+}
+
static uint32_t r300_depth_clear_value(enum pipe_format format,
double depth, unsigned stencil)
{
@@ -132,37 +141,46 @@ static void r300_clear(struct pipe_context* pipe,
double depth,
unsigned stencil)
{
- /* My notes about fastfill:
+ /* My notes about Zbuffer compression:
*
- * 1) Only the zbuffer is cleared.
+ * 1) The zbuffer must be micro-tiled and whole microtiles must be
+ * written if compression is enabled. If microtiling is disabled,
+ * it locks up.
*
- * 2) The zbuffer must be micro-tiled and whole microtiles must be
- * written. If microtiling is disabled, it locks up.
+ * 2) There is ZMASK RAM which contains a compressed zbuffer.
+ * Each dword of the Z Mask contains compression information
+ * for 16 4x4 pixel tiles, that is 2 bits for each tile.
+ * On chips with 2 Z pipes, every other dword maps to a different
+ * pipe. On newer chipsets, there is a new compression mode
+ * with 8x8 pixel tiles per 2 bits.
*
- * 3) There is Z Mask RAM which contains a compressed zbuffer and
- * it interacts with fastfill. We should figure out how to use it
- * to get more performance.
- * This is what we know about the Z Mask:
+ * 3) The FASTFILL bit has nothing to do with filling. It only tells hw
+ * it should look in the ZMASK RAM first before fetching from a real
+ * zbuffer.
*
- * Each dword of the Z Mask contains compression information
- * for 16 4x4 pixel blocks, that is 2 bits for each block.
- * On chips with 2 Z pipes, every other dword maps to a different
- * pipe.
+ * 4) If a pixel is in a cleared state, ZB_DEPTHCLEARVALUE is returned
+ * during zbuffer reads instead of the value that is actually stored
+ * in the zbuffer memory. A pixel is in a cleared state when its ZMASK
+ * is equal to 0. Therefore, if you clear ZMASK with zeros, you may
+ * leave the zbuffer memory uninitialized, but then you must enable
+ * compression, so that the ZMASK RAM is actually used.
*
- * 4) ZB_DEPTHCLEARVALUE is used to clear the zbuffer and the Z Mask must
- * be equal to 0. (clear the Z Mask RAM with zeros)
+ * 5) Each 4x4 (or 8x8) tile is automatically decompressed and recompressed
+ * during zbuffer updates. A special decompressing operation should be
+ * used to fully decompress a zbuffer, which basically just stores all
+ * compressed tiles in ZMASK to the zbuffer memory.
*
- * 5) For 16-bit zbuffer, compression causes a hung with one or
+ * 6) For a 16-bit zbuffer, compression causes a hung with one or
* two samples and should not be used.
*
- * 6) FORCE_COMPRESSED_STENCIL_VALUE should be enabled for stencil clears
+ * 7) FORCE_COMPRESSED_STENCIL_VALUE should be enabled for stencil clears
* to avoid needless decompression.
*
- * 7) Fastfill must not be used if reading of compressed Z data is disabled
+ * 8) 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.
*
- * 8) ZB_CB_CLEAR does not interact with fastfill in any way.
+ * 9) ZB_CB_CLEAR does not interact with zbuffer compression in any way.
*
* - Marek
*/
@@ -172,32 +190,30 @@ static void r300_clear(struct pipe_context* pipe,
(struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_hyperz_state *hyperz =
(struct r300_hyperz_state*)r300->hyperz_state.state;
- struct r300_texture *zstex =
- fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL;
+ struct r300_resource *zstex =
+ fb->zsbuf ? r300_resource(fb->zsbuf->texture) : NULL;
uint32_t width = fb->width;
uint32_t height = fb->height;
boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
uint32_t hyperz_dcv = hyperz->zb_depthclearvalue;
- /* Decompress zbuffers that are bound as textures. If we didn't flush here,
- * it would happen inside the blitter when updating derived state,
- * causing a blitter operation to be called from inside the blitter,
- * which would overwrite saved states and they would never get restored. */
- r300_flush_depth_textures(r300);
-
/* Enable fast Z clear.
* The zbuffer must be in micro-tiled mode, otherwise it locks up. */
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) {
hyperz_dcv = hyperz->zb_depthclearvalue =
r300_depth_clear_value(fb->zsbuf->format, depth, stencil);
- r300_mark_fb_state_dirty(r300, R300_CHANGED_ZCLEAR_FLAG);
- if (zstex->zmask_mem[fb->zsbuf->u.tex.level]) {
+ if (r300_fast_zclear_allowed(r300)) {
r300_mark_atom_dirty(r300, &r300->zmask_clear);
buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
}
+
if (zstex->hiz_mem[fb->zsbuf->u.tex.level])
r300_mark_atom_dirty(r300, &r300->hiz_clear);
+
+ /* XXX Change this to r300_mark_atom_dirty(r300, &r300->hyperz_state);
+ * once hiz offset is constant. */
+ r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG);
}
/* Enable CBZB clear. */
@@ -211,7 +227,7 @@ static void r300_clear(struct pipe_context* pipe,
height = surf->cbzb_height;
r300->cbzb_clear = TRUE;
- r300_mark_fb_state_dirty(r300, R300_CHANGED_CBZB_FLAG);
+ r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG);
}
/* Clear. */
@@ -225,7 +241,7 @@ static void r300_clear(struct pipe_context* pipe,
buffers, rgba, depth, stencil);
r300_blitter_end(r300);
} else if (r300->zmask_clear.dirty) {
- /* Just clear zmask and hiz now, this does not use a standard draw
+ /* Just clear zmask and hiz now, this does not use the standard draw
* procedure. */
unsigned dwords;
@@ -257,16 +273,15 @@ static void r300_clear(struct pipe_context* pipe,
if (r300->cbzb_clear) {
r300->cbzb_clear = FALSE;
hyperz->zb_depthclearvalue = hyperz_dcv;
- r300_mark_fb_state_dirty(r300, R300_CHANGED_CBZB_FLAG);
+ r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG);
}
/* Enable fastfill and/or hiz.
*
* If we cleared zmask/hiz, it's in use now. The Hyper-Z state update
* looks if zmask/hiz is in use and enables fastfill accordingly. */
- if (zstex &&
- (zstex->zmask_in_use[fb->zsbuf->u.tex.level] ||
- zstex->hiz_in_use[fb->zsbuf->u.tex.level])) {
+ if (r300->zmask_in_use ||
+ (zstex && zstex->hiz_in_use[fb->zsbuf->u.tex.level])) {
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}
@@ -280,16 +295,16 @@ static void r300_clear_render_target(struct pipe_context *pipe,
{
struct r300_context *r300 = r300_context(pipe);
- /* Decompress zbuffers that are bound as textures. If we didn't flush here,
- * it would happen inside the blitter when updating derived state,
- * causing a blitter operation to be called from inside the blitter,
- * which would overwrite saved states and they would never get restored. */
- r300_flush_depth_textures(r300);
+ r300->zmask_locked = TRUE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
r300_blitter_begin(r300, R300_CLEAR_SURFACE);
util_blitter_clear_render_target(r300->blitter, dst, rgba,
dstx, dsty, width, height);
r300_blitter_end(r300);
+
+ r300->zmask_locked = FALSE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
/* Clear a region of a depth stencil surface. */
@@ -302,83 +317,70 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe,
unsigned width, unsigned height)
{
struct r300_context *r300 = r300_context(pipe);
+ struct pipe_framebuffer_state *fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
- /* Decompress zbuffers that are bound as textures. If we didn't flush here,
- * it would happen inside the blitter when updating derived state,
- * causing a blitter operation to be called from inside the blitter,
- * which would overwrite saved states and they would never get restored. */
- r300_flush_depth_textures(r300);
+ if (r300->zmask_in_use && !r300->zmask_locked) {
+ if (fb->zsbuf->texture == dst->texture) {
+ r300_decompress_zmask(r300);
+ } else {
+ r300->zmask_locked = TRUE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
+ }
+ }
r300_blitter_begin(r300, R300_CLEAR_SURFACE);
util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil,
dstx, dsty, width, height);
r300_blitter_end(r300);
+
+ if (r300->zmask_locked) {
+ r300->zmask_locked = FALSE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
+ }
}
-/* Flush a depth stencil buffer. */
-static void r300_flush_depth_stencil(struct pipe_context *pipe,
- struct pipe_resource *dst,
- unsigned level,
- unsigned layer)
+void r300_decompress_zmask(struct r300_context *r300)
{
- struct r300_context *r300 = r300_context(pipe);
- struct pipe_surface *dstsurf, surf_tmpl;
- struct r300_texture *tex = r300_texture(dst);
+ struct pipe_framebuffer_state *fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
- if (!tex->zmask_mem[level])
- return;
- if (!tex->zmask_in_use[level])
+ if (!r300->zmask_in_use || r300->zmask_locked)
return;
- surf_tmpl.format = dst->format;
- surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL;
- surf_tmpl.u.tex.level = level;
- surf_tmpl.u.tex.first_layer = layer;
- surf_tmpl.u.tex.last_layer = layer;
- dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
+ r300->zmask_decompress = TRUE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
- r300->z_decomp_rd = TRUE;
-
- r300_blitter_begin(r300, R300_CLEAR_SURFACE);
- util_blitter_flush_depth_stencil(r300->blitter, dstsurf);
+ r300_blitter_begin(r300, R300_CLEAR);
+ util_blitter_clear_depth_custom(r300->blitter, fb->width, fb->height, 0,
+ r300->dsa_decompress_zmask);
r300_blitter_end(r300);
- r300->z_decomp_rd = FALSE;
- tex->zmask_in_use[level] = FALSE;
- pipe_surface_reference(&dstsurf, NULL);
+ r300->zmask_decompress = FALSE;
+ r300->zmask_in_use = FALSE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
-/* We can't use compressed zbuffers as samplers. */
-void r300_flush_depth_textures(struct r300_context *r300)
+void r300_decompress_zmask_locked_unsafe(struct r300_context *r300)
{
- struct r300_textures_state *state =
- (struct r300_textures_state*)r300->textures_state.state;
- unsigned i, level;
- unsigned count = MIN2(state->sampler_view_count,
- state->sampler_state_count);
-
- if (r300->z_decomp_rd)
- return;
-
- for (i = 0; i < count; i++)
- if (state->sampler_views[i] && state->sampler_states[i]) {
- struct pipe_resource *tex = state->sampler_views[i]->base.texture;
-
- if (tex->target == PIPE_TEXTURE_3D ||
- tex->target == PIPE_TEXTURE_CUBE)
- continue;
+ struct pipe_framebuffer_state fb = {0};
+ fb.width = r300->locked_zbuffer->width;
+ fb.height = r300->locked_zbuffer->height;
+ fb.nr_cbufs = 0;
+ fb.zsbuf = r300->locked_zbuffer;
+
+ r300->context.set_framebuffer_state(&r300->context, &fb);
+ r300_decompress_zmask(r300);
+}
- /* Ignore non-depth textures.
- * Also ignore reinterpreted depth textures, e.g. resource_copy. */
- if (!util_format_is_depth_or_stencil(tex->format))
- continue;
+void r300_decompress_zmask_locked(struct r300_context *r300)
+{
+ struct pipe_framebuffer_state saved_fb = {0};
- for (level = 0; level <= tex->last_level; level++)
- if (r300_texture(tex)->zmask_in_use[level]) {
- /* We don't handle 3D textures and cubemaps yet. */
- r300_flush_depth_stencil(&r300->context, tex, level, 0);
- }
- }
+ util_copy_framebuffer_state(&saved_fb, r300->fb_state.state);
+ r300_decompress_zmask_locked_unsafe(r300);
+ r300->context.set_framebuffer_state(&r300->context, &saved_fb);
+ util_unreference_framebuffer_state(&saved_fb);
}
/* Copy a block of pixels from one surface to another using HW. */
@@ -393,8 +395,6 @@ static void r300_hw_copy_region(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
r300_blitter_begin(r300, R300_COPY);
-
- /* Do a copy */
util_blitter_copy_region(r300->blitter, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box, TRUE);
r300_blitter_end(r300);
@@ -409,56 +409,102 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
unsigned src_level,
const struct pipe_box *src_box)
{
- enum pipe_format old_format = dst->format;
- enum pipe_format new_format = old_format;
- boolean is_depth;
-
- if (!pipe->screen->is_format_supported(pipe->screen,
- old_format, src->target,
- src->nr_samples,
- PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_SAMPLER_VIEW, 0) &&
- util_format_is_plain(old_format)) {
- switch (util_format_get_blocksize(old_format)) {
+ struct r300_context *r300 = r300_context(pipe);
+ struct pipe_framebuffer_state *fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
+ struct pipe_resource old_src = *src;
+ struct pipe_resource old_dst = *dst;
+ struct pipe_resource new_src = old_src;
+ struct pipe_resource new_dst = old_dst;
+ const struct util_format_description *desc =
+ util_format_description(dst->format);
+ struct pipe_box box;
+
+ if (r300->zmask_in_use && !r300->zmask_locked) {
+ if (fb->zsbuf->texture == src ||
+ fb->zsbuf->texture == dst) {
+ r300_decompress_zmask(r300);
+ } else {
+ r300->zmask_locked = TRUE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
+ }
+ }
+
+ /* Handle non-renderable plain formats. */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
+ (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ||
+ !pipe->screen->is_format_supported(pipe->screen,
+ src->format, src->target,
+ src->nr_samples,
+ PIPE_BIND_SAMPLER_VIEW, 0) ||
+ !pipe->screen->is_format_supported(pipe->screen,
+ dst->format, dst->target,
+ dst->nr_samples,
+ PIPE_BIND_RENDER_TARGET, 0))) {
+ switch (util_format_get_blocksize(old_dst.format)) {
case 1:
- new_format = PIPE_FORMAT_I8_UNORM;
+ new_dst.format = PIPE_FORMAT_I8_UNORM;
break;
case 2:
- new_format = PIPE_FORMAT_B4G4R4A4_UNORM;
+ new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
break;
case 4:
- new_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 8:
- new_format = PIPE_FORMAT_R16G16B16A16_UNORM;
+ new_dst.format = PIPE_FORMAT_R16G16B16A16_UNORM;
break;
default:
debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
"r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
- util_format_short_name(old_format));
+ util_format_short_name(dst->format));
}
+ new_src.format = new_dst.format;
}
- is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
- if (is_depth) {
- r300_flush_depth_stencil(pipe, src, src_level, src_box->z);
- }
+ /* Handle compressed formats. */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+ switch (util_format_get_blocksize(old_dst.format)) {
+ case 8:
+ /* 1 pixel = 4 bits,
+ * we set 1 pixel = 2 bytes ===> 4 times larger pixels. */
+ new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM;
+ break;
+ case 16:
+ /* 1 pixel = 8 bits,
+ * we set 1 pixel = 4 bytes ===> 4 times larger pixels. */
+ new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ }
- if (old_format != new_format) {
- r300_texture_reinterpret_format(pipe->screen,
- dst, new_format);
- r300_texture_reinterpret_format(pipe->screen,
- src, new_format);
+ /* Since the pixels are 4 times larger, we must decrease
+ * the image size and the coordinates 4 times. */
+ new_src.format = new_dst.format;
+ new_dst.height0 = (new_dst.height0 + 3) / 4;
+ new_src.height0 = (new_src.height0 + 3) / 4;
+ dsty /= 4;
+ box = *src_box;
+ box.y /= 4;
+ box.height = (box.height + 3) / 4;
+ src_box = &box;
}
+ if (old_src.format != new_src.format)
+ r300_resource_set_properties(pipe->screen, src, 0, &new_src);
+ if (old_dst.format != new_dst.format)
+ r300_resource_set_properties(pipe->screen, dst, 0, &new_dst);
+
r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box);
- if (old_format != new_format) {
- r300_texture_reinterpret_format(pipe->screen,
- dst, old_format);
- r300_texture_reinterpret_format(pipe->screen,
- src, old_format);
+ if (old_src.format != new_src.format)
+ r300_resource_set_properties(pipe->screen, src, 0, &old_src);
+ if (old_dst.format != new_dst.format)
+ r300_resource_set_properties(pipe->screen, dst, 0, &old_dst);
+
+ if (r300->zmask_locked) {
+ r300->zmask_locked = FALSE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}
diff --git a/src/gallium/drivers/r300/r300_cb.h b/src/gallium/drivers/r300/r300_cb.h
index 9d3d4fc1b19..b373937a1f9 100644
--- a/src/gallium/drivers/r300/r300_cb.h
+++ b/src/gallium/drivers/r300/r300_cb.h
@@ -61,40 +61,52 @@
* that they neatly hide away, and don't have the cost of function setup, so
* we're going to use them. */
-#ifdef DEBUG
-#define CB_DEBUG(x) x
-#else
-#define CB_DEBUG(x)
-#endif
-
-
/**
* Command buffer setup.
*/
+#ifdef DEBUG
+
#define CB_LOCALS \
- CB_DEBUG(int cs_count = 0;) \
+ int cs_count = 0; \
uint32_t *cs_ptr = NULL; \
- CB_DEBUG((void) cs_count;) (void) cs_ptr;
+ (void) cs_count; (void) cs_ptr
-#define NEW_CB(ptr, size) do { \
- assert(sizeof(*ptr) == sizeof(uint32_t)); \
- cs_ptr = (ptr) = (uint32_t*)malloc((size) * sizeof(uint32_t)); \
- CB_DEBUG(cs_count = size;) \
+#define BEGIN_CB(ptr, size) do { \
+ assert(sizeof(*(ptr)) == sizeof(uint32_t)); \
+ cs_count = (size); \
+ cs_ptr = (ptr); \
} while (0)
-#define BEGIN_CB(ptr, size) do { \
- assert(sizeof(*ptr) == sizeof(uint32_t)); \
- cs_ptr = ptr; \
- CB_DEBUG(cs_count = size;) \
+#define NEW_CB(ptr, size) \
+ do { \
+ assert(sizeof(*(ptr)) == sizeof(uint32_t)); \
+ cs_count = (size); \
+ cs_ptr = (ptr) = (uint32_t*)malloc((size) * sizeof(uint32_t)); \
} while (0)
#define END_CB do { \
- CB_DEBUG(if (cs_count != 0) \
+ if (cs_count != 0) \
debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \
- cs_count, __FUNCTION__, __FILE__, __LINE__);) \
+ cs_count, __FUNCTION__, __FILE__, __LINE__); \
} while (0)
+#define CB_USED_DW(x) cs_count -= x
+
+#else
+
+#define CB_LOCALS \
+ uint32_t *cs_ptr = NULL; (void) cs_ptr
+
+#define NEW_CB(ptr, size) \
+ cs_ptr = (ptr) = (uint32_t*)malloc((size) * sizeof(uint32_t))
+
+#define BEGIN_CB(ptr, size) cs_ptr = (ptr)
+#define END_CB
+#define CB_USED_DW(x)
+
+#endif
+
/**
* Storing pure DWORDs.
@@ -103,13 +115,13 @@
#define OUT_CB(value) do { \
*cs_ptr = (value); \
cs_ptr++; \
- CB_DEBUG(cs_count--;) \
+ CB_USED_DW(1); \
} while (0)
#define OUT_CB_TABLE(values, count) do { \
memcpy(cs_ptr, values, count * sizeof(uint32_t)); \
cs_ptr += count; \
- CB_DEBUG(cs_count -= count;) \
+ CB_USED_DW(count); \
} while (0)
#define OUT_CB_32F(value) \
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 2b183f62c56..1968d0feb35 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -241,7 +241,6 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x5A42:
caps->family = CHIP_FAMILY_RS400;
caps->has_tcl = FALSE;
- caps->zmask_ram = RV3xx_ZMASK_SIZE;
break;
case 0x5A61:
@@ -424,5 +423,6 @@ void r300_parse_chipset(struct r300_capabilities* caps)
}
caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
+ caps->z_compress = caps->is_rv350 ? R300_ZCOMP_8X8 : R300_ZCOMP_4X4;
caps->dxtc_swizzle = caps->is_r400 || caps->is_r500;
}
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index f2035d20092..0be161fa07a 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -33,6 +33,13 @@
#define PIPE_ZMASK_SIZE 4096
#define RV3xx_ZMASK_SIZE 5120
+/* The size of a compressed tile. Each compressed tile takes 2 bits
+ * in the ZMASK RAM, so there is always 16 tiles per one dword. */
+enum r300_zmask_compression {
+ R300_ZCOMP_4X4 = 4,
+ R300_ZCOMP_8X8 = 8
+};
+
/* Structure containing all the possible information about a specific Radeon
* in the R3xx, R4xx, and R5xx families. */
struct r300_capabilities {
@@ -50,10 +57,12 @@ struct r300_capabilities {
unsigned num_tex_units;
/* Whether or not TCL is physically present */
boolean has_tcl;
- /* Some chipsets do not have HiZ RAM - other have varying amounts . */
+ /* Some chipsets do not have HiZ RAM - other have varying amounts. */
int hiz_ram;
- /* some chipsets have zmask ram per pipe some don't */
+ /* Some chipsets have zmask ram per pipe some don't. */
int zmask_ram;
+ /* Compression mode for ZMASK. */
+ enum r300_zmask_compression z_compress;
/* Whether or not this is RV350 or newer, including all r400 and r500
* chipsets. The differences compared to the oldest r300 chips are:
* - Blend LTE/GTE thresholds
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 91263ad7bcd..9f85bd4ce5f 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -35,26 +35,24 @@
#include "r300_screen_buffer.h"
#include "r300_winsys.h"
-#ifdef HAVE_LLVM
-#include "gallivm/lp_bld_init.h"
-#endif
-
static void r300_update_num_contexts(struct r300_screen *r300screen,
int diff)
{
+ pipe_mutex_lock(r300screen->num_contexts_mutex);
if (diff > 0) {
- p_atomic_inc(&r300screen->num_contexts);
+ r300screen->num_contexts++;
if (r300screen->num_contexts > 1)
util_slab_set_thread_safety(&r300screen->pool_buffers,
UTIL_SLAB_MULTITHREADED);
} else {
- p_atomic_dec(&r300screen->num_contexts);
+ r300screen->num_contexts--;
if (r300screen->num_contexts <= 1)
util_slab_set_thread_safety(&r300screen->pool_buffers,
UTIL_SLAB_SINGLETHREADED);
}
+ pipe_mutex_unlock(r300screen->num_contexts_mutex);
}
static void r300_release_referenced_objects(struct r300_context *r300)
@@ -87,17 +85,14 @@ static void r300_release_referenced_objects(struct r300_context *r300)
/* The SWTCL VBO. */
pipe_resource_reference(&r300->vbo, NULL);
- /* Vertex buffers. */
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
- pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL);
- }
-
/* If there are any queries pending or not destroyed, remove them now. */
foreach_s(query, temp, &r300->query_list) {
remove_from_list(query);
FREE(query);
}
+
+ r300->context.delete_depth_stencil_alpha_state(&r300->context,
+ r300->dsa_decompress_zmask);
}
static void r300_destroy_context(struct pipe_context* context)
@@ -106,28 +101,15 @@ static void r300_destroy_context(struct pipe_context* context)
if (r300->blitter)
util_blitter_destroy(r300->blitter);
- if (r300->draw) {
+ if (r300->draw)
draw_destroy(r300->draw);
-#ifdef HAVE_LLVM
- gallivm_destroy(r300->gallivm);
-#endif
- }
-
- if (r300->upload_vb)
- u_upload_destroy(r300->upload_vb);
- if (r300->upload_ib)
- u_upload_destroy(r300->upload_ib);
-
- if (r300->tran.translate_cache)
- translate_cache_destroy(r300->tran.translate_cache);
+ if (r300->vbuf_mgr)
+ u_vbuf_mgr_destroy(r300->vbuf_mgr);
/* XXX: This function assumes r300->query_list was initialized */
r300_release_referenced_objects(r300);
- if (r300->zmask_mm)
- r300_hyperz_destroy_mm(r300);
-
if (r300->cs)
r300->rws->cs_destroy(r300->cs);
@@ -247,7 +229,7 @@ static boolean r300_setup_atoms(struct r300_context* r300)
if (has_hiz_ram)
R300_INIT_ATOM(hiz_clear, 0);
/* zmask clear */
- R300_INIT_ATOM(zmask_clear, 0);
+ R300_INIT_ATOM(zmask_clear, 4);
}
/* ZB (unpipelined), SU. */
R300_INIT_ATOM(query_start, 4);
@@ -432,12 +414,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300screen->caps.has_tcl) {
/* Create a Draw. This is used for SW TCL. */
-#ifdef HAVE_LLVM
- r300->gallivm = gallivm_create();
- r300->draw = draw_create_gallivm(&r300->context, r300->gallivm);
-#else
r300->draw = draw_create(&r300->context);
-#endif
if (r300->draw == NULL)
goto fail;
/* Enable our renderer. */
@@ -456,6 +433,13 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300_init_state_functions(r300);
r300_init_resource_functions(r300);
+ r300->vbuf_mgr = u_vbuf_mgr_create(&r300->context, 1024 * 1024, 16,
+ PIPE_BIND_VERTEX_BUFFER |
+ PIPE_BIND_INDEX_BUFFER,
+ U_VERTEX_FETCH_DWORD_ALIGNED);
+ if (!r300->vbuf_mgr)
+ goto fail;
+
r300->blitter = util_blitter_create(&r300->context);
if (r300->blitter == NULL)
goto fail;
@@ -470,23 +454,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300_hyperz_init_mm(r300))
goto fail;
- r300->upload_ib = u_upload_create(&r300->context,
- 64 * 1024, 16,
- PIPE_BIND_INDEX_BUFFER);
-
- if (r300->upload_ib == NULL)
- goto fail;
-
- r300->upload_vb = u_upload_create(&r300->context,
- 1024 * 1024, 16,
- PIPE_BIND_VERTEX_BUFFER);
- if (r300->upload_vb == NULL)
- goto fail;
-
- r300->tran.translate_cache = translate_cache_create();
- if (r300->tran.translate_cache == NULL)
- goto fail;
-
r300_init_states(&r300->context);
/* The KIL opcode needs the first texture unit to be enabled
@@ -515,7 +482,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
}
{
- struct pipe_resource vb = {};
+ struct pipe_resource vb;
+ memset(&vb, 0, sizeof(vb));
vb.target = PIPE_BUFFER;
vb.format = PIPE_FORMAT_R8_UNORM;
vb.bind = PIPE_BIND_VERTEX_BUFFER;
@@ -527,36 +495,44 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->dummy_vb = screen->resource_create(screen, &vb);
}
+ {
+ struct pipe_depth_stencil_alpha_state dsa;
+ memset(&dsa, 0, sizeof(dsa));
+ dsa.depth.writemask = 1;
+
+ r300->dsa_decompress_zmask =
+ r300->context.create_depth_stencil_alpha_state(&r300->context,
+ &dsa);
+ }
+
+ /* Print driver info. */
+#ifdef NDEBUG
+ if (DBG_ON(r300, DBG_INFO)) {
+#else
+ {
+#endif
+ fprintf(stderr,
+ "r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n"
+ "r300: GART size: %d MB, VRAM size: %d MB\n"
+ "r300: AA compression: %s, Z compression: %s, HiZ: %s\n",
+ rws->get_value(rws, R300_VID_DRM_MAJOR),
+ rws->get_value(rws, R300_VID_DRM_MINOR),
+ rws->get_value(rws, R300_VID_DRM_PATCHLEVEL),
+ screen->get_name(screen),
+ rws->get_value(rws, R300_VID_PCI_ID),
+ rws->get_value(rws, R300_VID_GB_PIPES),
+ rws->get_value(rws, R300_VID_Z_PIPES),
+ rws->get_value(rws, R300_VID_GART_SIZE) >> 20,
+ rws->get_value(rws, R300_VID_VRAM_SIZE) >> 20,
+ rws->get_value(rws, R300_CAN_AACOMPRESS) ? "YES" : "NO",
+ rws->get_value(rws, R300_CAN_HYPERZ) ? "YES" : "NO",
+ rws->get_value(rws, R300_CAN_HYPERZ) &&
+ r300->screen->caps.hiz_ram ? "YES" : "NO");
+ }
+
return &r300->context;
- fail:
+fail:
r300_destroy_context(&r300->context);
return NULL;
}
-
-void r300_finish(struct r300_context *r300)
-{
- struct pipe_framebuffer_state *fb;
- unsigned i;
-
- /* This is a preliminary implementation of glFinish.
- *
- * The ideal implementation should use something like EmitIrqLocked and
- * WaitIrq, or better, real fences.
- */
- if (r300->fb_state.state) {
- fb = r300->fb_state.state;
-
- for (i = 0; i < fb->nr_cbufs; i++) {
- if (fb->cbufs[i]->texture) {
- r300->rws->buffer_wait(r300->rws,
- r300_texture(fb->cbufs[i]->texture)->buffer);
- return;
- }
- }
- if (fb->zsbuf && fb->zsbuf->texture) {
- r300->rws->buffer_wait(r300->rws,
- r300_texture(fb->zsbuf->texture)->buffer);
- }
- }
-}
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index e09cf87f733..30073759476 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -30,11 +30,11 @@
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
-
-#include "translate/translate_cache.h"
+#include "util/u_vbuf_mgr.h"
#include "r300_defines.h"
#include "r300_screen.h"
+#include "r300_winsys.h"
struct u_upload_mgr;
struct r300_context;
@@ -189,11 +189,6 @@ struct r300_sampler_view {
uint32_t texcache_region;
};
-struct r300_texture_fb_state {
- uint32_t pitch[R300_MAX_TEXTURE_LEVELS]; /* COLORPITCH or DEPTHPITCH. */
- uint32_t format; /* US_OUT_FMT or R300_ZB_FORMAT */
-};
-
struct r300_texture_sampler_state {
struct r300_texture_format_state format;
uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */
@@ -273,14 +268,12 @@ struct r300_query {
/* How many results have been written, in dwords. It's incremented
* after end_query and flush. */
unsigned num_results;
- /* if we've flushed the query */
- boolean flushed;
/* if begin has been emitted */
boolean begin_emitted;
/* The buffer where query results are stored. */
- struct r300_winsys_buffer *buffer;
- struct r300_winsys_cs_buffer *cs_buffer;
+ struct r300_winsys_bo *buf;
+ struct r300_winsys_cs_handle *cs_buf;
/* The size of the buffer. */
unsigned buffer_size;
/* The domain of the buffer. */
@@ -291,28 +284,12 @@ struct r300_query {
struct r300_query* next;
};
-/* Fence object.
- *
- * This is a fake fence. Instead of syncing with the fence, we sync
- * with the context, which is inefficient but compliant.
- *
- * This is not a subclass of pipe_fence_handle because pipe_fence_handle is
- * never actually fully defined. So, rather than have it as a member, and do
- * subclass-style casting, we treat pipe_fence_handle as an opaque, and just
- * trust that our state tracker does not ever mess up fence objects.
- */
-struct r300_fence {
- struct pipe_reference reference;
- struct r300_context *ctx;
- boolean signalled;
-};
-
struct r300_surface {
struct pipe_surface base;
/* Winsys buffer backing the texture. */
- struct r300_winsys_buffer *buffer;
- struct r300_winsys_cs_buffer *cs_buffer;
+ struct r300_winsys_bo *buf;
+ struct r300_winsys_cs_handle *cs_buf;
enum r300_buffer_domain domain;
@@ -329,13 +306,9 @@ struct r300_surface {
/* Whether the CBZB clear is allowed on the surface. */
boolean cbzb_allowed;
-
};
struct r300_texture_desc {
- /* Parent class. */
- struct u_resource b;
-
/* Width, height, and depth.
* Most of the time, these are equal to pipe_texture::width0, height0,
* and depth0. However, NPOT 3D textures must have dimensions aligned
@@ -387,27 +360,38 @@ struct r300_texture_desc {
/* Whether CBZB fast color clear is allowed on the miplevel. */
boolean cbzb_allowed[R300_MAX_TEXTURE_LEVELS];
+
+ /* Zbuffer compression info for each miplevel. */
+ boolean zcomp8x8[R300_MAX_TEXTURE_LEVELS];
+ /* If zero, then disable compression. */
+ unsigned zmask_dwords[R300_MAX_TEXTURE_LEVELS];
};
-struct r300_texture {
- struct r300_texture_desc desc;
+struct r300_resource
+{
+ struct u_vbuf_resource b;
+ /* Winsys buffer backing this resource. */
+ struct r300_winsys_bo *buf;
+ struct r300_winsys_cs_handle *cs_buf;
enum r300_buffer_domain domain;
+ unsigned buf_size;
+
+ /* Constant buffers are in user memory. */
+ uint8_t *constant_buffer;
- /* Pipe buffer backing this texture. */
- struct r300_winsys_buffer *buffer;
- struct r300_winsys_cs_buffer *cs_buffer;
+ /* Texture description (addressing, layout, special features). */
+ struct r300_texture_desc tex;
/* Registers carrying texture format data. */
/* Only format-independent bits should be filled in. */
struct r300_texture_format_state tx_format;
- /* All bits should be filled in. */
- struct r300_texture_fb_state fb_state;
- /* hyper-z memory allocs */
+ /* Where the texture starts in the buffer. */
+ unsigned tex_offset;
+
+ /* HiZ memory allocations. */
struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS];
- struct mem_block *zmask_mem[R300_MAX_TEXTURE_LEVELS];
- boolean zmask_in_use[R300_MAX_TEXTURE_LEVELS];
boolean hiz_in_use[R300_MAX_TEXTURE_LEVELS];
/* This is the level tiling flags were last time set for.
@@ -418,32 +402,16 @@ struct r300_texture {
struct r300_vertex_element_state {
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+ unsigned format_size[PIPE_MAX_ATTRIBS];
- /* If (velem[i].src_format != hw_format[i]), the vertex buffer
- * referenced by this vertex element cannot be used for rendering and
- * its vertex data must be translated to hw_format[i]. */
- enum pipe_format hw_format[PIPE_MAX_ATTRIBS];
- unsigned hw_format_size[PIPE_MAX_ATTRIBS];
+ struct u_vbuf_mgr_elements *vmgr_elements;
/* The size of the vertex, in dwords. */
unsigned vertex_size_dwords;
- /* This might mean two things:
- * - src_format != hw_format, as discussed above.
- * - src_offset % 4 != 0. */
- boolean incompatible_layout;
-
struct r300_vertex_stream_state vertex_stream;
};
-struct r300_translate_context {
- /* Translate cache for incompatible vertex offset/stride/format fallback. */
- struct translate_cache *translate_cache;
-
- /* Saved and new vertex element state. */
- void *saved_velems, *new_velems;
-};
-
struct r300_context {
/* Parent class */
struct pipe_context context;
@@ -456,7 +424,6 @@ struct r300_context {
struct r300_screen *screen;
/* Draw module. Used mostly for SW TCL. */
- struct gallivm_state *gallivm;
struct draw_context* draw;
/* Vertex buffer for SW TCL. */
struct pipe_resource* vbo;
@@ -471,8 +438,6 @@ struct r300_context {
struct blitter_context* blitter;
/* Stencil two-sided reference value fallback. */
struct r300_stencilref_context *stencilref_fallback;
- /* For translating vertex buffers having incompatible vertex layout. */
- struct r300_translate_context tran;
/* The KIL opcode needs the first texture unit to be enabled
* on r3xx-r4xx. In order to calm down the CS checker, we bind this
@@ -554,14 +519,6 @@ struct r300_context {
/* The pointers to the first and the last atom. */
struct r300_atom *first_dirty, *last_dirty;
- /* Vertex buffers for Gallium. */
- /* May contain user buffers. */
- struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- /* Contains only non-user buffers. */
- struct pipe_resource *valid_vertex_buffer[PIPE_MAX_ATTRIBS];
- int vertex_buffer_count;
- int vertex_buffer_max_index;
- boolean any_user_vbs;
/* Vertex elements for Gallium. */
struct r300_vertex_element_state *velems;
@@ -588,21 +545,23 @@ struct r300_context {
int sprite_coord_enable;
/* Whether two-sided color selection is enabled (AKA light_twoside). */
boolean two_sided_color;
- /* Incompatible vertex buffer layout? (misaligned stride or buffer_offset) */
- boolean incompatible_vb_layout;
-#define R300_Z_COMPRESS_44 1
-#define RV350_Z_COMPRESS_88 2
- int z_compression;
+
boolean cbzb_clear;
- boolean z_decomp_rd;
+ /* Whether ZMASK is enabled. */
+ boolean zmask_in_use;
+ /* Whether ZMASK is being decompressed. */
+ boolean zmask_decompress;
+ /* Whether ZMASK is locked, i.e. should be disabled and cannot be taken over. */
+ boolean zmask_locked;
+ /* The zbuffer the ZMASK of which is locked. */
+ struct pipe_surface *locked_zbuffer;
+
+ void *dsa_decompress_zmask;
/* two mem block managers for hiz/zmask ram space */
struct mem_block *hiz_mm;
- struct mem_block *zmask_mm;
- /* upload managers */
- struct u_upload_mgr *upload_vb;
- struct u_upload_mgr *upload_ib;
+ struct u_vbuf_mgr *vbuf_mgr;
struct util_slab_mempool pool_transfers;
@@ -612,16 +571,10 @@ struct r300_context {
/* const tracking for VS */
int vs_const_base;
- /* AOS (PACKET3_3D_LOAD_VBPNTR) command buffer for the case offset=0. */
- uint32_t vertex_arrays_cb[(16 * 3 + 1) / 2];
+ /* Vertex array state info */
boolean vertex_arrays_dirty;
-
- /* Whether any buffer (FB, textures, VBOs) has been set, but buffers
- * haven't been validated yet. */
- boolean validate_buffers;
- /* Whether user buffers have been validated. */
- boolean upload_vb_validated;
- boolean upload_ib_validated;
+ boolean vertex_arrays_indexed;
+ int vertex_arrays_offset;
};
#define foreach_atom(r300, atom) \
@@ -641,9 +594,9 @@ static INLINE struct r300_surface* r300_surface(struct pipe_surface* surf)
return (struct r300_surface*)surf;
}
-static INLINE struct r300_texture* r300_texture(struct pipe_resource* tex)
+static INLINE struct r300_resource* r300_resource(struct pipe_resource* tex)
{
- return (struct r300_texture*)tex;
+ return (struct r300_resource*)tex;
}
static INLINE struct r300_context* r300_context(struct pipe_context* context)
@@ -675,7 +628,6 @@ static INLINE void r300_mark_atom_dirty(struct r300_context *r300,
struct pipe_context* r300_create_context(struct pipe_screen* screen,
void *priv);
-void r300_finish(struct r300_context *r300);
void r300_flush_cb(void *data);
/* Context initialization. */
@@ -688,7 +640,9 @@ void r300_init_state_functions(struct r300_context* r300);
void r300_init_resource_functions(struct r300_context* r300);
/* r300_blit.c */
-void r300_flush_depth_textures(struct r300_context *r300);
+void r300_decompress_zmask(struct r300_context *r300);
+void r300_decompress_zmask_locked_unsafe(struct r300_context *r300);
+void r300_decompress_zmask_locked(struct r300_context *r300);
/* r300_query.c */
void r300_resume_query(struct r300_context *r300,
@@ -696,9 +650,6 @@ void r300_resume_query(struct r300_context *r300,
void r300_stop_query(struct r300_context *r300);
/* r300_render_translate.c */
-void r300_begin_vertex_translate(struct r300_context *r300,
- int min_index, int max_index);
-void r300_end_vertex_translate(struct r300_context *r300);
void r300_translate_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned *index_size, unsigned index_offset,
@@ -714,8 +665,7 @@ void r500_emit_index_bias(struct r300_context *r300, int index_bias);
/* r300_state.c */
enum r300_fb_state_change {
R300_CHANGED_FB_STATE = 0,
- R300_CHANGED_CBZB_FLAG,
- R300_CHANGED_ZCLEAR_FLAG,
+ R300_CHANGED_HYPERZ_FLAG,
R300_CHANGED_MULTIWRITE
};
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 6726f100e1b..2e52dfa43c6 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -35,12 +35,6 @@
* that they neatly hide away, and don't have the cost of function setup,so
* we're going to use them. */
-#ifdef DEBUG
-#define CS_DEBUG(x) x
-#else
-#define CS_DEBUG(x)
-#endif
-
/**
* Command submission setup.
*/
@@ -50,22 +44,29 @@
struct r300_winsys_screen *cs_winsys = (context)->rws; \
int cs_count = 0; (void) cs_count; (void) cs_winsys;
+#ifdef DEBUG
+
#define BEGIN_CS(size) do { \
assert(size <= (R300_MAX_CMDBUF_DWORDS - cs_copy->cdw)); \
- CS_DEBUG(cs_count = size;) \
+ cs_count = size; \
} while (0)
-#ifdef DEBUG
#define END_CS do { \
if (cs_count != 0) \
debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \
cs_count, __FUNCTION__, __FILE__, __LINE__); \
cs_count = 0; \
} while (0)
+
+#define CS_USED_DW(x) cs_count -= (x)
+
#else
+
+#define BEGIN_CS(size)
#define END_CS
-#endif
+#define CS_USED_DW(x)
+#endif
/**
* Writing pure DWORDs.
@@ -73,7 +74,7 @@
#define OUT_CS(value) do { \
cs_copy->buf[cs_copy->cdw++] = (value); \
- CS_DEBUG(cs_count--;) \
+ CS_USED_DW(1); \
} while (0)
#define OUT_CS_32F(value) \
@@ -98,7 +99,7 @@
#define OUT_CS_TABLE(values, count) do { \
memcpy(cs_copy->buf + cs_copy->cdw, values, count * 4); \
cs_copy->cdw += count; \
- CS_DEBUG(cs_count -= count;) \
+ CS_USED_DW(count); \
} while (0)
@@ -106,27 +107,11 @@
* Writing relocations.
*/
-#define OUT_CS_RELOC(bo, offset) do { \
- assert(bo); \
- OUT_CS(offset); \
- cs_winsys->cs_write_reloc(cs_copy, bo); \
- CS_DEBUG(cs_count -= 2;) \
-} while (0)
-
-#define OUT_CS_BUF_RELOC(bo, offset) do { \
- assert(bo); \
- OUT_CS_RELOC(r300_buffer(bo)->cs_buf, offset); \
-} while (0)
-
-#define OUT_CS_TEX_RELOC(tex, offset) do { \
- assert(tex); \
- OUT_CS_RELOC(tex->cs_buffer, offset); \
-} while (0)
-
-#define OUT_CS_BUF_RELOC_NO_OFFSET(bo) do { \
- assert(bo); \
- cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->cs_buf); \
- CS_DEBUG(cs_count -= 2;) \
+#define OUT_CS_RELOC(r) do { \
+ assert((r)); \
+ assert((r)->cs_buf); \
+ cs_winsys->cs_write_reloc(cs_copy, (r)->cs_buf); \
+ CS_USED_DW(2); \
} while (0)
@@ -135,7 +120,7 @@
*/
#define WRITE_CS_TABLE(values, count) do { \
- CS_DEBUG(assert(cs_count == 0);) \
+ assert(cs_count == 0); \
memcpy(cs_copy->buf + cs_copy->cdw, (values), (count) * 4); \
cs_copy->cdw += (count); \
} while (0)
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index d6aa90bd053..b60cfd1f248 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -27,6 +27,7 @@
#include <stdio.h>
static const struct debug_named_value debug_options[] = {
+ { "info", DBG_INFO, "Print hardware info"},
{ "fp", DBG_FP, "Log fragment program compilation" },
{ "vp", DBG_VP, "Log vertex program compilation" },
{ "pstat", DBG_P_STAT, "Log vertex/fragment program stats" },
@@ -49,6 +50,8 @@ static const struct debug_named_value debug_options[] = {
{ "noimmd", DBG_NO_IMMD, "Disable immediate mode" },
{ "noopt", DBG_NO_OPT, "Disable shader optimizations" },
{ "nocbzb", DBG_NO_CBZB, "Disable fast color clear" },
+ { "nozmask", DBG_NO_ZMASK, "Disable zbuffer compression" },
+ { "nohiz", DBG_NO_HIZ, "Disable hierarchical zbuffer" },
/* must be last */
DEBUG_NAMED_VALUE_END
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d14cdcbbaf0..e2e4719ec82 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -89,7 +89,7 @@ static void get_rc_constant_state(
struct rc_constant * constant)
{
struct r300_textures_state* texstate = r300->textures_state.state;
- struct r300_texture *tex;
+ struct r300_resource *tex;
assert(constant->Type == RC_CONSTANT_STATE);
@@ -101,19 +101,19 @@ static void get_rc_constant_state(
/* Factor for converting rectangle coords to
* normalized coords. Should only show up on non-r500. */
case RC_STATE_R300_TEXRECT_FACTOR:
- tex = r300_texture(texstate->sampler_views[constant->u.State[1]]->base.texture);
- vec[0] = 1.0 / tex->desc.width0;
- vec[1] = 1.0 / tex->desc.height0;
+ tex = r300_resource(texstate->sampler_views[constant->u.State[1]]->base.texture);
+ vec[0] = 1.0 / tex->tex.width0;
+ vec[1] = 1.0 / tex->tex.height0;
vec[2] = 0;
vec[3] = 1;
break;
case RC_STATE_R300_TEXSCALE_FACTOR:
- tex = r300_texture(texstate->sampler_views[constant->u.State[1]]->base.texture);
+ tex = r300_resource(texstate->sampler_views[constant->u.State[1]]->base.texture);
/* Add a small number to the texture size to work around rounding errors in hw. */
- vec[0] = tex->desc.b.b.width0 / (tex->desc.width0 + 0.001f);
- vec[1] = tex->desc.b.b.height0 / (tex->desc.height0 + 0.001f);
- vec[2] = tex->desc.b.b.depth0 / (tex->desc.depth0 + 0.001f);
+ vec[0] = tex->b.b.b.width0 / (tex->tex.width0 + 0.001f);
+ vec[1] = tex->b.b.b.height0 / (tex->tex.height0 + 0.001f);
+ vec[2] = tex->b.b.b.depth0 / (tex->tex.depth0 + 0.001f);
vec[3] = 1;
break;
@@ -352,11 +352,9 @@ void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state)
OUT_CS_REG(R300_GB_AA_CONFIG, aa->aa_config);
if (aa->dest) {
- OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 1);
- OUT_CS_RELOC(aa->dest->cs_buffer, aa->dest->offset);
-
- OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_PITCH, 1);
- OUT_CS_RELOC(aa->dest->cs_buffer, aa->dest->pitch);
+ OUT_CS_REG(R300_RB3D_AARESOLVE_OFFSET, aa->dest->offset);
+ OUT_CS_RELOC(aa->dest);
+ OUT_CS_REG(R300_RB3D_AARESOLVE_PITCH, aa->dest->pitch);
}
OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, aa->aaresolve_ctl);
@@ -391,11 +389,11 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
for (i = 0; i < fb->nr_cbufs; i++) {
surf = r300_surface(fb->cbufs[i]);
- OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
- OUT_CS_RELOC(surf->cs_buffer, surf->offset);
+ OUT_CS_REG(R300_RB3D_COLOROFFSET0 + (4 * i), surf->offset);
+ OUT_CS_RELOC(surf);
- OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
- OUT_CS_RELOC(surf->cs_buffer, surf->pitch);
+ OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), surf->pitch);
+ OUT_CS_RELOC(surf);
}
/* Set up the ZB part of the CBZB clear. */
@@ -404,11 +402,11 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_REG(R300_ZB_FORMAT, surf->cbzb_format);
- OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_RELOC(surf->cs_buffer, surf->cbzb_midpoint_offset);
+ OUT_CS_REG(R300_ZB_DEPTHOFFSET, surf->cbzb_midpoint_offset);
+ OUT_CS_RELOC(surf);
- OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(surf->cs_buffer, surf->cbzb_pitch);
+ OUT_CS_REG(R300_ZB_DEPTHPITCH, surf->cbzb_pitch);
+ OUT_CS_RELOC(surf);
DBG(r300, DBG_CBZB,
"CBZB clearing cbuf %08x %08x\n", surf->cbzb_format,
@@ -420,19 +418,20 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_REG(R300_ZB_FORMAT, surf->format);
- OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_RELOC(surf->cs_buffer, surf->offset);
+ OUT_CS_REG(R300_ZB_DEPTHOFFSET, surf->offset);
+ OUT_CS_RELOC(surf);
- OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(surf->cs_buffer, surf->pitch);
+ OUT_CS_REG(R300_ZB_DEPTHPITCH, surf->pitch);
+ OUT_CS_RELOC(surf);
if (can_hyperz) {
uint32_t surf_pitch;
- struct r300_texture *tex;
+ struct r300_resource *tex;
int level = surf->base.u.tex.level;
- tex = r300_texture(surf->base.texture);
+ tex = r300_resource(surf->base.texture);
surf_pitch = surf->pitch & R300_DEPTHPITCH_MASK;
+
/* HiZ RAM. */
if (r300->screen->caps.hiz_ram) {
if (tex->hiz_mem[level]) {
@@ -443,14 +442,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0);
}
}
+
/* Z Mask RAM. (compressed zbuffer) */
- if (tex->zmask_mem[level]) {
- OUT_CS_REG(R300_ZB_ZMASK_OFFSET, tex->zmask_mem[level]->ofs << 2);
- OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf_pitch);
- } else {
- OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0);
- OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0);
- }
+ OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0);
+ OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf_pitch);
}
}
@@ -462,6 +457,7 @@ void r300_emit_hyperz_state(struct r300_context *r300,
{
struct r300_hyperz_state *z = state;
CS_LOCALS(r300);
+
if (z->flush)
WRITE_CS_TABLE(&z->cb_flush_begin, size);
else
@@ -563,14 +559,12 @@ void r300_emit_query_start(struct r300_context *r300, unsigned size, void*state)
OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
END_CS;
query->begin_emitted = TRUE;
- query->flushed = FALSE;
}
static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
struct r300_query *query)
{
struct r300_capabilities* caps = &r300->screen->caps;
- struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer;
CS_LOCALS(r300);
assert(caps->num_frag_pipes);
@@ -588,25 +582,25 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
case 4:
/* pipe 3 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 3) * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 3) * 4);
+ OUT_CS_RELOC(r300->query_current);
case 3:
/* pipe 2 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 2) * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 2) * 4);
+ OUT_CS_RELOC(r300->query_current);
case 2:
/* pipe 1 only */
/* As mentioned above, accomodate RV380 and older. */
OUT_CS_REG(R300_SU_REG_DEST,
1 << (caps->high_second_pipe ? 3 : 1));
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 1) * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 1) * 4);
+ OUT_CS_RELOC(r300->query_current);
case 1:
/* pipe 0 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 0) * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 0) * 4);
+ OUT_CS_RELOC(r300->query_current);
break;
default:
fprintf(stderr, "r300: Implementation error: Chipset reports %d"
@@ -622,13 +616,12 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
static void rv530_emit_query_end_single_z(struct r300_context *r300,
struct r300_query *query)
{
- struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer;
CS_LOCALS(r300);
BEGIN_CS(8);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, query->num_results * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, query->num_results * 4);
+ OUT_CS_RELOC(r300->query_current);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -636,16 +629,15 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300,
static void rv530_emit_query_end_double_z(struct r300_context *r300,
struct r300_query *query)
{
- struct r300_winsys_cs_buffer *buf = r300->query_current->cs_buffer;
CS_LOCALS(r300);
BEGIN_CS(14);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 0) * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 0) * 4);
+ OUT_CS_RELOC(r300->query_current);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 1) * 4);
+ OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 1) * 4);
+ OUT_CS_RELOC(r300->query_current);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -784,7 +776,7 @@ void r300_emit_textures_state(struct r300_context *r300,
{
struct r300_textures_state *allstate = (struct r300_textures_state*)state;
struct r300_texture_sampler_state *texstate;
- struct r300_texture *tex;
+ struct r300_resource *tex;
unsigned i;
CS_LOCALS(r300);
@@ -794,7 +786,7 @@ void r300_emit_textures_state(struct r300_context *r300,
for (i = 0; i < allstate->count; i++) {
if ((1 << i) & allstate->tx_enable) {
texstate = &allstate->regs[i];
- tex = r300_texture(allstate->sampler_views[i]->base.texture);
+ tex = r300_resource(allstate->sampler_views[i]->base.texture);
OUT_CS_REG(R300_TX_FILTER0_0 + (i * 4), texstate->filter0);
OUT_CS_REG(R300_TX_FILTER1_0 + (i * 4), texstate->filter1);
@@ -805,96 +797,56 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG(R300_TX_FORMAT1_0 + (i * 4), texstate->format.format1);
OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format.format2);
- OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_CS_TEX_RELOC(tex, texstate->format.tile_config);
+ OUT_CS_REG(R300_TX_OFFSET_0 + (i * 4), texstate->format.tile_config);
+ OUT_CS_RELOC(tex);
}
}
END_CS;
}
-static void r300_update_vertex_arrays_cb(struct r300_context *r300, unsigned packet_size)
+void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed)
{
- struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->vertex_buffer;
+ struct pipe_resource **valid_vbuf = r300->vbuf_mgr->real_vertex_buffer;
struct pipe_vertex_element *velem = r300->velems->velem;
- unsigned *hw_format_size = r300->velems->hw_format_size;
- unsigned size1, size2, vertex_array_count = r300->velems->count;
+ struct r300_resource *buf;
int i;
- CB_LOCALS;
+ unsigned vertex_array_count = r300->velems->count;
+ unsigned packet_size = (vertex_array_count * 3 + 1) / 2;
+ struct pipe_vertex_buffer *vb1, *vb2;
+ unsigned *hw_format_size;
+ unsigned size1, size2;
+ CS_LOCALS(r300);
+
+ BEGIN_CS(2 + packet_size + vertex_array_count * 2);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
+ OUT_CS(vertex_array_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
+
+ hw_format_size = r300->velems->format_size;
- BEGIN_CB(r300->vertex_arrays_cb, packet_size);
for (i = 0; i < vertex_array_count - 1; i += 2) {
vb1 = &vbuf[velem[i].vertex_buffer_index];
vb2 = &vbuf[velem[i+1].vertex_buffer_index];
size1 = hw_format_size[i];
size2 = hw_format_size[i+1];
- OUT_CB(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
- OUT_CB(vb1->buffer_offset + velem[i].src_offset);
- OUT_CB(vb2->buffer_offset + velem[i+1].src_offset);
+ 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 (vertex_array_count & 1) {
vb1 = &vbuf[velem[i].vertex_buffer_index];
size1 = hw_format_size[i];
- OUT_CB(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
- OUT_CB(vb1->buffer_offset + velem[i].src_offset);
- }
- END_CB;
-
- r300->vertex_arrays_dirty = FALSE;
-}
-
-void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed)
-{
- struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_resource **valid_vbuf = r300->valid_vertex_buffer;
- struct pipe_vertex_element *velem = r300->velems->velem;
- struct r300_buffer *buf;
- int i;
- unsigned vertex_array_count = r300->velems->count;
- unsigned packet_size = (vertex_array_count * 3 + 1) / 2;
- CS_LOCALS(r300);
-
- BEGIN_CS(2 + packet_size + vertex_array_count * 2);
- OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
- OUT_CS(vertex_array_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
-
- if (!offset) {
- if (r300->vertex_arrays_dirty) {
- r300_update_vertex_arrays_cb(r300, packet_size);
- }
- OUT_CS_TABLE(r300->vertex_arrays_cb, packet_size);
- } else {
- struct pipe_vertex_buffer *vb1, *vb2;
- unsigned *hw_format_size = r300->velems->hw_format_size;
- unsigned size1, size2;
-
- for (i = 0; i < vertex_array_count - 1; i += 2) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- vb2 = &vbuf[velem[i+1].vertex_buffer_index];
- size1 = hw_format_size[i];
- size2 = hw_format_size[i+1];
-
- 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 (vertex_array_count & 1) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- size1 = hw_format_size[i];
-
- OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
- OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
- }
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
}
for (i = 0; i < vertex_array_count; i++) {
- buf = r300_buffer(valid_vbuf[velem[i].vertex_buffer_index]);
- OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b);
+ buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]);
+ OUT_CS_RELOC(buf);
}
END_CS;
}
@@ -919,7 +871,8 @@ void r300_emit_vertex_arrays_swtcl(struct r300_context *r300, boolean indexed)
OUT_CS(r300->vertex_info.size |
(r300->vertex_info.size << 8));
OUT_CS(r300->draw_vbo_offset);
- OUT_CS_BUF_RELOC(r300->vbo, 0);
+ OUT_CS(0);
+ OUT_CS_RELOC(r300_resource(r300->vbo));
END_CS;
}
@@ -1097,17 +1050,6 @@ static void r300_emit_hiz_line_clear(struct r300_context *r300, int start, uint1
END_CS;
}
-static void r300_emit_zmask_line_clear(struct r300_context *r300, int start, uint16_t count, uint32_t val)
-{
- CS_LOCALS(r300);
- BEGIN_CS(4);
- OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2);
- OUT_CS(start);
- OUT_CS(count);
- OUT_CS(val);
- END_CS;
-}
-
#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
@@ -1118,13 +1060,13 @@ void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
(struct r300_hyperz_state*)r300->hyperz_state.state;
struct r300_screen* r300screen = r300->screen;
uint32_t stride, offset = 0, height, offset_shift;
- struct r300_texture* tex;
+ struct r300_resource* tex;
int i;
- tex = r300_texture(fb->zsbuf->texture);
+ tex = r300_resource(fb->zsbuf->texture);
offset = tex->hiz_mem[fb->zsbuf->u.tex.level]->ofs;
- stride = tex->desc.stride_in_pixels[fb->zsbuf->u.tex.level];
+ stride = tex->tex.stride_in_pixels[fb->zsbuf->u.tex.level];
/* convert from pixels to 4x4 blocks */
stride = ALIGN_DIVUP(stride, 4);
@@ -1153,42 +1095,21 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
{
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
- struct r300_screen* r300screen = r300->screen;
- uint32_t stride, offset = 0;
- struct r300_texture* tex;
- uint32_t i, height;
- int mult, offset_shift;
-
- tex = r300_texture(fb->zsbuf->texture);
- stride = tex->desc.stride_in_pixels[fb->zsbuf->u.tex.level];
-
- offset = tex->zmask_mem[fb->zsbuf->u.tex.level]->ofs;
-
- if (r300->z_compression == RV350_Z_COMPRESS_88)
- mult = 8;
- else
- mult = 4;
-
- height = ALIGN_DIVUP(fb->zsbuf->height, mult);
-
- offset_shift = 4;
- offset_shift += (r300screen->caps.num_frag_pipes / 2);
- stride = ALIGN_DIVUP(stride, r300screen->caps.num_frag_pipes);
+ struct r300_resource *tex;
+ CS_LOCALS(r300);
- /* okay have width in pixels - divide by block width */
- stride = ALIGN_DIVUP(stride, mult);
- /* have width in blocks - divide by number of fragment pipes screen width */
- /* 16 blocks per dword */
- stride = ALIGN_DIVUP(stride, 16);
+ tex = r300_resource(fb->zsbuf->texture);
- for (i = 0; i < height; i++) {
- offset = i * stride;
- offset <<= offset_shift;
- r300_emit_zmask_line_clear(r300, offset, stride, 0x0);//0xffffffff);
- }
+ BEGIN_CS(size);
+ OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2);
+ OUT_CS(0);
+ OUT_CS(tex->tex.zmask_dwords[fb->zsbuf->u.tex.level]);
+ OUT_CS(0);
+ END_CS;
/* Mark the current zbuffer's zmask as in use. */
- tex->zmask_in_use[fb->zsbuf->u.tex.level] = TRUE;
+ r300->zmask_in_use = TRUE;
+ r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
void r300_emit_ztop_state(struct r300_context* r300,
@@ -1219,7 +1140,7 @@ boolean r300_emit_buffer_validate(struct r300_context *r300,
(struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_textures_state *texstate =
(struct r300_textures_state*)r300->textures_state.state;
- struct r300_texture *tex;
+ struct r300_resource *tex;
unsigned i;
boolean flushed = FALSE;
@@ -1227,16 +1148,16 @@ validate:
if (r300->fb_state.dirty) {
/* Color buffers... */
for (i = 0; i < fb->nr_cbufs; i++) {
- tex = r300_texture(fb->cbufs[i]->texture);
- assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- r300->rws->cs_add_reloc(r300->cs, tex->cs_buffer, 0,
+ tex = r300_resource(fb->cbufs[i]->texture);
+ assert(tex && tex->buf && "cbuf is marked, but NULL!");
+ r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, 0,
r300_surface(fb->cbufs[i])->domain);
}
/* ...depth buffer... */
if (fb->zsbuf) {
- tex = r300_texture(fb->zsbuf->texture);
- assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
- r300->rws->cs_add_reloc(r300->cs, tex->cs_buffer, 0,
+ tex = r300_resource(fb->zsbuf->texture);
+ assert(tex && tex->buf && "zsbuf is marked, but NULL!");
+ r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, 0,
r300_surface(fb->zsbuf)->domain);
}
}
@@ -1247,35 +1168,35 @@ validate:
continue;
}
- tex = r300_texture(texstate->sampler_views[i]->base.texture);
- r300->rws->cs_add_reloc(r300->cs, tex->cs_buffer, tex->domain, 0);
+ tex = r300_resource(texstate->sampler_views[i]->base.texture);
+ r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, tex->domain, 0);
}
}
/* ...occlusion query buffer... */
if (r300->query_current)
- r300->rws->cs_add_reloc(r300->cs, r300->query_current->cs_buffer,
+ r300->rws->cs_add_reloc(r300->cs, r300->query_current->cs_buf,
0, r300->query_current->domain);
/* ...vertex buffer for SWTCL path... */
if (r300->vbo)
- r300->rws->cs_add_reloc(r300->cs, r300_buffer(r300->vbo)->cs_buf,
- r300_buffer(r300->vbo)->domain, 0);
+ r300->rws->cs_add_reloc(r300->cs, r300_resource(r300->vbo)->cs_buf,
+ r300_resource(r300->vbo)->domain, 0);
/* ...vertex buffers for HWTCL path... */
- if (do_validate_vertex_buffers) {
- struct pipe_resource **buf = r300->valid_vertex_buffer;
- struct pipe_resource **last = r300->valid_vertex_buffer +
- r300->vertex_buffer_count;
+ if (do_validate_vertex_buffers && r300->vertex_arrays_dirty) {
+ struct pipe_resource **buf = r300->vbuf_mgr->real_vertex_buffer;
+ struct pipe_resource **last = r300->vbuf_mgr->real_vertex_buffer +
+ r300->vbuf_mgr->nr_real_vertex_buffers;
for (; buf != last; buf++) {
if (!*buf)
continue;
- r300->rws->cs_add_reloc(r300->cs, r300_buffer(*buf)->cs_buf,
- r300_buffer(*buf)->domain, 0);
+ r300->rws->cs_add_reloc(r300->cs, r300_resource(*buf)->cs_buf,
+ r300_resource(*buf)->domain, 0);
}
}
/* ...and index buffer for HWTCL path. */
if (index_buffer)
- r300->rws->cs_add_reloc(r300->cs, r300_buffer(index_buffer)->cs_buf,
- r300_buffer(index_buffer)->domain, 0);
+ r300->rws->cs_add_reloc(r300->cs, r300_resource(index_buffer)->cs_buf,
+ r300_resource(index_buffer)->domain, 0);
/* Now do the validation. */
if (!r300->rws->cs_validate(r300->cs)) {
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index b250532ba92..c77cc08539d 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -36,16 +36,24 @@ static void r300_flush(struct pipe_context* pipe,
struct pipe_fence_handle** fence)
{
struct r300_context *r300 = r300_context(pipe);
- struct r300_query *query;
struct r300_atom *atom;
- struct r300_fence **rfence = (struct r300_fence**)fence;
-
- u_upload_flush(r300->upload_vb);
- u_upload_flush(r300->upload_ib);
+ struct r300_winsys_bo **rfence = (struct r300_winsys_bo**)fence;
if (r300->draw && !r300->draw_vbo_locked)
r300_draw_flush_vbuf(r300);
+ if (rfence) {
+ /* Create a fence, which is a dummy BO. */
+ *rfence = r300->rws->buffer_create(r300->rws, 1, 1,
+ PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STATIC,
+ R300_DOMAIN_GTT);
+ /* Add the fence as a dummy relocation. */
+ r300->rws->cs_add_reloc(r300->cs,
+ r300->rws->buffer_get_cs_handle(*rfence),
+ R300_DOMAIN_GTT, R300_DOMAIN_GTT);
+ }
+
if (r300->dirty_hw) {
r300_emit_hyperz_end(r300);
r300_emit_query_end(r300);
@@ -62,32 +70,29 @@ static void r300_flush(struct pipe_context* pipe,
r300_mark_atom_dirty(r300, atom);
}
}
+ r300->vertex_arrays_dirty = TRUE;
/* Unmark HWTCL state for SWTCL. */
if (!r300->screen->caps.has_tcl) {
r300->vs_state.dirty = FALSE;
r300->vs_constants.dirty = FALSE;
}
-
- r300->validate_buffers = TRUE;
- r300->upload_vb_validated = FALSE;
- r300->upload_ib_validated = FALSE;
} else {
- /* Even if hw is not dirty, we should at least reset the CS in case
- * the space checking failed for the first draw operation. */
- r300->rws->cs_flush(r300->cs);
- }
-
- /* reset flushed query */
- foreach(query, &r300->query_list) {
- query->flushed = TRUE;
+ if (rfence) {
+ /* We have to create a fence object, but the command stream is empty
+ * and we cannot emit an empty CS. We must write some regs then. */
+ CS_LOCALS(r300);
+ OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0);
+ r300->rws->cs_flush(r300->cs);
+ } else {
+ /* Even if hw is not dirty, we should at least reset the CS in case
+ * the space checking failed for the first draw operation. */
+ r300->rws->cs_flush(r300->cs);
+ }
}
- /* Create a new fence. */
- if (rfence) {
- *rfence = CALLOC_STRUCT(r300_fence);
- pipe_reference_init(&(*rfence)->reference, 1);
- (*rfence)->ctx = r300;
+ if (flags & PIPE_FLUSH_FRAME) {
+ r300->rws->cs_sync_flush(r300->cs);
}
}
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 6d4091dc87d..cec7473009a 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -152,13 +152,13 @@ static void get_external_state(
for (i = 0; i < texstate->sampler_state_count; i++) {
struct r300_sampler_state *s = texstate->sampler_states[i];
struct r300_sampler_view *v = texstate->sampler_views[i];
- struct r300_texture *t;
+ struct r300_resource *t;
if (!s || !v) {
continue;
}
- t = r300_texture(texstate->sampler_views[i]->base.texture);
+ t = r300_resource(texstate->sampler_views[i]->base.texture);
if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
state->unit[i].compare_mode_enabled = 1;
@@ -181,7 +181,7 @@ static void get_external_state(
state->unit[i].non_normalized_coords = !s->state.normalized_coords;
/* XXX this should probably take into account STR, not just S. */
- if (t->desc.is_npot) {
+ if (t->tex.is_npot) {
switch (s->state.wrap_s) {
case PIPE_TEX_WRAP_REPEAT:
state->unit[i].wrap_mode = RC_WRAP_REPEAT;
@@ -201,7 +201,7 @@ static void get_external_state(
state->unit[i].wrap_mode = RC_WRAP_NONE;
}
- if (t->desc.b.b.target == PIPE_TEXTURE_3D)
+ if (t->b.b.b.target == PIPE_TEXTURE_3D)
state->unit[i].clamp_and_scale_before_fetch = TRUE;
}
}
@@ -298,44 +298,98 @@ static void r300_emit_fs_code_to_buffer(
}
} else { /* r300 */
struct r300_fragment_program_code *code = &generic_code->code.r300;
-
- shader->cb_code_size = 19 +
- (r300->screen->caps.is_r400 ? 2 : 0) +
- code->alu.length * 4 +
- (code->tex.length ? (1 + code->tex.length) : 0) +
- imm_count * 5;
+ unsigned int alu_length = code->alu.length;
+ unsigned int alu_iterations = ((alu_length - 1) / 64) + 1;
+ unsigned int tex_length = code->tex.length;
+ unsigned int tex_iterations =
+ tex_length > 0 ? ((tex_length - 1) / 32) + 1 : 0;
+ unsigned int iterations =
+ alu_iterations > tex_iterations ? alu_iterations : tex_iterations;
+ unsigned int bank = 0;
+
+ shader->cb_code_size = 15 +
+ /* R400_US_CODE_BANK */
+ (r300->screen->caps.is_r400 ? 2 * (iterations + 1): 0) +
+ /* R400_US_CODE_EXT */
+ (r300->screen->caps.is_r400 ? 2 : 0) +
+ /* R300_US_ALU_{RGB,ALPHA}_{INST,ADDR}_0, R400_US_ALU_EXT_ADDR_0 */
+ (code->r390_mode ? (5 * alu_iterations) : 4) +
+ /* R400_US_ALU_EXT_ADDR_[0-63] */
+ (code->r390_mode ? (code->alu.length) : 0) +
+ /* R300_US_ALU_{RGB,ALPHA}_{INST,ADDR}_0 */
+ code->alu.length * 4 +
+ /* R300_US_TEX_INST_0, R300_US_TEX_INST_[0-31] */
+ (code->tex.length > 0 ? code->tex.length + tex_iterations : 0) +
+ imm_count * 5;
NEW_CB(shader->cb_code, shader->cb_code_size);
- if (r300->screen->caps.is_r400)
- OUT_CB_REG(R400_US_CODE_BANK, 0);
-
OUT_CB_REG(R300_US_CONFIG, code->config);
OUT_CB_REG(R300_US_PIXSIZE, code->pixsize);
OUT_CB_REG(R300_US_CODE_OFFSET, code->code_offset);
+ if (code->r390_mode) {
+ OUT_CB_REG(R400_US_CODE_EXT, code->r400_code_offset_ext);
+ } else if (r300->screen->caps.is_r400) {
+ /* This register appears to affect shaders even if r390_mode is
+ * disabled, so it needs to be set to 0 for shaders that
+ * don't use r390_mode. */
+ OUT_CB_REG(R400_US_CODE_EXT, 0);
+ }
+
OUT_CB_REG_SEQ(R300_US_CODE_ADDR_0, 4);
OUT_CB_TABLE(code->code_addr, 4);
- OUT_CB_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
- for (i = 0; i < code->alu.length; i++)
- OUT_CB(code->alu.inst[i].rgb_inst);
+ do {
+ unsigned int bank_alu_length = (alu_length < 64 ? alu_length : 64);
+ unsigned int bank_alu_offset = bank * 64;
+ unsigned int bank_tex_length = (tex_length < 32 ? tex_length : 32);
+ unsigned int bank_tex_offset = bank * 32;
+
+ if (r300->screen->caps.is_r400) {
+ OUT_CB_REG(R400_US_CODE_BANK, code->r390_mode ?
+ (bank << R400_BANK_SHIFT) | R400_R390_MODE_ENABLE : 0);//2
+ }
+
+ if (bank_alu_length > 0) {
+ OUT_CB_REG_SEQ(R300_US_ALU_RGB_INST_0, bank_alu_length);
+ for (i = 0; i < bank_alu_length; i++)
+ OUT_CB(code->alu.inst[i + bank_alu_offset].rgb_inst);
+
+ OUT_CB_REG_SEQ(R300_US_ALU_RGB_ADDR_0, bank_alu_length);
+ for (i = 0; i < bank_alu_length; i++)
+ OUT_CB(code->alu.inst[i + bank_alu_offset].rgb_addr);
- OUT_CB_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
- for (i = 0; i < code->alu.length; i++)
- OUT_CB(code->alu.inst[i].rgb_addr);
+ OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_INST_0, bank_alu_length);
+ for (i = 0; i < bank_alu_length; i++)
+ OUT_CB(code->alu.inst[i + bank_alu_offset].alpha_inst);
- OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
- for (i = 0; i < code->alu.length; i++)
- OUT_CB(code->alu.inst[i].alpha_inst);
+ OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, bank_alu_length);
+ for (i = 0; i < bank_alu_length; i++)
+ OUT_CB(code->alu.inst[i + bank_alu_offset].alpha_addr);
- OUT_CB_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
- for (i = 0; i < code->alu.length; i++)
- OUT_CB(code->alu.inst[i].alpha_addr);
+ if (code->r390_mode) {
+ OUT_CB_REG_SEQ(R400_US_ALU_EXT_ADDR_0, bank_alu_length);
+ for (i = 0; i < bank_alu_length; i++)
+ OUT_CB(code->alu.inst[i + bank_alu_offset].r400_ext_addr);
+ }
+ }
+
+ if (bank_tex_length > 0) {
+ OUT_CB_REG_SEQ(R300_US_TEX_INST_0, bank_tex_length);
+ OUT_CB_TABLE(code->tex.inst + bank_tex_offset, bank_tex_length);
+ }
+
+ alu_length -= bank_alu_length;
+ tex_length -= bank_tex_length;
+ bank++;
+ } while(code->r390_mode && (alu_length > 0 || tex_length > 0));
- if (code->tex.length) {
- OUT_CB_REG_SEQ(R300_US_TEX_INST_0, code->tex.length);
- OUT_CB_TABLE(code->tex.inst, code->tex.length);
+ /* R400_US_CODE_BANK needs to be reset to 0, otherwise some shaders
+ * will be rendered incorrectly. */
+ if (r300->screen->caps.is_r400) {
+ OUT_CB_REG(R400_US_CODE_BANK,
+ code->r390_mode ? R400_R390_MODE_ENABLE : 0);
}
/* Emit immediates. */
@@ -384,12 +438,17 @@ static void r300_translate_fragment_shader(
compiler.code = &shader->code;
compiler.state = shader->compare_state;
compiler.Base.is_r500 = r300->screen->caps.is_r500;
+ compiler.Base.is_r400 = r300->screen->caps.is_r400;
compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT);
compiler.Base.has_half_swizzles = TRUE;
compiler.Base.has_presub = TRUE;
- compiler.Base.max_temp_regs = compiler.Base.is_r500 ? 128 : 32;
+ compiler.Base.max_temp_regs =
+ compiler.Base.is_r500 ? 128 : (compiler.Base.is_r400 ? 64 : 32);
compiler.Base.max_constants = compiler.Base.is_r500 ? 256 : 32;
- compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 512 : 64;
+ compiler.Base.max_alu_insts =
+ (compiler.Base.is_r500 || compiler.Base.is_r400) ? 512 : 64;
+ compiler.Base.max_tex_insts =
+ (compiler.Base.is_r500 || compiler.Base.is_r400) ? 512 : 32;
compiler.AllocateHwInputs = &allocate_hardware_inputs;
compiler.UserData = &shader->inputs;
@@ -414,6 +473,13 @@ static void r300_translate_fragment_shader(
r300_tgsi_to_rc(&ttr, tokens);
+ if (ttr.error) {
+ fprintf(stderr, "r300 FP: Cannot translate a shader. "
+ "Using a dummy shader instead.\n");
+ r300_dummy_fragment_shader(r300, shader);
+ return;
+ }
+
if (!r300->screen->caps.is_r500 ||
compiler.Base.Program.Constants.Count > 200) {
compiler.Base.remove_unused_constants = TRUE;
diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c
index c22e307c679..873e0209d42 100644
--- a/src/gallium/drivers/r300/r300_hyperz.c
+++ b/src/gallium/drivers/r300/r300_hyperz.c
@@ -127,7 +127,7 @@ static boolean r300_can_hiz(struct r300_context *r300)
z->current_func, dsa_state->z_stencil_control);
return FALSE;
}
- }
+ }
return TRUE;
}
@@ -137,9 +137,8 @@ static void r300_update_hyperz(struct r300_context* r300)
(struct r300_hyperz_state*)r300->hyperz_state.state;
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
- struct r300_texture *zstex =
- fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL;
- boolean zmask_in_use = FALSE;
+ struct r300_resource *zstex =
+ fb->zsbuf ? r300_resource(fb->zsbuf->texture) : NULL;
boolean hiz_in_use = FALSE;
z->gb_z_peq_config = 0;
@@ -158,42 +157,40 @@ static void r300_update_hyperz(struct r300_context* r300)
if (!r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
return;
- zmask_in_use = zstex->zmask_in_use[fb->zsbuf->u.tex.level];
hiz_in_use = zstex->hiz_in_use[fb->zsbuf->u.tex.level];
- /* Z fastfill. */
- if (zmask_in_use) {
- z->zb_bw_cntl |= R300_FAST_FILL_ENABLE; /* | R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE;*/
- }
-
/* Zbuffer compression. */
- if (zmask_in_use && r300->z_compression) {
- z->zb_bw_cntl |= R300_RD_COMP_ENABLE;
- if (r300->z_decomp_rd == false)
+ if (r300->zmask_in_use && !r300->zmask_locked) {
+ z->zb_bw_cntl |= R300_FAST_FILL_ENABLE |
+ /*R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE |*/
+ R300_RD_COMP_ENABLE;
+
+ if (!r300->zmask_decompress) {
z->zb_bw_cntl |= R300_WR_COMP_ENABLE;
+ }
}
- /* RV350 and up optimizations. */
- /* The section 10.4.9 in the docs is a lie. */
- if (r300->z_compression == RV350_Z_COMPRESS_88)
+
+ if (zstex->tex.zcomp8x8[fb->zsbuf->u.tex.level]) {
z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8;
+ }
+
+ if (hiz_in_use && r300_can_hiz(r300)) {
+ z->zb_bw_cntl |= R300_HIZ_ENABLE |
+ r300_get_hiz_min(r300);
- if (hiz_in_use) {
- bool can_hiz = r300_can_hiz(r300);
- if (can_hiz) {
- z->zb_bw_cntl |= R300_HIZ_ENABLE;
- z->sc_hyperz |= R300_SC_HYPERZ_ENABLE;
- z->sc_hyperz |= r300_get_sc_hz_max(r300);
- z->zb_bw_cntl |= r300_get_hiz_min(r300);
+ z->sc_hyperz |= R300_SC_HYPERZ_ENABLE |
+ r300_get_sc_hz_max(r300);
+
+ if (r300->screen->caps.is_r500) {
+ z->zb_bw_cntl |= R500_HIZ_FP_EXP_BITS_3 |
+ R500_HIZ_EQUAL_REJECT_ENABLE;
}
}
/* R500-specific features and optimizations. */
if (r300->screen->caps.is_r500) {
- z->zb_bw_cntl |= R500_HIZ_FP_EXP_BITS_3;
- z->zb_bw_cntl |=
- R500_HIZ_EQUAL_REJECT_ENABLE |
- R500_PEQ_PACKING_ENABLE |
- R500_COVERED_PTR_MASKING_ENABLE;
+ z->zb_bw_cntl |= R500_PEQ_PACKING_ENABLE |
+ R500_COVERED_PTR_MASKING_ENABLE;
}
}
@@ -297,26 +294,10 @@ static void r300_update_hiz_clear(struct r300_context *r300)
r300->hiz_clear.size = height * 4;
}
-static void r300_update_zmask_clear(struct r300_context *r300)
-{
- struct pipe_framebuffer_state *fb =
- (struct pipe_framebuffer_state*)r300->fb_state.state;
- uint32_t height;
- int mult;
-
- if (r300->z_compression == RV350_Z_COMPRESS_88)
- mult = 8;
- else
- mult = 4;
-
- height = ALIGN_DIVUP(fb->zsbuf->height, mult);
-
- r300->zmask_clear.size = height * 4;
-}
-
void r300_update_hyperz_state(struct r300_context* r300)
{
r300_update_ztop(r300);
+
if (r300->hyperz_state.dirty) {
r300_update_hyperz(r300);
}
@@ -324,64 +305,24 @@ void r300_update_hyperz_state(struct r300_context* r300)
if (r300->hiz_clear.dirty) {
r300_update_hiz_clear(r300);
}
- if (r300->zmask_clear.dirty) {
- r300_update_zmask_clear(r300);
- }
}
void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf)
{
- struct r300_texture *tex;
+ struct r300_resource *tex;
uint32_t zsize, ndw;
int level = surf->base.u.tex.level;
- tex = r300_texture(surf->base.texture);
+ tex = r300_resource(surf->base.texture);
if (tex->hiz_mem[level])
return;
- zsize = tex->desc.layer_size_in_bytes[level];
- zsize /= util_format_get_blocksize(tex->desc.b.b.format);
+ zsize = tex->tex.layer_size_in_bytes[level];
+ zsize /= util_format_get_blocksize(tex->b.b.b.format);
ndw = ALIGN_DIVUP(zsize, 64);
tex->hiz_mem[level] = u_mmAllocMem(r300->hiz_mm, ndw, 0, 0);
- return;
-}
-
-void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress)
-{
- int bsize = 256;
- uint32_t zsize, ndw;
- int level = surf->base.u.tex.level;
- struct r300_texture *tex;
-
- tex = r300_texture(surf->base.texture);
-
- /* We currently don't handle decompression for 3D textures and cubemaps
- * correctly. */
- if (tex->desc.b.b.target != PIPE_TEXTURE_1D &&
- tex->desc.b.b.target != PIPE_TEXTURE_2D &&
- tex->desc.b.b.target != PIPE_TEXTURE_RECT)
- return;
-
- /* Cannot flush zmask of 16-bit zbuffers. */
- if (util_format_get_blocksizebits(tex->desc.b.b.format) == 16)
- return;
-
- if (tex->zmask_mem[level])
- return;
-
- zsize = tex->desc.layer_size_in_bytes[level];
- zsize /= util_format_get_blocksize(tex->desc.b.b.format);
-
- /* each zmask dword represents 16 4x4 blocks - which is 256 pixels
- or 16 8x8 depending on the gb peq flag = 1024 pixels */
- if (compress == RV350_Z_COMPRESS_88)
- bsize = 1024;
-
- ndw = ALIGN_DIVUP(zsize, bsize);
- tex->zmask_mem[level] = u_mmAllocMem(r300->zmask_mm, ndw, 0, 0);
- return;
}
boolean r300_hyperz_init_mm(struct r300_context *r300)
@@ -389,15 +330,9 @@ boolean r300_hyperz_init_mm(struct r300_context *r300)
struct r300_screen* r300screen = r300->screen;
int frag_pipes = r300screen->caps.num_frag_pipes;
- r300->zmask_mm = u_mmInit(0, r300screen->caps.zmask_ram * frag_pipes);
- if (!r300->zmask_mm)
- return FALSE;
-
if (r300screen->caps.hiz_ram) {
r300->hiz_mm = u_mmInit(0, r300screen->caps.hiz_ram * frag_pipes);
if (!r300->hiz_mm) {
- u_mmDestroy(r300->zmask_mm);
- r300->zmask_mm = NULL;
return FALSE;
}
}
@@ -413,7 +348,4 @@ void r300_hyperz_destroy_mm(struct r300_context *r300)
u_mmDestroy(r300->hiz_mm);
r300->hiz_mm = NULL;
}
-
- u_mmDestroy(r300->zmask_mm);
- r300->zmask_mm = NULL;
}
diff --git a/src/gallium/drivers/r300/r300_hyperz.h b/src/gallium/drivers/r300/r300_hyperz.h
index 30a23ec6493..d4c8e7c60a9 100644
--- a/src/gallium/drivers/r300/r300_hyperz.h
+++ b/src/gallium/drivers/r300/r300_hyperz.h
@@ -28,8 +28,8 @@ struct r300_context;
void r300_update_hyperz_state(struct r300_context* r300);
void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf);
-void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress);
boolean r300_hyperz_init_mm(struct r300_context *r300);
void r300_hyperz_destroy_mm(struct r300_context *r300);
+
#endif
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 6223e043210..717485f43cb 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -57,10 +57,10 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
insert_at_tail(&r300->query_list, q);
/* Open up the occlusion query buffer. */
- q->buffer = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096,
+ q->buf = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096,
PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM,
q->domain);
- q->cs_buffer = r300->rws->buffer_get_cs_handle(r300->rws, q->buffer);
+ q->cs_buf = r300->rws->buffer_get_cs_handle(q->buf);
return (struct pipe_query*)q;
}
@@ -68,10 +68,9 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
static void r300_destroy_query(struct pipe_context* pipe,
struct pipe_query* query)
{
- struct r300_context *r300 = r300_context(pipe);
struct r300_query* q = r300_query(query);
- r300->rws->buffer_reference(r300->rws, &q->buffer, NULL);
+ r300_winsys_bo_reference(&q->buf, NULL);
remove_from_list(q);
FREE(query);
}
@@ -128,16 +127,12 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
struct r300_query *q = r300_query(query);
- unsigned flags, i;
+ unsigned i;
uint32_t temp, *map;
- uint64_t *result = (uint64_t*)vresult;
-
- if (!q->flushed)
- pipe->flush(pipe, 0, NULL);
-
- flags = PIPE_TRANSFER_READ | (!wait ? PIPE_TRANSFER_DONTBLOCK : 0);
- map = r300->rws->buffer_map(r300->rws, q->buffer, r300->cs, flags);
+ map = r300->rws->buffer_map(q->buf, r300->cs,
+ PIPE_TRANSFER_READ |
+ (!wait ? PIPE_TRANSFER_DONTBLOCK : 0));
if (!map)
return FALSE;
@@ -148,9 +143,9 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
map++;
}
- r300->rws->buffer_unmap(r300->rws, q->buffer);
+ r300->rws->buffer_unmap(q->buf);
- *result = temp;
+ *((uint64_t*)vresult) = temp;
return TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index d1154dee40a..1d93dab2ca2 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -2162,14 +2162,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* R4xx extended fragment shader registers. */
#define R400_US_ALU_EXT_ADDR_0 0x4ac0 /* up to 63 (0x4bbc) */
-# define R400_ADDR0_EXT_RGB_MSB_BIT 0x01
-# define R400_ADDR1_EXT_RGB_MSB_BIT 0x02
-# define R400_ADDR2_EXT_RGB_MSB_BIT 0x04
+# define R400_ADDR_EXT_RGB_MSB_BIT(x) (1 << (x))
# define R400_ADDRD_EXT_RGB_MSB_BIT 0x08
-# define R400_ADDR0_EXT_A_MSB_BIT 0x10
-# define R400_ADDR1_EXT_A_MSB_BIT 0x20
-# define R400_ADDR2_EXT_A_MSB_BIT 0x40
+# define R400_ADDR_EXT_A_MSB_BIT(x) (1 << ((x) + 4))
# define R400_ADDRD_EXT_A_MSB_BIT 0x80
+
#define R400_US_CODE_BANK 0x46b8
# define R400_BANK_SHIFT 0
# define R400_BANK_MASK 0xf
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index b35822c82f8..2ead8667bda 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -127,6 +127,20 @@ void r500_emit_index_bias(struct r300_context *r300, int index_bias)
END_CS;
}
+static void r300_emit_draw_init(struct r300_context *r300, unsigned mode,
+ unsigned min_index, unsigned max_index)
+{
+ CS_LOCALS(r300);
+
+ BEGIN_CS(5);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, mode));
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(max_index);
+ OUT_CS(min_index);
+ END_CS;
+}
+
/* This function splits the index bias value into two parts:
* - buffer_offset: the value that can be safely added to buffer offsets
* in r300_emit_vertex_arrays (it must yield a positive offset when added to
@@ -136,7 +150,7 @@ void r500_emit_index_bias(struct r300_context *r300, int index_bias)
static void r300_split_index_bias(struct r300_context *r300, int index_bias,
int *buffer_offset, int *index_offset)
{
- struct pipe_vertex_buffer *vb, *vbufs = r300->vertex_buffer;
+ struct pipe_vertex_buffer *vb, *vbufs = r300->vbuf_mgr->vertex_buffer;
struct pipe_vertex_element *velem = r300->velems->velem;
unsigned i, size;
int max_neg_bias;
@@ -235,24 +249,11 @@ static boolean r300_emit_states(struct r300_context *r300,
/* Validate buffers and emit dirty state if needed. */
if (first_draw) {
- if (r300->validate_buffers) {
- if (!r300_emit_buffer_validate(r300, validate_vbos,
- index_buffer)) {
- fprintf(stderr, "r300: CS space validation failed. "
- "(not enough memory?) Skipping rendering.\n");
- return FALSE;
- }
-
- /* Consider the validation done only if everything was validated. */
- if (validate_vbos) {
- r300->validate_buffers = FALSE;
- if (r300->any_user_vbs)
- r300->upload_vb_validated = TRUE;
- if (r300->index_buffer.buffer &&
- r300_is_user_buffer(r300->index_buffer.buffer)) {
- r300->upload_ib_validated = TRUE;
- }
- }
+ if (!r300_emit_buffer_validate(r300, validate_vbos,
+ index_buffer)) {
+ fprintf(stderr, "r300: CS space validation failed. "
+ "(not enough memory?) Skipping rendering.\n");
+ return FALSE;
}
r300_emit_dirty_state(r300);
@@ -263,9 +264,17 @@ static boolean r300_emit_states(struct r300_context *r300,
r500_emit_index_bias(r300, 0);
}
- if (emit_vertex_arrays)
+ if (emit_vertex_arrays &&
+ (r300->vertex_arrays_dirty ||
+ r300->vertex_arrays_indexed != indexed ||
+ r300->vertex_arrays_offset != buffer_offset)) {
r300_emit_vertex_arrays(r300, buffer_offset, indexed);
+ r300->vertex_arrays_dirty = FALSE;
+ r300->vertex_arrays_indexed = indexed;
+ r300->vertex_arrays_offset = buffer_offset;
+ }
+
if (emit_vertex_arrays_swtcl)
r300_emit_vertex_arrays_swtcl(r300, indexed);
}
@@ -294,7 +303,8 @@ static boolean r300_prepare_for_rendering(struct r300_context *r300,
if (r300_reserve_cs_dwords(r300, flags, cs_dwords))
flags |= PREP_FIRST_DRAW;
- return r300_emit_states(r300, flags, index_buffer, buffer_offset, index_bias);
+ return r300_emit_states(r300, flags, index_buffer, buffer_offset,
+ index_bias);
}
static boolean immd_is_good_idea(struct r300_context *r300,
@@ -325,17 +335,12 @@ static boolean immd_is_good_idea(struct r300_context *r300,
vbi = velem->vertex_buffer_index;
if (!checked[vbi]) {
- buf = r300->valid_vertex_buffer[vbi];
+ buf = r300->vbuf_mgr->real_vertex_buffer[vbi];
- if (!(r300_buffer(buf)->domain & R300_DOMAIN_GTT)) {
+ if ((r300_resource(buf)->domain != R300_DOMAIN_GTT)) {
return FALSE;
}
- if (r300_buffer_is_referenced(&r300->context, buf,
- R300_REF_CS | R300_REF_HW)) {
- /* It's a very bad idea to map it... */
- return FALSE;
- }
checked[vbi] = TRUE;
}
}
@@ -346,10 +351,9 @@ static boolean immd_is_good_idea(struct r300_context *r300,
* The HWTCL draw functions. *
****************************************************************************/
-static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
- unsigned mode,
- unsigned start,
- unsigned count)
+static void r300_draw_arrays_immediate(struct r300_context *r300,
+ unsigned mode, unsigned start,
+ unsigned count)
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
@@ -360,7 +364,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
unsigned vertex_size = r300->velems->vertex_size_dwords;
/* The number of dwords for this draw operation. */
- unsigned dwords = 9 + count * vertex_size;
+ unsigned dwords = 4 + count * vertex_size;
/* Size of the vertex element, in dwords. */
unsigned size[PIPE_MAX_ATTRIBS];
@@ -370,9 +374,8 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
unsigned stride[PIPE_MAX_ATTRIBS];
/* Mapped vertex buffers. */
- uint32_t* map[PIPE_MAX_ATTRIBS];
+ uint32_t* map[PIPE_MAX_ATTRIBS] = {0};
uint32_t* mapelem[PIPE_MAX_ATTRIBS];
- struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {0};
CS_LOCALS(r300);
@@ -382,29 +385,25 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) {
velem = &r300->velems->velem[i];
- size[i] = r300->velems->hw_format_size[i] / 4;
+ size[i] = r300->velems->format_size[i] / 4;
vbi = velem->vertex_buffer_index;
- vbuf = &r300->vertex_buffer[vbi];
+ vbuf = &r300->vbuf_mgr->vertex_buffer[vbi];
stride[i] = vbuf->stride / 4;
/* Map the buffer. */
- if (!transfer[vbi]) {
- map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context,
- r300->valid_vertex_buffer[vbi],
- PIPE_TRANSFER_READ,
- &transfer[vbi]);
+ if (!map[vbi]) {
+ map[vbi] = (uint32_t*)r300->rws->buffer_map(
+ r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi])->buf,
+ r300->cs, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED);
map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start;
}
mapelem[i] = map[vbi] + (velem->src_offset / 4);
}
+ r300_emit_draw_init(r300, mode, 0, count-1);
+
BEGIN_CS(dwords);
- OUT_CS_REG(R300_GA_COLOR_CONTROL,
- r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
- OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
- OUT_CS(count - 1);
- OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
r300_translate_primitive(mode));
@@ -421,9 +420,9 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
for (i = 0; i < vertex_element_count; i++) {
vbi = r300->velems->velem[i].vertex_buffer_index;
- if (transfer[vbi]) {
- pipe_buffer_unmap(&r300->context, transfer[vbi]);
- transfer[vbi] = NULL;
+ if (map[vbi]) {
+ r300->rws->buffer_unmap(r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi])->buf);
+ map[vbi] = NULL;
}
}
}
@@ -441,15 +440,12 @@ static void r300_emit_draw_arrays(struct r300_context *r300,
return;
}
- BEGIN_CS(7 + (alt_num_verts ? 2 : 0));
+ r300_emit_draw_init(r300, mode, 0, count-1);
+
+ BEGIN_CS(2 + (alt_num_verts ? 2 : 0));
if (alt_num_verts) {
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
}
- OUT_CS_REG(R300_GA_COLOR_CONTROL,
- r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
- OUT_CS(count - 1);
- OUT_CS(0);
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) |
@@ -471,22 +467,16 @@ static void r300_emit_draw_elements(struct r300_context *r300,
boolean alt_num_verts = count > 65535;
CS_LOCALS(r300);
- if (count >= (1 << 24)) {
+ if (count >= (1 << 24) || maxIndex >= (1 << 24)) {
fprintf(stderr, "r300: Got a huge number of vertices: %i, "
- "refusing to render.\n", count);
+ "refusing to render (maxIndex: %i).\n", count, maxIndex);
return;
}
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
count, minIndex, maxIndex);
- BEGIN_CS(5);
- OUT_CS_REG(R300_GA_COLOR_CONTROL,
- r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
- OUT_CS(maxIndex);
- OUT_CS(minIndex);
- END_CS;
+ r300_emit_draw_init(r300, mode, minIndex, maxIndex);
/* If start is odd, render the first triangle with indices embedded
* in the command stream. This will increase start by 3 and make it
@@ -527,30 +517,105 @@ static void r300_emit_draw_elements(struct r300_context *r300,
(alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
}
- /* INDX_BUFFER is a truly special packet3.
- * Unlike most other packet3, where the offset is after the count,
- * the order is reversed, so the relocation ends up carrying the
- * size of the indexbuf instead of the offset.
- */
OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
OUT_CS(offset_dwords << 2);
- OUT_CS_BUF_RELOC(indexBuffer, count_dwords);
+ OUT_CS(count_dwords);
+ OUT_CS_RELOC(r300_resource(indexBuffer));
+ END_CS;
+}
+
+static void r300_draw_elements_immediate(struct r300_context *r300,
+ int indexBias, unsigned minIndex,
+ unsigned maxIndex, unsigned mode,
+ unsigned start, unsigned count)
+{
+ uint8_t *ptr1;
+ uint16_t *ptr2;
+ uint32_t *ptr4;
+ unsigned index_size = r300->index_buffer.index_size;
+ unsigned i, count_dwords = index_size == 4 ? count : (count + 1) / 2;
+ CS_LOCALS(r300);
+
+ /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
+ if (!r300_prepare_for_rendering(r300,
+ PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+ PREP_INDEXED, NULL, 2+count_dwords, 0, indexBias))
+ return;
+ r300_emit_draw_init(r300, mode, minIndex, maxIndex);
+
+ BEGIN_CS(2 + count_dwords);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count_dwords);
+
+ switch (index_size) {
+ case 1:
+ ptr1 = r300_resource(r300->index_buffer.buffer)->b.user_ptr;
+ ptr1 += start;
+
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ r300_translate_primitive(mode));
+
+ if (indexBias && !r300->screen->caps.index_bias_supported) {
+ for (i = 0; i < count-1; i += 2)
+ OUT_CS(((ptr1[i+1] + indexBias) << 16) |
+ (ptr1[i] + indexBias));
+
+ if (count & 1)
+ OUT_CS(ptr1[i] + indexBias);
+ } else {
+ for (i = 0; i < count-1; i += 2)
+ OUT_CS(((ptr1[i+1]) << 16) |
+ (ptr1[i] ));
+
+ if (count & 1)
+ OUT_CS(ptr1[i]);
+ }
+ break;
+
+ case 2:
+ ptr2 = (uint16_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
+ ptr2 += start;
+
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ r300_translate_primitive(mode));
+
+ if (indexBias && !r300->screen->caps.index_bias_supported) {
+ for (i = 0; i < count-1; i += 2)
+ OUT_CS(((ptr2[i+1] + indexBias) << 16) |
+ (ptr2[i] + indexBias));
+
+ if (count & 1)
+ OUT_CS(ptr2[i] + indexBias);
+ } else {
+ OUT_CS_TABLE(ptr2, count_dwords);
+ }
+ break;
+
+ case 4:
+ ptr4 = (uint32_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
+ ptr4 += start;
+
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
+ r300_translate_primitive(mode));
+
+ if (indexBias && !r300->screen->caps.index_bias_supported) {
+ for (i = 0; i < count; i++)
+ OUT_CS(ptr4[i] + indexBias);
+ } else {
+ OUT_CS_TABLE(ptr4, count_dwords);
+ }
+ break;
+ }
END_CS;
}
-/* This is the fast-path drawing & emission for HW TCL. */
-static void r300_draw_range_elements(struct pipe_context* pipe,
- int indexBias,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count)
+static void r300_draw_elements(struct r300_context *r300, int indexBias,
+ unsigned minIndex, unsigned maxIndex,
+ unsigned mode, unsigned start, unsigned count)
{
- struct r300_context* r300 = r300_context(pipe);
struct pipe_resource *indexBuffer = r300->index_buffer.buffer;
unsigned indexSize = r300->index_buffer.index_size;
struct pipe_resource* orgIndexBuffer = indexBuffer;
@@ -570,30 +635,28 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
/* Fallback for misaligned ushort indices. */
if (indexSize == 2 && (start & 1) &&
- !r300_is_user_buffer(indexBuffer)) {
- struct pipe_transfer *transfer;
- struct pipe_resource *userbuf;
-
- uint16_t *ptr = pipe_buffer_map(pipe, indexBuffer,
- PIPE_TRANSFER_READ, &transfer);
+ !r300_resource(indexBuffer)->b.user_ptr) {
+ /* If we got here, then orgIndexBuffer == indexBuffer. */
+ uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->buf,
+ r300->cs,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED);
if (mode == PIPE_PRIM_TRIANGLES) {
memcpy(indices3, ptr + start, 6);
} else {
/* Copy the mapped index buffer directly to the upload buffer.
* The start index will be aligned simply from the fact that
- * every sub-buffer in u_upload_mgr is aligned. */
- userbuf = pipe->screen->user_buffer_create(pipe->screen,
- ptr, 0,
- PIPE_BIND_INDEX_BUFFER);
- indexBuffer = userbuf;
- r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start, count);
- pipe_resource_reference(&userbuf, NULL);
+ * every sub-buffer in the upload buffer is aligned. */
+ r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start,
+ count, (uint8_t*)ptr);
}
- pipe_buffer_unmap(pipe, transfer);
+ r300->rws->buffer_unmap(r300_resource(orgIndexBuffer)->buf);
} else {
- if (r300_is_user_buffer(indexBuffer))
- r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start, count);
+ if (r300_resource(indexBuffer)->b.user_ptr)
+ r300_upload_index_buffer(r300, &indexBuffer, indexSize,
+ &start, count,
+ r300_resource(indexBuffer)->b.user_ptr);
}
/* 19 dwords for emit_draw_elements. Give up if the function fails. */
@@ -607,7 +670,11 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
minIndex, maxIndex, mode, start, count, indices3);
} else {
do {
- short_count = MIN2(count, 65534);
+ if (indexSize == 2 && (start & 1))
+ short_count = MIN2(count, 65535);
+ else
+ short_count = MIN2(count, 65534);
+
r300_emit_draw_elements(r300, indexBuffer, indexSize,
minIndex, maxIndex,
mode, start, short_count, indices3);
@@ -631,43 +698,38 @@ done:
}
}
-static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
+static void r300_draw_arrays(struct r300_context *r300, unsigned mode,
unsigned start, unsigned count)
{
- struct r300_context* r300 = r300_context(pipe);
boolean alt_num_verts = r300->screen->caps.is_r500 &&
count > 65536 &&
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
unsigned short_count;
- if (immd_is_good_idea(r300, count)) {
- r300_emit_draw_arrays_immediate(r300, mode, start, count);
+ /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
+ if (!r300_prepare_for_rendering(r300,
+ PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
+ NULL, 9, start, 0))
+ return;
+
+ if (alt_num_verts || count <= 65535) {
+ r300_emit_draw_arrays(r300, mode, count);
} else {
- /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
- if (!r300_prepare_for_rendering(r300,
- PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
- NULL, 9, start, 0))
- return;
+ do {
+ short_count = MIN2(count, 65535);
+ r300_emit_draw_arrays(r300, mode, short_count);
- if (alt_num_verts || count <= 65535) {
- r300_emit_draw_arrays(r300, mode, count);
- } else {
- do {
- short_count = MIN2(count, 65535);
- r300_emit_draw_arrays(r300, mode, short_count);
-
- start += short_count;
- count -= short_count;
-
- /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
- if (count) {
- if (!r300_prepare_for_rendering(r300,
- PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
- start, 0))
- return;
- }
- } while (count);
- }
+ start += short_count;
+ count -= short_count;
+
+ /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
+ if (count) {
+ if (!r300_prepare_for_rendering(r300,
+ PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
+ start, 0))
+ return;
+ }
+ } while (count);
}
}
@@ -676,83 +738,45 @@ static void r300_draw_vbo(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
unsigned count = info->count;
- boolean translate = FALSE;
+ boolean buffers_updated, uploader_flushed;
boolean indexed = info->indexed && r300->index_buffer.buffer;
- unsigned min_index = 0;
- unsigned max_index = r300->vertex_buffer_max_index;
+ unsigned start_indexed = info->start + r300->index_buffer.offset;
+ int max_index = MIN2(r300->vbuf_mgr->max_index, info->max_index);
- if (r300->skip_rendering) {
+ if (r300->skip_rendering ||
+ !u_trim_pipe_prim(info->mode, &count)) {
return;
}
- if (!u_trim_pipe_prim(info->mode, &count)) {
- return;
+ /* Start the vbuf manager and update buffers if needed. */
+ u_vbuf_mgr_draw_begin(r300->vbuf_mgr, info,
+ &buffers_updated, &uploader_flushed);
+ if (buffers_updated) {
+ r300->vertex_arrays_dirty = TRUE;
}
- if (indexed) {
- int real_min_index, real_max_index;
- /* Compute the start for draw_elements, taking the offset into account. */
- unsigned start_indexed =
- info->start +
- (r300->index_buffer.offset / r300->index_buffer.index_size);
-
- assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
-
- /* Index buffer range checking. */
- 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;
- }
-
- min_index = MAX2(min_index, info->min_index);
- max_index = MIN2(max_index, info->max_index);
- real_min_index = (int)min_index - info->index_bias;
- real_max_index = (int)max_index - info->index_bias;
-
- if (max_index >= (1 << 24) - 1) {
- fprintf(stderr, "r300: Invalid max_index: %i. Skipping rendering...\n", max_index);
- return;
- }
-
- r300_update_derived_state(r300);
-
- /* Set up the fallback for an incompatible vertex layout if needed. */
- if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
- r300_begin_vertex_translate(r300, real_min_index, real_max_index);
- translate = TRUE;
- }
+ /* Draw. */
+ r300_update_derived_state(r300);
- /* Upload vertex buffers. */
- if (r300->any_user_vbs) {
- r300_upload_user_buffers(r300, real_min_index, real_max_index);
+ if (indexed) {
+ if (count <= 8 &&
+ r300_resource(r300->index_buffer.buffer)->b.user_ptr) {
+ r300_draw_elements_immediate(r300, info->index_bias,
+ info->min_index, max_index,
+ info->mode, start_indexed, count);
+ } else {
+ r300_draw_elements(r300, info->index_bias, info->min_index,
+ max_index, info->mode, start_indexed, count);
}
-
- r300_draw_range_elements(pipe, info->index_bias, min_index, max_index,
- info->mode, start_indexed, count);
} else {
- min_index = MAX2(min_index, info->start);
- max_index = MIN2(max_index, info->start + count - 1);
-
- r300_update_derived_state(r300);
-
- /* Set up the fallback for an incompatible vertex layout if needed. */
- if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
- r300_begin_vertex_translate(r300, min_index, max_index);
- translate = TRUE;
- }
-
- /* Upload vertex buffers. */
- if (r300->any_user_vbs) {
- r300_upload_user_buffers(r300, min_index, max_index);
+ if (immd_is_good_idea(r300, count)) {
+ r300_draw_arrays_immediate(r300, info->mode, info->start, count);
+ } else {
+ r300_draw_arrays(r300, info->mode, info->start, count);
}
-
- r300_draw_arrays(pipe, info->mode, info->start, count);
}
- if (translate) {
- r300_end_vertex_translate(r300);
- }
+ u_vbuf_mgr_draw_end(r300->vbuf_mgr);
}
/****************************************************************************
@@ -787,11 +811,12 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
(indexed ? PREP_INDEXED : 0),
indexed ? 256 : 6);
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- if (r300->vertex_buffer[i].buffer) {
+ for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
+ if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
void *buf = pipe_buffer_map(pipe,
- r300->vertex_buffer[i].buffer,
- PIPE_TRANSFER_READ,
+ r300->vbuf_mgr->vertex_buffer[i].buffer,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
&vb_transfer[i]);
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
}
@@ -799,7 +824,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
if (indexed) {
indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
- PIPE_TRANSFER_READ, &ib_transfer);
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
}
draw_set_mapped_index_buffer(r300->draw, indices);
@@ -810,8 +836,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
draw_flush(r300->draw);
r300->draw_vbo_locked = FALSE;
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- if (r300->vertex_buffer[i].buffer) {
+ for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
+ if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
pipe_buffer_unmap(pipe, vb_transfer[i]);
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
}
@@ -874,10 +900,10 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
pipe_resource_reference(&r300->vbo, NULL);
r300->vbo = pipe_buffer_create(screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
R300_MAX_DRAW_VBO_SIZE);
r300->draw_vbo_offset = 0;
r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE;
- r300->validate_buffers = TRUE;
}
r300render->vertex_size = vertex_size;
@@ -896,7 +922,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render)
r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context,
r300->vbo,
- PIPE_TRANSFER_WRITE,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
&r300render->vbo_transfer);
assert(r300render->vbo_ptr);
@@ -963,7 +990,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
if (r300->draw_first_emitted) {
if (!r300_prepare_for_rendering(r300,
PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
- NULL, 6, 0, 0))
+ NULL, dwords, 0, 0))
return;
} else {
if (!r300_emit_states(r300,
@@ -972,23 +999,6 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
return;
}
- /* Uncomment to dump all VBOs rendered through this interface.
- * Slow and noisy!
- ptr = pipe_buffer_map(&r300render->r300->context,
- r300render->vbo, PIPE_TRANSFER_READ,
- &r300render->vbo_transfer);
-
- for (i = 0; i < count; i++) {
- printf("r300: Vertex %d\n", i);
- draw_dump_emitted_vertex(&r300->vertex_info, ptr);
- ptr += r300->vertex_info.size * 4;
- printf("\n");
- }
-
- pipe_buffer_unmap(&r300render->r300->context, r300render->vbo,
- r300render->vbo_transfer);
- */
-
BEGIN_CS(dwords);
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, r300render->prim));
@@ -1250,7 +1260,7 @@ static void r300_resource_resolve(struct pipe_context* pipe,
aa->aaresolve_ctl =
R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE |
R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE;
- r300->aa_state.size = 12;
+ r300->aa_state.size = 10;
r300_mark_atom_dirty(r300, &r300->aa_state);
/* Resolve the surface. */
diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c
index c48062c8084..f8c7558f4b4 100644
--- a/src/gallium/drivers/r300/r300_render_translate.c
+++ b/src/gallium/drivers/r300/r300_render_translate.c
@@ -20,207 +20,64 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**
- * The functions below translate vertex and index buffers to the layout
- * compatible with the hardware, so that all vertex and index fetches are
- * DWORD-aligned and all used vertex and index formats are supported.
- * For indices, an optional index offset is added to each index.
- */
-
#include "r300_context.h"
-#include "translate/translate.h"
#include "util/u_index_modify.h"
+#include "util/u_upload_mgr.h"
-/* XXX Optimization: use min_index and translate only that range. */
-/* XXX Use the uploader. */
-void r300_begin_vertex_translate(struct r300_context *r300,
- int min_index, int max_index)
-{
- struct pipe_context *pipe = &r300->context;
- struct translate_key key = {0};
- struct translate_element *te;
- unsigned tr_elem_index[PIPE_MAX_ATTRIBS] = {0};
- struct translate *tr;
- struct r300_vertex_element_state *ve = r300->velems;
- boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
- void *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
- struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}, *out_transfer;
- struct pipe_resource *out_buffer;
- unsigned i, num_verts;
- unsigned slot;
-
- /* Initialize the translate key, i.e. the recipe how vertices should be
- * translated. */
- for (i = 0; i < ve->count; i++) {
- struct pipe_vertex_buffer *vb =
- &r300->vertex_buffer[ve->velem[i].vertex_buffer_index];
- enum pipe_format output_format = ve->hw_format[i];
- unsigned output_format_size = ve->hw_format_size[i];
-
- /* Check for support. */
- if (ve->velem[i].src_format == ve->hw_format[i] &&
- (vb->buffer_offset + ve->velem[i].src_offset) % 4 == 0 &&
- vb->stride % 4 == 0) {
- continue;
- }
-
- /* Workaround for translate: output floats instead of halfs. */
- switch (output_format) {
- case PIPE_FORMAT_R16_FLOAT:
- output_format = PIPE_FORMAT_R32_FLOAT;
- output_format_size = 4;
- break;
- case PIPE_FORMAT_R16G16_FLOAT:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- output_format_size = 8;
- break;
- case PIPE_FORMAT_R16G16B16_FLOAT:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- output_format_size = 12;
- break;
- case PIPE_FORMAT_R16G16B16A16_FLOAT:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- output_format_size = 16;
- break;
- default:;
- }
-
- /* Add this vertex element. */
- te = &key.element[key.nr_elements];
- /*te->type;
- te->instance_divisor;*/
- te->input_buffer = ve->velem[i].vertex_buffer_index;
- te->input_format = ve->velem[i].src_format;
- te->input_offset = vb->buffer_offset + ve->velem[i].src_offset;
- te->output_format = output_format;
- te->output_offset = key.output_stride;
-
- key.output_stride += output_format_size;
- vb_translated[ve->velem[i].vertex_buffer_index] = TRUE;
- tr_elem_index[i] = key.nr_elements;
- key.nr_elements++;
- }
-
- /* Get a translate object. */
- tr = translate_cache_find(r300->tran.translate_cache, &key);
-
- /* Map buffers we want to translate. */
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- if (vb_translated[i]) {
- struct pipe_vertex_buffer *vb = &r300->vertex_buffer[i];
-
- vb_map[i] = pipe_buffer_map(pipe, vb->buffer,
- PIPE_TRANSFER_READ, &vb_transfer[i]);
-
- tr->set_buffer(tr, i, vb_map[i], vb->stride, max_index);
- }
- }
-
- /* Create and map the output buffer. */
- num_verts = max_index + 1;
-
- out_buffer = pipe_buffer_create(&r300->screen->screen,
- PIPE_BIND_VERTEX_BUFFER,
- key.output_stride * num_verts);
-
- out_map = pipe_buffer_map(pipe, out_buffer, PIPE_TRANSFER_WRITE,
- &out_transfer);
-
- /* Translate. */
- tr->run(tr, 0, num_verts, 0, out_map);
-
- /* Unmap all buffers. */
- for (i = 0; i < r300->vertex_buffer_count; i++) {
- if (vb_translated[i]) {
- pipe_buffer_unmap(pipe, vb_transfer[i]);
- }
- }
-
- pipe_buffer_unmap(pipe, out_transfer);
-
- /* Setup the new vertex buffer in the first free slot. */
- slot = ~0;
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- struct pipe_vertex_buffer *vb = &r300->vertex_buffer[i];
-
- if (!vb->buffer) {
- pipe_resource_reference(&r300->valid_vertex_buffer[i], out_buffer);
- vb->buffer_offset = 0;
- vb->stride = key.output_stride;
- slot = i;
- /* XXX probably need to preserve the real count for u_blitter_save_*. */
- r300->vertex_buffer_count = MAX2(r300->vertex_buffer_count, i+1);
- r300->validate_buffers = TRUE;
- break;
- }
- }
- /* XXX This may fail. */
- assert(slot != ~0);
-
- /* Save and replace vertex elements. */
- {
- struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
-
- r300->tran.saved_velems = r300->velems;
-
- for (i = 0; i < ve->count; i++) {
- if (vb_translated[ve->velem[i].vertex_buffer_index]) {
- te = &key.element[tr_elem_index[i]];
- new_velems[i].instance_divisor = ve->velem[i].instance_divisor;
- new_velems[i].src_format = te->output_format;
- new_velems[i].src_offset = te->output_offset;
- new_velems[i].vertex_buffer_index = slot;
- } else {
- memcpy(&new_velems[i], &ve->velem[i],
- sizeof(struct pipe_vertex_element));
- }
- }
-
- r300->tran.new_velems =
- pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
- pipe->bind_vertex_elements_state(pipe, r300->tran.new_velems);
- }
-
- pipe_resource_reference(&out_buffer, NULL);
-}
-void r300_end_vertex_translate(struct r300_context *r300)
-{
- struct pipe_context *pipe = &r300->context;
-
- /* Restore vertex elements. */
- pipe->bind_vertex_elements_state(pipe, r300->tran.saved_velems);
- pipe->delete_vertex_elements_state(pipe, r300->tran.new_velems);
-}
-
-/* XXX Use the uploader. */
void r300_translate_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned *index_size, unsigned index_offset,
unsigned *start, unsigned count)
{
+ struct pipe_resource *out_buffer = NULL;
+ unsigned out_offset;
+ void *ptr;
+ boolean flushed;
+
switch (*index_size) {
- case 1:
- util_shorten_ubyte_elts(&r300->context, index_buffer, index_offset, *start, count);
- *index_size = 2;
- *start = 0;
- r300->validate_buffers = TRUE;
- break;
+ case 1:
+ u_upload_alloc(r300->vbuf_mgr->uploader, 0, count * 2,
+ &out_offset, &out_buffer, &flushed, &ptr);
+
+ util_shorten_ubyte_elts_to_userptr(
+ &r300->context, *index_buffer, index_offset,
+ *start, count, ptr);
+
+ *index_buffer = NULL;
+ pipe_resource_reference(index_buffer, out_buffer);
+ *index_size = 2;
+ *start = out_offset / 2;
+ break;
+
+ case 2:
+ if (index_offset) {
+ u_upload_alloc(r300->vbuf_mgr->uploader, 0, count * 2,
+ &out_offset, &out_buffer, &flushed, &ptr);
+
+ util_rebuild_ushort_elts_to_userptr(&r300->context, *index_buffer,
+ index_offset, *start,
+ count, ptr);
+
+ *index_buffer = NULL;
+ pipe_resource_reference(index_buffer, out_buffer);
+ *start = out_offset / 2;
+ }
+ break;
- case 2:
- if (index_offset) {
- util_rebuild_ushort_elts(&r300->context, index_buffer, index_offset, *start, count);
- *start = 0;
- r300->validate_buffers = TRUE;
- }
- break;
+ case 4:
+ if (index_offset) {
+ u_upload_alloc(r300->vbuf_mgr->uploader, 0, count * 4,
+ &out_offset, &out_buffer, &flushed, &ptr);
- case 4:
- if (index_offset) {
- util_rebuild_uint_elts(&r300->context, index_buffer, index_offset, *start, count);
- *start = 0;
- r300->validate_buffers = TRUE;
- }
- break;
+ util_rebuild_uint_elts_to_userptr(&r300->context, *index_buffer,
+ index_offset, *start,
+ count, ptr);
+
+ *index_buffer = NULL;
+ pipe_resource_reference(index_buffer, out_buffer);
+ *start = out_offset / 4;
+ }
+ break;
}
}
diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c
index dd1df970594..f3d8c5b889f 100644
--- a/src/gallium/drivers/r300/r300_resource.c
+++ b/src/gallium/drivers/r300/r300_resource.c
@@ -38,26 +38,22 @@ r300_resource_create(struct pipe_screen *screen,
}
-static struct pipe_resource *
-r300_resource_from_handle(struct pipe_screen * screen,
- const struct pipe_resource *templ,
- struct winsys_handle *whandle)
+static unsigned r300_resource_is_referenced_by_cs(struct pipe_context *context,
+ struct pipe_resource *buf,
+ unsigned level, int layer)
{
- if (templ->target == PIPE_BUFFER)
- return NULL;
- else
- return r300_texture_from_handle(screen, templ, whandle);
+ return r300_buffer_is_referenced(context, buf);
}
void r300_init_resource_functions(struct r300_context *r300)
{
r300->context.get_transfer = u_get_transfer_vtbl;
r300->context.transfer_map = u_transfer_map_vtbl;
- r300->context.transfer_flush_region = u_transfer_flush_region_vtbl;
+ r300->context.transfer_flush_region = u_default_transfer_flush_region;
r300->context.transfer_unmap = u_transfer_unmap_vtbl;
r300->context.transfer_destroy = u_transfer_destroy_vtbl;
r300->context.transfer_inline_write = u_transfer_inline_write_vtbl;
- r300->context.is_resource_referenced = u_is_resource_referenced_vtbl;
+ r300->context.is_resource_referenced = r300_resource_is_referenced_by_cs;
r300->context.create_surface = r300_create_surface;
r300->context.surface_destroy = r300_surface_destroy;
}
@@ -65,8 +61,8 @@ void r300_init_resource_functions(struct r300_context *r300)
void r300_init_screen_resource_functions(struct r300_screen *r300screen)
{
r300screen->screen.resource_create = r300_resource_create;
- r300screen->screen.resource_from_handle = r300_resource_from_handle;
- r300screen->screen.resource_get_handle = u_resource_get_handle_vtbl;
+ r300screen->screen.resource_from_handle = r300_texture_from_handle;
+ r300screen->screen.resource_get_handle = r300_resource_get_handle;
r300screen->screen.resource_destroy = u_resource_destroy_vtbl;
r300screen->screen.user_buffer_create = r300_user_buffer_create;
}
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index c75aeaa10a7..77a9c6ad86f 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -34,10 +34,6 @@
#include "draw/draw_context.h"
-#ifdef HAVE_LLVM
-#include "gallivm/lp_bld_init.h"
-#endif
-
/* Return the identifier behind whom the brave coders responsible for this
* amalgamation of code, sweat, and duct tape, routinely obscure their names.
*
@@ -87,12 +83,8 @@ static const char* r300_get_name(struct pipe_screen* pscreen)
static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
{
struct r300_screen* r300screen = r300_screen(pscreen);
- boolean is_r400 = r300screen->caps.is_r400;
boolean is_r500 = r300screen->caps.is_r500;
- /* XXX extended shader capabilities of r400 unimplemented */
- is_r400 = FALSE;
-
switch (param) {
/* Supported features (boolean caps). */
case PIPE_CAP_NPOT_TEXTURES:
@@ -129,11 +121,13 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_DUAL_SOURCE_BLEND:
case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_INDEP_BLEND_FUNC:
- case PIPE_CAP_DEPTH_CLAMP: /* XXX implemented, but breaks Regnum Online */
+ case PIPE_CAP_DEPTH_CLAMP:
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_STREAM_OUTPUT:
case PIPE_CAP_PRIMITIVE_RESTART:
+ case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_ARRAY_TEXTURES:
return 0;
/* Texturing. */
@@ -175,9 +169,6 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
boolean is_r400 = r300screen->caps.is_r400;
boolean is_r500 = r300screen->caps.is_r500;
- /* XXX extended shader capabilities of r400 unimplemented */
- is_r400 = FALSE;
-
switch (shader)
{
case PIPE_SHADER_FRAGMENT:
@@ -407,6 +398,7 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
util_slab_destroy(&r300screen->pool_buffers);
+ pipe_mutex_destroy(r300screen->num_contexts_mutex);
if (rws)
rws->destroy(rws);
@@ -418,32 +410,28 @@ static void r300_fence_reference(struct pipe_screen *screen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
- struct r300_fence **oldf = (struct r300_fence**)ptr;
- struct r300_fence *newf = (struct r300_fence*)fence;
-
- if (pipe_reference(&(*oldf)->reference, &newf->reference))
- FREE(*oldf);
-
- *ptr = fence;
+ r300_winsys_bo_reference((struct r300_winsys_bo**)ptr,
+ (struct r300_winsys_bo*)fence);
}
static int r300_fence_signalled(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flags)
{
- struct r300_fence *rfence = (struct r300_fence*)fence;
+ struct r300_winsys_screen *rws = r300_screen(screen)->rws;
+ struct r300_winsys_bo *rfence = (struct r300_winsys_bo*)fence;
- return rfence->signalled ? 0 : 1; /* 0 == success */
+ return !rws->buffer_is_busy(rfence) ? 0 : 1; /* 0 == success */
}
static int r300_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flags)
{
- struct r300_fence *rfence = (struct r300_fence*)fence;
+ struct r300_winsys_screen *rws = r300_screen(screen)->rws;
+ struct r300_winsys_bo *rfence = (struct r300_winsys_bo*)fence;
- r300_finish(rfence->ctx);
- rfence->signalled = TRUE;
+ rws->buffer_wait(rfence);
return 0; /* 0 == success */
}
@@ -463,12 +451,19 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
r300_init_debug(r300screen);
r300_parse_chipset(&r300screen->caps);
+ if (SCREEN_DBG_ON(r300screen, DBG_NO_ZMASK))
+ r300screen->caps.zmask_ram = 0;
+ if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
+ r300screen->caps.hiz_ram = 0;
+
r300screen->caps.index_bias_supported =
r300screen->caps.is_r500 &&
rws->get_value(rws, R300_VID_DRM_2_3_0);
+ pipe_mutex_init(r300screen->num_contexts_mutex);
+
util_slab_create(&r300screen->pool_buffers,
- sizeof(struct r300_buffer), 64,
+ sizeof(struct r300_resource), 64,
UTIL_SLAB_SINGLETHREADED);
r300screen->rws = rws;
@@ -490,9 +485,5 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
util_format_s3tc_init();
-#ifdef HAVE_LLVM
- lp_build_init();
-#endif
-
return &r300screen->screen;
}
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 752f53b7579..576f9c1f4a9 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -52,6 +52,7 @@ struct r300_screen {
/* The number of created contexts to know whether we have multiple
* contexts or not. */
int num_contexts;
+ pipe_mutex num_contexts_mutex;
};
@@ -94,6 +95,7 @@ r300_winsys_screen(struct pipe_screen *screen) {
#define DBG_HYPERZ (1 << 12)
#define DBG_SCISSOR (1 << 13)
#define DBG_UPLOAD (1 << 14)
+#define DBG_INFO (1 << 15)
/* Features. */
#define DBG_ANISOHQ (1 << 16)
#define DBG_NO_TILING (1 << 17)
@@ -101,6 +103,8 @@ r300_winsys_screen(struct pipe_screen *screen) {
#define DBG_FAKE_OCC (1 << 19)
#define DBG_NO_OPT (1 << 20)
#define DBG_NO_CBZB (1 << 21)
+#define DBG_NO_ZMASK (1 << 22)
+#define DBG_NO_HIZ (1 << 23)
/* Statistics. */
#define DBG_P_STAT (1 << 25)
/*@}*/
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index cc3c1d7687e..1045911f3ae 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -34,117 +34,50 @@
#include "r300_winsys.h"
unsigned r300_buffer_is_referenced(struct pipe_context *context,
- struct pipe_resource *buf,
- enum r300_reference_domain domain)
+ struct pipe_resource *buf)
{
struct r300_context *r300 = r300_context(context);
- struct r300_buffer *rbuf = r300_buffer(buf);
+ struct r300_resource *rbuf = r300_resource(buf);
- if (r300_is_user_buffer(buf))
+ if (rbuf->b.user_ptr || rbuf->constant_buffer)
return PIPE_UNREFERENCED;
- if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain))
+ if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf))
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
return PIPE_UNREFERENCED;
}
-static unsigned r300_buffer_is_referenced_by_cs(struct pipe_context *context,
- struct pipe_resource *buf,
- unsigned level, int layer)
-{
- return r300_buffer_is_referenced(context, buf, R300_REF_CS);
-}
-
void r300_upload_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned index_size, unsigned *start,
- unsigned count)
+ unsigned count, uint8_t *ptr)
{
unsigned index_offset;
- uint8_t *ptr = r300_buffer(*index_buffer)->user_buffer;
boolean flushed;
*index_buffer = NULL;
- u_upload_data(r300->upload_ib,
+ u_upload_data(r300->vbuf_mgr->uploader,
0, count * index_size,
ptr + (*start * index_size),
&index_offset,
index_buffer, &flushed);
*start = index_offset / index_size;
-
- if (flushed || !r300->upload_ib_validated) {
- r300->upload_ib_validated = FALSE;
- r300->validate_buffers = TRUE;
- }
-}
-
-void r300_upload_user_buffers(struct r300_context *r300,
- int min_index, int max_index)
-{
- int i, nr = r300->velems->count;
- unsigned count = max_index + 1 - min_index;
- boolean flushed;
- boolean uploaded[16] = {0};
-
- for (i = 0; i < nr; i++) {
- unsigned index = r300->velems->velem[i].vertex_buffer_index;
- struct pipe_vertex_buffer *vb = &r300->vertex_buffer[index];
- struct r300_buffer *userbuf = r300_buffer(vb->buffer);
-
- if (userbuf && userbuf->user_buffer && !uploaded[index]) {
- unsigned first, size;
-
- if (vb->stride) {
- first = vb->stride * min_index;
- size = vb->stride * count;
- } else {
- first = 0;
- size = r300->velems->hw_format_size[i];
- }
-
- DBG(r300, DBG_UPLOAD,
- "Uploading %i bytes, index: %i, buffer: %p, userptr: %p "
- "offset: %i, stride: %i.\n",
- size, index, userbuf, userbuf->user_buffer,
- vb->buffer_offset, vb->stride);
-
- u_upload_data(r300->upload_vb, first, size,
- userbuf->user_buffer + first,
- &vb->buffer_offset,
- &r300->valid_vertex_buffer[index],
- &flushed);
-
- vb->buffer_offset -= first;
-
- r300->vertex_arrays_dirty = TRUE;
-
- if (flushed || !r300->upload_vb_validated) {
- r300->upload_vb_validated = FALSE;
- r300->validate_buffers = TRUE;
- }
- uploaded[index] = TRUE;
- } else {
- assert(r300->valid_vertex_buffer[index]);
- }
- }
- DBG(r300, DBG_UPLOAD, "-------\n");
}
static void r300_buffer_destroy(struct pipe_screen *screen,
struct pipe_resource *buf)
{
struct r300_screen *r300screen = r300_screen(screen);
- struct r300_buffer *rbuf = r300_buffer(buf);
- struct r300_winsys_screen *rws = r300screen->rws;
+ struct r300_resource *rbuf = r300_resource(buf);
if (rbuf->constant_buffer)
FREE(rbuf->constant_buffer);
if (rbuf->buf)
- rws->buffer_reference(rws, &rbuf->buf, NULL);
+ r300_winsys_bo_reference(&rbuf->buf, NULL);
util_slab_free(&r300screen->pool_buffers, rbuf);
}
@@ -188,15 +121,15 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
struct r300_context *r300 = r300_context(pipe);
struct r300_screen *r300screen = r300_screen(pipe->screen);
struct r300_winsys_screen *rws = r300screen->rws;
- struct r300_buffer *rbuf = r300_buffer(transfer->resource);
+ struct r300_resource *rbuf = r300_resource(transfer->resource);
uint8_t *map;
- if (rbuf->user_buffer)
- return (uint8_t *) rbuf->user_buffer + transfer->box.x;
+ if (rbuf->b.user_ptr)
+ return (uint8_t *) rbuf->b.user_ptr + transfer->box.x;
if (rbuf->constant_buffer)
return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
- map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage);
+ map = rws->buffer_map(rbuf->buf, r300->cs, transfer->usage);
if (map == NULL)
return NULL;
@@ -204,22 +137,15 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
return map + transfer->box.x;
}
-static void r300_buffer_transfer_flush_region( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box)
-{
- /* no-op */
-}
-
static void r300_buffer_transfer_unmap( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
struct r300_screen *r300screen = r300_screen(pipe->screen);
struct r300_winsys_screen *rws = r300screen->rws;
- struct r300_buffer *rbuf = r300_buffer(transfer->resource);
+ struct r300_resource *rbuf = r300_resource(transfer->resource);
if (rbuf->buf) {
- rws->buffer_unmap(rws, rbuf->buf);
+ rws->buffer_unmap(rbuf->buf);
}
}
@@ -234,32 +160,32 @@ static void r300_buffer_transfer_inline_write(struct pipe_context *pipe,
{
struct r300_context *r300 = r300_context(pipe);
struct r300_winsys_screen *rws = r300->screen->rws;
- struct r300_buffer *rbuf = r300_buffer(resource);
+ struct r300_resource *rbuf = r300_resource(resource);
uint8_t *map = NULL;
if (rbuf->constant_buffer) {
memcpy(rbuf->constant_buffer + box->x, data, box->width);
return;
}
- assert(rbuf->user_buffer == NULL);
+ assert(rbuf->b.user_ptr == NULL);
- map = rws->buffer_map(rws, rbuf->buf, r300->cs,
+ map = rws->buffer_map(rbuf->buf, r300->cs,
PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage);
memcpy(map + box->x, data, box->width);
- rws->buffer_unmap(rws, rbuf->buf);
+ rws->buffer_unmap(rbuf->buf);
}
-struct u_resource_vtbl r300_buffer_vtbl =
+static const struct u_resource_vtbl r300_buffer_vtbl =
{
- u_default_resource_get_handle, /* get_handle */
+ NULL, /* get_handle */
r300_buffer_destroy, /* resource_destroy */
- r300_buffer_is_referenced_by_cs, /* is_buffer_referenced */
+ NULL, /* is_buffer_referenced */
r300_buffer_get_transfer, /* get_transfer */
r300_buffer_transfer_destroy, /* transfer_destroy */
r300_buffer_transfer_map, /* transfer_map */
- r300_buffer_transfer_flush_region, /* transfer_flush_region */
+ NULL, /* transfer_flush_region */
r300_buffer_transfer_unmap, /* transfer_unmap */
r300_buffer_transfer_inline_write /* transfer_inline_write */
};
@@ -268,42 +194,41 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
{
struct r300_screen *r300screen = r300_screen(screen);
- struct r300_buffer *rbuf;
+ struct r300_resource *rbuf;
unsigned alignment = 16;
rbuf = util_slab_alloc(&r300screen->pool_buffers);
- rbuf->magic = R300_BUFFER_MAGIC;
-
- rbuf->b.b = *templ;
- rbuf->b.vtbl = &r300_buffer_vtbl;
- pipe_reference_init(&rbuf->b.b.reference, 1);
- rbuf->b.b.screen = screen;
+ rbuf->b.b.b = *templ;
+ rbuf->b.b.vtbl = &r300_buffer_vtbl;
+ pipe_reference_init(&rbuf->b.b.b.reference, 1);
+ rbuf->b.b.b.screen = screen;
+ rbuf->b.user_ptr = NULL;
rbuf->domain = R300_DOMAIN_GTT;
rbuf->buf = NULL;
+ rbuf->buf_size = templ->width0;
rbuf->constant_buffer = NULL;
- rbuf->user_buffer = NULL;
/* Alloc constant buffers in RAM. */
if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
rbuf->constant_buffer = MALLOC(templ->width0);
- return &rbuf->b.b;
+ return &rbuf->b.b.b;
}
rbuf->buf =
r300screen->rws->buffer_create(r300screen->rws,
- rbuf->b.b.width0, alignment,
- rbuf->b.b.bind, rbuf->b.b.usage,
+ rbuf->b.b.b.width0, alignment,
+ rbuf->b.b.b.bind, rbuf->b.b.b.usage,
rbuf->domain);
- rbuf->cs_buf =
- r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf);
-
if (!rbuf->buf) {
util_slab_free(&r300screen->pool_buffers, rbuf);
return NULL;
}
- return &rbuf->b.b;
+ rbuf->cs_buf =
+ r300screen->rws->buffer_get_cs_handle(rbuf->buf);
+
+ return &rbuf->b.b.b;
}
struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
@@ -311,27 +236,26 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
unsigned bind)
{
struct r300_screen *r300screen = r300_screen(screen);
- struct r300_buffer *rbuf;
+ struct r300_resource *rbuf;
rbuf = util_slab_alloc(&r300screen->pool_buffers);
- rbuf->magic = R300_BUFFER_MAGIC;
-
- pipe_reference_init(&rbuf->b.b.reference, 1);
- rbuf->b.vtbl = &r300_buffer_vtbl;
- rbuf->b.b.screen = screen;
- rbuf->b.b.target = PIPE_BUFFER;
- rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
- rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
- rbuf->b.b.bind = bind;
- rbuf->b.b.width0 = ~0;
- rbuf->b.b.height0 = 1;
- rbuf->b.b.depth0 = 1;
- rbuf->b.b.array_size = 1;
- rbuf->b.b.flags = 0;
+ pipe_reference_init(&rbuf->b.b.b.reference, 1);
+ rbuf->b.b.b.screen = screen;
+ rbuf->b.b.b.target = PIPE_BUFFER;
+ rbuf->b.b.b.format = PIPE_FORMAT_R8_UNORM;
+ rbuf->b.b.b.usage = PIPE_USAGE_IMMUTABLE;
+ rbuf->b.b.b.bind = bind;
+ rbuf->b.b.b.width0 = ~0;
+ rbuf->b.b.b.height0 = 1;
+ rbuf->b.b.b.depth0 = 1;
+ rbuf->b.b.b.array_size = 1;
+ rbuf->b.b.b.flags = 0;
+ rbuf->b.b.vtbl = &r300_buffer_vtbl;
+ rbuf->b.user_ptr = ptr;
rbuf->domain = R300_DOMAIN_GTT;
rbuf->buf = NULL;
+ rbuf->buf_size = size;
rbuf->constant_buffer = NULL;
- rbuf->user_buffer = ptr;
- return &rbuf->b.b;
+ return &rbuf->b.b.b;
}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
index 58dec8539b6..14bee460d5b 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.h
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -35,39 +35,12 @@
#include "r300_winsys.h"
#include "r300_context.h"
-#define R300_BUFFER_MAGIC 0xabcd1234
-#define R300_BUFFER_MAX_RANGES 32
-
-struct r300_buffer_range {
- uint32_t start;
- uint32_t end;
-};
-
-/* Vertex buffer. */
-struct r300_buffer
-{
- struct u_resource b;
-
- uint32_t magic;
-
- struct r300_winsys_buffer *buf;
- struct r300_winsys_cs_buffer *cs_buf;
-
- enum r300_buffer_domain domain;
-
- uint8_t *user_buffer;
- uint8_t *constant_buffer;
-};
-
/* Functions. */
-void r300_upload_user_buffers(struct r300_context *r300,
- int min_index, int max_index);
-
void r300_upload_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned index_size, unsigned *start,
- unsigned count);
+ unsigned count, uint8_t *ptr);
struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
const struct pipe_resource *templ);
@@ -77,8 +50,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
unsigned bind);
unsigned r300_buffer_is_referenced(struct pipe_context *context,
- struct pipe_resource *buf,
- enum r300_reference_domain domain);
+ struct pipe_resource *buf);
/* Inline functions. */
@@ -87,9 +59,4 @@ static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer)
return (struct r300_buffer *)buffer;
}
-static INLINE boolean r300_is_user_buffer(struct pipe_resource *buffer)
-{
- return r300_buffer(buffer)->user_buffer ? true : false;
-}
-
#endif
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 3a97b76a4c8..09f18b3e624 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -28,6 +28,7 @@
#include "util/u_mm.h"
#include "util/u_memory.h"
#include "util/u_pack_color.h"
+#include "util/u_transfer.h"
#include "tgsi/tgsi_parse.h"
@@ -442,8 +443,7 @@ static void r300_set_clip_state(struct pipe_context* pipe,
OUT_CB_TABLE(state->ucp, state->nr * 4);
}
OUT_CB_REG(R300_VAP_CLIP_CNTL, ((1 << state->nr) - 1) |
- R300_PS_UCP_MODE_CLIP_AS_TRIFAN |
- (state->depth_clamp ? R300_CLIP_DISABLE : 0));
+ R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
END_CB;
r300_mark_atom_dirty(r300, &r300->clip_state);
@@ -617,21 +617,16 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
}
static void r300_tex_set_tiling_flags(struct r300_context *r300,
- struct r300_texture *tex, unsigned level)
+ struct r300_resource *tex,
+ unsigned level)
{
/* Check if the macrotile flag needs to be changed.
* Skip changing the flags otherwise. */
- if (tex->desc.macrotile[tex->surface_level] !=
- tex->desc.macrotile[level]) {
- /* Tiling determines how DRM treats the buffer data.
- * We must flush CS when changing it if the buffer is referenced. */
- if (r300->rws->cs_is_buffer_referenced(r300->cs,
- tex->cs_buffer, R300_REF_CS))
- r300->context.flush(&r300->context, 0, NULL);
-
- r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->desc.microtile, tex->desc.macrotile[level],
- tex->desc.stride_in_bytes[0]);
+ if (tex->tex.macrotile[tex->surface_level] !=
+ tex->tex.macrotile[level]) {
+ r300->rws->buffer_set_tiling(tex->buf, r300->cs,
+ tex->tex.microtile, tex->tex.macrotile[level],
+ tex->tex.stride_in_bytes[0]);
tex->surface_level = level;
}
@@ -646,12 +641,12 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300,
/* Set tiling flags for new surfaces. */
for (i = 0; i < state->nr_cbufs; i++) {
r300_tex_set_tiling_flags(r300,
- r300_texture(state->cbufs[i]->texture),
+ r300_resource(state->cbufs[i]->texture),
state->cbufs[i]->u.tex.level);
}
if (state->zsbuf) {
r300_tex_set_tiling_flags(r300,
- r300_texture(state->zsbuf->texture),
+ r300_resource(state->zsbuf->texture),
state->zsbuf->u.tex.level);
}
}
@@ -660,7 +655,7 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
const char *binding)
{
struct pipe_resource *tex = surf->texture;
- struct r300_texture *rtex = r300_texture(tex);
+ struct r300_resource *rtex = r300_resource(tex);
fprintf(stderr,
"r300: %s[%i] Dim: %ix%i, Firstlayer: %i, "
@@ -673,9 +668,9 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
surf->u.tex.first_layer, surf->u.tex.last_layer, surf->u.tex.level,
util_format_short_name(surf->format),
- rtex->desc.macrotile[0] ? "YES" : " NO",
- rtex->desc.microtile ? "YES" : " NO",
- rtex->desc.stride_in_pixels[0],
+ rtex->tex.macrotile[0] ? "YES" : " NO",
+ rtex->tex.microtile ? "YES" : " NO",
+ rtex->tex.stride_in_pixels[0],
tex->width0, tex->height0, tex->depth0,
tex->last_level, util_format_short_name(tex->format));
}
@@ -695,8 +690,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
}
if (change == R300_CHANGED_FB_STATE ||
- change == R300_CHANGED_CBZB_FLAG ||
- change == R300_CHANGED_ZCLEAR_FLAG) {
+ change == R300_CHANGED_HYPERZ_FLAG) {
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
@@ -720,8 +714,8 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
}
static void
- r300_set_framebuffer_state(struct pipe_context* pipe,
- const struct pipe_framebuffer_state* state)
+r300_set_framebuffer_state(struct pipe_context* pipe,
+ const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
@@ -729,7 +723,6 @@ static void
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;
if (r300->screen->caps.is_r500) {
max_width = max_height = 4096;
@@ -745,6 +738,32 @@ static void
return;
}
+ if (old_state->zsbuf && r300->zmask_in_use && !r300->zmask_locked) {
+ /* There is a zmask in use, what are we gonna do? */
+ if (state->zsbuf) {
+ if (!pipe_surface_equal(old_state->zsbuf, state->zsbuf)) {
+ /* Decompress the currently bound zbuffer before we bind another one. */
+ r300_decompress_zmask(r300);
+ }
+ } else {
+ /* We don't bind another zbuffer, so lock the current one. */
+ r300->zmask_locked = TRUE;
+ pipe_surface_reference(&r300->locked_zbuffer, old_state->zsbuf);
+ }
+ } else if (r300->zmask_locked && r300->locked_zbuffer) {
+ /* We have a locked zbuffer now, what are we gonna do? */
+ if (state->zsbuf) {
+ if (!pipe_surface_equal(r300->locked_zbuffer, state->zsbuf)) {
+ /* We are binding some other zbuffer, so decompress the locked one,
+ * it gets unlocked automatically. */
+ r300_decompress_zmask_locked_unsafe(r300);
+ } else {
+ /* We are binding the locked zbuffer again, so unlock it. */
+ r300->zmask_locked = FALSE;
+ }
+ }
+ }
+
/* If nr_cbufs is changed from zero to non-zero or vice versa... */
if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
r300_mark_atom_dirty(r300, &r300->blend_state);
@@ -759,14 +778,14 @@ static void
util_copy_framebuffer_state(r300->fb_state.state, state);
+ if (!r300->zmask_locked) {
+ pipe_surface_reference(&r300->locked_zbuffer, NULL);
+ }
+
r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
- r300->validate_buffers = TRUE;
- r300->z_compression = false;
-
if (state->zsbuf) {
- blocksize = util_format_get_blocksize(state->zsbuf->texture->format);
- switch (blocksize) {
+ switch (util_format_get_blocksize(state->zsbuf->texture->format)) {
case 2:
zbuffer_bpp = 16;
break;
@@ -774,30 +793,19 @@ static void
zbuffer_bpp = 24;
break;
}
+
+ /* Setup Hyper-Z. */
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;
+ struct r300_resource *tex = r300_resource(zs_surf->base.texture);
int level = zs_surf->base.u.tex.level;
- tex = r300_texture(zs_surf->base.texture);
-
/* work out whether we can support hiz on this buffer */
r300_hiz_alloc_block(r300, zs_surf);
-
- /* work out whether we can support zmask features on this buffer */
- r300_zmask_alloc_block(r300, zs_surf, compress);
-
- if (tex->zmask_mem[level]) {
- /* compression causes hangs on 16-bit */
- if (zbuffer_bpp == 24)
- r300->z_compression = compress;
- }
+
DBG(r300, DBG_HYPERZ,
- "hyper-z features: hiz: %d @ %08x z-compression: %d z-fastfill: %d @ %08x\n", tex->hiz_mem[level] ? 1 : 0,
- tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef,
- r300->z_compression, tex->zmask_mem[level] ? 1 : 0,
- tex->zmask_mem[level] ? tex->zmask_mem[level]->ofs : 0xdeadbeef);
+ "hyper-z features: hiz: %d @ %08x\n", tex->hiz_mem[level] ? 1 : 0,
+ tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef);
}
/* Polygon offset depends on the zbuffer bit depth. */
@@ -1300,7 +1308,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
- struct r300_texture *texture;
+ struct r300_resource *texture;
unsigned i, real_num_views = 0, view_index = 0;
unsigned tex_units = r300->screen->caps.num_tex_units;
boolean dirty_tex = FALSE;
@@ -1329,8 +1337,8 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
/* Set the texrect factor in the fragment shader.
* Needed for RECT and NPOT fallback. */
- texture = r300_texture(views[i]->texture);
- if (texture->desc.is_npot) {
+ texture = r300_resource(views[i]->texture);
+ if (texture->tex.is_npot) {
r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);
}
@@ -1350,7 +1358,6 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
state->sampler_view_count = count;
r300_mark_atom_dirty(r300, &r300->textures_state);
- r300->validate_buffers = TRUE;
if (dirty_tex) {
r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
@@ -1363,7 +1370,7 @@ r300_create_sampler_view(struct pipe_context *pipe,
const struct pipe_sampler_view *templ)
{
struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
- struct r300_texture *tex = r300_texture(texture);
+ struct r300_resource *tex = r300_resource(texture);
boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle;
@@ -1465,10 +1472,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
- const struct pipe_vertex_buffer *vbo;
- unsigned i, max_index = (1 << 24) - 1;
- boolean any_user_buffer = FALSE;
- boolean any_nonuser_buffer = FALSE;
+ unsigned i;
struct pipe_vertex_buffer dummy_vb = {0};
/* There must be at least one vertex buffer set, otherwise it locks up. */
@@ -1478,90 +1482,20 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
count = 1;
}
- if (count == r300->vertex_buffer_count &&
- memcmp(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count) == 0) {
- return;
- }
+ u_vbuf_mgr_set_vertex_buffers(r300->vbuf_mgr, count, buffers);
if (r300->screen->caps.has_tcl) {
/* HW TCL. */
- r300->incompatible_vb_layout = FALSE;
-
- /* Check if the strides and offsets are aligned to the size of DWORD. */
- for (i = 0; i < count; i++) {
- if (buffers[i].buffer) {
- if (buffers[i].stride % 4 != 0 ||
- buffers[i].buffer_offset % 4 != 0) {
- r300->incompatible_vb_layout = TRUE;
- break;
- }
- }
- }
-
for (i = 0; i < count; i++) {
- vbo = &buffers[i];
-
- /* Skip NULL buffers */
- if (!vbo->buffer) {
- continue;
- }
-
- /* User buffers have no info about maximum index,
- * we will have to compute it in draw_vbo. */
- if (r300_is_user_buffer(vbo->buffer)) {
- any_user_buffer = TRUE;
- continue;
- }
- any_nonuser_buffer = TRUE;
-
- /* The stride of zero means we will be fetching only the first
- * vertex, so don't care about max_index. */
- if (!vbo->stride)
- continue;
-
- /* Update the maximum index. */
- {
- unsigned vbo_max_index =
- (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
- max_index = MIN2(max_index, vbo_max_index);
+ if (buffers[i].buffer &&
+ !r300_resource(buffers[i].buffer)->b.user_ptr) {
}
}
-
- r300->any_user_vbs = any_user_buffer;
- r300->vertex_buffer_max_index = max_index;
r300->vertex_arrays_dirty = TRUE;
- if (any_nonuser_buffer)
- r300->validate_buffers = TRUE;
- if (!any_user_buffer)
- r300->upload_vb_validated = FALSE;
} else {
/* SW TCL. */
draw_set_vertex_buffers(r300->draw, count, buffers);
}
-
- /* Common code. */
- for (i = 0; i < count; i++) {
- vbo = &buffers[i];
-
- /* Reference our buffer. */
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
- if (vbo->buffer && r300_is_user_buffer(vbo->buffer)) {
- pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL);
- } else {
- pipe_resource_reference(&r300->valid_vertex_buffer[i], vbo->buffer);
- }
- }
- for (; i < r300->vertex_buffer_count; i++) {
- /* Dereference any old buffers. */
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
- pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL);
- }
-
- memcpy(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count);
-
- r300->vertex_buffer_count = count;
}
static void r300_set_index_buffer(struct pipe_context* pipe,
@@ -1570,14 +1504,11 @@ static void r300_set_index_buffer(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
if (ib && ib->buffer) {
+ assert(ib->offset % ib->index_size == 0);
+
pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer);
memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer));
-
- if (r300->screen->caps.has_tcl &&
- !r300_is_user_buffer(ib->buffer)) {
- r300->validate_buffers = TRUE;
- r300->upload_ib_validated = FALSE;
- }
+ r300->index_buffer.offset /= r300->index_buffer.index_size;
}
else {
pipe_resource_reference(&r300->index_buffer.buffer, NULL);
@@ -1607,7 +1538,7 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
* so PSC should just route stuff based on the vertex elements,
* and not on attrib information. */
for (i = 0; i < velems->count; i++) {
- format = velems->hw_format[i];
+ format = velems->velem[i].src_format;
type = r300_translate_vertex_data_type(format);
if (type == R300_INVALID_FORMAT) {
@@ -1639,16 +1570,13 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
vstream->count = (i >> 1) + 1;
}
-#define FORMAT_REPLACE(what, withwhat) \
- case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
-
static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
unsigned count,
const struct pipe_vertex_element* attribs)
{
+ struct r300_context *r300 = r300_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. */
@@ -1660,77 +1588,26 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
- if (velems != NULL) {
- velems->count = count;
- memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
-
- if (r300_screen(pipe->screen)->caps.has_tcl) {
- /* Set the best hw format in case the original format is not
- * supported by hw. */
- for (i = 0; i < count; i++) {
- velems->hw_format[i] = velems->velem[i].src_format;
- format = &velems->hw_format[i];
-
- /* This is basically the list of unsupported formats.
- * For now we don't care about the alignment, that's going to
- * be sorted out after the PSC setup. */
- 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(R32_UNORM, R32_FLOAT);
- FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_USCALED, R32_FLOAT);
- FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_SNORM, R32_FLOAT);
- FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_SSCALED, R32_FLOAT);
- FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_FIXED, R32_FLOAT);
- FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT);
-
- default:;
- }
+ if (!velems)
+ return NULL;
- velems->incompatible_layout =
- velems->incompatible_layout ||
- velems->velem[i].src_format != velems->hw_format[i] ||
- velems->velem[i].src_offset % 4 != 0;
- }
+ velems->count = count;
+ velems->vmgr_elements =
+ u_vbuf_mgr_create_vertex_elements(r300->vbuf_mgr, count, attribs,
+ velems->velem);
- /* Now setup PSC.
- * The unused components will be replaced by (..., 0, 1). */
- r300_vertex_psc(velems);
-
- /* Align the formats to the size of DWORD.
- * We only care about the blocksizes of the formats since
- * 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
- * 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;
- }
+ if (r300_screen(pipe->screen)->caps.has_tcl) {
+ /* Setup PSC.
+ * The unused components will be replaced by (..., 0, 1). */
+ r300_vertex_psc(velems);
+
+ for (i = 0; i < count; i++) {
+ velems->format_size[i] =
+ align(util_format_get_blocksize(velems->velem[i].src_format), 4);
+ velems->vertex_size_dwords += velems->format_size[i] / 4;
}
}
+
return velems;
}
@@ -1746,6 +1623,8 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
r300->velems = velems;
+ u_vbuf_mgr_bind_vertex_elements(r300->vbuf_mgr, state, velems->vmgr_elements);
+
if (r300->draw) {
draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
return;
@@ -1758,7 +1637,11 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
{
- FREE(state);
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_vertex_element_state *velems = state;
+
+ u_vbuf_mgr_destroy_vertex_elements(r300->vbuf_mgr, velems->vmgr_elements);
+ FREE(state);
}
static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -1845,7 +1728,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
{
struct r300_context* r300 = r300_context(pipe);
struct r300_constant_buffer *cbuf;
- struct r300_buffer *rbuf = r300_buffer(buf);
+ struct r300_resource *rbuf = r300_resource(buf);
uint32_t *mapped;
switch (shader) {
@@ -1862,8 +1745,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
if (buf == NULL || buf->width0 == 0)
return;
- if (rbuf->user_buffer)
- mapped = (uint32_t*)rbuf->user_buffer;
+ if (rbuf->b.user_ptr)
+ mapped = (uint32_t*)rbuf->b.user_ptr;
else if (rbuf->constant_buffer)
mapped = (uint32_t*)rbuf->constant_buffer;
else
@@ -1947,6 +1830,7 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
r300->context.set_index_buffer = r300_set_index_buffer;
+ r300->context.redefine_user_buffer = u_default_redefine_user_buffer;
r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 95be7849f8f..003fe9a58cd 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -489,7 +489,8 @@ static void r300_update_rs_block(struct r300_context *r300)
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);
+ "not enough hardware slots (it's not a bug, do not "
+ "report it).\n", i);
}
}
@@ -524,7 +525,8 @@ static void r300_update_rs_block(struct r300_context *r300)
DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n");
} else {
fprintf(stderr, "r300: ERROR: FS input fog unassigned, "
- "not enough hardware slots.\n");
+ "not enough hardware slots. (it's not a bug, "
+ "do not report it)\n");
}
}
}
@@ -551,7 +553,8 @@ static void r300_update_rs_block(struct r300_context *r300)
} else {
if (fs_inputs->wpos != ATTR_UNUSED && tex_count >= 8) {
fprintf(stderr, "r300: ERROR: FS input WPOS unassigned, "
- "not enough hardware slots.\n");
+ "not enough hardware slots. (it's not a bug, do not "
+ "report it)\n");
}
}
@@ -674,7 +677,20 @@ static uint32_t r300_get_border_color(enum pipe_format format,
case 16:
if (desc->nr_channels <= 2) {
border_swizzled[0] = border_swizzled[2];
- util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_UNORM, &uc);
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
+ util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_FLOAT, &uc);
+ } else {
+ util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_UNORM, &uc);
+ }
+ } else {
+ util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
+ }
+ break;
+
+ case 32:
+ if (desc->nr_channels == 1) {
+ border_swizzled[0] = border_swizzled[2];
+ util_pack_color(border_swizzled, PIPE_FORMAT_R32_FLOAT, &uc);
} else {
util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
}
@@ -684,6 +700,25 @@ static uint32_t r300_get_border_color(enum pipe_format format,
return uc.ui;
}
+static boolean util_format_is_float(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ unsigned i;
+
+ if (!format)
+ return FALSE;
+
+ /* Find the first non-void channel. */
+ for (i = 0; i < 4; i++)
+ if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
+ break;
+
+ if (i == 4)
+ return FALSE;
+
+ return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE;
+}
+
static void r300_merge_textures_and_samplers(struct r300_context* r300)
{
struct r300_textures_state *state =
@@ -691,7 +726,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
struct r300_texture_sampler_state *texstate;
struct r300_sampler_state *sampler;
struct r300_sampler_view *view;
- struct r300_texture *tex;
+ struct r300_resource *tex;
unsigned min_level, max_level, i, j, size;
unsigned count = MIN2(state->sampler_view_count,
state->sampler_state_count);
@@ -709,7 +744,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
state->tx_enable |= 1 << i;
view = state->sampler_views[i];
- tex = r300_texture(view->base.texture);
+ tex = r300_resource(view->base.texture);
sampler = state->sampler_states[i];
texstate = &state->regs[i];
@@ -725,32 +760,37 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
/* determine min/max levels */
max_level = MIN3(sampler->max_lod + view->base.u.tex.first_level,
- tex->desc.b.b.last_level, view->base.u.tex.last_level);
+ tex->b.b.b.last_level, view->base.u.tex.last_level);
min_level = MIN2(sampler->min_lod + view->base.u.tex.first_level,
max_level);
- if (tex->desc.is_npot && min_level > 0) {
+ if (tex->tex.is_npot && min_level > 0) {
/* Even though we do not implement mipmapping for NPOT
* textures, we should at least honor the minimum level
* which is allowed to be displayed. We do this by setting up
- * an i-th mipmap level as the zero level. */
- r300_texture_setup_format_state(r300->screen, &tex->desc,
+ * the i-th mipmap level as the zero level. */
+ unsigned offset = tex->tex_offset +
+ tex->tex.offset_in_bytes[min_level];
+
+ r300_texture_setup_format_state(r300->screen, tex,
min_level,
&texstate->format);
- texstate->format.tile_config |=
- tex->desc.offset_in_bytes[min_level] & 0xffffffe0;
- assert((tex->desc.offset_in_bytes[min_level] & 0x1f) == 0);
+ texstate->format.tile_config |= offset & 0xffffffe0;
+ assert((offset & 0x1f) == 0);
+ } else {
+ texstate->format.tile_config |= tex->tex_offset & 0xffffffe0;
+ assert((tex->tex_offset & 0x1f) == 0);
}
/* Assign a texture cache region. */
texstate->format.format1 |= view->texcache_region;
/* Depth textures are kinda special. */
- if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
+ if (util_format_is_depth_or_stencil(tex->b.b.b.format)) {
unsigned char depth_swizzle[4];
if (!r300->screen->caps.is_r500 &&
- util_format_get_blocksizebits(tex->desc.b.b.format) == 32) {
+ util_format_get_blocksizebits(tex->b.b.b.format) == 32) {
/* X24x8 is sampled as Y16X16 on r3xx-r4xx.
* The depth here is at the Y component. */
for (j = 0; j < 4; j++)
@@ -775,17 +815,17 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
}
if (r300->screen->caps.dxtc_swizzle &&
- util_format_is_compressed(tex->desc.b.b.format)) {
+ util_format_is_compressed(tex->b.b.b.format)) {
texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE;
}
/* to emulate 1D textures through 2D ones correctly */
- if (tex->desc.b.b.target == PIPE_TEXTURE_1D) {
+ if (tex->b.b.b.target == PIPE_TEXTURE_1D) {
texstate->filter0 &= ~R300_TX_WRAP_T_MASK;
texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
}
- if (tex->desc.is_npot) {
+ if (tex->tex.is_npot) {
/* NPOT textures don't support mip filter, unfortunately.
* This prevents incorrect rendering. */
texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
@@ -814,6 +854,32 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
texstate->filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
}
+ /* Float textures only support nearest and mip-nearest filtering. */
+ if (util_format_is_float(tex->b.b.b.format)) {
+ /* No MAG linear filtering. */
+ if ((texstate->filter0 & R300_TX_MAG_FILTER_MASK) ==
+ R300_TX_MAG_FILTER_LINEAR) {
+ texstate->filter0 &= ~R300_TX_MAG_FILTER_MASK;
+ texstate->filter0 |= R300_TX_MAG_FILTER_NEAREST;
+ }
+ /* No MIN linear filtering. */
+ if ((texstate->filter0 & R300_TX_MIN_FILTER_MASK) ==
+ R300_TX_MIN_FILTER_LINEAR) {
+ texstate->filter0 &= ~R300_TX_MIN_FILTER_MASK;
+ texstate->filter0 |= R300_TX_MIN_FILTER_NEAREST;
+ }
+ /* No mipmap linear filtering. */
+ if ((texstate->filter0 & R300_TX_MIN_FILTER_MIP_MASK) ==
+ R300_TX_MIN_FILTER_MIP_LINEAR) {
+ texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
+ texstate->filter0 |= R300_TX_MIN_FILTER_MIP_NEAREST;
+ }
+ /* No anisotropic filtering. */
+ texstate->filter0 &= ~R300_TX_MAX_ANISO_MASK;
+ texstate->filter1 &= ~R500_TX_MAX_ANISO_MASK;
+ texstate->filter1 &= ~R500_TX_ANISO_HIGH_QUALITY;
+ }
+
texstate->filter0 |= i << 28;
size += 16;
@@ -862,11 +928,35 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
}
}
-void r300_update_derived_state(struct r300_context* r300)
+static void r300_decompress_depth_textures(struct r300_context *r300)
{
- r300_flush_depth_textures(r300);
+ struct r300_textures_state *state =
+ (struct r300_textures_state*)r300->textures_state.state;
+ struct pipe_resource *tex;
+ unsigned count = MIN2(state->sampler_view_count,
+ state->sampler_state_count);
+ unsigned i;
+
+ if (!r300->zmask_locked || !r300->locked_zbuffer) {
+ return;
+ }
+ for (i = 0; i < count; i++) {
+ if (state->sampler_views[i] && state->sampler_states[i]) {
+ tex = state->sampler_views[i]->base.texture;
+
+ if (tex == r300->locked_zbuffer->texture) {
+ r300_decompress_zmask_locked(r300);
+ return;
+ }
+ }
+ }
+}
+
+void r300_update_derived_state(struct r300_context* r300)
+{
if (r300->textures_state.dirty) {
+ r300_decompress_depth_textures(r300);
r300_merge_textures_and_samplers(r300);
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 7e501221b1f..06da04c7ad7 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -25,13 +25,9 @@
#define R300_STATE_INLINES_H
#include "draw/draw_vertex.h"
-
#include "pipe/p_format.h"
-
#include "util/u_format.h"
-
#include "r300_reg.h"
-
#include <stdio.h>
/* Some maths. These should probably find their way to u_math, if needed. */
@@ -341,24 +337,6 @@ static INLINE uint32_t r500_anisotropy(unsigned max_aniso)
R500_TX_ANISO_HIGH_QUALITY;
}
-/* Non-CSO state. (For now.) */
-
-static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
-{
- switch (pipe_count) {
- case 1:
- return R300_GB_TILE_PIPE_COUNT_RV300;
- case 2:
- return R300_GB_TILE_PIPE_COUNT_R300;
- case 3:
- return R300_GB_TILE_PIPE_COUNT_R420_3P;
- case 4:
- return R300_GB_TILE_PIPE_COUNT_R420;
- }
- return 0;
-}
-
-
/* Translate pipe_formats into PSC vertex types. */
static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) {
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 6fdc504ed54..354144cac79 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -370,14 +370,18 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_A8_UNORM:
+ /*case PIPE_FORMAT_A8_SNORM:*/
case PIPE_FORMAT_I8_UNORM:
+ /*case PIPE_FORMAT_I8_SNORM:*/
case PIPE_FORMAT_L8_UNORM:
+ /*case PIPE_FORMAT_L8_SNORM:*/
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return R300_COLOR_FORMAT_I8;
/* 16-bit buffers. */
case PIPE_FORMAT_L8A8_UNORM:
+ /*case PIPE_FORMAT_L8A8_SNORM:*/
case PIPE_FORMAT_R8G8_UNORM:
case PIPE_FORMAT_R8G8_SNORM:
return R300_COLOR_FORMAT_UV88;
@@ -395,13 +399,21 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
/* 32-bit buffers. */
case PIPE_FORMAT_B8G8R8A8_UNORM:
+ /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
case PIPE_FORMAT_B8G8R8X8_UNORM:
+ /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
case PIPE_FORMAT_A8R8G8B8_UNORM:
+ /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
case PIPE_FORMAT_X8R8G8B8_UNORM:
+ /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
case PIPE_FORMAT_A8B8G8R8_UNORM:
+ /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
+ /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/
case PIPE_FORMAT_R8G8B8X8_UNORM:
+ /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
return R300_COLOR_FORMAT_ARGB8888;
@@ -506,9 +518,12 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
/* 8-bit outputs, one channel.
* COLORFORMAT_I8 stores the C2 component. */
case PIPE_FORMAT_A8_UNORM:
+ /*case PIPE_FORMAT_A8_SNORM:*/
return modifier | R300_C2_SEL_A;
case PIPE_FORMAT_I8_UNORM:
+ /*case PIPE_FORMAT_I8_SNORM:*/
case PIPE_FORMAT_L8_UNORM:
+ /*case PIPE_FORMAT_L8_SNORM:*/
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return modifier | R300_C2_SEL_R;
@@ -516,6 +531,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
/* 16-bit outputs, two channels.
* COLORFORMAT_UV88 stores C2 and C0. */
case PIPE_FORMAT_L8A8_UNORM:
+ /*case PIPE_FORMAT_L8A8_SNORM:*/
return modifier | R300_C0_SEL_A | R300_C2_SEL_R;
case PIPE_FORMAT_R8G8_UNORM:
case PIPE_FORMAT_R8G8_SNORM:
@@ -528,7 +544,9 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
case PIPE_FORMAT_B8G8R8A8_UNORM:
+ /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
case PIPE_FORMAT_B8G8R8X8_UNORM:
+ /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
case PIPE_FORMAT_B10G10R10A2_UNORM:
return modifier |
R300_C0_SEL_B | R300_C1_SEL_G |
@@ -536,20 +554,26 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
/* ARGB outputs. */
case PIPE_FORMAT_A8R8G8B8_UNORM:
+ /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
case PIPE_FORMAT_X8R8G8B8_UNORM:
+ /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
return modifier |
R300_C0_SEL_A | R300_C1_SEL_R |
R300_C2_SEL_G | R300_C3_SEL_B;
/* ABGR outputs. */
case PIPE_FORMAT_A8B8G8R8_UNORM:
+ /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/
case PIPE_FORMAT_X8B8G8R8_UNORM:
+ /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/
return modifier |
R300_C0_SEL_A | R300_C1_SEL_B |
R300_C2_SEL_G | R300_C3_SEL_R;
/* RGBA outputs. */
case PIPE_FORMAT_R8G8B8X8_UNORM:
+ /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_R10G10B10A2_UNORM:
@@ -585,11 +609,12 @@ boolean r300_is_sampler_format_supported(enum pipe_format format)
}
void r300_texture_setup_format_state(struct r300_screen *screen,
- struct r300_texture_desc *desc,
+ struct r300_resource *tex,
unsigned level,
struct r300_texture_format_state *out)
{
- struct pipe_resource *pt = &desc->b.b;
+ struct pipe_resource *pt = &tex->b.b.b;
+ struct r300_texture_desc *desc = &tex->tex;
boolean is_r500 = screen->caps.is_r500;
/* Mask out all the fields we change. */
@@ -632,163 +657,152 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
R300_TXO_MICRO_TILE(desc->microtile);
}
-static void r300_texture_setup_fb_state(struct r300_screen* screen,
- struct r300_texture* tex)
+static void r300_texture_setup_fb_state(struct r300_surface *surf)
{
- unsigned i;
+ struct r300_resource *tex = r300_resource(surf->base.texture);
+ unsigned level = surf->base.u.tex.level;
/* Set framebuffer state. */
- if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
- for (i = 0; i <= tex->desc.b.b.last_level; i++) {
- tex->fb_state.pitch[i] =
- tex->desc.stride_in_pixels[i] |
- R300_DEPTHMACROTILE(tex->desc.macrotile[i]) |
- R300_DEPTHMICROTILE(tex->desc.microtile);
- }
- tex->fb_state.format = r300_translate_zsformat(tex->desc.b.b.format);
+ if (util_format_is_depth_or_stencil(surf->base.format)) {
+ surf->pitch =
+ tex->tex.stride_in_pixels[level] |
+ R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
+ R300_DEPTHMICROTILE(tex->tex.microtile);
+ surf->format = r300_translate_zsformat(surf->base.format);
} else {
- for (i = 0; i <= tex->desc.b.b.last_level; i++) {
- tex->fb_state.pitch[i] =
- tex->desc.stride_in_pixels[i] |
- r300_translate_colorformat(tex->desc.b.b.format) |
- R300_COLOR_TILE(tex->desc.macrotile[i]) |
- R300_COLOR_MICROTILE(tex->desc.microtile);
- }
- tex->fb_state.format = r300_translate_out_fmt(tex->desc.b.b.format);
+ surf->pitch =
+ tex->tex.stride_in_pixels[level] |
+ r300_translate_colorformat(surf->base.format) |
+ R300_COLOR_TILE(tex->tex.macrotile[level]) |
+ R300_COLOR_MICROTILE(tex->tex.microtile);
+ surf->format = r300_translate_out_fmt(surf->base.format);
}
}
-void r300_texture_reinterpret_format(struct pipe_screen *screen,
+boolean r300_resource_set_properties(struct pipe_screen *screen,
struct pipe_resource *tex,
- enum pipe_format new_format)
+ unsigned offset,
+ const struct pipe_resource *new_properties)
{
- struct r300_screen *r300screen = r300_screen(screen);
+ struct r300_screen *rscreen = r300_screen(screen);
+ struct r300_resource *res = r300_resource(tex);
- SCREEN_DBG(r300screen, DBG_TEX,
- "r300: texture_reinterpret_format: %s -> %s\n",
+ SCREEN_DBG(rscreen, DBG_TEX,
+ "r300: texture_set_properties: %s -> %s\n",
util_format_short_name(tex->format),
- util_format_short_name(new_format));
-
- tex->format = new_format;
+ util_format_short_name(new_properties->format));
- r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex));
-}
-
-static unsigned r300_texture_is_referenced(struct pipe_context *context,
- struct pipe_resource *texture,
- unsigned level, int layer)
-{
- struct r300_context *r300 = r300_context(context);
- struct r300_texture *rtex = (struct r300_texture *)texture;
-
- if (r300->rws->cs_is_buffer_referenced(r300->cs,
- rtex->cs_buffer, R300_REF_CS))
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+ if (!r300_texture_desc_init(rscreen, res, new_properties)) {
+ fprintf(stderr, "r300: ERROR: Cannot set texture properties.\n");
+ return FALSE;
+ }
+ res->tex_offset = offset;
+ r300_texture_setup_format_state(rscreen, res, 0, &res->tx_format);
- return PIPE_UNREFERENCED;
+ return TRUE;
}
static void r300_texture_destroy(struct pipe_screen *screen,
struct pipe_resource* texture)
{
- struct r300_texture* tex = (struct r300_texture*)texture;
- struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
+ struct r300_resource* tex = (struct r300_resource*)texture;
int i;
- rws->buffer_reference(rws, &tex->buffer, NULL);
+ r300_winsys_bo_reference(&tex->buf, NULL);
for (i = 0; i < R300_MAX_TEXTURE_LEVELS; i++) {
if (tex->hiz_mem[i])
u_mmFreeMem(tex->hiz_mem[i]);
- if (tex->zmask_mem[i])
- u_mmFreeMem(tex->zmask_mem[i]);
}
FREE(tex);
}
-static boolean r300_texture_get_handle(struct pipe_screen* screen,
- struct pipe_resource *texture,
- struct winsys_handle *whandle)
+boolean r300_resource_get_handle(struct pipe_screen* screen,
+ struct pipe_resource *texture,
+ struct winsys_handle *whandle)
{
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
- struct r300_texture* tex = (struct r300_texture*)texture;
+ struct r300_resource* tex = (struct r300_resource*)texture;
if (!tex) {
return FALSE;
}
- return rws->buffer_get_handle(rws, tex->buffer,
- tex->desc.stride_in_bytes[0], whandle);
+ return rws->buffer_get_handle(tex->buf,
+ tex->tex.stride_in_bytes[0], whandle);
}
-struct u_resource_vtbl r300_texture_vtbl =
+static const struct u_resource_vtbl r300_texture_vtbl =
{
- r300_texture_get_handle, /* get_handle */
- r300_texture_destroy, /* resource_destroy */
- r300_texture_is_referenced, /* is_resource_referenced */
- r300_texture_get_transfer, /* get_transfer */
- r300_texture_transfer_destroy, /* transfer_destroy */
- r300_texture_transfer_map, /* transfer_map */
- u_default_transfer_flush_region, /* transfer_flush_region */
- r300_texture_transfer_unmap, /* transfer_unmap */
- u_default_transfer_inline_write /* transfer_inline_write */
+ NULL, /* get_handle */
+ r300_texture_destroy, /* resource_destroy */
+ NULL, /* is_resource_referenced */
+ r300_texture_get_transfer, /* get_transfer */
+ r300_texture_transfer_destroy, /* transfer_destroy */
+ r300_texture_transfer_map, /* transfer_map */
+ NULL, /* transfer_flush_region */
+ r300_texture_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
};
/* The common texture constructor. */
-static struct r300_texture*
+static struct r300_resource*
r300_texture_create_object(struct r300_screen *rscreen,
const struct pipe_resource *base,
enum r300_buffer_tiling microtile,
enum r300_buffer_tiling macrotile,
unsigned stride_in_bytes_override,
unsigned max_buffer_size,
- struct r300_winsys_buffer *buffer)
+ struct r300_winsys_bo *buffer)
{
struct r300_winsys_screen *rws = rscreen->rws;
- struct r300_texture *tex = CALLOC_STRUCT(r300_texture);
+ struct r300_resource *tex = CALLOC_STRUCT(r300_resource);
if (!tex) {
if (buffer)
- rws->buffer_reference(rws, &buffer, NULL);
+ r300_winsys_bo_reference(&buffer, NULL);
return NULL;
}
- /* Initialize the descriptor. */
- if (!r300_texture_desc_init(rscreen, &tex->desc, base,
- microtile, macrotile,
- stride_in_bytes_override,
- max_buffer_size)) {
+ pipe_reference_init(&tex->b.b.b.reference, 1);
+ tex->b.b.b.screen = &rscreen->screen;
+ tex->b.b.b.usage = base->usage;
+ tex->b.b.b.bind = base->bind;
+ tex->b.b.b.flags = base->flags;
+ tex->b.b.vtbl = &r300_texture_vtbl;
+ tex->tex.microtile = microtile;
+ tex->tex.macrotile[0] = macrotile;
+ tex->tex.stride_in_bytes_override = stride_in_bytes_override;
+ tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
+ R300_DOMAIN_GTT :
+ R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
+ tex->buf_size = max_buffer_size;
+
+ if (!r300_resource_set_properties(&rscreen->screen, &tex->b.b.b, 0, base)) {
if (buffer)
- rws->buffer_reference(rws, &buffer, NULL);
+ r300_winsys_bo_reference(&buffer, NULL);
FREE(tex);
return NULL;
}
- /* Initialize the hardware state. */
- r300_texture_setup_format_state(rscreen, &tex->desc, 0, &tex->tx_format);
- r300_texture_setup_fb_state(rscreen, tex);
-
- tex->desc.b.vtbl = &r300_texture_vtbl;
- pipe_reference_init(&tex->desc.b.b.reference, 1);
- tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
- R300_DOMAIN_GTT :
- R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
- tex->buffer = buffer;
/* Create the backing buffer if needed. */
- if (!tex->buffer) {
- tex->buffer = rws->buffer_create(rws, tex->desc.size_in_bytes, 2048,
+ if (!buffer) {
+ tex->buf_size = tex->tex.size_in_bytes;
+ tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
base->bind, base->usage, tex->domain);
- if (!tex->buffer) {
+ if (!tex->buf) {
FREE(tex);
return NULL;
}
+ } else {
+ tex->buf = buffer;
}
- tex->cs_buffer = rws->buffer_get_cs_handle(rws, tex->buffer);
+ tex->cs_buf = rws->buffer_get_cs_handle(tex->buf);
- rws->buffer_set_tiling(rws, tex->buffer,
- tex->desc.microtile, tex->desc.macrotile[0],
- tex->desc.stride_in_bytes[0]);
+ rws->buffer_set_tiling(tex->buf, NULL,
+ tex->tex.microtile, tex->tex.macrotile[0],
+ tex->tex.stride_in_bytes[0]);
return tex;
}
@@ -820,7 +834,7 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
{
struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
struct r300_screen *rscreen = r300_screen(screen);
- struct r300_winsys_buffer *buffer;
+ struct r300_winsys_bo *buffer;
enum r300_buffer_tiling microtile, macrotile;
unsigned stride, size;
@@ -836,7 +850,7 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
if (!buffer)
return NULL;
- rws->buffer_get_tiling(rws, buffer, &microtile, &macrotile);
+ rws->buffer_get_tiling(buffer, &microtile, &macrotile);
/* Enforce a microtiled zbuffer. */
if (util_format_is_depth_or_stencil(base->format) &&
@@ -847,7 +861,7 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
break;
case 2:
- if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT))
+ if (rws->get_value(rws, R300_VID_DRM_2_1_0))
microtile = R300_BUFFER_SQUARETILED;
break;
}
@@ -864,7 +878,7 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
struct pipe_resource* texture,
const struct pipe_surface *surf_tmpl)
{
- struct r300_texture* tex = r300_texture(texture);
+ struct r300_resource* tex = r300_resource(texture);
struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
unsigned level = surf_tmpl->u.tex.level;
@@ -884,28 +898,27 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
- surface->buffer = tex->buffer;
- surface->cs_buffer = tex->cs_buffer;
+ surface->buf = tex->buf;
+ surface->cs_buf = tex->cs_buf;
/* Prefer VRAM if there are multiple domains to choose from. */
surface->domain = tex->domain;
if (surface->domain & R300_DOMAIN_VRAM)
surface->domain &= ~R300_DOMAIN_GTT;
- surface->offset = r300_texture_get_offset(&tex->desc, level,
+ surface->offset = r300_texture_get_offset(tex, level,
surf_tmpl->u.tex.first_layer);
- surface->pitch = tex->fb_state.pitch[level];
- surface->format = tex->fb_state.format;
+ r300_texture_setup_fb_state(surface);
/* Parameters for the CBZB clear. */
- surface->cbzb_allowed = tex->desc.cbzb_allowed[level];
+ surface->cbzb_allowed = tex->tex.cbzb_allowed[level];
surface->cbzb_width = align(surface->base.width, 64);
/* Height must be aligned to the size of a tile. */
- tile_height = r300_get_pixel_alignment(tex->desc.b.b.format,
- tex->desc.b.b.nr_samples,
- tex->desc.microtile,
- tex->desc.macrotile[level],
+ tile_height = r300_get_pixel_alignment(tex->b.b.b.format,
+ tex->b.b.b.nr_samples,
+ tex->tex.microtile,
+ tex->tex.macrotile[level],
DIM_HEIGHT, 0);
surface->cbzb_height = align((surface->base.height + 1) / 2,
@@ -914,7 +927,7 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
/* Offset must be aligned to 2K and must point at the beginning
* of a scanline. */
offset = surface->offset +
- tex->desc.stride_in_bytes[level] * surface->cbzb_height;
+ tex->tex.stride_in_bytes[level] * surface->cbzb_height;
surface->cbzb_midpoint_offset = offset & ~2047;
surface->cbzb_pitch = surface->pitch & 0x1ffffc;
@@ -929,8 +942,8 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
surface->cbzb_allowed ? "YES" : " NO",
surface->cbzb_width, surface->cbzb_height,
offset & 2047,
- tex->desc.microtile ? "YES" : " NO",
- tex->desc.macrotile[level] ? "YES" : " NO");
+ tex->tex.microtile ? "YES" : " NO",
+ tex->tex.macrotile[level] ? "YES" : " NO");
}
return &surface->base;
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 0ab22f747e4..158a387478f 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -32,7 +32,7 @@ struct pipe_resource;
struct winsys_handle;
struct r300_texture_format_state;
struct r300_texture_desc;
-struct r300_texture;
+struct r300_resource;
struct r300_screen;
unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
@@ -46,9 +46,10 @@ uint32_t r300_translate_texformat(enum pipe_format format,
uint32_t r500_tx_format_msb_bit(enum pipe_format format);
-void r300_texture_reinterpret_format(struct pipe_screen *screen,
+boolean r300_resource_set_properties(struct pipe_screen *screen,
struct pipe_resource *tex,
- enum pipe_format new_format);
+ unsigned offset,
+ const struct pipe_resource *new_properties);
boolean r300_is_colorbuffer_format_supported(enum pipe_format format);
@@ -57,10 +58,14 @@ boolean r300_is_zs_format_supported(enum pipe_format format);
boolean r300_is_sampler_format_supported(enum pipe_format format);
void r300_texture_setup_format_state(struct r300_screen *screen,
- struct r300_texture_desc *desc,
+ struct r300_resource *tex,
unsigned level,
struct r300_texture_format_state *out);
+boolean r300_resource_get_handle(struct pipe_screen* screen,
+ struct pipe_resource *texture,
+ struct winsys_handle *whandle);
+
struct pipe_resource*
r300_texture_from_handle(struct pipe_screen* screen,
const struct pipe_resource* base,
diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c
index 7b1739142d4..2cfeec7d751 100644
--- a/src/gallium/drivers/r300/r300_texture_desc.c
+++ b/src/gallium/drivers/r300/r300_texture_desc.c
@@ -90,19 +90,19 @@ unsigned r300_get_pixel_alignment(enum pipe_format format,
}
/* Return true if macrotiling should be enabled on the miplevel. */
-static boolean r300_texture_macro_switch(struct r300_texture_desc *desc,
+static boolean r300_texture_macro_switch(struct r300_resource *tex,
unsigned level,
boolean rv350_mode,
enum r300_dim dim)
{
unsigned tile, texdim;
- tile = r300_get_pixel_alignment(desc->b.b.format, desc->b.b.nr_samples,
- desc->microtile, R300_BUFFER_TILED, dim, 0);
+ tile = r300_get_pixel_alignment(tex->b.b.b.format, tex->b.b.b.nr_samples,
+ tex->tex.microtile, R300_BUFFER_TILED, dim, 0);
if (dim == DIM_WIDTH) {
- texdim = u_minify(desc->width0, level);
+ texdim = u_minify(tex->tex.width0, level);
} else {
- texdim = u_minify(desc->height0, level);
+ texdim = u_minify(tex->tex.height0, level);
}
/* See TX_FILTER1_n.MACRO_SWITCH. */
@@ -118,7 +118,7 @@ static boolean r300_texture_macro_switch(struct r300_texture_desc *desc,
* at the given level.
*/
static unsigned r300_texture_get_stride(struct r300_screen *screen,
- struct r300_texture_desc *desc,
+ struct r300_resource *tex,
unsigned level)
{
unsigned tile_width, width, stride;
@@ -126,62 +126,62 @@ static unsigned r300_texture_get_stride(struct r300_screen *screen,
screen->caps.family == CHIP_FAMILY_RS690 ||
screen->caps.family == CHIP_FAMILY_RS740);
- if (desc->stride_in_bytes_override)
- return desc->stride_in_bytes_override;
+ if (tex->tex.stride_in_bytes_override)
+ return tex->tex.stride_in_bytes_override;
/* Check the level. */
- if (level > desc->b.b.last_level) {
+ if (level > tex->b.b.b.last_level) {
SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
- __FUNCTION__, level, desc->b.b.last_level);
+ __FUNCTION__, level, tex->b.b.b.last_level);
return 0;
}
- width = u_minify(desc->width0, level);
+ width = u_minify(tex->tex.width0, level);
- if (util_format_is_plain(desc->b.b.format)) {
- tile_width = r300_get_pixel_alignment(desc->b.b.format,
- desc->b.b.nr_samples,
- desc->microtile,
- desc->macrotile[level],
+ if (util_format_is_plain(tex->b.b.b.format)) {
+ tile_width = r300_get_pixel_alignment(tex->b.b.b.format,
+ tex->b.b.b.nr_samples,
+ tex->tex.microtile,
+ tex->tex.macrotile[level],
DIM_WIDTH, is_rs690);
width = align(width, tile_width);
- stride = util_format_get_stride(desc->b.b.format, width);
+ stride = util_format_get_stride(tex->b.b.b.format, width);
/* The alignment to 32 bytes is sort of implied by the layout... */
return stride;
} else {
- return align(util_format_get_stride(desc->b.b.format, width), is_rs690 ? 64 : 32);
+ return align(util_format_get_stride(tex->b.b.b.format, width), is_rs690 ? 64 : 32);
}
}
-static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc,
+static unsigned r300_texture_get_nblocksy(struct r300_resource *tex,
unsigned level,
boolean *out_aligned_for_cbzb)
{
unsigned height, tile_height;
- height = u_minify(desc->height0, level);
+ height = u_minify(tex->tex.height0, level);
- if (util_format_is_plain(desc->b.b.format)) {
- tile_height = r300_get_pixel_alignment(desc->b.b.format,
- desc->b.b.nr_samples,
- desc->microtile,
- desc->macrotile[level],
+ /* Mipmapped and 3D textures must have their height aligned to POT. */
+ if ((tex->b.b.b.target != PIPE_TEXTURE_1D &&
+ tex->b.b.b.target != PIPE_TEXTURE_2D &&
+ tex->b.b.b.target != PIPE_TEXTURE_RECT) ||
+ tex->b.b.b.last_level != 0) {
+ height = util_next_power_of_two(height);
+ }
+
+ if (util_format_is_plain(tex->b.b.b.format)) {
+ tile_height = r300_get_pixel_alignment(tex->b.b.b.format,
+ tex->b.b.b.nr_samples,
+ tex->tex.microtile,
+ tex->tex.macrotile[level],
DIM_HEIGHT, 0);
height = align(height, tile_height);
- /* This is needed for the kernel checker, unfortunately. */
- if ((desc->b.b.target != PIPE_TEXTURE_1D &&
- desc->b.b.target != PIPE_TEXTURE_2D &&
- desc->b.b.target != PIPE_TEXTURE_RECT) ||
- desc->b.b.last_level != 0) {
- height = util_next_power_of_two(height);
- }
-
/* See if the CBZB clear can be used on the buffer,
* taking the texture size into account. */
if (out_aligned_for_cbzb) {
- if (desc->macrotile[level]) {
+ if (tex->tex.macrotile[level]) {
/* When clearing, the layer (width*height) is horizontally split
* into two, and the upper and lower halves are cleared by the CB
* and ZB units, respectively. Therefore, the number of macrotiles
@@ -189,10 +189,10 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc,
/* Align the height so that there is an even number of macrotiles.
* Do so for 3 or more macrotiles in the Y direction. */
- if (level == 0 && desc->b.b.last_level == 0 &&
- (desc->b.b.target == PIPE_TEXTURE_1D ||
- desc->b.b.target == PIPE_TEXTURE_2D ||
- desc->b.b.target == PIPE_TEXTURE_RECT) &&
+ if (level == 0 && tex->b.b.b.last_level == 0 &&
+ (tex->b.b.b.target == PIPE_TEXTURE_1D ||
+ tex->b.b.b.target == PIPE_TEXTURE_2D ||
+ tex->b.b.b.target == PIPE_TEXTURE_RECT) &&
height >= tile_height * 3) {
height = align(height, tile_height * 2);
}
@@ -204,11 +204,11 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc,
}
}
- return util_format_get_nblocksy(desc->b.b.format, height);
+ return util_format_get_nblocksy(tex->b.b.b.format, height);
}
static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
- struct r300_texture_desc *desc)
+ struct r300_resource *tex)
{
/* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures
* incorrectly. This is a workaround to prevent CS from being rejected. */
@@ -216,17 +216,17 @@ static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
unsigned i, size;
if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
- desc->b.b.target == PIPE_TEXTURE_3D &&
- desc->b.b.last_level > 0) {
+ tex->b.b.b.target == PIPE_TEXTURE_3D &&
+ tex->b.b.b.last_level > 0) {
size = 0;
- for (i = 0; i <= desc->b.b.last_level; i++) {
- size += desc->stride_in_bytes[i] *
- r300_texture_get_nblocksy(desc, i, FALSE);
+ for (i = 0; i <= tex->b.b.b.last_level; i++) {
+ size += tex->tex.stride_in_bytes[i] *
+ r300_texture_get_nblocksy(tex, i, FALSE);
}
- size *= desc->depth0;
- desc->size_in_bytes = size;
+ size *= tex->tex.depth0;
+ tex->tex.size_in_bytes = size;
}
}
@@ -239,15 +239,15 @@ static unsigned stride_to_width(enum pipe_format format,
}
static void r300_setup_miptree(struct r300_screen *screen,
- struct r300_texture_desc *desc,
+ struct r300_resource *tex,
boolean align_for_cbzb)
{
- struct pipe_resource *base = &desc->b.b;
+ struct pipe_resource *base = &tex->b.b.b;
unsigned stride, size, layer_size, nblocksy, i;
boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350;
boolean aligned_for_cbzb;
- desc->size_in_bytes = 0;
+ tex->tex.size_in_bytes = 0;
SCREEN_DBG(screen, DBG_TEXALLOC,
"r300: Making miptree for texture, format %s\n",
@@ -255,21 +255,21 @@ static void r300_setup_miptree(struct r300_screen *screen,
for (i = 0; i <= base->last_level; i++) {
/* Let's see if this miplevel can be macrotiled. */
- desc->macrotile[i] =
- (desc->macrotile[0] == R300_BUFFER_TILED &&
- r300_texture_macro_switch(desc, i, rv350_mode, DIM_WIDTH) &&
- r300_texture_macro_switch(desc, i, rv350_mode, DIM_HEIGHT)) ?
+ tex->tex.macrotile[i] =
+ (tex->tex.macrotile[0] == R300_BUFFER_TILED &&
+ r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) &&
+ r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ?
R300_BUFFER_TILED : R300_BUFFER_LINEAR;
- stride = r300_texture_get_stride(screen, desc, i);
+ stride = r300_texture_get_stride(screen, tex, i);
/* Compute the number of blocks in Y, see if the CBZB clear can be
* used on the texture. */
aligned_for_cbzb = FALSE;
- if (align_for_cbzb && desc->cbzb_allowed[i])
- nblocksy = r300_texture_get_nblocksy(desc, i, &aligned_for_cbzb);
+ if (align_for_cbzb && tex->tex.cbzb_allowed[i])
+ nblocksy = r300_texture_get_nblocksy(tex, i, &aligned_for_cbzb);
else
- nblocksy = r300_texture_get_nblocksy(desc, i, NULL);
+ nblocksy = r300_texture_get_nblocksy(tex, i, NULL);
layer_size = stride * nblocksy;
@@ -280,75 +280,136 @@ static void r300_setup_miptree(struct r300_screen *screen,
if (base->target == PIPE_TEXTURE_CUBE)
size = layer_size * 6;
else
- size = layer_size * u_minify(desc->depth0, i);
+ size = layer_size * u_minify(tex->tex.depth0, i);
- desc->offset_in_bytes[i] = desc->size_in_bytes;
- desc->size_in_bytes = desc->offset_in_bytes[i] + size;
- desc->layer_size_in_bytes[i] = layer_size;
- desc->stride_in_bytes[i] = stride;
- desc->stride_in_pixels[i] = stride_to_width(desc->b.b.format, stride);
- desc->cbzb_allowed[i] = desc->cbzb_allowed[i] && aligned_for_cbzb;
+ tex->tex.offset_in_bytes[i] = tex->tex.size_in_bytes;
+ tex->tex.size_in_bytes = tex->tex.offset_in_bytes[i] + size;
+ tex->tex.layer_size_in_bytes[i] = layer_size;
+ tex->tex.stride_in_bytes[i] = stride;
+ tex->tex.stride_in_pixels[i] = stride_to_width(tex->b.b.b.format, stride);
+ tex->tex.cbzb_allowed[i] = tex->tex.cbzb_allowed[i] && aligned_for_cbzb;
SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
"(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
- i, u_minify(desc->width0, i), u_minify(desc->height0, i),
- u_minify(desc->depth0, i), stride, desc->size_in_bytes,
- desc->macrotile[i] ? "TRUE" : "FALSE");
+ i, u_minify(tex->tex.width0, i), u_minify(tex->tex.height0, i),
+ u_minify(tex->tex.depth0, i), stride, tex->tex.size_in_bytes,
+ tex->tex.macrotile[i] ? "TRUE" : "FALSE");
}
}
-static void r300_setup_flags(struct r300_texture_desc *desc)
+static void r300_setup_flags(struct r300_resource *tex)
{
- desc->uses_stride_addressing =
- !util_is_power_of_two(desc->b.b.width0) ||
- (desc->stride_in_bytes_override &&
- stride_to_width(desc->b.b.format,
- desc->stride_in_bytes_override) != desc->b.b.width0);
-
- desc->is_npot =
- desc->uses_stride_addressing ||
- !util_is_power_of_two(desc->b.b.height0) ||
- !util_is_power_of_two(desc->b.b.depth0);
+ tex->tex.uses_stride_addressing =
+ !util_is_power_of_two(tex->b.b.b.width0) ||
+ (tex->tex.stride_in_bytes_override &&
+ stride_to_width(tex->b.b.b.format,
+ tex->tex.stride_in_bytes_override) != tex->b.b.b.width0);
+
+ tex->tex.is_npot =
+ tex->tex.uses_stride_addressing ||
+ !util_is_power_of_two(tex->b.b.b.height0) ||
+ !util_is_power_of_two(tex->b.b.b.depth0);
}
static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
- struct r300_texture_desc *desc)
+ struct r300_resource *tex)
{
unsigned i, bpp;
boolean first_level_valid;
- bpp = util_format_get_blocksizebits(desc->b.b.format);
+ bpp = util_format_get_blocksizebits(tex->b.b.b.format);
/* 1) The texture must be point-sampled,
* 2) The depth must be 16 or 32 bits.
* 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage
* with certain texture sizes. Macrotiling ensures the alignment. */
- first_level_valid = desc->b.b.nr_samples <= 1 &&
+ first_level_valid = tex->b.b.b.nr_samples <= 1 &&
(bpp == 16 || bpp == 32) &&
- desc->macrotile[0];
+ tex->tex.macrotile[0];
if (SCREEN_DBG_ON(rscreen, DBG_NO_CBZB))
first_level_valid = FALSE;
- for (i = 0; i <= desc->b.b.last_level; i++)
- desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i];
+ for (i = 0; i <= tex->b.b.b.last_level; i++)
+ tex->tex.cbzb_allowed[i] = first_level_valid && tex->tex.macrotile[i];
+}
+
+#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
+
+static void r300_setup_zmask_flags(struct r300_screen *screen,
+ struct r300_resource *tex)
+{
+ /* The tile size of 1 DWORD is:
+ *
+ * GPU Pipes 4x4 mode 8x8 mode
+ * ------------------------------------------
+ * R580 4P/1Z 32x32 64x64
+ * RV570 3P/1Z 48x16 96x32
+ * RV530 1P/2Z 32x16 64x32
+ * 1P/1Z 16x16 32x32
+ */
+ static unsigned num_blocks_x_per_dw[4] = {4, 8, 12, 8};
+ static unsigned num_blocks_y_per_dw[4] = {4, 4, 4, 8};
+
+ if (util_format_is_depth_or_stencil(tex->b.b.b.format) &&
+ util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
+ tex->tex.microtile) {
+ unsigned i, pipes;
+
+ if (screen->caps.family == CHIP_FAMILY_RV530) {
+ pipes = screen->caps.num_z_pipes;
+ } else {
+ pipes = screen->caps.num_frag_pipes;
+ }
+
+ for (i = 0; i <= tex->b.b.b.last_level; i++) {
+ unsigned numdw, compsize;
+
+ /* The 8x8 compression mode needs macrotiling. */
+ compsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
+ tex->tex.macrotile[i] &&
+ tex->b.b.b.nr_samples <= 1 ? 8 : 4;
+
+ /* Get the zbuffer size (with the aligned width and height). */
+ numdw = align(tex->tex.stride_in_pixels[i],
+ num_blocks_x_per_dw[pipes-1] * compsize) *
+ align(u_minify(tex->b.b.b.height0, i),
+ num_blocks_y_per_dw[pipes-1] * compsize);
+
+ /* Convert pixels -> dwords. */
+ numdw = ALIGN_DIVUP(numdw, num_blocks_x_per_dw[pipes-1] * compsize *
+ num_blocks_y_per_dw[pipes-1] * compsize);
+
+ /* Check that we have enough ZMASK memory. */
+ if (numdw <= screen->caps.zmask_ram * pipes) {
+ tex->tex.zmask_dwords[i] = numdw;
+ tex->tex.zcomp8x8[i] = compsize == 8;
+ } else {
+ tex->tex.zmask_dwords[i] = 0;
+ tex->tex.zcomp8x8[i] = FALSE;
+ }
+ }
+ }
}
static void r300_setup_tiling(struct r300_screen *screen,
- struct r300_texture_desc *desc)
+ struct r300_resource *tex)
{
struct r300_winsys_screen *rws = screen->rws;
- enum pipe_format format = desc->b.b.format;
+ enum pipe_format format = tex->b.b.b.format;
boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350;
boolean is_zb = util_format_is_depth_or_stencil(format);
boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);
+ tex->tex.microtile = R300_BUFFER_LINEAR;
+ tex->tex.macrotile[0] = R300_BUFFER_LINEAR;
+
if (!util_format_is_plain(format)) {
return;
}
/* If height == 1, disable microtiling except for zbuffer. */
- if (!is_zb && (desc->b.b.height0 == 1 || dbg_no_tiling)) {
+ if (!is_zb && (tex->b.b.b.height0 == 1 || dbg_no_tiling)) {
return;
}
@@ -357,12 +418,12 @@ static void r300_setup_tiling(struct r300_screen *screen,
case 1:
case 4:
case 8:
- desc->microtile = R300_BUFFER_TILED;
+ tex->tex.microtile = R300_BUFFER_TILED;
break;
case 2:
- if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
- desc->microtile = R300_BUFFER_SQUARETILED;
+ if (rws->get_value(rws, R300_VID_DRM_2_1_0)) {
+ tex->tex.microtile = R300_BUFFER_SQUARETILED;
}
break;
}
@@ -372,104 +433,100 @@ static void r300_setup_tiling(struct r300_screen *screen,
}
/* Set macrotiling. */
- if (r300_texture_macro_switch(desc, 0, rv350_mode, DIM_WIDTH) &&
- r300_texture_macro_switch(desc, 0, rv350_mode, DIM_HEIGHT)) {
- desc->macrotile[0] = R300_BUFFER_TILED;
+ if (r300_texture_macro_switch(tex, 0, rv350_mode, DIM_WIDTH) &&
+ r300_texture_macro_switch(tex, 0, rv350_mode, DIM_HEIGHT)) {
+ tex->tex.macrotile[0] = R300_BUFFER_TILED;
}
}
-static void r300_tex_print_info(struct r300_screen *rscreen,
- struct r300_texture_desc *desc,
+static void r300_tex_print_info(struct r300_resource *tex,
const char *func)
{
fprintf(stderr,
"r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, "
"LastLevel: %i, Size: %i, Format: %s\n",
func,
- desc->macrotile[0] ? "YES" : " NO",
- desc->microtile ? "YES" : " NO",
- desc->stride_in_pixels[0],
- desc->b.b.width0, desc->b.b.height0, desc->b.b.depth0,
- desc->b.b.last_level, desc->size_in_bytes,
- util_format_short_name(desc->b.b.format));
+ tex->tex.macrotile[0] ? "YES" : " NO",
+ tex->tex.microtile ? "YES" : " NO",
+ tex->tex.stride_in_pixels[0],
+ tex->b.b.b.width0, tex->b.b.b.height0, tex->b.b.b.depth0,
+ tex->b.b.b.last_level, tex->tex.size_in_bytes,
+ util_format_short_name(tex->b.b.b.format));
}
boolean r300_texture_desc_init(struct r300_screen *rscreen,
- struct r300_texture_desc *desc,
- const struct pipe_resource *base,
- enum r300_buffer_tiling microtile,
- enum r300_buffer_tiling macrotile,
- unsigned stride_in_bytes_override,
- unsigned max_buffer_size)
+ struct r300_resource *tex,
+ const struct pipe_resource *base)
{
- desc->b.b = *base;
- desc->b.b.screen = &rscreen->screen;
- desc->stride_in_bytes_override = stride_in_bytes_override;
- desc->width0 = base->width0;
- desc->height0 = base->height0;
- desc->depth0 = base->depth0;
-
- r300_setup_flags(desc);
+ tex->b.b.b.target = base->target;
+ tex->b.b.b.format = base->format;
+ tex->b.b.b.width0 = base->width0;
+ tex->b.b.b.height0 = base->height0;
+ tex->b.b.b.depth0 = base->depth0;
+ tex->b.b.b.array_size = base->array_size;
+ tex->b.b.b.last_level = base->last_level;
+ tex->b.b.b.nr_samples = base->nr_samples;
+ tex->tex.width0 = base->width0;
+ tex->tex.height0 = base->height0;
+ tex->tex.depth0 = base->depth0;
+
+ r300_setup_flags(tex);
/* Align a 3D NPOT texture to POT. */
- if (base->target == PIPE_TEXTURE_3D && desc->is_npot) {
- desc->width0 = util_next_power_of_two(desc->width0);
- desc->height0 = util_next_power_of_two(desc->height0);
- desc->depth0 = util_next_power_of_two(desc->depth0);
+ if (base->target == PIPE_TEXTURE_3D && tex->tex.is_npot) {
+ tex->tex.width0 = util_next_power_of_two(tex->tex.width0);
+ tex->tex.height0 = util_next_power_of_two(tex->tex.height0);
+ tex->tex.depth0 = util_next_power_of_two(tex->tex.depth0);
}
/* Setup tiling. */
- if (microtile == R300_BUFFER_SELECT_LAYOUT ||
- macrotile == R300_BUFFER_SELECT_LAYOUT) {
- r300_setup_tiling(rscreen, desc);
- } else {
- desc->microtile = microtile;
- desc->macrotile[0] = macrotile;
- assert(desc->b.b.last_level == 0);
+ if (tex->tex.microtile == R300_BUFFER_SELECT_LAYOUT) {
+ r300_setup_tiling(rscreen, tex);
}
- r300_setup_cbzb_flags(rscreen, desc);
+ r300_setup_cbzb_flags(rscreen, tex);
/* Setup the miptree description. */
- r300_setup_miptree(rscreen, desc, TRUE);
+ r300_setup_miptree(rscreen, tex, TRUE);
/* If the required buffer size is larger the given max size,
* try again without the alignment for the CBZB clear. */
- if (max_buffer_size && desc->size_in_bytes > max_buffer_size) {
- r300_setup_miptree(rscreen, desc, FALSE);
+ if (tex->buf_size && tex->tex.size_in_bytes > tex->buf_size) {
+ r300_setup_miptree(rscreen, tex, FALSE);
}
- r300_texture_3d_fix_mipmapping(rscreen, desc);
+ r300_texture_3d_fix_mipmapping(rscreen, tex);
+ r300_setup_zmask_flags(rscreen, tex);
- if (max_buffer_size) {
+ if (tex->buf_size) {
/* Make sure the buffer we got is large enough. */
- if (desc->size_in_bytes > max_buffer_size) {
+ if (tex->tex.size_in_bytes > tex->buf_size) {
fprintf(stderr, "r300: texture_desc_init: The buffer is not "
"large enough. Got: %i, Need: %i, Info:\n",
- max_buffer_size, desc->size_in_bytes);
- r300_tex_print_info(rscreen, desc, "texture_desc_init");
+ tex->buf_size, tex->tex.size_in_bytes);
+ r300_tex_print_info(tex, "texture_desc_init");
return FALSE;
}
- desc->buffer_size_in_bytes = max_buffer_size;
+ tex->tex.buffer_size_in_bytes = tex->buf_size;
} else {
- desc->buffer_size_in_bytes = desc->size_in_bytes;
+ tex->tex.buffer_size_in_bytes = tex->tex.size_in_bytes;
}
if (SCREEN_DBG_ON(rscreen, DBG_TEX))
- r300_tex_print_info(rscreen, desc, "texture_desc_init");
+ r300_tex_print_info(tex, "texture_desc_init");
return TRUE;
}
-unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
+unsigned r300_texture_get_offset(struct r300_resource *tex,
unsigned level, unsigned layer)
{
- unsigned offset = desc->offset_in_bytes[level];
+ unsigned offset = tex->tex.offset_in_bytes[level];
- switch (desc->b.b.target) {
+ switch (tex->b.b.b.target) {
case PIPE_TEXTURE_3D:
case PIPE_TEXTURE_CUBE:
- return offset + layer * desc->layer_size_in_bytes[level];
+ return offset + layer * tex->tex.layer_size_in_bytes[level];
default:
assert(layer == 0);
diff --git a/src/gallium/drivers/r300/r300_texture_desc.h b/src/gallium/drivers/r300/r300_texture_desc.h
index 121d215b4cb..ce6e9643ec6 100644
--- a/src/gallium/drivers/r300/r300_texture_desc.h
+++ b/src/gallium/drivers/r300/r300_texture_desc.h
@@ -30,7 +30,7 @@
struct pipe_resource;
struct r300_screen;
struct r300_texture_desc;
-struct r300_texture;
+struct r300_resource;
enum r300_dim {
DIM_WIDTH = 0,
@@ -44,14 +44,10 @@ unsigned r300_get_pixel_alignment(enum pipe_format format,
enum r300_dim dim, boolean is_rs690);
boolean r300_texture_desc_init(struct r300_screen *rscreen,
- struct r300_texture_desc *desc,
- const struct pipe_resource *base,
- enum r300_buffer_tiling microtile,
- enum r300_buffer_tiling macrotile,
- unsigned stride_in_bytes_override,
- unsigned max_buffer_size);
-
-unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
+ struct r300_resource *tex,
+ const struct pipe_resource *base);
+
+unsigned r300_texture_get_offset(struct r300_resource *tex,
unsigned level, unsigned layer);
#endif
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index 15a323989b2..97ec0a1a1f2 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -191,7 +191,12 @@ static void transform_dstreg(
dst->File = translate_register_file(src->Register.File);
dst->Index = translate_register_index(ttr, src->Register.File, src->Register.Index);
dst->WriteMask = src->Register.WriteMask;
- dst->RelAddr = src->Register.Indirect;
+
+ if (src->Register.Indirect) {
+ ttr->error = TRUE;
+ fprintf(stderr, "r300: Relative addressing of destination operands "
+ "is unsupported.\n");
+ }
}
static void transform_srcreg(
@@ -332,6 +337,8 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
unsigned imm_index = 0;
int i;
+ ttr->error = FALSE;
+
/* Allocate constants placeholders.
*
* Note: What if declared constants are not contiguous? */
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
index 97641a954b9..adb044cfe56 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.h
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
@@ -47,6 +47,9 @@ struct tgsi_to_rc {
/* Vertex shaders have no half swizzles, and no way to handle them, so
* until rc grows proper support, indicate if they're safe to use. */
boolean use_half_swizzles;
+
+ /* If an error occured. */
+ boolean error;
};
void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens);
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index ae93fab554e..30de9ec1e32 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -37,7 +37,7 @@ struct r300_transfer {
unsigned offset;
/* Linear texture. */
- struct r300_texture *linear_texture;
+ struct r300_resource *linear_texture;
};
/* Convenience cast wrapper. */
@@ -54,7 +54,7 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
struct pipe_resource *tex = transfer->resource;
- ctx->resource_copy_region(ctx, &r300transfer->linear_texture->desc.b.b, 0,
+ ctx->resource_copy_region(ctx, &r300transfer->linear_texture->b.b.b, 0,
0, 0, 0,
tex, transfer->level, &transfer->box);
}
@@ -70,7 +70,7 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
ctx->resource_copy_region(ctx, tex, transfer->level,
transfer->box.x, transfer->box.y, transfer->box.z,
- &r300transfer->linear_texture->desc.b.b, 0, &src_box);
+ &r300transfer->linear_texture->b.b.b, 0, &src_box);
ctx->flush(ctx, 0, NULL);
}
@@ -83,25 +83,24 @@ r300_texture_get_transfer(struct pipe_context *ctx,
const struct pipe_box *box)
{
struct r300_context *r300 = r300_context(ctx);
- struct r300_texture *tex = r300_texture(texture);
+ struct r300_resource *tex = r300_resource(texture);
struct r300_transfer *trans;
struct pipe_resource base;
boolean referenced_cs, referenced_hw, blittable;
+ const struct util_format_description *desc =
+ util_format_description(texture->format);
referenced_cs =
- r300->rws->cs_is_buffer_referenced(r300->cs,
- tex->cs_buffer, R300_REF_CS);
+ r300->rws->cs_is_buffer_referenced(r300->cs, tex->cs_buf);
if (referenced_cs) {
referenced_hw = TRUE;
} else {
referenced_hw =
- r300->rws->cs_is_buffer_referenced(r300->cs,
- tex->cs_buffer, R300_REF_HW);
+ r300->rws->buffer_is_busy(tex->buf);
}
- blittable = ctx->screen->is_format_supported(
- ctx->screen, texture->format, texture->target, 0,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET, 0);
+ blittable = desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
+ desc->layout == UTIL_FORMAT_LAYOUT_S3TC;
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
@@ -114,8 +113,13 @@ r300_texture_get_transfer(struct pipe_context *ctx,
/* If the texture is tiled, we must create a temporary detiled texture
* for this transfer.
* Also make write transfers pipelined. */
- if (tex->desc.microtile || tex->desc.macrotile[level] ||
- ((referenced_hw & !(usage & PIPE_TRANSFER_READ)) && blittable)) {
+ if (tex->tex.microtile || tex->tex.macrotile[level] ||
+ (referenced_hw && blittable && !(usage & PIPE_TRANSFER_READ))) {
+ if (r300->blitter->running) {
+ fprintf(stderr, "r300: ERROR: Blitter recursion in texture_get_transfer.\n");
+ os_break();
+ }
+
base.target = PIPE_TEXTURE_2D;
base.format = texture->format;
base.width0 = box->width;
@@ -140,7 +144,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
}
/* Create the temporary texture. */
- trans->linear_texture = r300_texture(
+ trans->linear_texture = r300_resource(
ctx->screen->resource_create(ctx->screen,
&base));
@@ -149,14 +153,14 @@ r300_texture_get_transfer(struct pipe_context *ctx,
* Let's flush and try again. */
ctx->flush(ctx, 0, NULL);
- trans->linear_texture = r300_texture(
+ trans->linear_texture = r300_resource(
ctx->screen->resource_create(ctx->screen,
&base));
if (!trans->linear_texture) {
/* For linear textures, it's safe to fallback to
* an unpipelined transfer. */
- if (!tex->desc.microtile && !tex->desc.macrotile[level]) {
+ if (!tex->tex.microtile && !tex->tex.macrotile[level]) {
goto unpipelined;
}
@@ -168,8 +172,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
}
}
- assert(!trans->linear_texture->desc.microtile &&
- !trans->linear_texture->desc.macrotile[0]);
+ assert(!trans->linear_texture->tex.microtile &&
+ !trans->linear_texture->tex.macrotile[0]);
/* Set the stride.
*
@@ -179,7 +183,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
* right thing internally.
*/
trans->transfer.stride =
- trans->linear_texture->desc.stride_in_bytes[0];
+ trans->linear_texture->tex.stride_in_bytes[0];
if (usage & PIPE_TRANSFER_READ) {
/* We cannot map a tiled texture directly because the data is
@@ -194,8 +198,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
unpipelined:
/* Unpipelined transfer. */
- trans->transfer.stride = tex->desc.stride_in_bytes[level];
- trans->offset = r300_texture_get_offset(&tex->desc, level, box->z);
+ trans->transfer.stride = tex->tex.stride_in_bytes[level];
+ trans->offset = r300_texture_get_offset(tex, level, box->z);
if (referenced_cs)
ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
@@ -227,20 +231,19 @@ void* r300_texture_transfer_map(struct pipe_context *ctx,
struct r300_context *r300 = r300_context(ctx);
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys;
struct r300_transfer *r300transfer = r300_transfer(transfer);
- struct r300_texture *tex = r300_texture(transfer->resource);
+ struct r300_resource *tex = r300_resource(transfer->resource);
char *map;
- enum pipe_format format = tex->desc.b.b.format;
+ enum pipe_format format = tex->b.b.b.format;
if (r300transfer->linear_texture) {
/* The detiled texture is of the same size as the region being mapped
* (no offset needed). */
- return rws->buffer_map(rws,
- r300transfer->linear_texture->buffer,
+ return rws->buffer_map(r300transfer->linear_texture->buf,
r300->cs,
transfer->usage);
} else {
/* Tiling is disabled. */
- map = rws->buffer_map(rws, tex->buffer, r300->cs,
+ map = rws->buffer_map(tex->buf, r300->cs,
transfer->usage);
if (!map) {
@@ -258,11 +261,11 @@ void r300_texture_transfer_unmap(struct pipe_context *ctx,
{
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys;
struct r300_transfer *r300transfer = r300_transfer(transfer);
- struct r300_texture *tex = r300_texture(transfer->resource);
+ struct r300_resource *tex = r300_resource(transfer->resource);
if (r300transfer->linear_texture) {
- rws->buffer_unmap(rws, r300transfer->linear_texture->buffer);
+ rws->buffer_unmap(r300transfer->linear_texture->buf);
} else {
- rws->buffer_unmap(rws, tex->buffer);
+ rws->buffer_unmap(tex->buf);
}
}
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 78021e2c5d4..b319890157f 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -226,6 +226,13 @@ void r300_translate_vertex_shader(struct r300_context *r300,
r300_tgsi_to_rc(&ttr, vs->state.tokens);
+ if (ttr.error) {
+ fprintf(stderr, "r300 VP: Cannot translate a shader. "
+ "Using a dummy shader instead.\n");
+ r300_dummy_vertex_shader(r300, vs);
+ return;
+ }
+
if (compiler.Base.Program.Constants.Count > 200) {
compiler.Base.remove_unused_constants = TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 460da77a4fb..d5c73585c81 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -28,38 +28,45 @@
* Any winsys hosting this pipe needs to implement r300_winsys_screen and then
* call r300_screen_create to start things. */
+#include "r300_defines.h"
+
+#include "pipebuffer/pb_bufmgr.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
-#include "r300_defines.h"
-
#define R300_MAX_CMDBUF_DWORDS (16 * 1024)
struct winsys_handle;
struct r300_winsys_screen;
-struct r300_winsys_buffer; /* for map/unmap etc. */
-struct r300_winsys_cs_buffer; /* for write_reloc etc. */
+#define r300_winsys_bo pb_buffer
+#define r300_winsys_bo_reference(pdst, src) pb_reference(pdst, src)
+
+struct r300_winsys_cs_handle; /* for write_reloc etc. */
struct r300_winsys_cs {
- unsigned cdw; /* Number of used dwords. */
- uint32_t buf[R300_MAX_CMDBUF_DWORDS]; /* The command buffer. */
+ unsigned cdw; /* Number of used dwords. */
+ uint32_t *buf; /* The command buffer. */
};
enum r300_value_id {
R300_VID_PCI_ID,
R300_VID_GB_PIPES,
R300_VID_Z_PIPES,
- R300_VID_SQUARE_TILING_SUPPORT,
- R300_VID_DRM_2_3_0, /* R500 VAP regs, MSPOS regs, fixed tex3D size checking */
- R300_VID_DRM_2_6_0, /* Hyper-Z, GB_Z_PEQ_CONFIG on rv350->r4xx, R500 FG_ALPHA_VALUE */
- R300_VID_DRM_2_8_0, /* R500 US_FORMAT regs, R500 ARGB2101010 colorbuffer */
- R300_CAN_HYPERZ,
-};
-
-enum r300_reference_domain { /* bitfield */
- R300_REF_CS = 1,
- R300_REF_HW = 2
+ R300_VID_GART_SIZE,
+ R300_VID_VRAM_SIZE,
+ R300_VID_DRM_MAJOR,
+ R300_VID_DRM_MINOR,
+ R300_VID_DRM_PATCHLEVEL,
+
+ /* These should probably go away: */
+ R300_VID_DRM_2_1_0, /* Square tiling. */
+ R300_VID_DRM_2_3_0, /* R500 VAP regs, MSPOS regs, fixed tex3D size checking */
+ R300_VID_DRM_2_6_0, /* Hyper-Z, GB_Z_PEQ_CONFIG on rv350->r4xx, R500 FG_ALPHA_VALUE */
+ R300_VID_DRM_2_8_0, /* R500 US_FORMAT regs, R500 ARGB2101010 colorbuffer, CMask */
+
+ R300_CAN_HYPERZ, /* ZMask + HiZ */
+ R300_CAN_AACOMPRESS, /* CMask */
};
struct r300_winsys_screen {
@@ -98,91 +105,78 @@ struct r300_winsys_screen {
* \param domain A bitmask of the R300_DOMAIN_* flags.
* \return The created buffer object.
*/
- struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws,
+ struct r300_winsys_bo *(*buffer_create)(struct r300_winsys_screen *ws,
unsigned size,
unsigned alignment,
unsigned bind,
unsigned usage,
enum r300_buffer_domain domain);
- struct r300_winsys_cs_buffer *(*buffer_get_cs_handle)(
- struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf);
-
- /**
- * Reference a buffer object (assign with reference counting).
- *
- * \param ws The winsys this function is called from.
- * \param pdst A destination pointer to set the source buffer to.
- * \param src A source buffer object.
- */
- void (*buffer_reference)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer **pdst,
- struct r300_winsys_buffer *src);
+ struct r300_winsys_cs_handle *(*buffer_get_cs_handle)(
+ struct r300_winsys_bo *buf);
/**
* Map the entire data store of a buffer object into the client's address
* space.
*
- * \param ws The winsys this function is called from.
* \param buf A winsys buffer object to map.
* \param cs A command stream to flush if the buffer is referenced by it.
* \param usage A bitmask of the PIPE_TRANSFER_* flags.
* \return The pointer at the beginning of the buffer.
*/
- void *(*buffer_map)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf,
+ void *(*buffer_map)(struct r300_winsys_bo *buf,
struct r300_winsys_cs *cs,
enum pipe_transfer_usage usage);
/**
* Unmap a buffer object from the client's address space.
*
- * \param ws The winsys this function is called from.
* \param buf A winsys buffer object to unmap.
*/
- void (*buffer_unmap)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf);
+ void (*buffer_unmap)(struct r300_winsys_bo *buf);
+
+ /**
+ * Return TRUE if a buffer object is being used by the GPU.
+ *
+ * \param buf A winsys buffer object.
+ */
+ boolean (*buffer_is_busy)(struct r300_winsys_bo *buf);
/**
* Wait for a buffer object until it is not used by a GPU. This is
* equivalent to a fence placed after the last command using the buffer,
* and synchronizing to the fence.
*
- * \param ws The winsys this function is called from.
* \param buf A winsys buffer object to wait for.
*/
- void (*buffer_wait)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf);
+ void (*buffer_wait)(struct r300_winsys_bo *buf);
/**
* Return tiling flags describing a memory layout of a buffer object.
*
- * \param ws The winsys this function is called from.
* \param buf A winsys buffer object to get the flags from.
* \param macrotile A pointer to the return value of the microtile flag.
* \param microtile A pointer to the return value of the macrotile flag.
*
* \note microtile and macrotile are not bitmasks!
*/
- void (*buffer_get_tiling)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf,
+ void (*buffer_get_tiling)(struct r300_winsys_bo *buf,
enum r300_buffer_tiling *microtile,
enum r300_buffer_tiling *macrotile);
/**
* Set tiling flags describing a memory layout of a buffer object.
*
- * \param ws The winsys this function is called from.
* \param buf A winsys buffer object to set the flags for.
+ * \param cs A command stream to flush if the buffer is referenced by it.
* \param macrotile A macrotile flag.
* \param microtile A microtile flag.
* \param stride A stride of the buffer in bytes, for texturing.
*
* \note microtile and macrotile are not bitmasks!
*/
- void (*buffer_set_tiling)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf,
+ void (*buffer_set_tiling)(struct r300_winsys_bo *buf,
+ struct r300_winsys_cs *cs,
enum r300_buffer_tiling microtile,
enum r300_buffer_tiling macrotile,
unsigned stride);
@@ -197,7 +191,7 @@ struct r300_winsys_screen {
* \param stride The returned buffer stride in bytes.
* \param size The returned buffer size.
*/
- struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *ws,
+ struct r300_winsys_bo *(*buffer_from_handle)(struct r300_winsys_screen *ws,
struct winsys_handle *whandle,
unsigned *stride,
unsigned *size);
@@ -206,14 +200,12 @@ struct r300_winsys_screen {
* Get a winsys handle from a winsys buffer. The internal structure
* of the handle is platform-specific and only a winsys should access it.
*
- * \param ws The winsys this function is called from.
* \param buf A winsys buffer object to get the handle from.
* \param whandle A winsys handle pointer.
* \param stride A stride of the buffer in bytes, for texturing.
* \return TRUE on success.
*/
- boolean (*buffer_get_handle)(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf,
+ boolean (*buffer_get_handle)(struct r300_winsys_bo *buf,
unsigned stride,
struct winsys_handle *whandle);
@@ -248,7 +240,7 @@ struct r300_winsys_screen {
* \param wd A write domain containing a bitmask of the R300_DOMAIN_* flags.
*/
void (*cs_add_reloc)(struct r300_winsys_cs *cs,
- struct r300_winsys_cs_buffer *buf,
+ struct r300_winsys_cs_handle *buf,
enum r300_buffer_domain rd,
enum r300_buffer_domain wd);
@@ -269,7 +261,7 @@ struct r300_winsys_screen {
* \param wd A write domain containing a bitmask of the R300_DOMAIN_* flags.
*/
void (*cs_write_reloc)(struct r300_winsys_cs *cs,
- struct r300_winsys_cs_buffer *buf);
+ struct r300_winsys_cs_handle *buf);
/**
* Flush a command stream.
@@ -279,6 +271,13 @@ struct r300_winsys_screen {
void (*cs_flush)(struct r300_winsys_cs *cs);
/**
+ * Wait until the last flush is completed.
+ *
+ * \param cs A command stream.
+ */
+ void (*cs_sync_flush)(struct r300_winsys_cs *cs);
+
+ /**
* Set a flush callback which is called from winsys when flush is
* required.
*
@@ -291,16 +290,13 @@ struct r300_winsys_screen {
void *user);
/**
- * Return TRUE if a buffer is referenced by a command stream or by hardware
- * (i.e. is busy), based on the domain parameter.
+ * Return TRUE if a buffer is referenced by a command stream.
*
* \param cs A command stream.
* \param buf A winsys buffer.
- * \param domain A bitmask of the R300_REF_* enums.
*/
boolean (*cs_is_buffer_referenced)(struct r300_winsys_cs *cs,
- struct r300_winsys_cs_buffer *buf,
- enum r300_reference_domain domain);
+ struct r300_winsys_cs_handle *buf);
};
#endif /* R300_WINSYS_H */