From c78748a5274e58bcbb122923edf81065be9bbe16 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 2 Dec 2009 02:08:26 +0100 Subject: gallium: adapt drivers to interface cleanups --- src/gallium/drivers/r300/r300_emit.c | 12 ++++++------ src/gallium/drivers/r300/r300_screen.c | 9 +++------ src/gallium/drivers/r300/r300_texture.c | 12 +++++------- 3 files changed, 14 insertions(+), 19 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 98a39390bf..a479842f9e 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -631,10 +631,10 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) for (i = 0; i < aos_count - 1; i += 2) { int buf_num1 = velem[i].vertex_buffer_index; int buf_num2 = velem[i+1].vertex_buffer_index; - assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0); - assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0); - OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) | - (pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22)); + assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_blocksize(velem[i].src_format) % 4 == 0); + assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_blocksize(velem[i+1].src_format) % 4 == 0); + OUT_CS((pf_get_blocksize(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) | + (pf_get_blocksize(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22)); OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset + offset * vbuf[buf_num1].stride); OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset + @@ -642,8 +642,8 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) } if (aos_count & 1) { int buf_num = velem[i].vertex_buffer_index; - assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0); - OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6)); + assert(vbuf[buf_num].stride % 4 == 0 && pf_get_blocksize(velem[i].src_format) % 4 == 0); + OUT_CS((pf_get_blocksize(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6)); OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset + offset * vbuf[buf_num].stride); } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 390b63007e..032fa69ec0 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -311,14 +311,10 @@ r300_get_tex_transfer(struct pipe_screen *screen, trans = CALLOC_STRUCT(r300_transfer); if (trans) { pipe_texture_reference(&trans->transfer.texture, texture); - trans->transfer.format = texture->format; trans->transfer.x = x; trans->transfer.y = y; trans->transfer.width = w; trans->transfer.height = h; - trans->transfer.block = texture->block; - trans->transfer.nblocksx = texture->nblocksx[level]; - trans->transfer.nblocksy = texture->nblocksy[level]; trans->transfer.stride = r300_texture_get_stride(tex, level); trans->transfer.usage = usage; @@ -344,6 +340,7 @@ static void* r300_transfer_map(struct pipe_screen* screen, { struct r300_texture* tex = (struct r300_texture*)transfer->texture; char* map; + enum pipe_format format = tex->tex.format; map = pipe_buffer_map(screen, tex->buffer, pipe_transfer_buffer_flags(transfer)); @@ -353,8 +350,8 @@ static void* r300_transfer_map(struct pipe_screen* screen, } return map + r300_transfer(transfer)->offset + - transfer->y / transfer->block.height * transfer->stride + - transfer->x / transfer->block.width * transfer->block.size; + transfer->y / pf_get_blockheight(format) * transfer->stride + + transfer->x / pf_get_blockwidth(format) * pf_get_blocksize(format); } static void r300_transfer_unmap(struct pipe_screen* screen, diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 093a21ebe2..63fc6a235a 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -105,7 +105,7 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) return 0; } - return align(pf_get_stride(&tex->tex.block, u_minify(tex->tex.width0, level)), 32); + return align(pf_get_stride(tex->tex.format, u_minify(tex->tex.width0, level)), 32); } static void r300_setup_miptree(struct r300_texture* tex) @@ -115,11 +115,10 @@ static void r300_setup_miptree(struct r300_texture* tex) int i; for (i = 0; i <= base->last_level; i++) { - base->nblocksx[i] = pf_get_nblocksx(&base->block, u_minify(base->width0, i)); - base->nblocksy[i] = pf_get_nblocksy(&base->block, u_minify(base->height0, i)); + unsigned nblocksy = pf_get_nblocksy(base->format, u_minify(base->height0, i)); stride = r300_texture_get_stride(tex, i); - layer_size = stride * base->nblocksy[i]; + layer_size = stride * nblocksy; if (base->target == PIPE_TEXTURE_CUBE) size = layer_size * 6; @@ -129,7 +128,7 @@ static void r300_setup_miptree(struct r300_texture* tex) tex->offset[i] = align(tex->size, 32); tex->size = tex->offset[i] + size; tex->layer_size[i] = layer_size; - tex->pitch[i] = stride / base->block.size; + tex->pitch[i] = stride / pf_get_blocksize(base->format); debug_printf("r300: Texture miptree: Level %d " "(%dx%dx%d px, pitch %d bytes)\n", @@ -245,7 +244,7 @@ static struct pipe_texture* tex->tex.screen = screen; tex->stride_override = *stride; - tex->pitch[0] = *stride / base->block.size; + tex->pitch[0] = *stride / pf_get_blocksize(base->format); r300_setup_flags(tex); r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); @@ -283,7 +282,6 @@ r300_video_surface_create(struct pipe_screen *screen, template.width0 = util_next_power_of_two(width); template.height0 = util_next_power_of_two(height); template.depth0 = 1; - pf_get_block(template.format, &template.block); template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; -- cgit v1.2.3 From 225bc70b77fcf107dd8abc93be27a15c27743071 Mon Sep 17 00:00:00 2001 From: Coleman Kane Date: Fri, 4 Dec 2009 08:44:57 -0700 Subject: r300g: use $(MAKE) variable Fixes bug 24501 --- src/gallium/drivers/r300/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index d7a2c8c462..8d0c6e33bb 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -38,4 +38,4 @@ include ../../Makefile.template .PHONY : $(COMPILER_ARCHIVE) $(COMPILER_ARCHIVE): - cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make + $(MAKE) -C $(TOP)/src/mesa/drivers/dri/r300/compiler -- cgit v1.2.3 From 3da8265cd3233e2b22ab0f8a28fbba892984e399 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 4 Dec 2009 16:06:16 +0100 Subject: r300g: fix warnings --- src/gallium/drivers/r300/r300_context.c | 4 ++-- src/gallium/drivers/r300/r300_winsys.h | 2 ++ src/gallium/winsys/drm/radeon/core/radeon_buffer.c | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 68a17dcb63..5b337f03ac 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -36,8 +36,8 @@ #include "r300_screen.h" #include "r300_state_derived.h" #include "r300_state_invariant.h" - -#include "radeon_winsys.h" +#include "r300_texture.h" +#include "r300_winsys.h" static enum pipe_error r300_clear_hash_table(void* key, void* value, void* data) diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index f86985841f..1ae6de70fe 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -35,6 +35,8 @@ extern "C" { #include "pipe/p_state.h" #include "pipe/internal/p_winsys_screen.h" +#include "radeon_winsys.h" + struct pipe_context* r300_create_context(struct pipe_screen* screen, struct radeon_winsys* radeon_winsys); diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 65f7babff2..0ca7b39255 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -35,7 +35,9 @@ #include "radeon_bo_gem.h" #include "softpipe/sp_texture.h" #include "r300_context.h" +#include "util/u_math.h" #include + struct radeon_vl_context { Display *display; -- cgit v1.2.3 From 7679447b5835fd73ab44b3d77b12a034c95af5c5 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 2 Dec 2009 17:15:27 +0100 Subject: r300g, radeong: fix the CS overflow --- src/gallium/drivers/r300/r300_cs.h | 2 +- src/gallium/drivers/r300/r300_emit.c | 9 ++++++++- src/gallium/winsys/drm/radeon/core/radeon_r300.c | 5 +++-- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 8b100375fd..9fcf3ab538 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -55,7 +55,7 @@ int cs_count = 0; #define CHECK_CS(size) \ - cs_winsys->check_cs(cs_winsys, (size)) + assert(cs_winsys->check_cs(cs_winsys, (size))) #define BEGIN_CS(size) do { \ CHECK_CS(size); \ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index a479842f9e..3bb42f9e43 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -871,10 +871,17 @@ void r300_emit_dirty_state(struct r300_context* r300) return; } + /* Check size of CS. */ + /* Make sure we have at least 8*1024 spare dwords. */ + /* XXX It would be nice to know the number of dwords we really need to + * XXX emit. */ + if (!r300->winsys->check_cs(r300->winsys, 8*1024)) { + r300->context.flush(&r300->context, 0, NULL); + } + /* Clean out BOs. */ r300->winsys->reset_bos(r300->winsys); - /* XXX check size */ validate: /* Color buffers... */ for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) { diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index 7362279b77..ba0596c30d 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -52,8 +52,9 @@ static boolean radeon_validate(struct radeon_winsys* winsys) static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) { - /* XXX check size here, lazy ass! */ - return radeon_validate(winsys); + struct radeon_cs* cs = winsys->priv->cs; + + return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; } static void radeon_begin_cs(struct radeon_winsys* winsys, -- cgit v1.2.3 From 042b524d48ebb15215430149b9b1653f4b46dee3 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 4 Dec 2009 15:54:29 +0100 Subject: radeong: flush CS if a buffer being mapped is referenced by it Also, overlapping occlusion queries seems to work now. --- src/gallium/drivers/r300/r300_emit.c | 2 -- src/gallium/winsys/drm/radeon/core/radeon_buffer.c | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3bb42f9e43..60be03f54f 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -382,8 +382,6 @@ static void r300_emit_query_start(struct r300_context *r300) if (!query) return; - /* XXX This will almost certainly not return good results - * for overlapping queries. */ BEGIN_CS(4); if (caps->family == CHIP_FAMILY_RV530) { OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 0ca7b39255..2a8daed051 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -140,10 +140,15 @@ static void *radeon_buffer_map(struct pipe_winsys *ws, struct pipe_buffer *buffer, unsigned flags) { + struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv; struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; int write = 0; + if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) { + priv->cs->space_flush_fn(priv->cs->space_flush_data); + } + if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { uint32_t domain; -- cgit v1.2.3 From 56a4342a0493ad1d502d4791ab941ef171d36e60 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 5 Dec 2009 17:48:00 +0100 Subject: r300g: Need to emit a hardware scissor rectangle even if scissor is disabled. Just make it cover the whole framebuffer in that case. Otherwise the kernel CS checker may complain, e.g. running progs/demos/gearbox. That runs fast now here, but doesn't look right yet. --- src/gallium/drivers/r300/r300_context.h | 2 ++ src/gallium/drivers/r300/r300_emit.c | 9 +++++++-- src/gallium/drivers/r300/r300_state.c | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index dd3f6ac143..11cd9f855f 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -101,6 +101,8 @@ struct r300_sampler_state { struct r300_scissor_state { uint32_t scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ + uint32_t no_scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ + uint32_t no_scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ }; struct r300_texture_state { diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 60be03f54f..04dca29216 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -570,8 +570,13 @@ void r300_emit_scissor_state(struct r300_context* r300, BEGIN_CS(3); OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); - OUT_CS(scissor->scissor_top_left); - OUT_CS(scissor->scissor_bottom_right); + if (r300->rs_state->rs.scissor) { + OUT_CS(scissor->scissor_top_left); + OUT_CS(scissor->scissor_bottom_right); + } else { + OUT_CS(scissor->no_scissor_top_left); + OUT_CS(scissor->no_scissor_bottom_right); + } END_CS; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 442af70e14..2bc2b79c02 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -302,6 +302,25 @@ static void r300->framebuffer_state = *state; r300->dirty_state |= R300_NEW_FRAMEBUFFERS; + + if (r300_screen(r300->context.screen)->caps->is_r500) { + r300->scissor_state->no_scissor_top_left = + (0 << R300_SCISSORS_X_SHIFT) | + (0 << R300_SCISSORS_Y_SHIFT); + r300->scissor_state->no_scissor_bottom_right = + ((state->width - 1) << R300_SCISSORS_X_SHIFT) | + ((state->height - 1) << R300_SCISSORS_Y_SHIFT); + } else { + /* Offset of 1440 in non-R500 chipsets. */ + r300->scissor_state->no_scissor_top_left = + ((0 + 1440) << R300_SCISSORS_X_SHIFT) | + ((0 + 1440) << R300_SCISSORS_Y_SHIFT); + r300->scissor_state->no_scissor_bottom_right = + (((state->width - 1) + 1440) << R300_SCISSORS_X_SHIFT) | + (((state->height - 1) + 1440) << R300_SCISSORS_Y_SHIFT); + } + + r300->dirty_state |= R300_NEW_SCISSOR; } /* Create fragment shader state. */ -- cgit v1.2.3 From e1380cae885df37d4a211d0271f59487d9f2db78 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 5 Dec 2009 19:17:20 +0100 Subject: r300g: remove redundant code and clean up --- src/gallium/drivers/r300/r300_context.h | 11 +++-- src/gallium/drivers/r300/r300_emit.c | 19 +++++---- src/gallium/drivers/r300/r300_state.c | 73 +++++++++++++++++---------------- 3 files changed, 57 insertions(+), 46 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 11cd9f855f..23ea32c57e 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -98,11 +98,14 @@ struct r300_sampler_state { unsigned min_lod, max_lod; }; +struct r300_scissor_regs { + uint32_t top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ + uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ +}; + struct r300_scissor_state { - uint32_t scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ - uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ - uint32_t no_scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ - uint32_t no_scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ + struct r300_scissor_regs framebuffer; + struct r300_scissor_regs scissor; }; struct r300_texture_state { diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 04dca29216..dbf316a9b5 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -563,21 +563,26 @@ void r300_emit_rs_block_state(struct r300_context* r300, END_CS; } -void r300_emit_scissor_state(struct r300_context* r300, - struct r300_scissor_state* scissor) +static void r300_emit_scissor_regs(struct r300_context* r300, + struct r300_scissor_regs* scissor) { CS_LOCALS(r300); BEGIN_CS(3); OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); + OUT_CS(scissor->top_left); + OUT_CS(scissor->bottom_right); + END_CS; +} + +void r300_emit_scissor_state(struct r300_context* r300, + struct r300_scissor_state* scissor) +{ if (r300->rs_state->rs.scissor) { - OUT_CS(scissor->scissor_top_left); - OUT_CS(scissor->scissor_bottom_right); + r300_emit_scissor_regs(r300, &scissor->scissor); } else { - OUT_CS(scissor->no_scissor_top_left); - OUT_CS(scissor->no_scissor_bottom_right); + r300_emit_scissor_regs(r300, &scissor->framebuffer); } - END_CS; } void r300_emit_texture(struct r300_context* r300, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 2bc2b79c02..d3233557ce 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -289,11 +289,34 @@ static void r300_set_edgeflags(struct pipe_context* pipe, /* XXX and even worse, I have no idea WTF the bitfield is */ } +static void r300_set_scissor_regs(const struct pipe_scissor_state* state, + struct r300_scissor_regs *scissor, + boolean is_r500) +{ + if (is_r500) { + scissor->top_left = + (state->minx << R300_SCISSORS_X_SHIFT) | + (state->miny << R300_SCISSORS_Y_SHIFT); + scissor->bottom_right = + ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) | + ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT); + } else { + /* Offset of 1440 in non-R500 chipsets. */ + scissor->top_left = + ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) | + ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT); + scissor->bottom_right = + (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | + (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); + } +} + static void r300_set_framebuffer_state(struct pipe_context* pipe, const struct pipe_framebuffer_state* state) { struct r300_context* r300 = r300_context(pipe); + struct pipe_scissor_state scissor; if (r300->draw) { draw_flush(r300->draw); @@ -301,26 +324,17 @@ static void r300->framebuffer_state = *state; - r300->dirty_state |= R300_NEW_FRAMEBUFFERS; + scissor.minx = scissor.miny = 0; + scissor.maxx = state->width; + scissor.maxy = state->height; + r300_set_scissor_regs(&scissor, &r300->scissor_state->framebuffer, + r300_screen(r300->context.screen)->caps->is_r500); - if (r300_screen(r300->context.screen)->caps->is_r500) { - r300->scissor_state->no_scissor_top_left = - (0 << R300_SCISSORS_X_SHIFT) | - (0 << R300_SCISSORS_Y_SHIFT); - r300->scissor_state->no_scissor_bottom_right = - ((state->width - 1) << R300_SCISSORS_X_SHIFT) | - ((state->height - 1) << R300_SCISSORS_Y_SHIFT); - } else { - /* Offset of 1440 in non-R500 chipsets. */ - r300->scissor_state->no_scissor_top_left = - ((0 + 1440) << R300_SCISSORS_X_SHIFT) | - ((0 + 1440) << R300_SCISSORS_Y_SHIFT); - r300->scissor_state->no_scissor_bottom_right = - (((state->width - 1) + 1440) << R300_SCISSORS_X_SHIFT) | - (((state->height - 1) + 1440) << R300_SCISSORS_Y_SHIFT); + /* Don't rely on the order of states being set for the first time. */ + if (!r300->rs_state || !r300->rs_state->rs.scissor) { + r300->dirty_state |= R300_NEW_SCISSOR; } - - r300->dirty_state |= R300_NEW_SCISSOR; + r300->dirty_state |= R300_NEW_FRAMEBUFFERS; } /* Create fragment shader state. */ @@ -642,24 +656,13 @@ static void r300_set_scissor_state(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); - if (r300_screen(r300->context.screen)->caps->is_r500) { - r300->scissor_state->scissor_top_left = - (state->minx << R300_SCISSORS_X_SHIFT) | - (state->miny << R300_SCISSORS_Y_SHIFT); - r300->scissor_state->scissor_bottom_right = - ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) | - ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT); - } else { - /* Offset of 1440 in non-R500 chipsets. */ - r300->scissor_state->scissor_top_left = - ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) | - ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT); - r300->scissor_state->scissor_bottom_right = - (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | - (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); - } + r300_set_scissor_regs(state, &r300->scissor_state->scissor, + r300_screen(r300->context.screen)->caps->is_r500); - r300->dirty_state |= R300_NEW_SCISSOR; + /* Don't rely on the order of states being set for the first time. */ + if (!r300->rs_state || r300->rs_state->rs.scissor) { + r300->dirty_state |= R300_NEW_SCISSOR; + } } static void r300_set_viewport_state(struct pipe_context* pipe, -- cgit v1.2.3 From 07487643515edb731c6abc3e931c329a89dd9293 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 5 Dec 2009 20:39:11 +0100 Subject: r300g: don't render if everything is culled by scissoring Otherwise a CS is refused by kernel 2.6.31 (and maybe all later versions, not sure). --- src/gallium/drivers/r300/r300_context.h | 3 +++ src/gallium/drivers/r300/r300_render.c | 23 +++++++++++++++++++++++ src/gallium/drivers/r300/r300_state.c | 3 +++ 3 files changed, 29 insertions(+) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 23ea32c57e..0be190392a 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -101,6 +101,9 @@ struct r300_sampler_state { struct r300_scissor_regs { uint32_t top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ + + /* Whether everything is culled by scissoring. */ + boolean empty_area; }; struct r300_scissor_state { diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 4c5fb405c6..35b335df6a 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -70,6 +70,12 @@ uint32_t r300_translate_primitive(unsigned prim) } } +static boolean r300_nothing_to_draw(struct r300_context *r300) +{ + return r300->rs_state->rs.scissor && + r300->scissor_state->scissor.empty_area; +} + static void r300_emit_draw_arrays(struct r300_context *r300, unsigned mode, unsigned count) @@ -173,10 +179,15 @@ boolean r300_draw_range_elements(struct pipe_context* pipe, return FALSE; } + if (count > 65535) { return FALSE; } + if (r300_nothing_to_draw(r300)) { + return TRUE; + } + r300_update_derived_state(r300); if (!r300_setup_vertex_buffers(r300)) { @@ -218,6 +229,10 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return FALSE; } + if (r300_nothing_to_draw(r300)) { + return TRUE; + } + r300_update_derived_state(r300); if (!r300_setup_vertex_buffers(r300)) { @@ -251,6 +266,10 @@ boolean r300_swtcl_draw_arrays(struct pipe_context* pipe, return FALSE; } + if (r300_nothing_to_draw(r300)) { + return TRUE; + } + for (i = 0; i < r300->vertex_buffer_count; i++) { void* buf = pipe_buffer_map(pipe->screen, r300->vertex_buffer[i].buffer, @@ -292,6 +311,10 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe, return FALSE; } + if (r300_nothing_to_draw(r300)) { + return TRUE; + } + for (i = 0; i < r300->vertex_buffer_count; i++) { void* buf = pipe_buffer_map(pipe->screen, r300->vertex_buffer[i].buffer, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index d3233557ce..8ef0b3b268 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -309,6 +309,9 @@ static void r300_set_scissor_regs(const struct pipe_scissor_state* state, (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); } + + scissor->empty_area = state->minx >= state->maxx || + state->miny >= state->maxy; } static void -- cgit v1.2.3 From 7091afed789dbba8364deaea0b7a5a99a12ff25e Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 5 Dec 2009 01:27:59 +0100 Subject: r300g: enhance ZTOP conditions --- src/gallium/drivers/r300/r300_state_derived.c | 37 ++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index cd969d633b..d448866ef0 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -462,6 +462,31 @@ static void r300_update_derived_shader_state(struct r300_context* r300) r300->dirty_state |= R300_NEW_RS_BLOCK; } +static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) +{ + /* We are interested only in the cases when a new depth or stencil value + * can be written and changed. */ + + /* We might optionally check for [Z func: never] and inspect the stencil + * state in a similar fashion, but it's not terribly important. */ + return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) + || + (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) + || + ((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) && + (dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK)); +} + +static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa) +{ + /* We are interested only in the cases when alpha testing can kill + * a fragment. */ + uint32_t af = dsa->alpha_function; + + return (af & R300_FG_ALPHA_FUNC_ENABLE) && + (af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS; +} + static void r300_update_ztop(struct r300_context* r300) { r300->ztop_state.z_buffer_top = R300_ZTOP_ENABLE; @@ -484,13 +509,13 @@ static void r300_update_ztop(struct r300_context* r300) * * ~C. */ - if (r300->dsa_state->alpha_function) { - r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; - } else if (r300->fs->info.uses_kill) { - r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; - } else if (r300_fragment_shader_writes_depth(r300->fs)) { + + if (r300->query_current || + r300_fragment_shader_writes_depth(r300->fs)) { r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; - } else if (r300->query_current) { + } else if (r300_dsa_writes_depth_stencil(r300->dsa_state) && + (r300->fs->info.uses_kill || + r300_dsa_alpha_test_enabled(r300->dsa_state))) { r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; } } -- cgit v1.2.3 From c99fb991a3b46c5978248b00eef0efd742127a44 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Sun, 6 Dec 2009 23:33:41 -0800 Subject: r300g: Clean up previous commit. If *I* can't read it, there's a strong possibility others can't, either. --- src/gallium/drivers/r300/r300_state_derived.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index d448866ef0..6af49888b9 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -469,10 +469,8 @@ static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) /* We might optionally check for [Z func: never] and inspect the stencil * state in a similar fashion, but it's not terribly important. */ - return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) - || - (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) - || + return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) || + (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) || ((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) && (dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK)); } @@ -503,19 +501,25 @@ static void r300_update_ztop(struct r300_context* r300) * The docs claim that for the first three cases, if no ZS writes happen, * then ZTOP can be used. * + * (3) will never apply since we do not support chroma-keyed operations. + * (4) will need to be re-examined (and this comment updated) if/when + * Hyper-Z becomes supported. + * * Additionally, the following conditions require disabled ZTOP: - * ~) Depth writes in fragment shader - * ~) Outstanding occlusion queries + * 5) Depth writes in fragment shader + * 6) Outstanding occlusion queries * * ~C. */ - if (r300->query_current || - r300_fragment_shader_writes_depth(r300->fs)) { + /* ZS writes */ + if (r300_dsa_writes_depth_stencil(r300->dsa_state) && + (r300_dsa_alpha_test_enabled(r300->dsa_state) || /* (1) */ + r300->fs->info.uses_kill)) { /* (2) */ + r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; + } else if (r300_fragment_shader_writes_depth(r300->fs)) { /* (5) */ r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; - } else if (r300_dsa_writes_depth_stencil(r300->dsa_state) && - (r300->fs->info.uses_kill || - r300_dsa_alpha_test_enabled(r300->dsa_state))) { + } else if (r300->query_current) { /* (6) */ r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE; } } -- cgit v1.2.3 From 3456f9149b3009fcfce80054759d05883d3c4ee5 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 7 Dec 2009 20:35:42 +0100 Subject: gallium/util: fix util_color_[un]pack[-ub] to be strict aliasing safe use pointer to union instead of void pointer. gcc complained a lot, depending what the pointer originally actually was. Looks like it's in fact maybe legal to cast for instance uint pointers to union pointers as long as union contains a uint type, hence use this with some callers, other just use union util_color in the first place. --- src/gallium/auxiliary/util/u_clear.h | 8 +- src/gallium/auxiliary/util/u_pack_color.h | 147 +++++++++++-------------- src/gallium/drivers/cell/ppu/cell_clear.c | 6 +- src/gallium/drivers/llvmpipe/lp_clear.c | 5 +- src/gallium/drivers/r300/r300_state.c | 4 +- src/gallium/drivers/softpipe/sp_clear.c | 7 +- src/gallium/drivers/svga/svga_pipe_clear.c | 6 +- src/gallium/drivers/svga/svga_pipe_sampler.c | 2 +- src/gallium/state_trackers/vega/vg_translate.c | 54 ++++----- src/mesa/state_tracker/st_atom_pixeltransfer.c | 2 +- 10 files changed, 113 insertions(+), 128 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h index 1e65a035ae..2c32db6175 100644 --- a/src/gallium/auxiliary/util/u_clear.h +++ b/src/gallium/auxiliary/util/u_clear.h @@ -46,13 +46,13 @@ util_clear(struct pipe_context *pipe, { if (buffers & PIPE_CLEAR_COLOR) { struct pipe_surface *ps = framebuffer->cbufs[0]; - unsigned color; + union util_color uc; - util_pack_color(rgba, ps->format, &color); + util_pack_color(rgba, ps->format, &uc); if (pipe->surface_fill) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); } else { - util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); } } diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 9dacc6d83d..a2e0f26686 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -40,101 +40,97 @@ #include "util/u_math.h" + +union util_color { + ubyte ub; + ushort us; + uint ui; + float f[4]; +}; + /** * Pack ubyte R,G,B,A into dest pixel. */ static INLINE void util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, - enum pipe_format format, void *dest) + enum pipe_format format, union util_color *uc) { switch (format) { case PIPE_FORMAT_R8G8B8A8_UNORM: { - uint *d = (uint *) dest; - *d = (r << 24) | (g << 16) | (b << 8) | a; + uc->ui = (r << 24) | (g << 16) | (b << 8) | a; } return; case PIPE_FORMAT_R8G8B8X8_UNORM: { - uint *d = (uint *) dest; - *d = (r << 24) | (g << 16) | (b << 8) | 0xff; + uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; } return; case PIPE_FORMAT_A8R8G8B8_UNORM: { - uint *d = (uint *) dest; - *d = (a << 24) | (r << 16) | (g << 8) | b; + uc->ui = (a << 24) | (r << 16) | (g << 8) | b; } return; case PIPE_FORMAT_X8R8G8B8_UNORM: { - uint *d = (uint *) dest; - *d = (0xff << 24) | (r << 16) | (g << 8) | b; + uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; } return; case PIPE_FORMAT_B8G8R8A8_UNORM: { - uint *d = (uint *) dest; - *d = (b << 24) | (g << 16) | (r << 8) | a; + uc->ui = (b << 24) | (g << 16) | (r << 8) | a; } return; case PIPE_FORMAT_B8G8R8X8_UNORM: { - uint *d = (uint *) dest; - *d = (b << 24) | (g << 16) | (r << 8) | 0xff; + uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; } return; case PIPE_FORMAT_R5G6B5_UNORM: { - ushort *d = (ushort *) dest; - *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); } return; case PIPE_FORMAT_A1R5G5B5_UNORM: { - ushort *d = (ushort *) dest; - *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); + uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); } return; case PIPE_FORMAT_A4R4G4B4_UNORM: { - ushort *d = (ushort *) dest; - *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); + uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; case PIPE_FORMAT_A8_UNORM: { - ubyte *d = (ubyte *) dest; - *d = a; + uc->ub = a; } return; case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_I8_UNORM: { - ubyte *d = (ubyte *) dest; - *d = r; + uc->ub = a; } return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { - float *d = (float *) dest; - d[0] = (float)r / 255.0f; - d[1] = (float)g / 255.0f; - d[2] = (float)b / 255.0f; - d[3] = (float)a / 255.0f; + uc->f[0] = (float)r / 255.0f; + uc->f[1] = (float)g / 255.0f; + uc->f[2] = (float)b / 255.0f; + uc->f[3] = (float)a / 255.0f; } return; case PIPE_FORMAT_R32G32B32_FLOAT: { - float *d = (float *) dest; - d[0] = (float)r / 255.0f; - d[1] = (float)g / 255.0f; - d[2] = (float)b / 255.0f; + uc->f[0] = (float)r / 255.0f; + uc->f[1] = (float)g / 255.0f; + uc->f[2] = (float)b / 255.0f; } return; /* XXX lots more cases to add */ default: + uc->ui = 0; /* keep compiler happy */ debug_print_format("gallium: unhandled format in util_pack_color_ub()", format); assert(0); } @@ -145,13 +141,13 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, * Unpack RGBA from a packed pixel, returning values as ubytes in [0,255]. */ static INLINE void -util_unpack_color_ub(enum pipe_format format, const void *src, +util_unpack_color_ub(enum pipe_format format, union util_color *uc, ubyte *r, ubyte *g, ubyte *b, ubyte *a) { switch (format) { case PIPE_FORMAT_R8G8B8A8_UNORM: { - uint p = ((const uint *) src)[0]; + uint p = uc->ui; *r = (ubyte) ((p >> 24) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 8) & 0xff); @@ -160,7 +156,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_R8G8B8X8_UNORM: { - uint p = ((const uint *) src)[0]; + uint p = uc->ui; *r = (ubyte) ((p >> 24) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 8) & 0xff); @@ -169,7 +165,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_A8R8G8B8_UNORM: { - uint p = ((const uint *) src)[0]; + uint p = uc->ui; *r = (ubyte) ((p >> 16) & 0xff); *g = (ubyte) ((p >> 8) & 0xff); *b = (ubyte) ((p >> 0) & 0xff); @@ -178,7 +174,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_X8R8G8B8_UNORM: { - uint p = ((const uint *) src)[0]; + uint p = uc->ui; *r = (ubyte) ((p >> 16) & 0xff); *g = (ubyte) ((p >> 8) & 0xff); *b = (ubyte) ((p >> 0) & 0xff); @@ -187,7 +183,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_B8G8R8A8_UNORM: { - uint p = ((const uint *) src)[0]; + uint p = uc->ui; *r = (ubyte) ((p >> 8) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 24) & 0xff); @@ -196,7 +192,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_B8G8R8X8_UNORM: { - uint p = ((const uint *) src)[0]; + uint p = uc->ui; *r = (ubyte) ((p >> 8) & 0xff); *g = (ubyte) ((p >> 16) & 0xff); *b = (ubyte) ((p >> 24) & 0xff); @@ -205,7 +201,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_R5G6B5_UNORM: { - ushort p = ((const ushort *) src)[0]; + ushort p = uc->us; *r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7)); *g = (ubyte) (((p >> 3) & 0xfc) | ((p >> 9) & 0x3)); *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7)); @@ -214,7 +210,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_A1R5G5B5_UNORM: { - ushort p = ((const ushort *) src)[0]; + ushort p = uc->us; *r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7)); *g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7)); *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7)); @@ -223,7 +219,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_A4R4G4B4_UNORM: { - ushort p = ((const ushort *) src)[0]; + ushort p = uc->us; *r = (ubyte) (((p >> 4) & 0xf0) | ((p >> 8) & 0xf)); *g = (ubyte) (((p >> 0) & 0xf0) | ((p >> 4) & 0xf)); *b = (ubyte) (((p << 4) & 0xf0) | ((p >> 0) & 0xf)); @@ -232,27 +228,27 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_A8_UNORM: { - ubyte p = ((const ubyte *) src)[0]; + ubyte p = uc->ub; *r = *g = *b = (ubyte) 0xff; *a = p; } return; case PIPE_FORMAT_L8_UNORM: { - ubyte p = ((const ubyte *) src)[0]; + ubyte p = uc->ub; *r = *g = *b = p; *a = (ubyte) 0xff; } return; case PIPE_FORMAT_I8_UNORM: { - ubyte p = ((const ubyte *) src)[0]; + ubyte p = uc->ub; *r = *g = *b = *a = p; } return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { - const float *p = (const float *) src; + const float *p = &uc->f[0]; *r = float_to_ubyte(p[0]); *g = float_to_ubyte(p[1]); *b = float_to_ubyte(p[2]); @@ -261,7 +257,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, return; case PIPE_FORMAT_R32G32B32_FLOAT: { - const float *p = (const float *) src; + const float *p = &uc->f[0]; *r = float_to_ubyte(p[0]); *g = float_to_ubyte(p[1]); *b = float_to_ubyte(p[2]); @@ -271,7 +267,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, case PIPE_FORMAT_R32G32_FLOAT: { - const float *p = (const float *) src; + const float *p = &uc->f[0]; *r = float_to_ubyte(p[0]); *g = float_to_ubyte(p[1]); *b = *a = (ubyte) 0xff; @@ -280,7 +276,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src, case PIPE_FORMAT_R32_FLOAT: { - const float *p = (const float *) src; + const float *p = &uc->f[0]; *r = float_to_ubyte(p[0]); *g = *b = *a = (ubyte) 0xff; } @@ -293,14 +289,13 @@ util_unpack_color_ub(enum pipe_format format, const void *src, assert(0); } } - /** * Note rgba outside [0,1] will be clamped for int pixel formats. */ static INLINE void -util_pack_color(const float rgba[4], enum pipe_format format, void *dest) +util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc) { ubyte r = 0; ubyte g = 0; @@ -318,90 +313,78 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) switch (format) { case PIPE_FORMAT_R8G8B8A8_UNORM: { - uint *d = (uint *) dest; - *d = (r << 24) | (g << 16) | (b << 8) | a; + uc->ui = (r << 24) | (g << 16) | (b << 8) | a; } return; case PIPE_FORMAT_R8G8B8X8_UNORM: { - uint *d = (uint *) dest; - *d = (r << 24) | (g << 16) | (b << 8) | 0xff; + uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; } return; case PIPE_FORMAT_A8R8G8B8_UNORM: { - uint *d = (uint *) dest; - *d = (a << 24) | (r << 16) | (g << 8) | b; + uc->ui = (a << 24) | (r << 16) | (g << 8) | b; } return; case PIPE_FORMAT_X8R8G8B8_UNORM: { - uint *d = (uint *) dest; - *d = (0xff << 24) | (r << 16) | (g << 8) | b; + uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; } return; case PIPE_FORMAT_B8G8R8A8_UNORM: { - uint *d = (uint *) dest; - *d = (b << 24) | (g << 16) | (r << 8) | a; + uc->ui = (b << 24) | (g << 16) | (r << 8) | a; } return; case PIPE_FORMAT_B8G8R8X8_UNORM: { - uint *d = (uint *) dest; - *d = (b << 24) | (g << 16) | (r << 8) | 0xff; + uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; } return; case PIPE_FORMAT_R5G6B5_UNORM: { - ushort *d = (ushort *) dest; - *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); } return; case PIPE_FORMAT_A1R5G5B5_UNORM: { - ushort *d = (ushort *) dest; - *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); + uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); } return; case PIPE_FORMAT_A4R4G4B4_UNORM: { - ushort *d = (ushort *) dest; - *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); + uc->ub = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; case PIPE_FORMAT_A8_UNORM: { - ubyte *d = (ubyte *) dest; - *d = a; + uc->ub = a; } return; case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_I8_UNORM: { - ubyte *d = (ubyte *) dest; - *d = r; + uc->ub = r; } return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { - float *d = (float *) dest; - d[0] = rgba[0]; - d[1] = rgba[1]; - d[2] = rgba[2]; - d[3] = rgba[3]; + uc->f[0] = rgba[0]; + uc->f[1] = rgba[1]; + uc->f[2] = rgba[2]; + uc->f[3] = rgba[3]; } return; case PIPE_FORMAT_R32G32B32_FLOAT: { - float *d = (float *) dest; - d[0] = rgba[0]; - d[1] = rgba[1]; - d[2] = rgba[2]; + uc->f[0] = rgba[0]; + uc->f[1] = rgba[1]; + uc->f[2] = rgba[2]; } return; /* XXX lots more cases to add */ default: + uc->ui = 0; /* keep compiler happy */ debug_print_format("gallium: unhandled format in util_pack_color()", format); assert(0); } diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index 79ad687ea9..3a3f968a49 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -59,9 +59,9 @@ cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, if (buffers & PIPE_CLEAR_COLOR) { uint surfIndex = 0; - uint clearValue; + union util_color uc; - util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &clearValue); + util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &uc); /* Build a CLEAR command and place it in the current batch buffer */ STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0); @@ -70,7 +70,7 @@ cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, cell_batch_alloc16(cell, sizeof(*clr)); clr->opcode[0] = CELL_CMD_CLEAR_SURFACE; clr->surface = surfIndex; - clr->value = clearValue; + clr->value = uc.ui; } if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c index bdcff94b9b..08d9f2e273 100644 --- a/src/gallium/drivers/llvmpipe/lp_clear.c +++ b/src/gallium/drivers/llvmpipe/lp_clear.c @@ -50,6 +50,7 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + union util_color uc; unsigned cv; uint i; @@ -64,8 +65,8 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i]; - util_pack_color(rgba, ps->format, &cv); - lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv); + util_pack_color(rgba, ps->format, &uc); + lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, uc.ui); } llvmpipe->dirty_render_cache = TRUE; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 442af70e14..4ddbb357b6 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -153,7 +153,7 @@ static void r300_set_blend_color(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, - &r300->blend_color_state->blend_color); + (union util_color *)&r300->blend_color_state->blend_color); /* XXX if FP16 blending is enabled, we should use the FP16 format */ r300->blend_color_state->blend_color_red_alpha = @@ -535,7 +535,7 @@ static void* sampler->filter1 |= r300_anisotropy(state->max_anisotropy); util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, - &sampler->border_color); + (union util_color *)&sampler->border_color); /* R500-specific fixups and optimizations */ if (r300_screen(r300->context.screen)->caps->is_r500) { diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index 8fac8e6e05..f98087deb8 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -48,6 +48,7 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil) { struct softpipe_context *softpipe = softpipe_context(pipe); + union util_color uc; unsigned cv; uint i; @@ -62,12 +63,12 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; - util_pack_color(rgba, ps->format, &cv); - sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, cv); + util_pack_color(rgba, ps->format, &uc); + sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, uc.ui); #if !TILE_CLEAR_OPTIMIZATION /* non-cached surface */ - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); #endif } } diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index 6195c3897e..409b3b41cb 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -46,7 +46,7 @@ try_clear(struct svga_context *svga, boolean restore_viewport = FALSE; SVGA3dClearFlag flags = 0; struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; - unsigned color = 0; + union util_color uc; ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); if (ret) @@ -54,7 +54,7 @@ try_clear(struct svga_context *svga, if ((buffers & PIPE_CLEAR_COLOR) && fb->cbufs[0]) { flags |= SVGA3D_CLEAR_COLOR; - util_pack_color(rgba, PIPE_FORMAT_A8R8G8B8_UNORM, &color); + util_pack_color(rgba, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); rect.w = fb->cbufs[0]->width; rect.h = fb->cbufs[0]->height; @@ -77,7 +77,7 @@ try_clear(struct svga_context *svga, return ret; } - ret = SVGA3D_ClearRect(svga->swc, flags, color, depth, stencil, + ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui, depth, stencil, rect.x, rect.y, rect.w, rect.h); if (ret != PIPE_OK) return ret; diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index b4e57c5d15..7f530083d6 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -122,7 +122,7 @@ svga_create_sampler_state(struct pipe_context *pipe, util_pack_color_ub( r, g, b, a, PIPE_FORMAT_B8G8R8A8_UNORM, - &cso->bordercolor ); + (union util_color *)&cso->bordercolor ); } /* No SVGA3D support for: diff --git a/src/gallium/state_trackers/vega/vg_translate.c b/src/gallium/state_trackers/vega/vg_translate.c index 00e0764706..5051d83831 100644 --- a/src/gallium/state_trackers/vega/vg_translate.c +++ b/src/gallium/state_trackers/vega/vg_translate.c @@ -487,7 +487,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -503,7 +503,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -520,7 +520,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -537,7 +537,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[3] = 1.f; util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -553,7 +553,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[3] = ((*src >> 0) & 1)/1.; util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -569,7 +569,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[3] = ((*src >> 0) & 15)/15.; util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -579,7 +579,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, src += offset; for (i = 0; i < n; ++i) { util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -595,7 +595,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -611,7 +611,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -628,7 +628,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -639,7 +639,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, src += offset; for (i = 0; i < n; ++i) { util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -649,7 +649,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, src += offset; for (i = 0; i < n; ++i) { util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } } @@ -668,7 +668,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[3] = 1.f; util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i+j]); + (union util_color *)rgba[i+j]); } ++src; } @@ -689,7 +689,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[3] = (((*src) & (1<> shift); util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i+j]); + (union util_color *)rgba[i+j]); } ++src; } @@ -716,7 +716,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[3] = ((*src) & (bitter)) >> shift; util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i +j]); + (union util_color *)rgba[i +j]); } ++src; } @@ -736,7 +736,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -753,7 +753,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -776,7 +776,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -793,7 +793,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -812,7 +812,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -829,7 +829,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -854,7 +854,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -871,7 +871,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, a = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -890,7 +890,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -907,7 +907,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -930,7 +930,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; @@ -947,7 +947,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 0) & 0xff; util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - rgba[i]); + (union util_color *)rgba[i]); ++src; } return; diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 4b35f59cc2..5e2ae1bb36 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -167,7 +167,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize]; ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize]; ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize]; - util_pack_color_ub(r, g, b, a, pt->format, dest + k); + util_pack_color_ub(r, g, b, a, pt->format, (union util_color *)(dest + k)); } } -- cgit v1.2.3 From ee1720b99dfb5964962f2346406a4e3e88374a68 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 8 Dec 2009 19:13:48 +0100 Subject: gallium: fix more potential strict aliasing issues In particular, gcc man page warns that union a_union { int i; double d; }; int f() { double d = 3.0; return ((union a_union *) &d)->i; } "might" not be ok (why not?), even though it doesn't seem to generate any warnings. Hence don't use this and do the extra step to actually use assignment to get the values in/out of the union. This changes parts of 3456f9149b3009fcfce80054759d05883d3c4ee5. --- src/gallium/drivers/r300/r300_state.c | 10 +- src/gallium/drivers/svga/svga_pipe_sampler.c | 5 +- src/gallium/state_trackers/vega/vg_translate.c | 190 ++++++++++++++++++------- src/mesa/state_tracker/st_atom_pixeltransfer.c | 4 +- 4 files changed, 148 insertions(+), 61 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 4ddbb357b6..a83075df92 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -151,9 +151,10 @@ static void r300_set_blend_color(struct pipe_context* pipe, const struct pipe_blend_color* color) { struct r300_context* r300 = r300_context(pipe); + union util_color uc; - util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, - (union util_color *)&r300->blend_color_state->blend_color); + util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); + r300->blend_color_state->blend_color = uc.ui; /* XXX if FP16 blending is enabled, we should use the FP16 format */ r300->blend_color_state->blend_color_red_alpha = @@ -513,6 +514,7 @@ static void* struct r300_context* r300 = r300_context(pipe); struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); int lod_bias; + union util_color uc; sampler->filter0 |= (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | @@ -534,8 +536,8 @@ static void* sampler->filter1 |= r300_anisotropy(state->max_anisotropy); - util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, - (union util_color *)&sampler->border_color); + util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); + sampler->border_color = uc.ui; /* R500-specific fixups and optimizations */ if (r300_screen(r300->context.screen)->caps->is_r500) { diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 7f530083d6..78053e755e 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -101,6 +101,7 @@ svga_create_sampler_state(struct pipe_context *pipe, { struct svga_context *svga = svga_context(pipe); struct svga_sampler_state *cso = CALLOC_STRUCT( svga_sampler_state ); + union util_color uc; cso->mipfilter = translate_mip_filter(sampler->min_mip_filter); cso->magfilter = translate_img_filter( sampler->mag_img_filter ); @@ -121,8 +122,8 @@ svga_create_sampler_state(struct pipe_context *pipe, ubyte a = float_to_ubyte(sampler->border_color[3]); util_pack_color_ub( r, g, b, a, - PIPE_FORMAT_B8G8R8A8_UNORM, - (union util_color *)&cso->bordercolor ); + PIPE_FORMAT_B8G8R8A8_UNORM, &uc); + cso->bordercolor = uc.ui; } /* No SVGA3D support for: diff --git a/src/gallium/state_trackers/vega/vg_translate.c b/src/gallium/state_trackers/vega/vg_translate.c index 5051d83831..03575ca3dd 100644 --- a/src/gallium/state_trackers/vega/vg_translate.c +++ b/src/gallium/state_trackers/vega/vg_translate.c @@ -474,6 +474,7 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, VGfloat rgba[][4]) { VGint i; + union util_color uc; switch (dataFormat) { case VG_sRGBX_8888: { @@ -486,8 +487,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 8) & 0xff; a = 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -502,8 +506,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -519,8 +526,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -536,8 +546,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[2] = ((*src >> 0) & 31)/31.; clr[3] = 1.f; - util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -552,8 +565,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[2] = ((*src >> 1) & 31)/31.; clr[3] = ((*src >> 0) & 1)/1.; - util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -568,8 +584,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[2] = ((*src >> 4) & 15)/15.; clr[3] = ((*src >> 0) & 15)/15.; - util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -578,8 +597,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, VGubyte *src = (VGubyte *)data; src += offset; for (i = 0; i < n; ++i) { - util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -594,8 +616,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 8) & 0xff; a = 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -610,8 +635,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -627,8 +655,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, b = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -638,8 +669,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, VGubyte *src = (VGubyte *)data; src += offset; for (i = 0; i < n; ++i) { - util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -648,8 +682,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, VGubyte *src = (VGubyte *)data; src += offset; for (i = 0; i < n; ++i) { - util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } } @@ -667,8 +704,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[2] = clr[0]; clr[3] = 1.f; - util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i+j]); + util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i+j][0] = uc.f[0]; + rgba[i+j][1] = uc.f[1]; + rgba[i+j][2] = uc.f[2]; + rgba[i+j][3] = uc.f[3]; } ++src; } @@ -688,8 +728,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[2] = 0.f; clr[3] = (((*src) & (1<> shift); - util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i+j]); + util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i+j][0] = uc.f[0]; + rgba[i+j][1] = uc.f[1]; + rgba[i+j][2] = uc.f[2]; + rgba[i+j][3] = uc.f[3]; } ++src; } @@ -715,8 +758,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, clr[2] = 0.f; clr[3] = ((*src) & (bitter)) >> shift; - util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i +j]); + util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i+j][0] = uc.f[0]; + rgba[i+j][1] = uc.f[1]; + rgba[i+j][2] = uc.f[2]; + rgba[i+j][3] = uc.f[3]; } ++src; } @@ -735,8 +781,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; b = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -752,8 +801,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; b = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -775,8 +827,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; b = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -792,8 +847,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; b = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -811,8 +869,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -828,8 +889,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -853,8 +917,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -870,8 +937,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, r = (*src >> 8) & 0xff; a = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -889,8 +959,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; r = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -906,8 +979,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; r = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -929,8 +1005,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; r = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; @@ -946,8 +1025,11 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx, g = (*src >> 8) & 0xff; r = (*src >> 0) & 0xff; - util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, - (union util_color *)rgba[i]); + util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc); + rgba[i][0] = uc.f[0]; + rgba[i][1] = uc.f[1]; + rgba[i][2] = uc.f[2]; + rgba[i][3] = uc.f[3]; ++src; } return; diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 5e2ae1bb36..6a5854e9ba 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -162,12 +162,14 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) */ for (i = 0; i < texSize; i++) { for (j = 0; j < texSize; j++) { + union util_color uc; int k = (i * texSize + j); ubyte r = ctx->PixelMaps.RtoR.Map8[j * rSize / texSize]; ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize]; ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize]; ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize]; - util_pack_color_ub(r, g, b, a, pt->format, (union util_color *)(dest + k)); + util_pack_color_ub(r, g, b, a, pt->format, &uc); + *(dest + k) = uc.ui; } } -- cgit v1.2.3 From 8cc570a48c2e8e18622027cbd76f16a746b430bc Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 9 Dec 2009 00:55:51 +0100 Subject: r300g: clean up r300_emit_aos --- src/gallium/drivers/r300/r300_cs.h | 9 +++++ src/gallium/drivers/r300/r300_emit.c | 71 +++++++++++++++++++++++------------- src/gallium/drivers/r300/r300_reg.h | 5 +++ 3 files changed, 59 insertions(+), 26 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 9fcf3ab538..d142fee050 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -115,6 +115,15 @@ cs_count -= 3; \ } while (0) +#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ + DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \ + "domains (%d, %d, %d)\n", \ + bo, rd, wd, flags); \ + assert(bo); \ + cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ + cs_count -= 2; \ +} while (0) + #define END_CS do { \ if (VERY_VERBOSE_CS) { \ DBG(cs_context_copy, DBG_CS, "r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index dbf316a9b5..7620c73cac 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson + * Copyright 2009 Marek Olšák * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -623,50 +624,68 @@ void r300_emit_texture(struct r300_context* r300, END_CS; } -/* XXX I can't read this and that's not good */ -void r300_emit_aos(struct r300_context* r300, unsigned offset) +static boolean r300_validate_aos(struct r300_context *r300) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; - CS_LOCALS(r300); int i; - unsigned aos_count = r300->vertex_element_count; + /* Check if formats and strides are aligned to the size of DWORD. */ + for (i = 0; i < r300->vertex_element_count; i++) { + if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || + pf_get_blocksize(velem[i].src_format) % 4 != 0) { + return FALSE; + } + } + return TRUE; +} + +void r300_emit_aos(struct r300_context* r300, unsigned offset) +{ + struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; + struct pipe_vertex_element *velem = r300->vertex_element; + int i; + unsigned size1, size2, aos_count = r300->vertex_element_count; unsigned packet_size = (aos_count * 3 + 1) / 2; + CS_LOCALS(r300); + + /* XXX Move this checking to a more approriate place. */ + if (!r300_validate_aos(r300)) { + /* XXX We should fallback using Draw. */ + assert(0); + } + BEGIN_CS(2 + packet_size + aos_count * 2); OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); OUT_CS(aos_count); + for (i = 0; i < aos_count - 1; i += 2) { - int buf_num1 = velem[i].vertex_buffer_index; - int buf_num2 = velem[i+1].vertex_buffer_index; - assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_blocksize(velem[i].src_format) % 4 == 0); - assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_blocksize(velem[i+1].src_format) % 4 == 0); - OUT_CS((pf_get_blocksize(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) | - (pf_get_blocksize(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22)); - OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset + - offset * vbuf[buf_num1].stride); - OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset + - offset * vbuf[buf_num2].stride); + vb1 = &vbuf[velem[i].vertex_buffer_index]; + vb2 = &vbuf[velem[i+1].vertex_buffer_index]; + size1 = pf_get_blocksize(velem[i].src_format); + size2 = pf_get_blocksize(velem[i+1].src_format); + + OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) | + R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride)); + OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); + OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride); } + if (aos_count & 1) { - int buf_num = velem[i].vertex_buffer_index; - assert(vbuf[buf_num].stride % 4 == 0 && pf_get_blocksize(velem[i].src_format) % 4 == 0); - OUT_CS((pf_get_blocksize(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6)); - OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset + - offset * vbuf[buf_num].stride); + vb1 = &vbuf[velem[i].vertex_buffer_index]; + size1 = pf_get_blocksize(velem[i].src_format); + + OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride)); + OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); } - /* XXX bare CS reloc */ for (i = 0; i < aos_count; i++) { - cs_winsys->write_cs_reloc(cs_winsys, - vbuf[velem[i].vertex_buffer_index].buffer, - RADEON_GEM_DOMAIN_GTT, - 0, - 0); - cs_count -= 2; + OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, + RADEON_GEM_DOMAIN_GTT, 0, 0); } END_CS; } + #if 0 void r300_emit_draw_packet(struct r300_context* r300) { diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 85b1ea568a..c1ea87d11e 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -3293,6 +3293,11 @@ enum { */ #define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 +# define R300_VBPNTR_SIZE0(x) ((x) >> 2) +# define R300_VBPNTR_STRIDE0(x) (((x) >> 2) << 8) +# define R300_VBPNTR_SIZE1(x) (((x) >> 2) << 16) +# define R300_VBPNTR_STRIDE1(x) (((x) >> 2) << 24) + #define R300_PACKET3_INDX_BUFFER 0x00003300 # define R300_INDX_BUFFER_DST_SHIFT 0 # define R300_INDX_BUFFER_SKIP_SHIFT 16 -- cgit v1.2.3 From 87b822e024797ef2fdb51ec9364f21eeb4d07161 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 8 Dec 2009 04:55:32 +0100 Subject: r300g: make pow(0,0) return 1 instead of NaN in the R500 fragment shader Unfortunately we can't fix this easily in the R300 fragment shader, and it's probably not worth the effort. --- src/gallium/drivers/r300/r300_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 7620c73cac..55bc2b3528 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -277,7 +277,7 @@ void r500_emit_fragment_program_code(struct r300_context* r300, BEGIN_CS(13 + ((code->inst_end + 1) * 6)); - OUT_CS_REG(R500_US_CONFIG, 0); + OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); OUT_CS_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); -- cgit v1.2.3 From 6de7ac73bf027b9ace6f5f0c8063cbf724d95cee Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 8 Dec 2009 21:53:19 +0100 Subject: r300g: always disable unused colorbuffers --- src/gallium/drivers/r300/r300_emit.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 55bc2b3528..f784e1fa8e 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -331,7 +331,13 @@ void r300_emit_fb_state(struct r300_context* r300, int i; CS_LOCALS(r300); - BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4); + /* Shouldn't fail unless there is a bug in the state tracker. */ + assert(fb->nr_cbufs <= 4); + + BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + + (fb->zsbuf ? 10 : 0) + 4); + + /* Flush and free renderbuffer caches. */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); @@ -339,6 +345,7 @@ void r300_emit_fb_state(struct r300_context* r300, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + /* Set up colorbuffers. */ for (i = 0; i < fb->nr_cbufs; i++) { surf = fb->cbufs[i]; tex = (struct r300_texture*)surf->texture; @@ -356,6 +363,12 @@ void r300_emit_fb_state(struct r300_context* r300, r300_translate_out_fmt(surf->format)); } + /* Disable unused colorbuffers. */ + for (; i < 4; i++) { + OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), R300_US_OUT_FMT_UNUSED); + } + + /* Set up a zbuffer. */ if (fb->zsbuf) { surf = fb->zsbuf; tex = (struct r300_texture*)surf->texture; -- cgit v1.2.3 From c6b450033d7ec2a415b1d761da1d94588358c94b Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 9 Dec 2009 00:45:18 +0100 Subject: r300g: fix routing of vertex streams if TCL is bypassed Generating mipmaps finally works, among other things. Yay! --- src/gallium/drivers/r300/r300_state.c | 2 -- src/gallium/drivers/r300/r300_state_derived.c | 17 +++++++++++---- src/gallium/drivers/r300/r300_vs.c | 31 +++++++++++---------------- src/gallium/drivers/r300/r300_vs.h | 4 +++- 4 files changed, 29 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 68c5408a64..edf7114bbb 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -419,8 +419,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, if (state->bypass_vs_clip_and_viewport || !r300_screen(pipe->screen)->caps->has_tcl) { rs->vap_control_status |= R300_VAP_TCL_BYPASS; - } else { - rs->rs.bypass_vs_clip_and_viewport = TRUE; } rs->point_size = pack_float_16_6x(state->point_size) | diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 6af49888b9..29bc701a86 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -134,6 +134,16 @@ static void r300_vertex_psc(struct r300_context* r300) uint16_t type, swizzle; enum pipe_format format; unsigned i; + int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + int* stream_tab; + + /* If TCL is bypassed, map vertex streams to equivalent VS output + * locations. */ + if (r300->rs_state->enable_vte) { + stream_tab = identity; + } else { + stream_tab = r300->vs->stream_loc_notcl; + } /* Vertex shaders have no semantics on their inputs, * so PSC should just route stuff based on the vertex elements, @@ -147,10 +157,10 @@ static void r300_vertex_psc(struct r300_context* r300) format = r300->vertex_element[i].src_format; type = r300_translate_vertex_data_type(format) | - (i << R300_DST_VEC_LOC_SHIFT); + (stream_tab[i] << R300_DST_VEC_LOC_SHIFT); swizzle = r300_translate_vertex_data_swizzle(format); - if (i % 2) { + if (i & 1) { vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; } else { @@ -159,7 +169,6 @@ static void r300_vertex_psc(struct r300_context* r300) } } - assert(i <= 15); /* Set the last vector in the PSC. */ @@ -178,7 +187,7 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; - int* vs_output_tab = r300->vs->output_stream_loc_swtcl; + int* vs_output_tab = r300->vs->stream_loc_notcl; /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index 31248346bc..fa207c939c 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -143,35 +143,33 @@ static void r300_shader_vap_output_fmt( assert(gen_count <= 8); } -/* Set VS output stream locations for SWTCL. */ -static void r300_stream_locations_swtcl( +/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed + * or isn't present. */ +static void r300_stream_locations_notcl( struct r300_shader_semantics* vs_outputs, - int* output_stream_loc) + int* stream_loc) { int i, tabi = 0, gen_count; - /* XXX Check whether the numbers (0, 1, 2+i, etc.) are correct. - * These should go to VAP_PROG_STREAM_CNTL/DST_VEC_LOC. */ - /* Position. */ - output_stream_loc[tabi++] = 0; + stream_loc[tabi++] = 0; /* Point size. */ if (vs_outputs->psize != ATTR_UNUSED) { - output_stream_loc[tabi++] = 1; + stream_loc[tabi++] = 1; } /* Colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (vs_outputs->color[i] != ATTR_UNUSED) { - output_stream_loc[tabi++] = 2 + i; + stream_loc[tabi++] = 2 + i; } } /* Back-face colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (vs_outputs->bcolor[i] != ATTR_UNUSED) { - output_stream_loc[tabi++] = 4 + i; + stream_loc[tabi++] = 4 + i; } } @@ -180,7 +178,7 @@ static void r300_stream_locations_swtcl( for (i = 0; i < ATTR_GENERIC_COUNT; i++) { if (vs_outputs->bcolor[i] != ATTR_UNUSED) { assert(tabi < 16); - output_stream_loc[tabi++] = 6 + gen_count; + stream_loc[tabi++] = 6 + gen_count; gen_count++; } } @@ -188,7 +186,7 @@ static void r300_stream_locations_swtcl( /* Fog coordinates. */ if (vs_outputs->fog != ATTR_UNUSED) { assert(tabi < 16); - output_stream_loc[tabi++] = 6 + gen_count; + stream_loc[tabi++] = 6 + gen_count; gen_count++; } @@ -196,7 +194,7 @@ static void r300_stream_locations_swtcl( assert(gen_count <= 8); for (; tabi < 16;) { - output_stream_loc[tabi++] = -1; + stream_loc[tabi++] = -1; } } @@ -254,10 +252,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* Initialize. */ r300_shader_read_vs_outputs(&vs->info, &vs->outputs); r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt); - - if (!r300_screen(r300->context.screen)->caps->has_tcl) { - r300_stream_locations_swtcl(&vs->outputs, vs->output_stream_loc_swtcl); - } + r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl); /* Setup the compiler */ rc_init(&compiler.Base); @@ -283,7 +278,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { - /* XXX Fail gracefully */ + /* XXX We should fallback using Draw. */ fprintf(stderr, "r300 VP: Compiler error\n"); abort(); } diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 283dd5a9e8..67e9db5366 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -38,9 +38,11 @@ struct r300_vertex_shader { struct tgsi_shader_info info; struct r300_shader_semantics outputs; - int output_stream_loc_swtcl[16]; uint hwfmt[4]; + /* Stream locations for SWTCL or if TCL is bypassed. */ + int stream_loc_notcl[16]; + /* Has this shader been translated yet? */ boolean translated; -- cgit v1.2.3 From 38a97148bf5df3c32087a5fdd799912d0275267d Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 13 Dec 2009 01:32:39 +0100 Subject: r300g: add acceleration of the clear, surface_copy, and surface_fill functions --- src/gallium/drivers/r300/Makefile | 2 +- src/gallium/drivers/r300/SConscript | 2 +- src/gallium/drivers/r300/r300_blit.c | 130 ++++++++++++++++++++++++++++++++ src/gallium/drivers/r300/r300_blit.h | 48 ++++++++++++ src/gallium/drivers/r300/r300_clear.c | 38 ---------- src/gallium/drivers/r300/r300_clear.h | 34 --------- src/gallium/drivers/r300/r300_context.c | 9 ++- src/gallium/drivers/r300/r300_context.h | 4 + 8 files changed, 192 insertions(+), 75 deletions(-) create mode 100644 src/gallium/drivers/r300/r300_blit.c create mode 100644 src/gallium/drivers/r300/r300_blit.h delete mode 100644 src/gallium/drivers/r300/r300_clear.c delete mode 100644 src/gallium/drivers/r300/r300_clear.h (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 9c9fc6f64b..8cfd4147c2 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -4,8 +4,8 @@ include $(TOP)/configs/current LIBNAME = r300 C_SOURCES = \ + r300_blit.c \ r300_chipset.c \ - r300_clear.c \ r300_context.c \ r300_debug.c \ r300_emit.c \ diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 97989040d2..0d2de17be9 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -9,8 +9,8 @@ env.Append(CPPPATH = ['#/src/mesa/drivers/dri/r300/compiler', '#/include', '#/sr r300 = env.ConvenienceLibrary( target = 'r300', source = [ + 'r300_blit.c', 'r300_chipset.c', - 'r300_clear.c', 'r300_context.c', 'r300_debug.c', 'r300_emit.c', diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c new file mode 100644 index 0000000000..ffe066d536 --- /dev/null +++ b/src/gallium/drivers/r300/r300_blit.c @@ -0,0 +1,130 @@ +/* + * Copyright 2009 Marek Olšák + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_blit.h" +#include "r300_context.h" + +#include "util/u_rect.h" + +static void r300_blitter_save_states(struct r300_context* r300) +{ + util_blitter_save_blend(r300->blitter, r300->blend_state); + util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state); + util_blitter_save_rasterizer(r300->blitter, r300->rs_state); + util_blitter_save_fragment_shader(r300->blitter, r300->fs); + util_blitter_save_vertex_shader(r300->blitter, r300->vs); +} + +/* Clear currently bound buffers. */ +void r300_clear(struct pipe_context* pipe, + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil) +{ + /* XXX Implement fastfill. + * + * If fastfill is enabled, a few facts should be considered: + * + * 1) Zbuffer must be micro-tiled and whole microtiles must be + * written. + * + * 2) ZB_DEPTHCLEARVALUE is used to clear a zbuffer and Z Mask must be + * equal to 0. + * + * 3) RB3D_COLOR_CLEAR_VALUE is used to clear a colorbuffer and + * RB3D_COLOR_CHANNEL_MASK must be equal to 0. + * + * 4) ZB_CB_CLEAR can be used to make the ZB units help in clearing + * the colorbuffer. The color clear value is supplied through both + * RB3D_COLOR_CLEAR_VALUE and ZB_DEPTHCLEARVALUE, and the colorbuffer + * must be set in ZB_DEPTHOFFSET and ZB_DEPTHPITCH in addition to + * RB3D_COLOROFFSET and RB3D_COLORPITCH. It's obvious that the zbuffer + * will not be cleared and multiple render targets cannot be cleared + * this way either. + * + * 5) For 16-bit integer buffering, compression causes a hung with one or + * two samples and should not be used. + * + * 6) Fastfill must not be used if reading of compressed Z data is disabled + * and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE), + * i.e. it cannot be used to compress the zbuffer. + * (what the hell does that mean and how does it fit in clearing + * the buffers?) + * + * - Marek + */ + + struct r300_context* r300 = r300_context(pipe); + + r300_blitter_save_states(r300); + + util_blitter_clear(r300->blitter, + r300->framebuffer_state.width, + r300->framebuffer_state.height, + r300->framebuffer_state.nr_cbufs, + buffers, rgba, depth, stencil); +} + +/* Copy a block of pixels from one surface to another. */ +void r300_surface_copy(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + struct pipe_surface* src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct r300_context* r300 = r300_context(pipe); + + /* Yeah we have to save all those states to ensure this blitter operation + * is really transparent. The states will be restored by the blitter once + * copying is done. */ + r300_blitter_save_states(r300); + util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state); + + util_blitter_save_fragment_sampler_states( + r300->blitter, r300->sampler_count, (void**)r300->sampler_states); + + util_blitter_save_fragment_sampler_textures( + r300->blitter, r300->texture_count, + (struct pipe_texture**)r300->textures); + + /* Do a copy */ + util_blitter_copy(r300->blitter, + dst, dstx, dsty, src, srcx, srcy, width, height, TRUE); +} + +/* Fill a region of a surface with a constant value. */ +void r300_surface_fill(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value) +{ + struct r300_context* r300 = r300_context(pipe); + + r300_blitter_save_states(r300); + util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state); + + util_blitter_fill(r300->blitter, + dst, dstx, dsty, width, height, value); +} diff --git a/src/gallium/drivers/r300/r300_blit.h b/src/gallium/drivers/r300/r300_blit.h new file mode 100644 index 0000000000..029e4f98e7 --- /dev/null +++ b/src/gallium/drivers/r300/r300_blit.h @@ -0,0 +1,48 @@ +/* + * Copyright 2008 Marek Olšák + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_BLIT_H +#define R300_BLIT_H + +struct pipe_context; +struct pipe_surface; + +void r300_clear(struct pipe_context* pipe, + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil); + +void r300_surface_copy(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + struct pipe_surface* src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height); + +void r300_surface_fill(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value); + +#endif /* R300_BLIT_H */ diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c deleted file mode 100644 index 02d6d504fc..0000000000 --- a/src/gallium/drivers/r300/r300_clear.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "r300_clear.h" -#include "r300_context.h" - -#include "util/u_clear.h" - -/* Clears currently bound buffers. */ -void r300_clear(struct pipe_context* pipe, - unsigned buffers, - const float* rgba, - double depth, - unsigned stencil) -{ - /* XXX we can and should do one clear if both color and zs are set */ - util_clear(pipe, &r300_context(pipe)->framebuffer_state, - buffers, rgba, depth, stencil); -} diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_clear.h deleted file mode 100644 index b8fcdf273c..0000000000 --- a/src/gallium/drivers/r300/r300_clear.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef R300_CLEAR_H -#define R300_CLEAR_H - -struct pipe_context; - -void r300_clear(struct pipe_context* pipe, - unsigned buffers, - const float* rgba, - double depth, - unsigned stencil); - -#endif /* R300_CLEAR_H */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 5b337f03ac..d5c2d63d39 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -28,7 +28,7 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" -#include "r300_clear.h" +#include "r300_blit.h" #include "r300_context.h" #include "r300_flush.h" #include "r300_query.h" @@ -52,6 +52,8 @@ static void r300_destroy_context(struct pipe_context* context) struct r300_context* r300 = r300_context(context); struct r300_query* query, * temp; + util_blitter_destroy(r300->blitter); + util_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table, NULL); util_hash_table_destroy(r300->shader_hash_table); @@ -124,6 +126,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.destroy = r300_destroy_context; r300->context.clear = r300_clear; + r300->context.surface_copy = r300_surface_copy; + r300->context.surface_fill = r300_surface_fill; if (r300screen->caps->has_tcl) { r300->context.draw_arrays = r300_draw_arrays; @@ -175,5 +179,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw++; + + r300->blitter = util_blitter_create(&r300->context); + return &r300->context; } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 0be190392a..6bd2766730 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -25,6 +25,8 @@ #include "draw/draw_vertex.h" +#include "util/u_blitter.h" + #include "pipe/p_context.h" #include "pipe/p_inlines.h" @@ -248,6 +250,8 @@ struct r300_context { struct radeon_winsys* winsys; /* Draw module. Used mostly for SW TCL. */ struct draw_context* draw; + /* Accelerated blit support. */ + struct blitter_context* blitter; /* Vertex buffer for rendering. */ struct pipe_buffer* vbo; -- cgit v1.2.3 From c5e0b0bc37315cd29a84e71854dca951149b8bc8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 13 Dec 2009 02:19:18 +0100 Subject: r300g: add Z24X8 to the list of unsupported sampler formats on R3xx-R4xx --- src/gallium/drivers/r300/r300_screen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index c0d9797020..feb571a23d 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -220,12 +220,18 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, /* Z buffer or texture */ case PIPE_FORMAT_Z16_UNORM: + retval = usage & + (PIPE_TEXTURE_USAGE_DEPTH_STENCIL | + PIPE_TEXTURE_USAGE_SAMPLER); + break; + + /* 24bit Z buffer can only be used as a texture on R500. */ case PIPE_FORMAT_Z24X8_UNORM: /* Z buffer with stencil or texture */ case PIPE_FORMAT_Z24S8_UNORM: retval = usage & (PIPE_TEXTURE_USAGE_DEPTH_STENCIL | - PIPE_TEXTURE_USAGE_SAMPLER); + (is_r500 ? PIPE_TEXTURE_USAGE_SAMPLER : 0)); break; /* Definitely unsupported formats. */ -- cgit v1.2.3 From de0befc4b2e3061f865a5b39295d64a8f003e9e8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Dec 2009 05:22:36 +0100 Subject: r300g: remove unnecessary flush in set_sampler_textures --- src/gallium/drivers/r300/r300_state.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index edf7114bbb..3cfa2e63f9 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -626,8 +626,6 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, return; } - r300->context.flush(&r300->context, 0, NULL); - for (i = 0; i < count; i++) { if (r300->textures[i] != (struct r300_texture*)texture[i]) { pipe_texture_reference((struct pipe_texture**)&r300->textures[i], -- cgit v1.2.3 From cf85bf9cd0c168caed6210a896df285c3d86db03 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Dec 2009 05:47:54 +0100 Subject: r300g: set the number of colorbuffers in RB3D_CCTL --- src/gallium/drivers/r300/r300_emit.c | 5 ++++- src/gallium/drivers/r300/r300_reg.h | 1 + src/gallium/drivers/r300/r300_state_invariant.c | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f784e1fa8e..9644efb717 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -335,7 +335,7 @@ void r300_emit_fb_state(struct r300_context* r300, assert(fb->nr_cbufs <= 4); BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + - (fb->zsbuf ? 10 : 0) + 4); + (fb->zsbuf ? 10 : 0) + 6); /* Flush and free renderbuffer caches. */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -345,6 +345,9 @@ void r300_emit_fb_state(struct r300_context* r300, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + /* Set the number of colorbuffers. */ + OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs)); + /* Set up colorbuffers. */ for (i = 0; i < fb->nr_cbufs; i++) { surf = fb->cbufs[i]; diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index c1ea87d11e..d8d08fbe26 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -2145,6 +2145,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Unpipelined. */ #define R300_RB3D_CCTL 0x4e00 +# define R300_RB3D_CCTL_NUM_MULTIWRITES(x) (MAX2(((x)-1), 0) << 5) # define R300_RB3D_CCTL_NUM_MULTIWRITES_1_BUFFER (0 << 5) # define R300_RB3D_CCTL_NUM_MULTIWRITES_2_BUFFERS (1 << 5) # define R300_RB3D_CCTL_NUM_MULTIWRITES_3_BUFFERS (2 << 5) diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index 46d1cb39b5..3320d43b27 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -84,7 +84,7 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(56 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0)); + BEGIN_CS(54 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0)); /* Flush PVS. */ OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -123,7 +123,6 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000); OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C); OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525); - OUT_CS_REG(R300_RB3D_CCTL, 0x00000000); OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000); if (caps->is_r500) { OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000); -- cgit v1.2.3 From a6d701d1c6ed8e0a649d62104aeded8fb25c66d8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Dec 2009 05:29:12 +0100 Subject: r300g: if no colorbuffers are set, disable blending and set the color mask to 0 This seems to be the only way to disable the first colorbuffer. --- src/gallium/drivers/r300/r300_emit.c | 13 ++++++++++--- src/gallium/drivers/r300/r300_state.c | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 9644efb717..55e4f94afe 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -41,9 +41,16 @@ void r300_emit_blend_state(struct r300_context* r300, CS_LOCALS(r300); BEGIN_CS(8); OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3); - OUT_CS(blend->blend_control); - OUT_CS(blend->alpha_blend_control); - OUT_CS(blend->color_channel_mask); + if (r300->framebuffer_state.nr_cbufs) { + OUT_CS(blend->blend_control); + OUT_CS(blend->alpha_blend_control); + OUT_CS(blend->color_channel_mask); + } else { + OUT_CS(0); + OUT_CS(0); + OUT_CS(0); + /* XXX also disable fastfill here once it's supported */ + } OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop); OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither); END_CS; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 3cfa2e63f9..91cf972ede 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -339,6 +339,7 @@ static void r300->dirty_state |= R300_NEW_SCISSOR; } r300->dirty_state |= R300_NEW_FRAMEBUFFERS; + r300->dirty_state |= R300_NEW_BLEND; } /* Create fragment shader state. */ -- cgit v1.2.3 From acce4824ec284b2a9bfdc847d7d79b8064912db9 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Dec 2009 06:39:08 +0100 Subject: r300g: clamp vertex indices to [min,max] everywhere --- src/gallium/drivers/r300/r300_render.c | 8 +++++--- src/gallium/drivers/r300/r300_state_invariant.c | 5 +---- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 35b335df6a..4b210f72db 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -82,8 +82,9 @@ static void r300_emit_draw_arrays(struct r300_context *r300, { CS_LOCALS(r300); - BEGIN_CS(4); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count); + BEGIN_CS(6); + OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); + OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300_translate_primitive(mode)); @@ -108,7 +109,8 @@ static void r300_emit_draw_elements(struct r300_context *r300, assert((start * indexSize) % 4 == 0); assert(offset_dwords == 0); - BEGIN_CS(10); + BEGIN_CS(12); + OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); if (indexSize == 4) { diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index 3320d43b27..d80e20a493 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -43,7 +43,7 @@ void r300_emit_invariant_state(struct r300_context* r300) struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; CS_LOCALS(r300); - BEGIN_CS(24 + (caps->has_tcl ? 2: 0)); + BEGIN_CS(20 + (caps->has_tcl ? 2: 0)); /*** Graphics Backend (GB) ***/ /* Various GB enables */ @@ -70,9 +70,6 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R300_US_W_FMT, 0x0); /*** VAP ***/ - /* Max and min vertex index clamp. */ - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0x0); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, 0xffffff); /* Sign/normalize control */ OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO); /* TCL-only stuff */ -- cgit v1.2.3 From ded4ecde60e36bbf7204ebb3b43c6ec065ff1f06 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Dec 2009 06:55:54 +0100 Subject: r300g: clean up the invariant state --- src/gallium/drivers/r300/r300_state_invariant.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index d80e20a493..bcd4c030f9 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -81,15 +81,11 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(54 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0)); - /* Flush PVS. */ - OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); + BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + (caps->is_r500 ? 4 : 0)); - OUT_CS_REG(R300_SE_VTE_CNTL, R300_VPORT_X_SCALE_ENA | - R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA | - R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA | - R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT); if (caps->has_tcl) { + /*Flushing PVS is required before the VAP_GB registers can be changed*/ + OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0); OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4); OUT_CS_32F(1.0); OUT_CS_32F(1.0); @@ -125,13 +121,10 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000); OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFFFFFFFF); } - OUT_CS_REG(R300_ZB_FORMAT, 0x00000002); - OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, 0x00000003); OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000); OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000); - OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F); /* XXX */ OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa); -- cgit v1.2.3 From 2ddee2cfbcef59128b2a251d5391ddc2b4aea4bb Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 15 Dec 2009 05:35:03 +0100 Subject: r300g: fix emission of which textures are enabled It fixes most of the "Bad CS" issues in piglit/texCombine and piglit/fbo. Some other issues of this kind will get fixed in the kernel soon (depth-only rendering, S3TC, and RGTC). --- src/gallium/drivers/r300/r300_emit.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 55e4f94afe..55c8aa07bd 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -883,10 +883,21 @@ void r300_emit_viewport_state(struct r300_context* r300, void r300_emit_texture_count(struct r300_context* r300) { + uint32_t tx_enable = 0; + int i; CS_LOCALS(r300); + /* Notice that texture_count and sampler_count are just sizes + * of the respective arrays. We still have to check for the individual + * elements. */ + for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) { + if (r300->textures[i]) { + tx_enable |= 1 << i; + } + } + BEGIN_CS(2); - OUT_CS_REG(R300_TX_ENABLE, (1 << r300->texture_count) - 1); + OUT_CS_REG(R300_TX_ENABLE, tx_enable); END_CS; } -- cgit v1.2.3