From 22d5a71e4dedfc047e1a14082b7d0d287cfe910e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 24 Apr 2011 08:30:08 +1000 Subject: r600g: PV/PS have cycle restrictions in scalar operations In the R600 ISA document: Section 4.7.5 Cycle restrictions for the ALU.trans states that PV/PS have cycle restrictions wrt constants. This is part of a fix for the LIT tests Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_asm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 7e854b1b81d..4cdd1ed698f 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -709,8 +709,12 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, if (r) return r; } - // Constants already processed - // No restrictions on PV, PS + // PV PS restrictions + if (const_count && (sel == 254 || sel == 255)) { + cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; + if (cycle < const_count) + return -1; + } } return 0; } -- cgit v1.2.3 From 77dc4c154cc6a8c3bc2369112c46f0be6ac444ae Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 24 Apr 2011 08:33:19 +1000 Subject: r600g: fix bank swizzle calcs for scalar only operations. In the initial code if we had nothing in the vector slots r would never get reset to 0, so we'd fail to compile shaders, after the previous commit this would happen for the LIT tests. When I fixed that we did a lot of unnecessary loops through all the vector states when we had no vector slots filled. So this patch optimises thing for the scalar only state. This fixes the 3 LIT piglit tests on r600g. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_asm.c | 40 +++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 4cdd1ed698f..efb22fdb8ee 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -725,13 +725,15 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, struct alu_bank_swizzle bs; int bank_swizzle[5]; int i, r = 0, forced = 0; - - for (i = 0; i < 5; i++) + boolean scalar_only = true; + for (i = 0; i < 5; i++) { if (slots[i] && slots[i]->bank_swizzle_force) { slots[i]->bank_swizzle = slots[i]->bank_swizzle_force; forced = 1; } - + if (i < 4 && slots[i]) + scalar_only = false; + } if (forced) return 0; @@ -742,13 +744,17 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, bank_swizzle[4] = SQ_ALU_SCL_210; while(bank_swizzle[4] <= SQ_ALU_SCL_221) { init_bank_swizzle(&bs); - for (i = 0; i < 4; i++) { - if (slots[i]) { - r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); - if (r) - break; + if (scalar_only == false) { + for (i = 0; i < 4; i++) { + if (slots[i]) { + r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); + if (r) + break; + } } - } + } else + r = 0; + if (!r && slots[4]) { r = check_scalar(bc, slots[4], &bs, bank_swizzle[4]); } @@ -760,12 +766,16 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, return 0; } - for (i = 0; i < 5; i++) { - bank_swizzle[i]++; - if (bank_swizzle[i] <= SQ_ALU_VEC_210) - break; - else - bank_swizzle[i] = SQ_ALU_VEC_012; + if (scalar_only) { + bank_swizzle[4]++; + } else { + for (i = 0; i < 5; i++) { + bank_swizzle[i]++; + if (bank_swizzle[i] <= SQ_ALU_VEC_210) + break; + else + bank_swizzle[i] = SQ_ALU_VEC_012; + } } } -- cgit v1.2.3 From 6372660d122f4056dffb56d1b93dbd1bbc661f67 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 24 Apr 2011 11:04:46 +1000 Subject: r600g: fix glsl-fs-abs-neg the hw does neg after abs, so don't neg the source in the ABS instruction case. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_shader.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 188cea0ff88..2f901be28fa 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -911,6 +911,8 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap) break; case TGSI_OPCODE_ABS: alu.src[0].abs = 1; + if (alu.src[0].neg) + alu.src[0].neg = 0; break; default: break; -- cgit v1.2.3 From 0c71da18ee29e8c29538104a0a8d07c9e9aae9a7 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 24 Apr 2011 11:48:46 +0200 Subject: r300g: fix exposing caps on r300-r400 Broken with 72239d16cd08113e994ea3508f91193c682b0930. --- src/gallium/drivers/r300/r300_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 9ec16c6562f..92e59293fe4 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -113,10 +113,10 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: - case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - return is_r500 ? 1 : 0; + return 1; case PIPE_CAP_TEXTURE_SWIZZLE: return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; + case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: return is_r500 ? 1 : 0; -- cgit v1.2.3 From 0b3122cfcb26e195f14470d8ea6e3cce240c2f79 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 24 Apr 2011 11:59:16 +0200 Subject: r300g: reorder caps --- src/gallium/drivers/r300/r300_screen.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 92e59293fe4..e8e16e08172 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -113,14 +113,21 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; + + /* r300 cannot do swizzling of compressed textures. Supported otherwise. */ case PIPE_CAP_TEXTURE_SWIZZLE: return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; + + /* Supported on r500 only. */ case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_SM3: return is_r500 ? 1 : 0; - /* Unsupported features (boolean caps). */ + /* Unsupported features. */ case PIPE_CAP_TIMER_QUERY: case PIPE_CAP_DUAL_SOURCE_BLEND: case PIPE_CAP_INDEP_BLEND_ENABLE: @@ -130,6 +137,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_ARRAY_TEXTURES: case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: return 0; /* SWTCL-only features. */ @@ -141,8 +151,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: case PIPE_CAP_MAX_COMBINED_SAMPLERS: return r300screen->caps.num_tex_units; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: @@ -153,16 +161,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_RENDER_TARGETS: return 4; - /* General shader limits and features. */ - case PIPE_CAP_SM3: - return is_r500 ? 1 : 0; - /* Fragment coordinate conventions. */ - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; default: debug_printf("r300: Warning: Unknown CAP %d in get_param.\n", param); -- cgit v1.2.3 From 0a9cec3475fb14be8aa5fa66557d338556cd8ed5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 24 Apr 2011 20:20:55 +1000 Subject: r600g: fix glean clipflat test. the provoking vertex doesn't apply to quad/strip/polygon. This fixes clipFlat on r600g. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_pipe.h | 1 - src/gallium/drivers/r600/r600_state_common.c | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 88aff0e81bb..40987a0e2de 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -241,7 +241,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs, /* r600_state.c */ void r600_init_state_functions(struct r600_pipe_context *rctx); -void r600_spi_update(struct r600_pipe_context *rctx); void r600_init_config(struct r600_pipe_context *rctx); void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 997c9a597ee..2f1068a0631 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -277,7 +277,7 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) } /* FIXME optimize away spi update when it's not needed */ -void r600_spi_update(struct r600_pipe_context *rctx) +static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim) { struct r600_pipe_shader *shader = rctx->ps_shader; struct r600_pipe_state rstate; @@ -309,6 +309,12 @@ void r600_spi_update(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL); } + + if (prim == PIPE_PRIM_QUADS || prim == PIPE_PRIM_QUAD_STRIP || prim == PIPE_PRIM_POLYGON) { + r600_pipe_state_add_reg(&rstate, R_028814_PA_SU_SC_MODE_CNTL, + S_028814_PROVOKING_VTX_LAST(1), + S_028814_PROVOKING_VTX_LAST(1), NULL); + } r600_context_pipe_state_set(&rctx->ctx, &rstate); } @@ -508,7 +514,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; } - r600_spi_update(rctx); + r600_spi_update(rctx, draw.info.mode); mask = 0; for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) { -- cgit v1.2.3 From de48199693484fc903627ce53b007901af2e37a8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 25 Apr 2011 06:55:09 +1000 Subject: r600g: enable EXT_draw_buffers2 Doesn't cause any piglit regression and passes the fbo-draw-buffers-blend test. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_pipe.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index d0d380392a0..4bc56448bce 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -375,6 +375,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: return 1; case PIPE_CAP_INDEP_BLEND_ENABLE: + case PIPE_CAP_INDEP_BLEND_FUNC: /* R600 doesn't support per-MRT blends */ if (family == CHIP_R600) return 0; @@ -387,12 +388,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* Unsupported features (boolean caps). */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - /* R600 doesn't support per-MRT blends */ - if (family == CHIP_R600) - return 0; - else return 0; case PIPE_CAP_ARRAY_TEXTURES: -- cgit v1.2.3 From d737857ed2ff4313fd6046dcd80018c6308a53c5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 25 Apr 2011 09:05:08 +1000 Subject: r600g: drop r600_helper.c no point in it move the one function into state common Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/Makefile | 1 - src/gallium/drivers/r600/r600_helper.c | 69 ---------------------------- src/gallium/drivers/r600/r600_pipe.h | 3 -- src/gallium/drivers/r600/r600_state_common.c | 39 ++++++++++++++++ 4 files changed, 39 insertions(+), 73 deletions(-) delete mode 100644 src/gallium/drivers/r600/r600_helper.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index a484f38e9f1..7e21e3e32b1 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -10,7 +10,6 @@ C_SOURCES = \ r600_asm.c \ r600_blit.c \ r600_buffer.c \ - r600_helper.c \ r600_pipe.c \ r600_query.c \ r600_resource.c \ diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c deleted file mode 100644 index 7e131093060..00000000000 --- a/src/gallium/drivers/r600/r600_helper.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * 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. - * - * Authors: - * Jerome Glisse - */ -#include -#include -#include -#include "r600_pipe.h" -#include "r600d.h" - -int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) -{ - switch (pprim) { - case PIPE_PRIM_POINTS: - *prim = V_008958_DI_PT_POINTLIST; - return 0; - case PIPE_PRIM_LINES: - *prim = V_008958_DI_PT_LINELIST; - return 0; - case PIPE_PRIM_LINE_STRIP: - *prim = V_008958_DI_PT_LINESTRIP; - return 0; - case PIPE_PRIM_LINE_LOOP: - *prim = V_008958_DI_PT_LINELOOP; - return 0; - case PIPE_PRIM_TRIANGLES: - *prim = V_008958_DI_PT_TRILIST; - return 0; - case PIPE_PRIM_TRIANGLE_STRIP: - *prim = V_008958_DI_PT_TRISTRIP; - return 0; - case PIPE_PRIM_TRIANGLE_FAN: - *prim = V_008958_DI_PT_TRIFAN; - return 0; - case PIPE_PRIM_POLYGON: - *prim = V_008958_DI_PT_POLYGON; - return 0; - case PIPE_PRIM_QUADS: - *prim = V_008958_DI_PT_QUADLIST; - return 0; - case PIPE_PRIM_QUAD_STRIP: - *prim = V_008958_DI_PT_QUADSTRIP; - return 0; - default: - fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); - return -EINVAL; - } -} diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 40987a0e2de..d6e47594116 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -252,9 +252,6 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, struct r600_resource *rbuffer, unsigned offset, unsigned stride); -/* r600_helper.h */ -int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); - /* r600_texture.c */ void r600_init_screen_texture_functions(struct pipe_screen *screen); void r600_init_surface_functions(struct r600_pipe_context *r600); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 2f1068a0631..a0817d09a15 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -31,6 +31,45 @@ #include "r600_pipe.h" #include "r600d.h" +static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) +{ + switch (pprim) { + case PIPE_PRIM_POINTS: + *prim = V_008958_DI_PT_POINTLIST; + return 0; + case PIPE_PRIM_LINES: + *prim = V_008958_DI_PT_LINELIST; + return 0; + case PIPE_PRIM_LINE_STRIP: + *prim = V_008958_DI_PT_LINESTRIP; + return 0; + case PIPE_PRIM_LINE_LOOP: + *prim = V_008958_DI_PT_LINELOOP; + return 0; + case PIPE_PRIM_TRIANGLES: + *prim = V_008958_DI_PT_TRILIST; + return 0; + case PIPE_PRIM_TRIANGLE_STRIP: + *prim = V_008958_DI_PT_TRISTRIP; + return 0; + case PIPE_PRIM_TRIANGLE_FAN: + *prim = V_008958_DI_PT_TRIFAN; + return 0; + case PIPE_PRIM_POLYGON: + *prim = V_008958_DI_PT_POLYGON; + return 0; + case PIPE_PRIM_QUADS: + *prim = V_008958_DI_PT_QUADLIST; + return 0; + case PIPE_PRIM_QUAD_STRIP: + *prim = V_008958_DI_PT_QUADSTRIP; + return 0; + default: + fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); + return -1; + } +} + /* common state between evergreen and r600 */ void r600_bind_blend_state(struct pipe_context *ctx, void *state) { -- cgit v1.2.3 From def6a91a62beb79956cb55805bff7d4c3e5461ec Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 24 Apr 2011 14:00:55 +0200 Subject: r600g: trivially implement LATC/3DC Passes fbo-generatemipmap-formats. --- src/gallium/drivers/r600/r600_texture.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index dc351bfb62d..90f34f7afb1 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -883,13 +883,17 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, switch (format) { case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_LATC1_SNORM: word4 |= sign_bit[0]; case PIPE_FORMAT_RGTC1_UNORM: + case PIPE_FORMAT_LATC1_UNORM: result = FMT_BC4; goto out_word4; case PIPE_FORMAT_RGTC2_SNORM: + case PIPE_FORMAT_LATC2_SNORM: word4 |= sign_bit[0] | sign_bit[1]; case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_LATC2_UNORM: result = FMT_BC5; goto out_word4; default: -- cgit v1.2.3 From 512c81484978014fe43bb3bd3f2ce1aaaee05868 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Thu, 21 Apr 2011 17:20:27 +0200 Subject: r600g: do not reset device to 0 when doing unrelated operations Seems to be a copy-paste bug. --- src/gallium/winsys/r600/drm/r600_drm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index ddd8ee3d6dd..311324f4f71 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -199,7 +199,6 @@ static int radeon_get_clock_crystal_freq(struct radeon *radeon) uint32_t clock_crystal_freq; int r; - radeon->device = 0; info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ; info.value = (uintptr_t)&clock_crystal_freq; r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, @@ -218,7 +217,6 @@ static int radeon_get_num_backends(struct radeon *radeon) uint32_t num_backends; int r; - radeon->device = 0; info.request = RADEON_INFO_NUM_BACKENDS; info.value = (uintptr_t)&num_backends; r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, -- cgit v1.2.3 From 71667533d1ccec698246b83bfd05df51a44cd298 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Thu, 21 Apr 2011 17:24:50 +0200 Subject: r600g: remove some pointless and unused functions --- src/gallium/winsys/r600/drm/r600_bo.c | 2 +- src/gallium/winsys/r600/drm/r600_hw_context.c | 4 ++-- src/gallium/winsys/r600/drm/r600_priv.h | 18 ------------------ 3 files changed, 3 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index 122a68884b4..e9c650d23be 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -178,7 +178,7 @@ boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *bo, whandle->stride = stride; switch(whandle->type) { case DRM_API_HANDLE_TYPE_KMS: - whandle->handle = r600_bo_get_handle(bo); + whandle->handle = bo->bo->handle; break; case DRM_API_HANDLE_TYPE_SHARED: if (radeon_bo_get_name(radeon, bo->bo, &whandle->handle)) diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 662455be28c..e28ef1f162d 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -798,7 +798,7 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, unsigned flush_mask, struct r600_bo *rbo) { struct radeon_bo *bo; - bo = r600_bo_get_bo(rbo); + bo = rbo->bo; /* if bo has already been flushed */ if (!(~bo->last_flush & flush_flags)) { bo->last_flush &= flush_mask; @@ -818,7 +818,7 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *r { struct radeon_bo *bo; - bo = r600_bo_get_bo(rbo); + bo = rbo->bo; assert(bo != NULL); if (bo->reloc) { *pm4 = bo->reloc_id; diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index ed0f3e584d3..27bdf2b1df8 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -201,24 +201,6 @@ static inline void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo) assert(bo->map_count >= 0); } -/* - * r600_bo - */ -static inline struct radeon_bo *r600_bo_get_bo(struct r600_bo *bo) -{ - return bo->bo; -} - -static unsigned inline r600_bo_get_handle(struct r600_bo *bo) -{ - return bo->bo->handle; -} - -static unsigned inline r600_bo_get_size(struct r600_bo *bo) -{ - return bo->size; -} - /* * fence */ -- cgit v1.2.3 From 077b1a6144a71418d0e127e45174c3907e646da0 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Sun, 24 Apr 2011 23:58:39 -0700 Subject: r600g: Remove r600_helper.c from SConscript. This is a follow-up to commit d737857ed2ff4313fd6046dcd80018c6308a53c5. --- src/gallium/drivers/r600/SConscript | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index 5a5fa6d65fd..0135808f10a 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -19,7 +19,6 @@ r600 = env.ConvenienceLibrary( 'r600_asm.c', 'r600_buffer.c', 'r600_blit.c', - 'r600_helper.c', 'r600_pipe.c', 'r600_query.c', 'r600_resource.c', -- cgit v1.2.3 From 32001c2244521a606ab210cd3a3fea3481131879 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 25 Apr 2011 13:28:55 +0200 Subject: r600g: Use EG constants in EG r600_colorformat_endian_swap(). This would actually fail to compile when PIPE_ARCH_BIG_ENDIAN is defined. Signed-off-by: Henri Verbeet --- src/gallium/drivers/r600/eg_state_inlines.h | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index a67e72e4f35..1ceea0bb486 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -510,44 +510,44 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { #ifdef PIPE_ARCH_BIG_ENDIAN switch(colorformat) { - case V_0280A0_COLOR_4_4: + case V_028C70_COLOR_4_4: return(ENDIAN_NONE); /* 8-bit buffers. */ - case V_0280A0_COLOR_8: + case V_028C70_COLOR_8: return(ENDIAN_NONE); /* 16-bit buffers. */ - case V_0280A0_COLOR_5_6_5: - case V_0280A0_COLOR_1_5_5_5: - case V_0280A0_COLOR_4_4_4_4: - case V_0280A0_COLOR_16: - case V_0280A0_COLOR_8_8: + case V_028C70_COLOR_5_6_5: + case V_028C70_COLOR_1_5_5_5: + case V_028C70_COLOR_4_4_4_4: + case V_028C70_COLOR_16: + case V_028C70_COLOR_8_8: return(ENDIAN_8IN16); /* 32-bit buffers. */ - case V_0280A0_COLOR_8_8_8_8: - case V_0280A0_COLOR_2_10_10_10: - case V_0280A0_COLOR_8_24: - case V_0280A0_COLOR_24_8: - case V_0280A0_COLOR_32_FLOAT: - case V_0280A0_COLOR_16_16_FLOAT: - case V_0280A0_COLOR_16_16: + case V_028C70_COLOR_8_8_8_8: + case V_028C70_COLOR_2_10_10_10: + case V_028C70_COLOR_8_24: + case V_028C70_COLOR_24_8: + case V_028C70_COLOR_32_FLOAT: + case V_028C70_COLOR_16_16_FLOAT: + case V_028C70_COLOR_16_16: return(ENDIAN_8IN32); /* 64-bit buffers. */ - case V_0280A0_COLOR_16_16_16_16: - case V_0280A0_COLOR_16_16_16_16_FLOAT: + case V_028C70_COLOR_16_16_16_16: + case V_028C70_COLOR_16_16_16_16_FLOAT: return(ENDIAN_8IN16); - case V_0280A0_COLOR_32_32_FLOAT: - case V_0280A0_COLOR_32_32: + case V_028C70_COLOR_32_32_FLOAT: + case V_028C70_COLOR_32_32: return(ENDIAN_8IN32); /* 128-bit buffers. */ - case V_0280A0_COLOR_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32: + case V_028C70_COLOR_32_32_32_FLOAT: + case V_028C70_COLOR_32_32_32_32_FLOAT: + case V_028C70_COLOR_32_32_32_32: return(ENDIAN_8IN32); default: return ENDIAN_NONE; /* Unsupported. */ -- cgit v1.2.3 From d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1d Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 25 Apr 2011 13:28:55 +0200 Subject: r600g: Cleanup the big endian support a bit. In particular, make sure the code is at least compiled on little endian systems. Signed-off-by: Henri Verbeet --- src/gallium/drivers/r600/eg_state_inlines.h | 92 +++++++++++++-------------- src/gallium/drivers/r600/evergreen_state.c | 4 +- src/gallium/drivers/r600/r600_asm.c | 30 +++------ src/gallium/drivers/r600/r600_buffer.c | 37 ++++++----- src/gallium/drivers/r600/r600_formats.h | 25 ++++++++ src/gallium/drivers/r600/r600_pipe.h | 6 ++ src/gallium/drivers/r600/r600_shader.c | 20 ++---- src/gallium/drivers/r600/r600_state.c | 4 +- src/gallium/drivers/r600/r600_state_common.c | 13 ++-- src/gallium/drivers/r600/r600_state_inlines.h | 92 +++++++++++++-------------- src/gallium/drivers/r600/r600d.h | 5 -- 11 files changed, 166 insertions(+), 162 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index 1ceea0bb486..1b4f75947b3 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -508,53 +508,53 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { -#ifdef PIPE_ARCH_BIG_ENDIAN - switch(colorformat) { - case V_028C70_COLOR_4_4: - return(ENDIAN_NONE); - - /* 8-bit buffers. */ - case V_028C70_COLOR_8: - return(ENDIAN_NONE); - - /* 16-bit buffers. */ - case V_028C70_COLOR_5_6_5: - case V_028C70_COLOR_1_5_5_5: - case V_028C70_COLOR_4_4_4_4: - case V_028C70_COLOR_16: - case V_028C70_COLOR_8_8: - return(ENDIAN_8IN16); - - /* 32-bit buffers. */ - case V_028C70_COLOR_8_8_8_8: - case V_028C70_COLOR_2_10_10_10: - case V_028C70_COLOR_8_24: - case V_028C70_COLOR_24_8: - case V_028C70_COLOR_32_FLOAT: - case V_028C70_COLOR_16_16_FLOAT: - case V_028C70_COLOR_16_16: - return(ENDIAN_8IN32); - - /* 64-bit buffers. */ - case V_028C70_COLOR_16_16_16_16: - case V_028C70_COLOR_16_16_16_16_FLOAT: - return(ENDIAN_8IN16); - - case V_028C70_COLOR_32_32_FLOAT: - case V_028C70_COLOR_32_32: - return(ENDIAN_8IN32); - - /* 128-bit buffers. */ - case V_028C70_COLOR_32_32_32_FLOAT: - case V_028C70_COLOR_32_32_32_32_FLOAT: - case V_028C70_COLOR_32_32_32_32: - return(ENDIAN_8IN32); - default: - return ENDIAN_NONE; /* Unsupported. */ + if (R600_BIG_ENDIAN) { + switch(colorformat) { + case V_028C70_COLOR_4_4: + return(ENDIAN_NONE); + + /* 8-bit buffers. */ + case V_028C70_COLOR_8: + return(ENDIAN_NONE); + + /* 16-bit buffers. */ + case V_028C70_COLOR_5_6_5: + case V_028C70_COLOR_1_5_5_5: + case V_028C70_COLOR_4_4_4_4: + case V_028C70_COLOR_16: + case V_028C70_COLOR_8_8: + return(ENDIAN_8IN16); + + /* 32-bit buffers. */ + case V_028C70_COLOR_8_8_8_8: + case V_028C70_COLOR_2_10_10_10: + case V_028C70_COLOR_8_24: + case V_028C70_COLOR_24_8: + case V_028C70_COLOR_32_FLOAT: + case V_028C70_COLOR_16_16_FLOAT: + case V_028C70_COLOR_16_16: + return(ENDIAN_8IN32); + + /* 64-bit buffers. */ + case V_028C70_COLOR_16_16_16_16: + case V_028C70_COLOR_16_16_16_16_FLOAT: + return(ENDIAN_8IN16); + + case V_028C70_COLOR_32_32_FLOAT: + case V_028C70_COLOR_32_32: + return(ENDIAN_8IN32); + + /* 128-bit buffers. */ + case V_028C70_COLOR_32_32_32_FLOAT: + case V_028C70_COLOR_32_32_32_32_FLOAT: + case V_028C70_COLOR_32_32_32_32: + return(ENDIAN_8IN32); + default: + return ENDIAN_NONE; /* Unsupported. */ + } + } else { + return ENDIAN_NONE; } -#else - return ENDIAN_NONE; -#endif } static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index a972f82fb1d..9813e01c966 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1574,9 +1574,7 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, -#ifdef PIPE_ARCH_BIG_ENDIAN - S_030008_ENDIAN_SWAP(ENDIAN_8IN32) | -#endif + S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | S_030008_STRIDE(stride), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index efb22fdb8ee..f037423f4bb 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -33,12 +33,6 @@ #include "r600_formats.h" #include "r600d.h" -#ifdef PIPE_ARCH_BIG_ENDIAN -#define CPU_TO_LE32(x) bswap_32(x) -#else -#define CPU_TO_LE32(x) (x) -#endif - #define NUM_OF_CYCLES 3 #define NUM_OF_COMPONENTS 4 @@ -1404,7 +1398,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign S_SQ_VTX_WORD1_SRF_MODE_ALL(vtx->srf_mode_all) | S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr); bc->bytecode[id++] = S_SQ_VTX_WORD2_OFFSET(vtx->offset) | - S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) | + S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) | S_SQ_VTX_WORD2_MEGA_FETCH(1); bc->bytecode[id++] = 0; return 0; @@ -1974,6 +1968,8 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, } } + *endian = r600_endian_swap(desc->channel[i].size); + switch (desc->channel[i].type) { /* Half-floats, floats, ints */ case UTIL_FORMAT_TYPE_FLOAT: @@ -1991,9 +1987,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_16_16_16_16_FLOAT; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN16; -#endif break; case 32: switch (desc->nr_channels) { @@ -2010,9 +2003,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_32_32_32_32_FLOAT; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN32; -#endif break; default: goto out_unknown; @@ -2050,9 +2040,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_16_16_16_16; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN16; -#endif break; case 32: switch (desc->nr_channels) { @@ -2069,9 +2056,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_32_32_32_32; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN32; -#endif break; default: goto out_unknown; @@ -2216,8 +2200,12 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru return -ENOMEM; } - for(i = 0; i < ve->fs_size / 4; i++) { - *(bytecode + i) = CPU_TO_LE32(*(bc.bytecode + i)); + if (R600_BIG_ENDIAN) { + for (i = 0; i < ve->fs_size / 4; ++i) { + bytecode[i] = bswap_32(bc.bytecode[i]); + } + } else { + memcpy(bytecode, bc.bytecode, ve->fs_size); } r600_bo_unmap(rctx->radeon, ve->fetch_shader); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 71b47e1b056..b89901d6248 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -268,31 +268,30 @@ void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resour uint8_t *ptr = (*rbuffer)->r.b.user_ptr; unsigned size = (*rbuffer)->r.b.b.b.width0; boolean flushed; -#ifdef PIPE_ARCH_BIG_ENDIAN - int i; - uint32_t *tmpPtr; *rbuffer = NULL; - tmpPtr = (uint32_t *)malloc(size); - /* big endian swap */ - if(tmpPtr == NULL) { - return; - } - for(i = 0; i < size / 4; i++) { - tmpPtr[i] = bswap_32(*((uint32_t *)ptr + i)); - } + if (R600_BIG_ENDIAN) { + uint32_t *tmpPtr; + unsigned i; - u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset, - (struct pipe_resource**)rbuffer, &flushed); + if (!(tmpPtr = malloc(size))) { + R600_ERR("Failed to allocate BE swap buffer.\n"); + return; + } - free(tmpPtr); -#else - *rbuffer = NULL; + for (i = 0; i < size / 4; ++i) { + tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]); + } - u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset, - (struct pipe_resource**)rbuffer, &flushed); -#endif + u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); + + free(tmpPtr); + } else { + u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); + } } else { *const_offset = 0; } diff --git a/src/gallium/drivers/r600/r600_formats.h b/src/gallium/drivers/r600/r600_formats.h index 0c91a212384..c9af631da41 100644 --- a/src/gallium/drivers/r600/r600_formats.h +++ b/src/gallium/drivers/r600/r600_formats.h @@ -1,6 +1,8 @@ #ifndef R600_FORMATS_H #define R600_FORMATS_H +#include "r600_pipe.h" + /* list of formats from R700 ISA document - apply across GPUs in different registers */ #define FMT_INVALID 0x00000000 #define FMT_8 0x00000001 @@ -53,4 +55,27 @@ #define FMT_BC4 0x00000034 #define FMT_BC5 0x00000035 +#define ENDIAN_NONE 0 +#define ENDIAN_8IN16 1 +#define ENDIAN_8IN32 2 +#define ENDIAN_8IN64 3 + +static INLINE unsigned r600_endian_swap(unsigned size) +{ + if (R600_BIG_ENDIAN) { + switch (size) { + case 64: + return ENDIAN_8IN64; + case 32: + return ENDIAN_8IN32; + case 16: + return ENDIAN_8IN16; + default: + return ENDIAN_NONE; + } + } else { + return ENDIAN_NONE; + } +} + #endif diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index d6e47594116..ae2a57e1416 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -40,6 +40,12 @@ #define R600_MAX_CONST_BUFFERS 1 #define R600_MAX_CONST_BUFFER_SIZE 4096 +#ifdef PIPE_ARCH_BIG_ENDIAN +#define R600_BIG_ENDIAN 1 +#else +#define R600_BIG_ENDIAN 0 +#endif + enum r600_pipe_state_id { R600_PIPE_STATE_BLEND = 0, R600_PIPE_STATE_BLEND_COLOR, diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 2f901be28fa..96ac59b2e93 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -35,12 +35,6 @@ #include #include -#ifdef PIPE_ARCH_BIG_ENDIAN -#define CPU_TO_LE32(x) bswap_32(x) -#else -#define CPU_TO_LE32(x) (x) -#endif - int r600_find_vs_semantic_index(struct r600_shader *vs, struct r600_shader *ps, int id) { @@ -69,8 +63,12 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s return -ENOMEM; } ptr = (uint32_t*)r600_bo_map(rctx->radeon, shader->bo, 0, NULL); - for(i = 0; i < rshader->bc.ndw; i++) { - *(ptr + i) = CPU_TO_LE32(*(rshader->bc.bytecode + i)); + if (R600_BIG_ENDIAN) { + for (i = 0; i < rshader->bc.ndw; ++i) { + ptr[i] = bswap_32(rshader->bc.bytecode[i]); + } + } else { + memcpy(ptr, rshader->bc.bytecode, rshader->bc.ndw * sizeof(*ptr)); } r600_bo_unmap(rctx->radeon, shader->bo); } @@ -477,11 +475,7 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx, unsigned int offset vtx.num_format_all = 2; /* NUM_FORMAT_SCALED */ vtx.format_comp_all = 1; /* FORMAT_COMP_SIGNED */ vtx.srf_mode_all = 1; /* SRF_MODE_NO_ZERO */ -#ifdef PIPE_ARCH_BIG_ENDIAN - vtx.endian = ENDIAN_8IN32; -#else - vtx.endian = ENDIAN_NONE; -#endif + vtx.endian = r600_endian_swap(32); if ((r = r600_bc_add_vtx(ctx->bc, &vtx))) return r; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index ac2e8986b97..1e3f81548a2 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1461,9 +1461,7 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2, -#ifdef PIPE_ARCH_BIG_ENDIAN - S_038008_ENDIAN_SWAP(ENDIAN_8IN32) | -#endif + S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | S_038008_STRIDE(stride), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3, 0x00000000, 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index a0817d09a15..cf605e11ade 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -28,6 +28,7 @@ #include #include #include "pipe/p_shader_tokens.h" +#include "r600_formats.h" #include "r600_pipe.h" #include "r600d.h" @@ -517,16 +518,16 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) case 2: vgt_draw_initiator = 0; vgt_dma_index_type = 0; -#ifdef PIPE_ARCH_BIG_ENDIAN - vgt_dma_swap_mode = ENDIAN_8IN16; -#endif + if (R600_BIG_ENDIAN) { + vgt_dma_swap_mode = ENDIAN_8IN16; + } break; case 4: vgt_draw_initiator = 0; vgt_dma_index_type = 1; -#ifdef PIPE_ARCH_BIG_ENDIAN - vgt_dma_swap_mode = ENDIAN_8IN32; -#endif + if (R600_BIG_ENDIAN) { + vgt_dma_swap_mode = ENDIAN_8IN32; + } break; case 0: vgt_draw_initiator = 2; diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 5d6145661a0..45fb0ce5e82 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -503,53 +503,53 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { -#ifdef PIPE_ARCH_BIG_ENDIAN - switch(colorformat) { - case V_0280A0_COLOR_4_4: - return(ENDIAN_NONE); - - /* 8-bit buffers. */ - case V_0280A0_COLOR_8: - return(ENDIAN_NONE); - - /* 16-bit buffers. */ - case V_0280A0_COLOR_5_6_5: - case V_0280A0_COLOR_1_5_5_5: - case V_0280A0_COLOR_4_4_4_4: - case V_0280A0_COLOR_16: - case V_0280A0_COLOR_8_8: - return(ENDIAN_8IN16); - - /* 32-bit buffers. */ - case V_0280A0_COLOR_8_8_8_8: - case V_0280A0_COLOR_2_10_10_10: - case V_0280A0_COLOR_8_24: - case V_0280A0_COLOR_24_8: - case V_0280A0_COLOR_32_FLOAT: - case V_0280A0_COLOR_16_16_FLOAT: - case V_0280A0_COLOR_16_16: - return(ENDIAN_8IN32); - - /* 64-bit buffers. */ - case V_0280A0_COLOR_16_16_16_16: - case V_0280A0_COLOR_16_16_16_16_FLOAT: - return(ENDIAN_8IN16); - - case V_0280A0_COLOR_32_32_FLOAT: - case V_0280A0_COLOR_32_32: - return(ENDIAN_8IN32); - - /* 128-bit buffers. */ - case V_0280A0_COLOR_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32: - return(ENDIAN_8IN32); - default: - return ENDIAN_NONE; /* Unsupported. */ + if (R600_BIG_ENDIAN) { + switch(colorformat) { + case V_0280A0_COLOR_4_4: + return(ENDIAN_NONE); + + /* 8-bit buffers. */ + case V_0280A0_COLOR_8: + return(ENDIAN_NONE); + + /* 16-bit buffers. */ + case V_0280A0_COLOR_5_6_5: + case V_0280A0_COLOR_1_5_5_5: + case V_0280A0_COLOR_4_4_4_4: + case V_0280A0_COLOR_16: + case V_0280A0_COLOR_8_8: + return(ENDIAN_8IN16); + + /* 32-bit buffers. */ + case V_0280A0_COLOR_8_8_8_8: + case V_0280A0_COLOR_2_10_10_10: + case V_0280A0_COLOR_8_24: + case V_0280A0_COLOR_24_8: + case V_0280A0_COLOR_32_FLOAT: + case V_0280A0_COLOR_16_16_FLOAT: + case V_0280A0_COLOR_16_16: + return(ENDIAN_8IN32); + + /* 64-bit buffers. */ + case V_0280A0_COLOR_16_16_16_16: + case V_0280A0_COLOR_16_16_16_16_FLOAT: + return(ENDIAN_8IN16); + + case V_0280A0_COLOR_32_32_FLOAT: + case V_0280A0_COLOR_32_32: + return(ENDIAN_8IN32); + + /* 128-bit buffers. */ + case V_0280A0_COLOR_32_32_32_FLOAT: + case V_0280A0_COLOR_32_32_32_32_FLOAT: + case V_0280A0_COLOR_32_32_32_32: + return(ENDIAN_8IN32); + default: + return ENDIAN_NONE; /* Unsupported. */ + } + } else { + return ENDIAN_NONE; } -#else - return ENDIAN_NONE; -#endif } static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 2bff52bec8c..8296b52eb94 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -3461,9 +3461,4 @@ #define SQ_TEX_INST_SAMPLE_L 0x11 #define SQ_TEX_INST_SAMPLE_C 0x18 -#define ENDIAN_NONE 0 -#define ENDIAN_8IN16 1 -#define ENDIAN_8IN32 2 -#define ENDIAN_8IN64 3 - #endif -- cgit v1.2.3 From b2a98c3531c276b76024bb9b10fdd6c3360cb0c9 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 25 Apr 2011 13:28:55 +0200 Subject: r600g: Unify comment style somewhat. Signed-off-by: Henri Verbeet --- src/gallium/drivers/r600/eg_state_inlines.h | 4 +- src/gallium/drivers/r600/evergreen_state.c | 6 ++- src/gallium/drivers/r600/r600_asm.c | 72 +++++++++++++-------------- src/gallium/drivers/r600/r600_pipe.c | 5 +- src/gallium/drivers/r600/r600_shader.c | 8 +-- src/gallium/drivers/r600/r600_state_inlines.h | 4 +- src/gallium/drivers/r600/r600_texture.c | 2 +- 7 files changed, 53 insertions(+), 48 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index 1b4f75947b3..586b7cf2d11 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -348,7 +348,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: - // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ return V_028C70_SWAP_STD_REV; case PIPE_FORMAT_Z24X8_UNORM: @@ -501,7 +501,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - //R600_ERR("unsupported color format %d\n", format); + /* R600_ERR("unsupported color format %d\n", format); */ return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 9813e01c966..89a8d942a54 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1232,9 +1232,11 @@ void evergreen_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_009100_SPI_CONFIG_CNTL, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_00913C_SPI_CONFIG_CNTL_1, S_00913C_VTX_DONE_DELAY(4), 0xFFFFFFFF, NULL); -// r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL); +#if 0 + r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL); -// r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL); +#endif r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL_1, 0x0, 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index f037423f4bb..033e84665f5 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -525,19 +525,19 @@ static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first, else if (is_alu_vec_unit_inst(bc, alu)) trans = 0; else if (assignment[chan]) - trans = 1; // assume ALU_INST_PREFER_VECTOR + trans = 1; /* Assume ALU_INST_PREFER_VECTOR. */ else trans = 0; if (trans) { if (assignment[4]) { - assert(0); //ALU.Trans has already been allocated + assert(0); /* ALU.Trans has already been allocated. */ return -1; } assignment[4] = alu; } else { if (assignment[chan]) { - assert(0); //ALU.chan has already been allocated + assert(0); /* ALU.chan has already been allocated. */ return -1; } assignment[chan] = alu; @@ -589,7 +589,7 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan, if (bs->hw_gpr[cycle][chan] == -1) bs->hw_gpr[cycle][chan] = sel; else if (bs->hw_gpr[cycle][chan] != (int)sel) { - // Another scalar operation has already used GPR read port for channel + /* Another scalar operation has already used the GPR read port for the channel. */ return -1; } return 0; @@ -609,9 +609,9 @@ static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsign return 0; } else if (bs->hw_cfile_addr[res] == sel && bs->hw_cfile_elem[res] == chan) - return 0; // Read for this scalar element already reserved, nothing to do here. + return 0; /* Read for this scalar element already reserved, nothing to do here. */ } - // All cfile read ports are used, cannot reference vector element + /* All cfile read ports are used, cannot reference vector element. */ return -1; } @@ -626,8 +626,8 @@ static int is_gpr(unsigned sel) static int is_cfile(unsigned sel) { return (sel > 255 && sel < 512) || - (sel > 511 && sel < 4607) || // Kcache before translate - (sel > 127 && sel < 192); // Kcache after translate + (sel > 511 && sel < 4607) || /* Kcache before translation. */ + (sel > 127 && sel < 192); /* Kcache after translation. */ } static int is_const(int sel) @@ -649,8 +649,8 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, if (is_gpr(sel)) { cycle = cycle_for_bank_swizzle_vec[bank_swizzle][src]; if (src == 1 && sel == alu->src[0].sel && elem == alu->src[0].chan) - // Nothing to do; special-case optimization, - // second source uses first source’s reservation + /* Nothing to do; special-case optimization, + * second source uses first source’s reservation. */ continue; else { r = reserve_gpr(bs, sel, elem, cycle); @@ -662,7 +662,7 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, if (r) return r; } - // No restrictions on PV, PS, literal or special constants + /* No restrictions on PV, PS, literal or special constants. */ } return 0; } @@ -676,10 +676,10 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, for (const_count = 0, src = 0; src < num_src; ++src) { sel = alu->src[src].sel; elem = alu->src[src].chan; - if (is_const(sel)) { // Any constant, including literal and inline constants + if (is_const(sel)) { /* Any constant, including literal and inline constants. */ if (const_count >= 2) - // More than two references to a constant in - // transcendental operation. + /* More than two references to a constant in + * transcendental operation. */ return -1; else const_count++; @@ -696,14 +696,14 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, if (is_gpr(sel)) { cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; if (cycle < const_count) - // Cycle for GPR load conflicts with - // constant load in transcendental operation. + /* Cycle for GPR load conflicts with + * constant load in transcendental operation. */ return -1; r = reserve_gpr(bs, sel, elem, cycle); if (r) return r; } - // PV PS restrictions + /* PV PS restrictions */ if (const_count && (sel == 254 || sel == 255)) { cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; if (cycle < const_count) @@ -731,8 +731,8 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, if (forced) return 0; - // just check every possible combination of bank swizzle - // not very efficent, but works on the first try in most of the cases + /* Just check every possible combination of bank swizzle. + * Not very efficent, but works on the first try in most of the cases. */ for (i = 0; i < 4; i++) bank_swizzle[i] = SQ_ALU_VEC_012; bank_swizzle[4] = SQ_ALU_SCL_210; @@ -773,7 +773,7 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, } } - // couldn't find a working swizzle + /* Couldn't find a working swizzle. */ return -1; } @@ -843,17 +843,17 @@ void r600_bc_special_constants(u32 value, unsigned *sel, unsigned *neg) case -1: *sel = V_SQ_ALU_SRC_M_1_INT; break; - case 0x3F800000: // 1.0f + case 0x3F800000: /* 1.0f */ *sel = V_SQ_ALU_SRC_1; break; - case 0x3F000000: // 0.5f + case 0x3F000000: /* 0.5f */ *sel = V_SQ_ALU_SRC_0_5; break; - case 0xBF800000: // -1.0f + case 0xBF800000: /* -1.0f */ *sel = V_SQ_ALU_SRC_1; *neg ^= 1; break; - case 0xBF000000: // -0.5f + case 0xBF000000: /* -0.5f */ *sel = V_SQ_ALU_SRC_0_5; *neg ^= 1; break; @@ -946,13 +946,13 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral)) return 0; - // let's check used slots + /* Let's check used slots. */ if (prev[i] && !slots[i]) { result[i] = prev[i]; continue; } else if (prev[i] && slots[i]) { if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { - // trans unit is still free try to use it + /* Trans unit is still free try to use it. */ if (is_alu_any_unit_inst(bc, slots[i])) { result[i] = prev[i]; result[4] = slots[i]; @@ -971,14 +971,14 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], alu = slots[i]; num_once_inst += is_alu_once_inst(bc, alu); - // let's check dst gpr + /* Let's check dst gpr. */ if (alu->dst.rel) { if (have_mova) return 0; have_rel = 1; } - // let's check source gprs + /* Let's check source gprs */ num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { if (alu->src[src].rel) { @@ -987,7 +987,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], have_rel = 1; } - // constants doesn't matter + /* Constants don't matter. */ if (!is_gpr(alu->src[src].sel)) continue; @@ -995,7 +995,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], if (!prev[j] || !prev[j]->dst.write) continue; - // if it's relative then we can't determin which gpr is really used + /* If it's relative then we can't determin which gpr is really used. */ if (prev[j]->dst.chan == alu->src[src].chan && (prev[j]->dst.sel == alu->src[src].sel || prev[j]->dst.rel || alu->src[src].rel)) @@ -1935,7 +1935,7 @@ void r600_bc_dump(struct r600_bc *bc) fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]); fprintf(stderr, "ENDIAN:%d ", vtx->endian); fprintf(stderr, "OFFSET:%d\n", vtx->offset); - //TODO + /* TODO */ id++; fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]); id++; @@ -2091,11 +2091,11 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru u32 *bytecode; int i, r; - /* vertex elements offset need special handling, if offset is bigger - + * than what we can put in fetch instruction then we need to alterate - * the vertex resource offset. In such case in order to simplify code - * we will bound one resource per elements. It's a worst case scenario. - */ + /* Vertex element offsets need special handling. If the offset is + * bigger than what we can put in the fetch instruction we need to + * alter the vertex resource offset. In order to simplify code we + * will bind one resource per element in such cases. It's a worst + * case scenario. */ for (i = 0; i < ve->count; i++) { ve->vbuffer_offset[i] = C_SQ_VTX_WORD2_OFFSET & elements[i].src_offset; if (ve->vbuffer_offset[i]) { diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 4bc56448bce..e28d834dfee 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -487,9 +487,10 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e else return 16; case PIPE_SHADER_CAP_MAX_TEMPS: - return 256; //max native temporaries + return 256; /* Max native temporaries. */ case PIPE_SHADER_CAP_MAX_ADDRS: - return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */ + /* FIXME Isn't this equal to TEMPS? */ + return 1; /* Max native address registers */ case PIPE_SHADER_CAP_MAX_CONSTS: return R600_MAX_CONST_BUFFER_SIZE; case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 96ac59b2e93..0f4c0134dce 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -1993,9 +1993,11 @@ static int tgsi_exp(struct r600_shader_ctx *ctx) r600_bc_src(&alu.src[0], &ctx->src[0], 0); alu.dst.sel = ctx->temp_reg; -// r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); -// if (r) -// return r; +#if 0 + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; +#endif alu.dst.write = 1; alu.dst.chan = 1; diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 45fb0ce5e82..09d07f78407 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -342,7 +342,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: - // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ return V_0280A0_SWAP_STD_REV; case PIPE_FORMAT_Z24X8_UNORM: @@ -496,7 +496,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - //R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); + /* R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); */ return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 90f34f7afb1..eb696b73ee8 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -1083,6 +1083,6 @@ out_word4: *yuv_format_p = yuv_format; return result; out_unknown: -// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); + /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ return ~0; } -- cgit v1.2.3 From aaa3c0d6de7fc2c8d209d3adba11eba1133c61d1 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 23 Apr 2011 14:14:29 +0200 Subject: winsys: Add wayland shm sw winsys --- configure.ac | 1 + src/gallium/winsys/sw/Makefile | 4 + src/gallium/winsys/sw/wayland/Makefile | 13 + src/gallium/winsys/sw/wayland/wayland_sw_winsys.c | 285 ++++++++++++++++++++++ src/gallium/winsys/sw/wayland/wayland_sw_winsys.h | 41 ++++ 5 files changed, 344 insertions(+) create mode 100644 src/gallium/winsys/sw/wayland/Makefile create mode 100644 src/gallium/winsys/sw/wayland/wayland_sw_winsys.c create mode 100644 src/gallium/winsys/sw/wayland/wayland_sw_winsys.h (limited to 'src/gallium') diff --git a/configure.ac b/configure.ac index 1012ca56f4c..3b05ca35380 100644 --- a/configure.ac +++ b/configure.ac @@ -1636,6 +1636,7 @@ yes) PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-server],, \ [AC_MSG_ERROR([cannot find libwayland-client])]) WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS" + GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/wayland" fi done EGL_PLATFORMS="$egl_platforms" diff --git a/src/gallium/winsys/sw/Makefile b/src/gallium/winsys/sw/Makefile index 094e811d57d..2fad717eb16 100644 --- a/src/gallium/winsys/sw/Makefile +++ b/src/gallium/winsys/sw/Makefile @@ -14,6 +14,10 @@ ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),) SUBDIRS += fbdev endif +ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) +SUBDIRS += wayland +endif + default install clean: @for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ diff --git a/src/gallium/winsys/sw/wayland/Makefile b/src/gallium/winsys/sw/wayland/Makefile new file mode 100644 index 00000000000..561fcabcfb5 --- /dev/null +++ b/src/gallium/winsys/sw/wayland/Makefile @@ -0,0 +1,13 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = ws_wayland + +LIBRARY_INCLUDES = $(WALAND_CFLAGS) + +LIBRARY_DEFINES = + +C_SOURCES = \ + wayland_sw_winsys.c + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c new file mode 100644 index 00000000000..1a31ada0296 --- /dev/null +++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c @@ -0,0 +1,285 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 +#include +#include +#include + +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "state_tracker/sw_winsys.h" + +#include +#include "wayland_sw_winsys.h" + +struct wayland_sw_displaytarget +{ + int fd; + unsigned size; + + unsigned width; + unsigned height; + unsigned stride; + + enum pipe_format format; + + void *map; + unsigned map_count; +}; + +struct wayland_sw_winsys +{ + struct sw_winsys base; + + struct wl_display *display; +}; + +static INLINE struct wayland_sw_displaytarget * +wayland_sw_displaytarget(struct sw_displaytarget *dt) +{ + return (struct wayland_sw_displaytarget *) dt; +} + +static INLINE struct wayland_sw_winsys * +wayland_sw_winsys(struct sw_winsys *ws) +{ + return (struct wayland_sw_winsys *) ws; +} + +static void +wayland_displaytarget_display(struct sw_winsys *ws, + struct sw_displaytarget *dt, + void *context_private) +{ +} + +static void +wayland_displaytarget_unmap(struct sw_winsys *ws, + struct sw_displaytarget *dt) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + + wldt->map_count--; + if (wldt->map_count > 0) + return; + + munmap(wldt->map, wldt->size); + wldt->map = NULL; +} + +static void * +wayland_displaytarget_map(struct sw_winsys *ws, + struct sw_displaytarget *dt, + unsigned flags) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + uint mmap_flags = 0; + + if (wldt->map) { + wldt->map_count++; + return wldt->map; + } + + if (flags & PIPE_TRANSFER_READ) + mmap_flags |= PROT_READ; + if (flags & PIPE_TRANSFER_WRITE) + mmap_flags |= PROT_WRITE; + + wldt->map = mmap(NULL, wldt->size, mmap_flags, + MAP_SHARED, wldt->fd, 0); + + if (wldt->map == MAP_FAILED) + return NULL; + + wldt->map_count = 1; + + return wldt->map; +} + +static void +wayland_displaytarget_destroy(struct sw_winsys *ws, + struct sw_displaytarget *dt) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + + if (wldt->map) + wayland_displaytarget_unmap(ws, dt); + + FREE(wldt); +} + +static boolean +wayland_is_displaytarget_format_supported(struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8A8_UNORM: + return TRUE; + default: + return FALSE; + } +} + +static struct sw_displaytarget * +wayland_displaytarget_create(struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) +{ + struct wayland_sw_displaytarget *wldt; + unsigned nblocksy, format_stride; + char filename[] = "/tmp/wayland-shm-XXXXXX"; + + if (!wayland_is_displaytarget_format_supported(ws, tex_usage, format)) + return NULL; + + wldt = CALLOC_STRUCT(wayland_sw_displaytarget); + if (!wldt) + return NULL; + + wldt->map = NULL; + + wldt->format = format; + wldt->width = width; + wldt->height = height; + + format_stride = util_format_get_stride(format, width); + wldt->stride = align(format_stride, alignment); + + nblocksy = util_format_get_nblocksy(format, height); + wldt->size = wldt->stride * nblocksy; + + wldt->fd = mkstemp(filename); + if (wldt->fd < 0) { + FREE(wldt); + return NULL; + } + + if (ftruncate(wldt->fd, wldt->size) < 0) { + unlink(filename); + close(wldt->fd); + FREE(wldt); + return NULL; + } + + unlink(filename); + + *stride = wldt->stride; + + return (struct sw_displaytarget *) wldt; +} + +static struct sw_displaytarget * +wayland_displaytarget_from_handle(struct sw_winsys *ws, + const struct pipe_resource *templet, + struct winsys_handle *whandle, + unsigned *stride) +{ + struct wayland_sw_displaytarget *wldt; + unsigned nblocksy; + + if (!wayland_is_displaytarget_format_supported(ws, 0, templet->format)) + return NULL; + + wldt = CALLOC_STRUCT(wayland_sw_displaytarget); + if (!wldt) + return NULL; + + wldt->fd = whandle->fd; + wldt->stride = whandle->stride; + wldt->width = templet->width0; + wldt->height = templet->height0; + wldt->format = templet->format; + + nblocksy = util_format_get_nblocksy(wldt->format, wldt->height); + + wldt->size = wldt->stride * nblocksy; + + wldt->map = NULL; + + *stride = wldt->stride; + + return (struct sw_displaytarget *) wldt; +} + + +static boolean +wayland_displaytarget_get_handle(struct sw_winsys *ws, + struct sw_displaytarget *dt, + struct winsys_handle *whandle) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + + whandle->fd = wldt->fd; + whandle->stride = wldt->stride; + + return TRUE; +} + +static void +wayland_destroy(struct sw_winsys *ws) +{ + struct wayland_sw_winsys *wayland = wayland_sw_winsys(ws); + + FREE(wayland); +} + +struct sw_winsys * +wayland_create_sw_winsys(struct wl_display *display) +{ + struct wayland_sw_winsys *wlws; + + wlws = CALLOC_STRUCT(wayland_sw_winsys); + if (!wlws) + return NULL; + + wlws->display = display; + + wlws->base.destroy = wayland_destroy; + wlws->base.is_displaytarget_format_supported = + wayland_is_displaytarget_format_supported; + + wlws->base.displaytarget_create = wayland_displaytarget_create; + wlws->base.displaytarget_from_handle = wayland_displaytarget_from_handle; + wlws->base.displaytarget_get_handle = wayland_displaytarget_get_handle; + wlws->base.displaytarget_destroy = wayland_displaytarget_destroy; + wlws->base.displaytarget_map = wayland_displaytarget_map; + wlws->base.displaytarget_unmap = wayland_displaytarget_unmap; + + wlws->base.displaytarget_display = wayland_displaytarget_display; + + return &wlws->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h new file mode 100644 index 00000000000..5e3cfd0bf23 --- /dev/null +++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h @@ -0,0 +1,41 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 WAYLAND_SW_WINSYS +#define WAYLAND_SW_WINSYS + +struct sw_winsys; + +struct winsys_handle { + int fd; + unsigned stride; +}; + +struct sw_winsys * +wayland_create_sw_winsys(struct wl_display *display); + +#endif /* WAYLAND_SW_WINSYS */ + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ -- cgit v1.2.3 From 34fd282b270dbaf0ce87e342b3183eb3a4bf4a44 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 23 Apr 2011 14:20:24 +0200 Subject: st/egl: Generalize wayland backend a bit --- .../state_trackers/egl/wayland/native_drm.c | 303 +++++++++++++++++++++ .../state_trackers/egl/wayland/native_wayland.c | 293 ++++---------------- .../state_trackers/egl/wayland/native_wayland.h | 18 +- 3 files changed, 361 insertions(+), 253 deletions(-) create mode 100644 src/gallium/state_trackers/egl/wayland/native_drm.c (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c new file mode 100644 index 00000000000..75c871d6030 --- /dev/null +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -0,0 +1,303 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 "util/u_memory.h" +#include "util/u_inlines.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/drm_driver.h" + +#include "egllog.h" +#include + +#include "native_wayland.h" + +/* see get_drm_screen_name */ +#include +#include "radeon/drm/radeon_drm_public.h" + +#include +#include "wayland-drm-client-protocol.h" +#include "wayland-egl-priv.h" + +#include +#include +#include +#include + +struct wayland_drm_display { + struct wayland_display base; + + struct native_event_handler *event_handler; + + struct wl_drm *wl_drm; + int fd; + char *device_name; + boolean authenticated; +}; + +static INLINE struct wayland_drm_display * +wayland_drm_display(const struct native_display *ndpy) +{ + return (struct wayland_drm_display *) ndpy; +} + +static void +sync_callback(void *data) +{ + int *done = data; + + *done = 1; +} + +static void +force_roundtrip(struct wl_display *display) +{ + int done = 0; + + wl_display_sync_callback(display, sync_callback, &done); + wl_display_iterate(display, WL_DISPLAY_WRITABLE); + while (!done) + wl_display_iterate(display, WL_DISPLAY_READABLE); +} + +static void +wayland_drm_display_destroy(struct native_display *ndpy) +{ + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + + if (drmdpy->fd) + close(drmdpy->fd); + if (drmdpy->wl_drm) + wl_drm_destroy(drmdpy->wl_drm); + if (drmdpy->device_name) + FREE(drmdpy->device_name); + if (drmdpy->base.config) + FREE(drmdpy->base.config); + + ndpy_uninit(ndpy); + + FREE(drmdpy); +} + +static struct wl_buffer * +wayland_create_drm_buffer(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment) +{ + struct wayland_drm_display *drmdpy = (struct wayland_drm_display *) display; + struct pipe_screen *screen = drmdpy->base.base.screen; + struct pipe_resource *resource; + struct winsys_handle wsh; + uint width, height; + struct wl_visual *visual; + + resource = resource_surface_get_single_resource(surface->rsurf, attachment); + resource_surface_get_size(surface->rsurf, &width, &height); + + wsh.type = DRM_API_HANDLE_TYPE_SHARED; + screen->resource_get_handle(screen, resource, &wsh); + + pipe_resource_reference(&resource, NULL); + + switch (surface->type) { + case WL_WINDOW_SURFACE: + visual = surface->win->visual; + break; + case WL_PIXMAP_SURFACE: + visual = surface->pix->visual; + break; + default: + return NULL; + } + + return wl_drm_create_buffer(drmdpy->wl_drm, wsh.handle, + width, height, wsh.stride, visual); +} + +static const char * +get_drm_screen_name(int fd, drmVersionPtr version) +{ + const char *name = version->name; + + if (name && !strcmp(name, "radeon")) { + int chip_id; + struct drm_radeon_info info; + + memset(&info, 0, sizeof(info)); + info.request = RADEON_INFO_DEVICE_ID; + info.value = pointer_to_intptr(&chip_id); + if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) + return NULL; + + name = is_r3xx(chip_id) ? "r300" : "r600"; + } + + return name; +} + +static void +drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + struct wayland_drm_display *drmdpy = data; + drm_magic_t magic; + + drmdpy->device_name = strdup(device); + if (!drmdpy->device_name) + return; + + drmdpy->fd = open(drmdpy->device_name, O_RDWR); + if (drmdpy->fd == -1) { + _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", + drmdpy->device_name, strerror(errno)); + return; + } + + drmGetMagic(drmdpy->fd, &magic); + wl_drm_authenticate(drmdpy->wl_drm, magic); +} + +static void +drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + struct wayland_drm_display *drmdpy = data; + + drmdpy->authenticated = true; +} + +static const struct wl_drm_listener drm_listener = { + drm_handle_device, + drm_handle_authenticated +}; + +static boolean +wayland_drm_display_init_screen(struct native_display *ndpy) +{ + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + drmVersionPtr version; + const char *driver_name; + uint32_t id; + + id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1); + if (id == 0) + wl_display_iterate(drmdpy->base.dpy, WL_DISPLAY_READABLE); + id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1); + if (id == 0) + return FALSE; + + drmdpy->wl_drm = wl_drm_create(drmdpy->base.dpy, id, 1); + if (!drmdpy->wl_drm) + return FALSE; + + wl_drm_add_listener(drmdpy->wl_drm, &drm_listener, drmdpy); + force_roundtrip(drmdpy->base.dpy); + if (drmdpy->fd == -1) + return FALSE; + + force_roundtrip(drmdpy->base.dpy); + if (!drmdpy->authenticated) + return FALSE; + + version = drmGetVersion(drmdpy->fd); + if (!version) { + _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd); + return FALSE; + } + + /* FIXME: share this with native_drm or egl_dri2 */ + driver_name = get_drm_screen_name(drmdpy->fd, version); + + drmdpy->base.base.screen = + drmdpy->event_handler->new_drm_screen(&drmdpy->base.base, + driver_name, drmdpy->fd); + drmFreeVersion(version); + + if (!drmdpy->base.base.screen) { + _eglLog(_EGL_WARNING, "failed to create DRM screen"); + return FALSE; + } + + return TRUE; +} + +static struct pipe_resource * +wayland_drm_display_import_buffer(struct native_display *ndpy, + const struct pipe_resource *templ, + void *buf) +{ + return ndpy->screen->resource_from_handle(ndpy->screen, + templ, (struct winsys_handle *) buf); +} + +static boolean +wayland_drm_display_export_buffer(struct native_display *ndpy, + struct pipe_resource *res, + void *buf) +{ + return ndpy->screen->resource_get_handle(ndpy->screen, + res, (struct winsys_handle *) buf); +} + +static struct native_display_buffer wayland_drm_display_buffer = { + wayland_drm_display_import_buffer, + wayland_drm_display_export_buffer +}; + +struct wayland_display * +wayland_create_drm_display(struct wl_display *dpy, + struct native_event_handler *event_handler, + void *user_data) +{ + struct wayland_drm_display *drmdpy; + + drmdpy = CALLOC_STRUCT(wayland_drm_display); + if (!drmdpy) + return NULL; + + drmdpy->event_handler = event_handler; + drmdpy->base.base.user_data = user_data; + + drmdpy->base.dpy = dpy; + if (!drmdpy->base.dpy) { + wayland_drm_display_destroy(&drmdpy->base.base); + return NULL; + } + + if (!wayland_drm_display_init_screen(&drmdpy->base.base)) { + wayland_drm_display_destroy(&drmdpy->base.base); + return NULL; + } + drmdpy->base.base.destroy = wayland_drm_display_destroy; + drmdpy->base.base.buffer = &wayland_drm_display_buffer; + + drmdpy->base.create_buffer = wayland_create_drm_buffer; + + return &drmdpy->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c index b9cf8c48f1e..a684025d6b3 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c @@ -31,25 +31,10 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "state_tracker/drm_driver.h" - #include "egllog.h" -#include #include "native_wayland.h" -/* see get_drm_screen_name */ -#include -#include "radeon/drm/radeon_drm_public.h" - -#include -#include "wayland-drm-client-protocol.h" -#include "wayland-egl-priv.h" - -#include -#include -#include -#include - static struct native_event_handler *wayland_event_handler; static void @@ -113,12 +98,12 @@ wayland_display_get_param(struct native_display *ndpy, int val; switch (param) { - case NATIVE_PARAM_USE_NATIVE_BUFFER: - case NATIVE_PARAM_PRESERVE_BUFFER: - case NATIVE_PARAM_MAX_SWAP_INTERVAL: - default: - val = 0; - break; + case NATIVE_PARAM_USE_NATIVE_BUFFER: + case NATIVE_PARAM_PRESERVE_BUFFER: + case NATIVE_PARAM_MAX_SWAP_INTERVAL: + default: + val = 0; + break; } return val; @@ -134,48 +119,6 @@ wayland_display_is_pixmap_supported(struct native_display *ndpy, return TRUE; } -static void -wayland_display_destroy(struct native_display *ndpy) -{ - struct wayland_display *display = wayland_display(ndpy); - - if (display->fd) - close(display->fd); - if (display->wl_drm) - wl_drm_destroy(display->wl_drm); - if (display->device_name) - FREE(display->device_name); - if (display->config) - FREE(display->config); - - ndpy_uninit(ndpy); - - FREE(display); -} - - -static struct wl_buffer * -wayland_create_buffer(struct wayland_surface *surface, - enum native_attachment attachment) -{ - struct wayland_display *display = surface->display; - struct pipe_resource *resource; - struct winsys_handle wsh; - uint width, height; - - resource = resource_surface_get_single_resource(surface->rsurf, attachment); - resource_surface_get_size(surface->rsurf, &width, &height); - - wsh.type = DRM_API_HANDLE_TYPE_SHARED; - display->base.screen->resource_get_handle(display->base.screen, resource, &wsh); - - pipe_resource_reference(&resource, NULL); - - return wl_drm_create_buffer(display->wl_drm, wsh.handle, - width, height, - wsh.stride, surface->win->visual); -} - static void wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) { @@ -188,7 +131,7 @@ wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) wl_buffer_destroy(egl_pixmap->buffer); egl_pixmap->buffer = NULL; } - + egl_pixmap->driver_private = NULL; egl_pixmap->destroy = NULL; } @@ -196,26 +139,16 @@ wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) static void wayland_pixmap_surface_initialize(struct wayland_surface *surface) { - struct native_display *ndpy = &surface->display->base; - struct pipe_resource *resource; - struct winsys_handle wsh; + struct wayland_display *display = wayland_display(&surface->display->base); const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; if (surface->pix->buffer != NULL) return; - resource = resource_surface_get_single_resource(surface->rsurf, front_natt); - - wsh.type = DRM_API_HANDLE_TYPE_SHARED; - ndpy->screen->resource_get_handle(ndpy->screen, resource, &wsh); - - surface->pix->buffer = - wl_drm_create_buffer(surface->display->wl_drm, wsh.handle, - surface->pix->width, surface->pix->height, - wsh.stride, surface->pix->visual); - - surface->pix->destroy = wayland_pixmap_destroy; - surface->pix->driver_private = resource; + surface->pix->buffer = display->create_buffer(display, surface, front_natt); + surface->pix->destroy = wayland_pixmap_destroy; + surface->pix->driver_private = + resource_surface_get_single_resource(surface->rsurf, front_natt); } static void @@ -237,11 +170,11 @@ wayland_window_surface_handle_resize(struct wayland_surface *surface) struct pipe_resource *front_resource; const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; int i; - + front_resource = resource_surface_get_single_resource(surface->rsurf, front_natt); if (resource_surface_set_size(surface->rsurf, - surface->win->width, surface->win->height)) { + surface->win->width, surface->win->height)) { if (surface->pending_resource) force_roundtrip(display->dpy); @@ -328,17 +261,19 @@ wayland_surface_swap_buffers(struct native_surface *nsurf) if (surface->type == WL_WINDOW_SURFACE) { resource_surface_swap_buffers(surface->rsurf, - NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE); + NATIVE_ATTACHMENT_FRONT_LEFT, + NATIVE_ATTACHMENT_BACK_LEFT, FALSE); wayland_buffers_swap(surface->buffer, WL_BUFFER_FRONT, WL_BUFFER_BACK); if (surface->buffer[WL_BUFFER_FRONT] == NULL) surface->buffer[WL_BUFFER_FRONT] = - wayland_create_buffer(surface, NATIVE_ATTACHMENT_FRONT_LEFT); + display->create_buffer(display, surface, + NATIVE_ATTACHMENT_FRONT_LEFT); wl_surface_attach(surface->win->surface, surface->buffer[WL_BUFFER_FRONT], surface->dx, surface->dy); - + resource_surface_get_size(surface->rsurf, (uint *) &surface->win->attached_width, (uint *) &surface->win->attached_height); @@ -348,7 +283,8 @@ wayland_surface_swap_buffers(struct native_surface *nsurf) surface->sequence_number++; wayland_event_handler->invalid_surface(&display->base, - &surface->base, surface->sequence_number); + &surface->base, + surface->sequence_number); return TRUE; } @@ -408,6 +344,8 @@ wayland_surface_destroy(struct native_surface *nsurf) FREE(surface); } + + static struct native_surface * wayland_create_pixmap_surface(struct native_display *ndpy, EGLNativePixmapType pix, @@ -417,6 +355,8 @@ wayland_create_pixmap_surface(struct native_display *ndpy, struct wayland_surface *surface; struct wl_egl_pixmap *egl_pixmap = (struct wl_egl_pixmap *) pix; enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT; + uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT; surface = CALLOC_STRUCT(wayland_surface); if (!surface) @@ -434,15 +374,13 @@ wayland_create_pixmap_surface(struct native_display *ndpy, surface->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT); - + surface->rsurf = resource_surface_create(display->base.screen, - surface->color_format, - PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT); + surface->color_format, bind); if (!surface->rsurf) { - FREE(surface); - return NULL; + FREE(surface); + return NULL; } resource_surface_set_size(surface->rsurf, @@ -461,6 +399,7 @@ wayland_create_pixmap_surface(struct native_display *ndpy, return &surface->base; } + static struct native_surface * wayland_create_window_surface(struct native_display *ndpy, EGLNativeWindowType win, @@ -469,6 +408,8 @@ wayland_create_window_surface(struct native_display *ndpy, struct wayland_display *display = wayland_display(ndpy); struct wayland_config *config = wayland_config(nconf); struct wayland_surface *surface; + uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT; surface = CALLOC_STRUCT(wayland_surface); if (!surface) @@ -486,16 +427,14 @@ wayland_create_window_surface(struct native_display *ndpy, surface->buffer[WL_BUFFER_FRONT] = NULL; surface->buffer[WL_BUFFER_BACK] = NULL; surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT) | - (1 << NATIVE_ATTACHMENT_BACK_LEFT); + (1 << NATIVE_ATTACHMENT_BACK_LEFT); surface->rsurf = resource_surface_create(display->base.screen, - surface->color_format, - PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT); + surface->color_format, bind); if (!surface->rsurf) { - FREE(surface); - return NULL; + FREE(surface); + return NULL; } surface->base.destroy = wayland_surface_destroy; @@ -506,178 +445,36 @@ wayland_create_window_surface(struct native_display *ndpy, return &surface->base; } -static const char * -get_drm_screen_name(int fd, drmVersionPtr version) -{ - const char *name = version->name; - - if (name && !strcmp(name, "radeon")) { - int chip_id; - struct drm_radeon_info info; - - memset(&info, 0, sizeof(info)); - info.request = RADEON_INFO_DEVICE_ID; - info.value = pointer_to_intptr(&chip_id); - if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) - return NULL; - - name = is_r3xx(chip_id) ? "r300" : "r600"; - } - - return name; -} - static void -drm_handle_device(void *data, struct wl_drm *drm, const char *device) -{ - struct wayland_display *display = data; - drm_magic_t magic; - - display->device_name = strdup(device); - if (!display->device_name) - return; - - display->fd = open(display->device_name, O_RDWR); - if (display->fd == -1) { - _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", - display->device_name, strerror(errno)); - return; - } - - drmGetMagic(display->fd, &magic); - wl_drm_authenticate(display->wl_drm, magic); -} - -static void -drm_handle_authenticated(void *data, struct wl_drm *drm) -{ - struct wayland_display *display = data; - - display->authenticated = true; -} - -static const struct wl_drm_listener drm_listener = { - drm_handle_device, - drm_handle_authenticated -}; - -static boolean -wayland_display_init_screen(struct native_display *ndpy) -{ - struct wayland_display *display = wayland_display(ndpy); - drmVersionPtr version; - const char *driver_name; - uint32_t id; - - id = wl_display_get_global(display->dpy, "wl_drm", 1); - if (id == 0) - wl_display_iterate(display->dpy, WL_DISPLAY_READABLE); - id = wl_display_get_global(display->dpy, "wl_drm", 1); - if (id == 0) - return FALSE; - - display->wl_drm = wl_drm_create(display->dpy, id, 1); - if (!display->wl_drm) - return FALSE; - - wl_drm_add_listener(display->wl_drm, &drm_listener, display); - force_roundtrip(display->dpy); - if (display->fd == -1) - return FALSE; - - force_roundtrip(display->dpy); - if (!display->authenticated) - return FALSE; - - version = drmGetVersion(display->fd); - if (!version) { - _eglLog(_EGL_WARNING, "invalid fd %d", display->fd); - return FALSE; - } - - /* FIXME: share this with native_drm or egl_dri2 */ - driver_name = get_drm_screen_name(display->fd, version); - - display->base.screen = - wayland_event_handler->new_drm_screen(&display->base, - driver_name, display->fd); - drmFreeVersion(version); - - if (!display->base.screen) { - _eglLog(_EGL_WARNING, "failed to create DRM screen"); - return FALSE; - } - - return TRUE; -} - - -static void -wayland_set_event_handler(struct native_event_handler *event_handler) +native_set_event_handler(struct native_event_handler *event_handler) { wayland_event_handler = event_handler; } -static struct pipe_resource * -wayland_display_import_buffer(struct native_display *ndpy, - const struct pipe_resource *templ, - void *buf) -{ - return ndpy->screen->resource_from_handle(ndpy->screen, - templ, (struct winsys_handle *) buf); -} - -static boolean -wayland_display_export_buffer(struct native_display *ndpy, - struct pipe_resource *res, - void *buf) -{ - return ndpy->screen->resource_get_handle(ndpy->screen, - res, (struct winsys_handle *) buf); -} - -static struct native_display_buffer wayland_display_buffer = { - wayland_display_import_buffer, - wayland_display_export_buffer -}; - static struct native_display * -wayland_display_create(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw, void *user_data) { - struct wayland_display *display; + struct wayland_display *display = NULL; - display = CALLOC_STRUCT(wayland_display); + display = wayland_create_drm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); if (!display) return NULL; - display->base.user_data = user_data; - - display->dpy = dpy; - if (!display->dpy) { - wayland_display_destroy(&display->base); - return NULL; - } - - if (!wayland_display_init_screen(&display->base)) { - wayland_display_destroy(&display->base); - return NULL; - } - - display->base.destroy = wayland_display_destroy; display->base.get_param = wayland_display_get_param; display->base.get_configs = wayland_display_get_configs; display->base.is_pixmap_supported = wayland_display_is_pixmap_supported; display->base.create_window_surface = wayland_create_window_surface; display->base.create_pixmap_surface = wayland_create_pixmap_surface; - display->base.buffer = &wayland_display_buffer; return &display->base; } static const struct native_platform wayland_platform = { "wayland", /* name */ - wayland_set_event_handler, - wayland_display_create + native_set_event_handler, + native_create_display }; const struct native_platform * @@ -685,3 +482,5 @@ native_get_wayland_platform(void) { return &wayland_platform; } + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h index 14fc9b0fbb2..5c034421f3d 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.h +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h @@ -33,17 +33,18 @@ #include "common/native_helper.h" #include "wayland-egl-priv.h" -#include "wayland-drm-client-protocol.h" + +struct wayland_surface; struct wayland_display { struct native_display base; struct wayland_config *config; struct wl_display *dpy; - struct wl_drm *wl_drm; - int fd; - char *device_name; - boolean authenticated; + + struct wl_buffer *(*create_buffer)(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment); }; enum wayland_buffer_type { @@ -78,7 +79,7 @@ struct wayland_surface { }; struct wayland_config { - struct native_config base; + struct native_config base; }; static INLINE struct wayland_display * @@ -99,4 +100,9 @@ wayland_config(const struct native_config *nconf) return (struct wayland_config *) nconf; } +struct wayland_display * +wayland_create_drm_display(struct wl_display *display, + struct native_event_handler *event_handler, + void *user_data); + #endif /* _NATIVE_WAYLAND_H_ */ -- cgit v1.2.3 From d72e7f0dd95fdf28cf64c0b5b6d42c16f087008a Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 23 Apr 2011 14:21:05 +0200 Subject: st/egl: Add wayland shm softpipe support --- .../state_trackers/egl/wayland/native_shm.c | 174 +++++++++++++++++++++ .../state_trackers/egl/wayland/native_wayland.c | 16 +- .../state_trackers/egl/wayland/native_wayland.h | 4 + src/gallium/targets/egl/Makefile | 1 + 4 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 src/gallium/state_trackers/egl/wayland/native_shm.c (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c new file mode 100644 index 00000000000..609fc0cd04a --- /dev/null +++ b/src/gallium/state_trackers/egl/wayland/native_shm.c @@ -0,0 +1,174 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 "util/u_memory.h" +#include "util/u_inlines.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +#include "sw/wayland/wayland_sw_winsys.h" + +#include "egllog.h" + +#include "native_wayland.h" + +#include +#include "wayland-egl-priv.h" + +#include +#include +#include + +struct wayland_shm_display { + struct wayland_display base; + + struct native_event_handler *event_handler; + struct wl_shm *wl_shm; +}; + +static INLINE struct wayland_shm_display * +wayland_shm_display(const struct native_display *ndpy) +{ + return (struct wayland_shm_display *) ndpy; +} + + +static void +wayland_shm_display_destroy(struct native_display *ndpy) +{ + struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy); + + if (shmdpy->base.config) + FREE(shmdpy->base.config); + + ndpy_uninit(ndpy); + + FREE(shmdpy); +} + + +static struct wl_buffer * +wayland_create_shm_buffer(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment) +{ + struct wayland_shm_display *shmdpy = (struct wayland_shm_display *) display; + struct pipe_screen *screen = shmdpy->base.base.screen; + struct pipe_resource *resource; + struct winsys_handle wsh; + uint width, height; + struct wl_visual *visual; + + resource = resource_surface_get_single_resource(surface->rsurf, attachment); + resource_surface_get_size(surface->rsurf, &width, &height); + + screen->resource_get_handle(screen, resource, &wsh); + + pipe_resource_reference(&resource, NULL); + + switch (surface->type) { + case WL_WINDOW_SURFACE: + visual = surface->win->visual; + break; + case WL_PIXMAP_SURFACE: + visual = surface->pix->visual; + break; + default: + return NULL; + } + + return wl_shm_create_buffer(shmdpy->wl_shm, wsh.fd, + width, height, + wsh.stride, visual); +} + +static boolean +wayland_shm_display_init_screen(struct native_display *ndpy) +{ + struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy); + struct sw_winsys *winsys = NULL; + uint32_t id; + + id = wl_display_get_global(shmdpy->base.dpy, "wl_shm", 1); + if (id == 0) + wl_display_iterate(shmdpy->base.dpy, WL_DISPLAY_READABLE); + id = wl_display_get_global(shmdpy->base.dpy, "wl_shm", 1); + if (id == 0) + return FALSE; + + shmdpy->wl_shm = wl_shm_create(shmdpy->base.dpy, id, 1); + if (!shmdpy->wl_shm) + return FALSE; + + winsys = wayland_create_sw_winsys(shmdpy->base.dpy); + if (!winsys) + return FALSE; + + shmdpy->base.base.screen = + shmdpy->event_handler->new_sw_screen(&shmdpy->base.base, winsys); + + if (!shmdpy->base.base.screen) { + _eglLog(_EGL_WARNING, "failed to create shm screen"); + return FALSE; + } + + return TRUE; +} + +struct wayland_display * +wayland_create_shm_display(struct wl_display *dpy, + struct native_event_handler *event_handler, + void *user_data) +{ + struct wayland_shm_display *shmdpy; + + shmdpy = CALLOC_STRUCT(wayland_shm_display); + if (!shmdpy) + return NULL; + + shmdpy->event_handler = event_handler; + shmdpy->base.base.user_data = user_data; + + shmdpy->base.dpy = dpy; + if (!shmdpy->base.dpy) { + wayland_shm_display_destroy(&shmdpy->base.base); + return NULL; + } + + if (!wayland_shm_display_init_screen(&shmdpy->base.base)) { + wayland_shm_display_destroy(&shmdpy->base.base); + return NULL; + } + + shmdpy->base.base.destroy = wayland_shm_display_destroy; + shmdpy->base.create_buffer = wayland_create_shm_buffer; + + return &shmdpy->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c index a684025d6b3..e7ed9d64b7e 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c @@ -456,9 +456,19 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) { struct wayland_display *display = NULL; - display = wayland_create_drm_display((struct wl_display *) dpy, - wayland_event_handler, - user_data); + use_sw = use_sw || debug_get_bool_option("EGL_SOFTWARE", FALSE); + + if (use_sw) { + _eglLog(_EGL_INFO, "use software fallback"); + display = wayland_create_shm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); + } else { + display = wayland_create_drm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); + } + if (!display) return NULL; diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h index 5c034421f3d..e69a8f00f82 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.h +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h @@ -100,6 +100,10 @@ wayland_config(const struct native_config *nconf) return (struct wayland_config *) nconf; } +struct wayland_display * +wayland_create_shm_display(struct wl_display *display, + struct native_event_handler *event_handler, + void *user_data); struct wayland_display * wayland_create_drm_display(struct wl_display *display, struct native_event_handler *event_handler, diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index de01939e5f1..9d76a706122 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -48,6 +48,7 @@ egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a endif ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) egl_SYS += $(WAYLAND_LIBS) $(LIBDRM_LIB) +egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a endif ifneq ($(findstring drm, $(EGL_PLATFORMS)),) egl_SYS += $(LIBDRM_LIB) -- cgit v1.2.3 From 6a35ed1f66f0839fb0a6fdb6c07167257a0a2e72 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Mon, 25 Apr 2011 18:16:35 +0200 Subject: winsys/wayland: Fix typo in Makefile Reported by dir1212 on irc. --- src/gallium/winsys/sw/wayland/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/sw/wayland/Makefile b/src/gallium/winsys/sw/wayland/Makefile index 561fcabcfb5..b3f2081686e 100644 --- a/src/gallium/winsys/sw/wayland/Makefile +++ b/src/gallium/winsys/sw/wayland/Makefile @@ -3,7 +3,7 @@ include $(TOP)/configs/current LIBNAME = ws_wayland -LIBRARY_INCLUDES = $(WALAND_CFLAGS) +LIBRARY_INCLUDES = $(WAYLAND_CFLAGS) LIBRARY_DEFINES = -- cgit v1.2.3 From 39cd791f3428ab48723fd4c73c4b1223e883ab2d Mon Sep 17 00:00:00 2001 From: nobled Date: Sun, 18 Jul 2010 16:08:19 +0000 Subject: os: simplify ifdef The actual code that needs this include is just using "if defined (PIPE_OS_UNIX)", and the two conditions should match. This should also make the file compile under Hurd. --- src/gallium/auxiliary/os/os_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c index 84907215fe6..325f316784c 100644 --- a/src/gallium/auxiliary/os/os_time.c +++ b/src/gallium/auxiliary/os/os_time.c @@ -37,7 +37,7 @@ #if !defined(PIPE_OS_EMBEDDED) -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_UNIX) # include /* timeval */ #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) # include -- cgit v1.2.3 From 1e5dc6a7788f4c548fbed38813090978fdacd984 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 13:02:32 +0200 Subject: svga: fix warning: ‘uc.ui’ may be used uninitialized in this function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is safe because it's initialized if buffers & PIPE_CLEAR_COLOR and probably doesn't have any effect otherwise. --- src/gallium/drivers/svga/svga_pipe_clear.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index b288c3eb2a6..2bba77769ad 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; - union util_color uc; + union util_color uc = {0}; ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); if (ret) -- cgit v1.2.3 From 31200d0688b67a0d764ad7fe4c2761d0f8d993d8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 13:05:53 +0200 Subject: gallivm: fix warning: ‘value’ may be used uninitialized in this function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The path where it's uninitialized is guarded by an assert. --- src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index d1585c8e2b7..d8adb9fbfaf 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -2565,7 +2565,7 @@ lp_build_system_values_array(struct gallivm_state *gallivm, for (i = 0; i < info->num_system_values; i++) { LLVMValueRef index = lp_build_const_int32(gallivm, i * 4); - LLVMValueRef ptr, value; + LLVMValueRef ptr, value = 0; switch (info->system_value_semantic_name[i]) { case TGSI_SEMANTIC_INSTANCEID: -- cgit v1.2.3 From 7e5953fca219ae472f3a933fc93c9e6bb61f7a49 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 13:08:25 +0200 Subject: gallium/nouveau: fix printf warnings --- src/gallium/drivers/nouveau/nouveau_mm.c | 2 +- src/gallium/drivers/nv50/nv50_screen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 7edeb4d21d6..6c6d28c17f6 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -143,7 +143,7 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order) cache->allocated += size; - debug_printf("MM: new slab, total memory = %lu KiB\n", + debug_printf("MM: new slab, total memory = %llu KiB\n", cache->allocated / 1024); return PIPE_OK; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 641ad7e2780..a2f13e3d703 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -469,7 +469,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tls_size = tls_space * max_warps * 32; - debug_printf("max_warps = %i, tls_size = %lu KiB\n", + debug_printf("max_warps = %i, tls_size = %llu KiB\n", max_warps, screen->tls_size >> 10); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, -- cgit v1.2.3 From b8de75d53760fb359d10d6f4794f28097210cef4 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 12:54:24 +0200 Subject: util: make macros MIN3, MAX3, MIN4, MAX4 little more efficient --- src/gallium/auxiliary/util/u_math.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index e3d4c06b6f9..dad6a101fd7 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -581,11 +581,11 @@ util_bswap16(uint16_t n) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) -#define MIN3( A, B, C ) MIN2( MIN2( A, B ), C ) -#define MAX3( A, B, C ) MAX2( MAX2( A, B ), C ) +#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) +#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) -#define MIN4( A, B, C, D ) MIN2( MIN2( A, B ), MIN2(C, D) ) -#define MAX4( A, B, C, D ) MAX2( MAX2( A, B ), MAX2(C, D) ) +#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D)) +#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D)) /** -- cgit v1.2.3 From 0be6ae74e9a56e84df088392ef3b09229508404f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 25 Apr 2011 10:26:19 -0600 Subject: svga: emit user-defined clip plane state User-defined clip planes were a swtnl fallback before. --- src/gallium/drivers/svga/svga_state_framebuffer.c | 23 ++++++++++++++++++++--- src/gallium/drivers/svga/svga_state_need_swtnl.c | 8 -------- src/gallium/drivers/svga/svga_state_rss.c | 6 ++++++ 3 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index cc4819431ad..502f21fc42c 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -474,9 +474,26 @@ static int emit_clip_planes( struct svga_context *svga, /* TODO: just emit directly from svga_set_clip_state()? */ for (i = 0; i < svga->curr.clip.nr; i++) { - ret = SVGA3D_SetClipPlane( svga->swc, - i, - svga->curr.clip.ucp[i] ); + /* need to express the plane in D3D-style coordinate space. + * GL coords get converted to D3D coords with the matrix: + * [ 1 0 0 0 ] + * [ 0 -1 0 0 ] + * [ 0 0 2 0 ] + * [ 0 0 -1 1 ] + * Apply that matrix to our plane equation, and invert Y. + */ + float a = svga->curr.clip.ucp[i][0]; + float b = svga->curr.clip.ucp[i][1]; + float c = svga->curr.clip.ucp[i][2]; + float d = svga->curr.clip.ucp[i][3]; + float plane[4]; + + plane[0] = a; + plane[1] = b; + plane[2] = 2.0f * c; + plane[3] = d - c; + + ret = SVGA3D_SetClipPlane(svga->swc, i, plane); if(ret != PIPE_OK) return ret; } diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c index 68c02578789..5a37f9fc287 100644 --- a/src/gallium/drivers/svga/svga_state_need_swtnl.c +++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c @@ -139,13 +139,6 @@ static int update_need_pipeline( struct svga_context *svga, need_pipeline = TRUE; } - /* SVGA_NEW_CLIP - */ - if (svga->curr.clip.nr) { - SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__); - need_pipeline = TRUE; - } - if (need_pipeline != svga->state.sw.need_pipeline) { svga->state.sw.need_pipeline = need_pipeline; svga->dirty |= SVGA_NEW_NEED_PIPELINE; @@ -163,7 +156,6 @@ struct svga_tracked_state svga_update_need_pipeline = { "need pipeline", (SVGA_NEW_RAST | - SVGA_NEW_CLIP | SVGA_NEW_VS | SVGA_NEW_REDUCED_PRIMITIVE), update_need_pipeline diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index ab13f3fdf19..28f32793742 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -240,6 +240,11 @@ static int emit_rss( struct svga_context *svga, EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail ); } + if (dirty & SVGA_NEW_CLIP) { + /* the number of clip planes is how many planes to enable */ + unsigned enabled = (1 << svga->curr.clip.nr) - 1; + EMIT_RS( svga, enabled, CLIPPLANEENABLE, fail ); + } if (queue.rs_count) { SVGA3dRenderState *rs; @@ -276,6 +281,7 @@ struct svga_tracked_state svga_hw_rss = (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR | + SVGA_NEW_CLIP | SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_STENCIL_REF | SVGA_NEW_RAST | -- cgit v1.2.3 From 284191560b191ebb2219e0f5fe2de4128ad172a5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 28 Apr 2011 07:38:53 -0600 Subject: llvmpipe: move active_query assignment in lp_setup_begin_query() If we run out of bin memory and do an early return from lp_setup_begin_query() we'd omit setting the setup->active_query pointer. Then, when lp_setup_end_query() was later called, the assertion for setup->active_query == pq would fail. Moving the assigment in lp_setup_begin_query() avoids that. Reviewed-by: Jose Fonseca --- src/gallium/drivers/llvmpipe/lp_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index c82ab821c7e..5700918856b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -1063,6 +1063,8 @@ lp_setup_begin_query(struct lp_setup_context *setup, /* init the query to its beginning state */ assert(setup->active_query == NULL); + setup->active_query = pq; + set_scene_state(setup, SETUP_ACTIVE, "begin_query"); if (setup->scene) { @@ -1080,8 +1082,6 @@ lp_setup_begin_query(struct lp_setup_context *setup, } } } - - setup->active_query = pq; } -- cgit v1.2.3 From 8cce283038bf51a03de6734523c3e9ea8c8a6f33 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 28 Apr 2011 12:41:45 -0600 Subject: llvmpipe: move active_query assignment Fixes piglit regression. --- src/gallium/drivers/llvmpipe/lp_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 5700918856b..cbe06e58a78 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -1063,10 +1063,10 @@ lp_setup_begin_query(struct lp_setup_context *setup, /* init the query to its beginning state */ assert(setup->active_query == NULL); - setup->active_query = pq; - set_scene_state(setup, SETUP_ACTIVE, "begin_query"); + setup->active_query = pq; + if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, -- cgit v1.2.3 From 608a4a17feea9fba2812d4e5c01dd6dbadc5d6e0 Mon Sep 17 00:00:00 2001 From: Christopher Egert Date: Fri, 29 Apr 2011 02:13:35 +0200 Subject: i915g: Enable S3TC texture support Reviewed-by: Jakob Bornecrantz Reviewed-by: Daniel Vetter Signed-off-by: Christopher Egert Signed-off-by: Jakob Bornecrantz --- src/gallium/drivers/i915/i915_screen.c | 7 +++++++ src/gallium/drivers/i915/i915_state_sampler.c | 10 ++++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 0f4327fdc81..0e427749636 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -28,6 +28,7 @@ #include "draw/draw_context.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -267,6 +268,10 @@ i915_is_format_supported(struct pipe_screen *screen, PIPE_FORMAT_YUYV, /* XXX why not? PIPE_FORMAT_Z16_UNORM, */ + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_NONE /* list terminator */ @@ -432,5 +437,7 @@ i915_screen_create(struct i915_winsys *iws) i915_debug_init(is); + util_format_s3tc_init(); + return &is->base; } diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 916cb767536..be70e7a92c9 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -223,15 +223,13 @@ static uint translate_texture_format(enum pipe_format pipeFormat) #endif case PIPE_FORMAT_Z16_UNORM: return (MAPSURF_16BIT | MT_16BIT_L16); -#if 0 - case PIPE_FORMAT_RGBA_DXT1: - case PIPE_FORMAT_RGB_DXT1: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT1_RGB: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - case PIPE_FORMAT_RGBA_DXT3: + case PIPE_FORMAT_DXT3_RGBA: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - case PIPE_FORMAT_RGBA_DXT5: + case PIPE_FORMAT_DXT5_RGBA: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); -#endif case PIPE_FORMAT_Z24_UNORM_S8_USCALED: case PIPE_FORMAT_Z24X8_UNORM: return (MAPSURF_32BIT | MT_32BIT_xI824); -- cgit v1.2.3 From 349184be36e59f49309b8c1f371d99efceaf6d5f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 26 Apr 2011 02:29:00 +0200 Subject: util: implement R9G9B9E5 pack and unpack functions softpipe and llvmpipe support done (sampler only). Reviewed-by: Brian Paul --- src/gallium/auxiliary/util/u_format_other.c | 87 +++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index fa42ec37138..a44cc01673b 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -28,6 +28,7 @@ #include "u_math.h" #include "u_format_other.h" +#include "../../../mesa/main/rgb9e5.h" void @@ -35,7 +36,23 @@ util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + for(y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, dst); + dst[3] = 1; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } } void @@ -43,14 +60,34 @@ util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride const float *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + for(y = 0; y < height; y += 1) { + const float *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value = float3_to_rgb9e5(src); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } } void util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) { - + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, dst); + dst[3] = 1; /* a */ } @@ -59,7 +96,27 @@ util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_str const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, p); + dst[0] = float_to_ubyte(p[0]); /* r */ + dst[1] = float_to_ubyte(p[1]); /* g */ + dst[2] = float_to_ubyte(p[2]); /* b */ + dst[3] = 255; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } } @@ -68,7 +125,27 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value; + p[0] = ubyte_to_float(src[0]); + p[1] = ubyte_to_float(src[1]); + p[2] = ubyte_to_float(src[2]); + value = float3_to_rgb9e5(p); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } } -- cgit v1.2.3 From de9f55437ab7110dd79ebebaac543d35493380ce Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 26 Apr 2011 02:24:47 +0200 Subject: r600g: trivially implement EXT_texture_shared_exponent Nothing else needed. --- src/gallium/drivers/r600/r600_texture.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index eb696b73ee8..b22eb7bbdeb 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -930,6 +930,11 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, } } + if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { + result = FMT_5_9_9_9_SHAREDEXP; + goto out_word4; + } + for (i = 0; i < desc->nr_channels; i++) { if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { -- cgit v1.2.3 From 1271424615b62544662a606bb23f6d7117a8b0e7 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 12:52:10 +0200 Subject: mesa, util: move RGB9E5 conversion functions to gallium/util Also use MAX3 and incorporate Ian's suggestion in texformat.c. I don't think wrapping u_format_rgb9e5.h in another header and thus making it more complicated is worth it. --- src/gallium/auxiliary/util/u_format_other.c | 2 +- src/gallium/auxiliary/util/u_format_rgb9e5.h | 164 +++++++++++++++++++++++++ src/mesa/main/mipmap.c | 2 +- src/mesa/main/pack.c | 2 +- src/mesa/main/rgb9e5.h | 173 --------------------------- src/mesa/main/texfetch.c | 2 +- src/mesa/main/texformat.c | 4 +- src/mesa/main/texstore.c | 2 +- 8 files changed, 171 insertions(+), 180 deletions(-) create mode 100644 src/gallium/auxiliary/util/u_format_rgb9e5.h delete mode 100644 src/mesa/main/rgb9e5.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index a44cc01673b..1beb61868eb 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -28,7 +28,7 @@ #include "u_math.h" #include "u_format_other.h" -#include "../../../mesa/main/rgb9e5.h" +#include "u_format_rgb9e5.h" void diff --git a/src/gallium/auxiliary/util/u_format_rgb9e5.h b/src/gallium/auxiliary/util/u_format_rgb9e5.h new file mode 100644 index 00000000000..c2a3f6f3e9d --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_rgb9e5.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2011 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* Copied from EXT_texture_shared_exponent and edited. */ + +#ifndef RGB9E5_H +#define RGB9E5_H + +#include +#include + +#define RGB9E5_EXPONENT_BITS 5 +#define RGB9E5_MANTISSA_BITS 9 +#define RGB9E5_EXP_BIAS 15 +#define RGB9E5_MAX_VALID_BIASED_EXP 31 + +#define MAX_RGB9E5_EXP (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS) +#define RGB9E5_MANTISSA_VALUES (1< 0.0) { + if (x >= MAX_RGB9E5) { + return MAX_RGB9E5; + } else { + return x; + } + } else { + /* NaN gets here too since comparisons with NaN always fail! */ + return 0.0; + } +} + +/* Ok, FloorLog2 is not correct for the denorm and zero values, but we + are going to do a max of this value with the minimum rgb9e5 exponent + that will hide these problem cases. */ +static INLINE int rgb9e5_FloorLog2(float x) +{ + float754 f; + + f.value = x; + return (f.field.biasedexponent - 127); +} + +static INLINE unsigned float3_to_rgb9e5(const float rgb[3]) +{ + rgb9e5 retval; + float maxrgb; + int rm, gm, bm; + float rc, gc, bc; + int exp_shared, maxm; + double denom; + + rc = rgb9e5_ClampRange(rgb[0]); + gc = rgb9e5_ClampRange(rgb[1]); + bc = rgb9e5_ClampRange(rgb[2]); + + maxrgb = MAX3(rc, gc, bc); + exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS; + assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); + assert(exp_shared >= 0); + /* This pow function could be replaced by a table. */ + denom = pow(2, exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS); + + maxm = (int) floor(maxrgb / denom + 0.5); + if (maxm == MAX_RGB9E5_MANTISSA+1) { + denom *= 2; + exp_shared += 1; + assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); + } else { + assert(maxm <= MAX_RGB9E5_MANTISSA); + } + + rm = (int) floor(rc / denom + 0.5); + gm = (int) floor(gc / denom + 0.5); + bm = (int) floor(bc / denom + 0.5); + + assert(rm <= MAX_RGB9E5_MANTISSA); + assert(gm <= MAX_RGB9E5_MANTISSA); + assert(bm <= MAX_RGB9E5_MANTISSA); + assert(rm >= 0); + assert(gm >= 0); + assert(bm >= 0); + + retval.field.r = rm; + retval.field.g = gm; + retval.field.b = bm; + retval.field.biasedexponent = exp_shared; + + return retval.raw; +} + +static INLINE void rgb9e5_to_float3(unsigned rgb, float retval[3]) +{ + rgb9e5 v; + int exponent; + float scale; + + v.raw = rgb; + exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; + scale = (float) pow(2, exponent); + + retval[0] = v.field.r * scale; + retval[1] = v.field.g * scale; + retval[2] = v.field.b * scale; +} + +#endif diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 88cb5b53bf7..a6e3652c789 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -35,7 +35,7 @@ #include "texstore.h" #include "image.h" #include "macros.h" -#include "rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index 37608f26364..9c3d0854927 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -38,7 +38,7 @@ #include "pack.h" #include "pixeltransfer.h" #include "imports.h" -#include "rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" /** diff --git a/src/mesa/main/rgb9e5.h b/src/mesa/main/rgb9e5.h deleted file mode 100644 index 9bb431ffe9c..00000000000 --- a/src/mesa/main/rgb9e5.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2011 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 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - */ - -/* Copied from EXT_texture_shared_exponent and edited. */ - -#ifndef RGB9E5_H -#define RGB9E5_H - -#include -#include - -#define RGB9E5_EXPONENT_BITS 5 -#define RGB9E5_MANTISSA_BITS 9 -#define RGB9E5_EXP_BIAS 15 -#define RGB9E5_MAX_VALID_BIASED_EXP 31 - -#define MAX_RGB9E5_EXP (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS) -#define RGB9E5_MANTISSA_VALUES (1< 0.0) { - if (x >= MAX_RGB9E5) { - return MAX_RGB9E5; - } else { - return x; - } - } else { - /* NaN gets here too since comparisons with NaN always fail! */ - return 0.0; - } -} - -static INLINE float rgb9e5_MaxOf3(float x, float y, float z) -{ - if (x > y) { - return MAX2(x, z); - } else { - return MAX2(y, z); - } -} - -/* Ok, FloorLog2 is not correct for the denorm and zero values, but we - are going to do a max of this value with the minimum rgb9e5 exponent - that will hide these problem cases. */ -static INLINE int rgb9e5_FloorLog2(float x) -{ - float754 f; - - f.value = x; - return (f.field.biasedexponent - 127); -} - -static INLINE unsigned float3_to_rgb9e5(const float rgb[3]) -{ - rgb9e5 retval; - float maxrgb; - int rm, gm, bm; - float rc, gc, bc; - int exp_shared, maxm; - double denom; - - rc = rgb9e5_ClampRange(rgb[0]); - gc = rgb9e5_ClampRange(rgb[1]); - bc = rgb9e5_ClampRange(rgb[2]); - - maxrgb = rgb9e5_MaxOf3(rc, gc, bc); - exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS; - assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); - assert(exp_shared >= 0); - /* This pow function could be replaced by a table. */ - denom = pow(2, exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS); - - maxm = (int) floor(maxrgb / denom + 0.5); - if (maxm == MAX_RGB9E5_MANTISSA+1) { - denom *= 2; - exp_shared += 1; - assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); - } else { - assert(maxm <= MAX_RGB9E5_MANTISSA); - } - - rm = (int) floor(rc / denom + 0.5); - gm = (int) floor(gc / denom + 0.5); - bm = (int) floor(bc / denom + 0.5); - - assert(rm <= MAX_RGB9E5_MANTISSA); - assert(gm <= MAX_RGB9E5_MANTISSA); - assert(bm <= MAX_RGB9E5_MANTISSA); - assert(rm >= 0); - assert(gm >= 0); - assert(bm >= 0); - - retval.field.r = rm; - retval.field.g = gm; - retval.field.b = bm; - retval.field.biasedexponent = exp_shared; - - return retval.raw; -} - -static INLINE void rgb9e5_to_float3(unsigned rgb, float retval[3]) -{ - rgb9e5 v; - int exponent; - float scale; - - v.raw = rgb; - exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; - scale = (float) pow(2, exponent); - - retval[0] = v.field.r * scale; - retval[1] = v.field.g * scale; - retval[2] = v.field.b * scale; -} - -#endif diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c index 4acc938d093..d6d7b6b8f16 100644 --- a/src/mesa/main/texfetch.c +++ b/src/mesa/main/texfetch.c @@ -41,7 +41,7 @@ #include "texcompress_rgtc.h" #include "texfetch.h" #include "teximage.h" -#include "rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" /** diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 3520f24382f..15fa61f9f79 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -385,8 +385,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, if (ctx->Extensions.EXT_texture_shared_exponent) { switch (internalFormat) { case GL_RGB9_E5: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB9_E5_FLOAT); - break; + ASSERT(ctx->TextureFormatSupported[MESA_FORMAT_RGB9_E5_FLOAT]); + return MESA_FORMAT_RGB9_E5_FLOAT; default: ; /* fallthrough */ } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 5cdde4524b2..39f59e3cbd9 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -70,7 +70,7 @@ #include "teximage.h" #include "texstore.h" #include "enums.h" -#include "rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" enum { -- cgit v1.2.3 From b48359184e36ecd11510e9c87e3db535935c99e2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 13:37:27 +0200 Subject: util: implement R11G11B10_FLOAT pack/unpack functions Reviewed-by: Brian Paul --- src/gallium/auxiliary/util/u_format.csv | 2 +- src/gallium/auxiliary/util/u_format_other.c | 119 ++++++++++++++ src/gallium/auxiliary/util/u_format_other.h | 26 ++++ src/gallium/auxiliary/util/u_format_r11g11b10f.h | 190 +++++++++++++++++++++++ 4 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_format_r11g11b10f.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 990bcff7234..a8baad111f1 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -147,7 +147,7 @@ PIPE_FORMAT_G8R8_G8B8_UNORM , subsampled, 2, 1, x32 , , , , xyz # some special formats not fitting anywhere else PIPE_FORMAT_R10G10B10A2_USCALED , plain, 1, 1, u10 , u10 , u10 , u2 , xyzw, rgb -PIPE_FORMAT_R11G11B10_FLOAT , plain, 1, 1, f11 , f11 , f10 , , xyz1, rgb +PIPE_FORMAT_R11G11B10_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_R9G9B9E5_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_R1_UNORM , other, 8, 1, x8 , , , , x001, rgb # A.k.a. D3DFMT_CxV8U8 diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index 1beb61868eb..c23f4ee4ac5 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -29,6 +29,7 @@ #include "u_math.h" #include "u_format_other.h" #include "u_format_rgb9e5.h" +#include "u_format_r11g11b10f.h" void @@ -149,6 +150,124 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid } +void +util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + for(y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, dst); + dst[3] = 1; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } +} + +void +util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, + const float *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + for(y = 0; y < height; y += 1) { + const float *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value = float3_to_r11g11b10f(src); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + +void +util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, + unsigned i, unsigned j) +{ + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, dst); + dst[3] = 1; /* a */ +} + + +void +util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, p); + dst[0] = float_to_ubyte(p[0]); /* r */ + dst[1] = float_to_ubyte(p[1]); /* g */ + dst[2] = float_to_ubyte(p[2]); /* b */ + dst[3] = 255; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } +} + + +void +util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value; + p[0] = ubyte_to_float(src[0]); + p[1] = ubyte_to_float(src[1]); + p[2] = ubyte_to_float(src[2]); + value = float3_to_r11g11b10f(p); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + + void util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, diff --git a/src/gallium/auxiliary/util/u_format_other.h b/src/gallium/auxiliary/util/u_format_other.h index 98c97be33fa..2f6a908bbe8 100644 --- a/src/gallium/auxiliary/util/u_format_other.h +++ b/src/gallium/auxiliary/util/u_format_other.h @@ -57,6 +57,32 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, + const float *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, + unsigned i, unsigned j); + +void +util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + + void util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, diff --git a/src/gallium/auxiliary/util/u_format_r11g11b10f.h b/src/gallium/auxiliary/util/u_format_r11g11b10f.h new file mode 100644 index 00000000000..c4181d0e34e --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_r11g11b10f.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2011 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* Based on code from The OpenGL Programming Guide / 7th Edition, Appendix J. + * Available here: http://www.opengl-redbook.com/appendices/ + * The algorithm in the book contains a bug though, which is fixed in the code + * below. + */ + +#define UF11_EXPONENT_BIAS 15 +#define UF11_EXPONENT_BITS 0x1F +#define UF11_EXPONENT_SHIFT 6 +#define UF11_MANTISSA_BITS 0x3F +#define UF11_MANTISSA_SHIFT (23 - UF11_EXPONENT_SHIFT) +#define UF11_MAX_EXPONENT (UF11_EXPONENT_BITS << UF11_EXPONENT_SHIFT) + +#define UF10_EXPONENT_BIAS 15 +#define UF10_EXPONENT_BITS 0x1F +#define UF10_EXPONENT_SHIFT 5 +#define UF10_MANTISSA_BITS 0x3F +#define UF10_MANTISSA_SHIFT (23 - UF10_EXPONENT_SHIFT) +#define UF10_MAX_EXPONENT (UF10_EXPONENT_BITS << UF10_EXPONENT_SHIFT) + +#define F32_INFINITY 0x7f800000 + +static INLINE unsigned f32_to_uf11(float val) +{ + uint32_t f32 = (*(uint32_t *) &val); + uint16_t uf11 = 0; + + /* Decode little-endian 32-bit floating-point value */ + int sign = (f32 >> 16) & 0x8000; + /* Map exponent to the range [-127,128] */ + int exponent = ((f32 >> 23) & 0xff) - 127; + int mantissa = f32 & 0x007fffff; + + if (sign) return 0; + + if (exponent == 128) { /* Infinity or NaN */ + uf11 = UF11_MAX_EXPONENT; + if (mantissa) uf11 |= (mantissa & UF11_MANTISSA_BITS); + } + else if (exponent > 15) { /* Overflow - flush to Infinity */ + uf11 = UF11_MAX_EXPONENT; + } + else if (exponent > -15) { /* Representable value */ + exponent += UF11_EXPONENT_BIAS; + mantissa >>= UF11_MANTISSA_SHIFT; + uf11 = exponent << UF11_EXPONENT_SHIFT | mantissa; + } + + return uf11; +} + +static INLINE float uf11_to_f32(uint16_t val) +{ + union { + float f; + uint32_t ui; + } f32; + + int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } + else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } + else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0 / (1 << -exponent); + } + else { + scale = 1 << exponent; + } + decimal = 1.0 + (float) mantissa / 64; + f32.f = scale * decimal; + } + + return f32.f; +} + +static INLINE unsigned f32_to_uf10(float val) +{ + uint32_t f32 = (*(uint32_t *) &val); + uint16_t uf10 = 0; + + /* Decode little-endian 32-bit floating-point value */ + int sign = (f32 >> 16) & 0x8000; + /* Map exponent to the range [-127,128] */ + int exponent = ((f32 >> 23) & 0xff) - 127; + int mantissa = f32 & 0x007fffff; + + if (sign) return 0; + + if (exponent == 128) { /* Infinity or NaN */ + uf10 = UF10_MAX_EXPONENT; + if (mantissa) uf10 |= (mantissa & UF10_MANTISSA_BITS); + } + else if (exponent > 15) { /* Overflow - flush to Infinity */ + uf10 = UF10_MAX_EXPONENT; + } + else if (exponent > -15) { /* Representable value */ + exponent += UF10_EXPONENT_BIAS; + mantissa >>= UF10_MANTISSA_SHIFT; + uf10 = exponent << UF10_EXPONENT_SHIFT | mantissa; + } + + return uf10; +} + +static INLINE float uf10_to_f32(uint16_t val) +{ + union { + float f; + uint32_t ui; + } f32; + + int exponent = (val & 0x07c0) >> UF10_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } + else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } + else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0 / (1 << -exponent); + } + else { + scale = 1 << exponent; + } + decimal = 1.0 + (float) mantissa / 32; + f32.f = scale * decimal; + } + + return f32.f; +} + +static INLINE unsigned float3_to_r11g11b10f(const float rgb[3]) +{ + return ( f32_to_uf11(rgb[0]) & 0x7ff) | + ((f32_to_uf11(rgb[1]) & 0x7ff) << 11) | + ((f32_to_uf10(rgb[2]) & 0x3ff) << 22); +} + +static INLINE void r11g11b10f_to_float3(unsigned rgb, float retval[3]) +{ + retval[0] = uf11_to_f32( rgb & 0x7ff); + retval[1] = uf11_to_f32((rgb >> 11) & 0x7ff); + retval[2] = uf10_to_f32((rgb >> 22) & 0x3ff); +} -- cgit v1.2.3 From 8b558451ad7560a53263f1848b5c826069aa8f51 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 27 Apr 2011 16:30:28 +0200 Subject: r600g: implement EXT_packed_float --- src/gallium/drivers/r600/eg_state_inlines.h | 4 ++++ src/gallium/drivers/r600/r600_state_inlines.h | 3 +++ src/gallium/drivers/r600/r600_texture.c | 3 +++ 3 files changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index 586b7cf2d11..b780dba3e33 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -367,6 +367,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_B10G10R10A2_UNORM: return V_028C70_SWAP_ALT; + case PIPE_FORMAT_R11G11B10_FLOAT: case PIPE_FORMAT_R32_FLOAT: case PIPE_FORMAT_R16G16_FLOAT: case PIPE_FORMAT_R16G16_UNORM: @@ -468,6 +469,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R16G16_UNORM: return V_028C70_COLOR_16_16; + case PIPE_FORMAT_R11G11B10_FLOAT: + return V_028C70_COLOR_10_11_11_FLOAT; + /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16_USCALED: case PIPE_FORMAT_R16G16B16A16_USCALED: diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 09d07f78407..53a649cf8b2 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -361,6 +361,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_B10G10R10A2_UNORM: return V_0280A0_SWAP_ALT; + case PIPE_FORMAT_R11G11B10_FLOAT: case PIPE_FORMAT_R16G16_UNORM: case PIPE_FORMAT_R16G16_FLOAT: case PIPE_FORMAT_R32_FLOAT: @@ -462,6 +463,8 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R16G16_UNORM: return V_0280A0_COLOR_16_16; + case PIPE_FORMAT_R11G11B10_FLOAT: + return V_0280A0_COLOR_10_11_11_FLOAT; /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16_USCALED: diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index b22eb7bbdeb..7ffea6961de 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -933,6 +933,9 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { result = FMT_5_9_9_9_SHAREDEXP; goto out_word4; + } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) { + result = FMT_10_11_11_FLOAT; + goto out_word4; } -- cgit v1.2.3 From f8279fb9d82cbbbbaf8a5cc26486142c21d4d2d2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 29 Apr 2011 13:16:24 +0200 Subject: r600g: print opcodes names instead of numbers --- src/gallium/drivers/r600/r600_shader.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 0f4c0134dce..845d41ace02 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -21,6 +21,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_dump.h" @@ -824,7 +825,8 @@ out_err: static int tgsi_unsupported(struct r600_shader_ctx *ctx) { - R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode); + R600_ERR("%s tgsi opcode unsupported\n", + tgsi_get_opcode_name(ctx->inst_info->tgsi_opcode)); return -EINVAL; } -- cgit v1.2.3 From dc520d4fefa6a92b3a8f2eed3c5a1044dfccb3ff Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Fri, 29 Apr 2011 17:04:11 +0200 Subject: egl/wayland: Fix possible lockup in drm initialization Lockup happens when wl_drm interface is not available. --- src/egl/drivers/dri2/platform_wayland.c | 2 +- src/gallium/state_trackers/egl/wayland/native_drm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 030c68777af..1b75ffea0c5 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -680,7 +680,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) id = wl_display_get_global(dri2_dpy->wl_dpy, "wl_drm", 1); if (id == 0) - wl_display_iterate(dri2_dpy->wl_dpy, WL_DISPLAY_READABLE); + force_roundtrip(dri2_dpy->wl_dpy); id = wl_display_get_global(dri2_dpy->wl_dpy, "wl_drm", 1); if (id == 0) goto cleanup_dpy; diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c index 75c871d6030..604720f6e5f 100644 --- a/src/gallium/state_trackers/egl/wayland/native_drm.c +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -205,7 +205,7 @@ wayland_drm_display_init_screen(struct native_display *ndpy) id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1); if (id == 0) - wl_display_iterate(drmdpy->base.dpy, WL_DISPLAY_READABLE); + force_roundtrip(drmdpy->base.dpy); id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1); if (id == 0) return FALSE; -- cgit v1.2.3 From fe622bac0c1b5b9f2a9fcf9f35b51232a06bea42 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 11 Jan 2011 00:05:08 -0800 Subject: r300/compiler: Rewrite register allocator The new allocator uses ra and does swizzle packing. Also, a data structure (struct rc_variable) and associated functions have been added for generating UD and DU chains. --- src/gallium/drivers/r300/r300_tgsi_to_rc.c | 1 + src/mesa/drivers/dri/r300/compiler/Makefile | 3 + src/mesa/drivers/dri/r300/compiler/SConscript | 2 + .../drivers/dri/r300/compiler/r300_fragprog_emit.c | 2 +- src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c | 3 +- .../drivers/dri/r300/compiler/r500_fragprog_emit.c | 9 +- .../dri/r300/compiler/radeon_compiler_util.c | 256 +++++++ .../dri/r300/compiler/radeon_compiler_util.h | 25 + .../drivers/dri/r300/compiler/radeon_dataflow.c | 57 +- .../drivers/dri/r300/compiler/radeon_dataflow.h | 10 + src/mesa/drivers/dri/r300/compiler/radeon_list.c | 88 +++ src/mesa/drivers/dri/r300/compiler/radeon_list.h | 46 ++ .../dri/r300/compiler/radeon_pair_regalloc.c | 742 +++++++++++++++------ .../drivers/dri/r300/compiler/radeon_program.h | 3 + .../dri/r300/compiler/radeon_program_constants.h | 1 + .../dri/r300/compiler/radeon_program_pair.c | 14 + .../dri/r300/compiler/radeon_program_pair.h | 4 + .../drivers/dri/r300/compiler/radeon_variable.c | 434 ++++++++++++ .../drivers/dri/r300/compiler/radeon_variable.h | 84 +++ 19 files changed, 1548 insertions(+), 236 deletions(-) create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_list.c create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_list.h create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_variable.c create mode 100644 src/mesa/drivers/dri/r300/compiler/radeon_variable.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 6a000cfe2c6..0561ab9bfa4 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -266,6 +266,7 @@ static void transform_texture(struct rc_instruction * dst, struct tgsi_instructi *shadowSamplers |= 1 << dst->U.I.TexSrcUnit; break; } + dst->U.I.TexSwizzle = RC_SWIZZLE_XYZW; } static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src) diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile index 90bd8e86768..5c9f57b4eac 100644 --- a/src/mesa/drivers/dri/r300/compiler/Makefile +++ b/src/mesa/drivers/dri/r300/compiler/Makefile @@ -24,9 +24,11 @@ C_SOURCES = \ radeon_dataflow.c \ radeon_dataflow_deadcode.c \ radeon_dataflow_swizzles.c \ + radeon_list.c \ radeon_optimize.c \ radeon_remove_constants.c \ radeon_rename_regs.c \ + radeon_variable.c \ r3xx_fragprog.c \ r300_fragprog.c \ r300_fragprog_swizzle.c \ @@ -49,6 +51,7 @@ INCLUDES = \ -I. \ -I$(TOP)/include \ -I$(TOP)/src/mesa \ + -I$(TOP)/src/glsl \ ##### TARGETS ##### diff --git a/src/mesa/drivers/dri/r300/compiler/SConscript b/src/mesa/drivers/dri/r300/compiler/SConscript index d44b745562c..bebb9ebe623 100755 --- a/src/mesa/drivers/dri/r300/compiler/SConscript +++ b/src/mesa/drivers/dri/r300/compiler/SConscript @@ -31,6 +31,8 @@ r300compiler = env.ConvenienceLibrary( 'radeon_dataflow.c', 'radeon_dataflow_deadcode.c', 'radeon_dataflow_swizzles.c', + 'radeon_variable.c', + 'radeon_list.c', 'r3xx_fragprog.c', 'r300_fragprog.c', 'r300_fragprog_swizzle.c', diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c index 8b73409136f..e6fd1fde62d 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c @@ -93,7 +93,7 @@ static unsigned int use_source(struct r300_fragment_program_code* code, struct r if (src.File == RC_FILE_CONSTANT) { return src.Index | (1 << 5); - } else if (src.File == RC_FILE_TEMPORARY) { + } else if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) { use_temporary(code, src.Index); return src.Index & 0x1f; } diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index cdfda0b3196..ff022a51037 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -149,8 +149,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) {"pair translate", 1, 1, rc_pair_translate, NULL}, {"pair scheduling", 1, 1, rc_pair_schedule, NULL}, {"dead sources", 1, 1, rc_pair_remove_dead_sources, NULL}, - {"register allocation", 1, opt, rc_pair_regalloc, NULL}, - {"dumb register allocation", 1, !opt, rc_pair_regalloc_inputs_only, NULL}, + {"register allocation", 1, 1, rc_pair_regalloc, opt}, {"final code validation", 0, 1, rc_validate_final_shader, NULL}, {"machine code generation", 0, is_r500, r500BuildFragmentProgramHwCode, NULL}, {"machine code generation", 0, !is_r500, r300BuildFragmentProgramHwCode, NULL}, diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index c7f79bc53c7..5f2588bdfe5 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -207,7 +207,7 @@ static unsigned int use_source(struct r500_fragment_program_code* code, struct r if (src.File == RC_FILE_CONSTANT) { return src.Index | R500_RGB_ADDR0_CONST; - } else if (src.File == RC_FILE_TEMPORARY) { + } else if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) { use_temporary(code, src.Index); return src.Index; } @@ -407,8 +407,11 @@ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_inst code->inst[ip].inst2 = R500_TEX_SRC_ADDR(inst->SrcReg[0].Index) | (translate_strq_swizzle(inst->SrcReg[0].Swizzle) << 8) | R500_TEX_DST_ADDR(inst->DstReg.Index) - | R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G - | R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; + | (GET_SWZ(inst->TexSwizzle, 0) << 24) + | (GET_SWZ(inst->TexSwizzle, 1) << 26) + | (GET_SWZ(inst->TexSwizzle, 2) << 28) + | (GET_SWZ(inst->TexSwizzle, 3) << 30) + ; return 1; } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c index 15ec4418cb8..ae61d20fb9b 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c @@ -124,6 +124,160 @@ unsigned swizzle_mask(unsigned swizzle, unsigned mask) return ret; } +static unsigned int srcs_need_rewrite(const struct rc_opcode_info * info) +{ + if (info->HasTexture) { + return 0; + } + switch (info->Opcode) { + case RC_OPCODE_DP2: + case RC_OPCODE_DP3: + case RC_OPCODE_DP4: + case RC_OPCODE_DDX: + case RC_OPCODE_DDY: + return 0; + default: + return 1; + } +} + +static unsigned int adjust_channels( + unsigned int old_swizzle, + unsigned int conversion_swizzle) +{ + unsigned int i; + unsigned int new_swizzle = rc_init_swizzle(RC_SWIZZLE_UNUSED, 0); + for (i = 0; i < 4; i++) { + unsigned int new_chan = get_swz(conversion_swizzle, i); + if (new_chan == RC_SWIZZLE_UNUSED) { + continue; + } + SET_SWZ(new_swizzle, new_chan, GET_SWZ(old_swizzle, i)); + } + return new_swizzle; +} + +static unsigned int rewrite_writemask( + unsigned int old_mask, + unsigned int conversion_swizzle) +{ + unsigned int new_mask = 0; + unsigned int i; + + for (i = 0; i < 4; i++) { + if (!GET_BIT(old_mask, i) + || GET_SWZ(conversion_swizzle, i) == RC_SWIZZLE_UNUSED) { + continue; + } + new_mask |= (1 << GET_SWZ(conversion_swizzle, i)); + } + + return new_mask; +} + +/** + * This function rewrites the writemask of sub and adjusts the swizzles + * of all its source registers based on the conversion_swizzle. + * conversion_swizzle represents a mapping of the old writemask to the + * new writemask. For a detailed description of how conversion swizzles + * work see rc_rewrite_swizzle(). + */ +void rc_pair_rewrite_writemask( + struct rc_pair_sub_instruction * sub, + unsigned int conversion_swizzle) +{ + const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode); + unsigned int i; + + sub->WriteMask = rewrite_writemask(sub->WriteMask, conversion_swizzle); + + if (!srcs_need_rewrite(info)) { + return ; + } + + for (i = 0; i < info->NumSrcRegs; i++) { + sub->Arg[i].Swizzle = + adjust_channels(sub->Arg[i].Swizzle, conversion_swizzle); + } +} + +static void normal_rewrite_writemask_cb( + void * userdata, + struct rc_instruction * inst, + struct rc_src_register * src) +{ + unsigned int * new_mask = (unsigned int *)userdata; + src->Swizzle = adjust_channels(src->Swizzle, *new_mask); +} + +/** + * This function is the same as rc_pair_rewrite_writemask() except it + * operates on normal instructions. + */ +void rc_normal_rewrite_writemask( + struct rc_instruction * inst, + unsigned int conversion_swizzle) +{ + unsigned int new_mask; + struct rc_sub_instruction * sub = &inst->U.I; + const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode); + sub->DstReg.WriteMask = + rewrite_writemask(sub->DstReg.WriteMask, conversion_swizzle); + + if (info->HasTexture) { + unsigned int i; + assert(sub->TexSwizzle == RC_SWIZZLE_XYZW); + for (i = 0; i < 4; i++) { + unsigned int swz = GET_SWZ(conversion_swizzle, i); + if (swz > 3) + continue; + SET_SWZ(sub->TexSwizzle, swz, i); + } + } + + if (!srcs_need_rewrite(info)) { + return; + } + + new_mask = sub->DstReg.WriteMask; + rc_for_all_reads_src(inst, normal_rewrite_writemask_cb, &new_mask); +} + +/** + * This function replaces each value 'swz' in swizzle with the value of + * GET_SWZ(conversion_swizzle, swz). So, if you want to change all the X's + * in swizzle to Y, then conversion_swizzle should be Y___ (0xff9). If you want + * to change all the Y's in swizzle to X, then conversion_swizzle should be + * _X__ (0xfc7). If you want to change the Y's to X and the X's to Y, then + * conversion swizzle should be YX__ (0xfc1). + * @param swizzle The swizzle to change + * @param conversion_swizzle Describes the conversion to perform on the swizzle + * @return A converted swizzle + */ +unsigned int rc_rewrite_swizzle( + unsigned int swizzle, + unsigned int conversion_swizzle) +{ + unsigned int chan; + unsigned int out_swizzle = swizzle; + + for (chan = 0; chan < 4; chan++) { + unsigned int swz = GET_SWZ(swizzle, chan); + unsigned int new_swz; + if (swz > 3) { + SET_SWZ(out_swizzle, chan, swz); + } else { + new_swz = GET_SWZ(conversion_swizzle, swz); + if (new_swz != RC_SWIZZLE_UNUSED) { + SET_SWZ(out_swizzle, chan, new_swz); + } else { + SET_SWZ(out_swizzle, chan, swz); + } + } + } + return out_swizzle; +} + /** * Left multiplication of a register with a swizzle */ @@ -281,3 +435,105 @@ unsigned int rc_inst_can_use_presub( return 1; } +struct max_data { + unsigned int Max; + unsigned int HasFileType; + rc_register_file File; +}; + +static void max_callback( + void * userdata, + struct rc_instruction * inst, + rc_register_file file, + unsigned int index, + unsigned int mask) +{ + struct max_data * d = (struct max_data*)userdata; + if (file == d->File && (!d->HasFileType || index > d->Max)) { + d->Max = index; + d->HasFileType = 1; + } +} + +/** + * @return The maximum index of the specified register file used by the + * program. + */ +int rc_get_max_index( + struct radeon_compiler * c, + rc_register_file file) +{ + struct max_data data; + data.Max = 0; + data.HasFileType = 0; + data.File = file; + struct rc_instruction * inst; + for (inst = c->Program.Instructions.Next; + inst != &c->Program.Instructions; + inst = inst->Next) { + rc_for_all_reads_mask(inst, max_callback, &data); + rc_for_all_writes_mask(inst, max_callback, &data); + } + if (!data.HasFileType) { + return -1; + } else { + return data.Max; + } +} + +static unsigned int get_source_readmask( + struct rc_pair_sub_instruction * sub, + unsigned int source, + unsigned int src_type) +{ + unsigned int i; + unsigned int readmask = 0; + const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode); + + for (i = 0; i < info->NumSrcRegs; i++) { + if (sub->Arg[i].Source != source + || src_type != rc_source_type_swz(sub->Arg[i].Swizzle)) { + continue; + } + readmask |= rc_swizzle_to_writemask(sub->Arg[i].Swizzle); + } + return readmask; +} + +/** + * This function attempts to remove a source from a pair instructions. + * @param inst + * @param src_type RC_SOURCE_RGB, RC_SOURCE_ALPHA, or both bitwise or'd + * @param source The index of the source to remove + * @param new_readmask A mask representing the components that are read by + * the source that is intended to replace the one you are removing. If you + * want to remove a source only and not replace it, this parameter should be + * zero. + * @return 1 if the source was successfully removed, 0 if it was not + */ +unsigned int rc_pair_remove_src( + struct rc_instruction * inst, + unsigned int src_type, + unsigned int source, + unsigned int new_readmask) +{ + unsigned int readmask = 0; + + readmask |= get_source_readmask(&inst->U.P.RGB, source, src_type); + readmask |= get_source_readmask(&inst->U.P.Alpha, source, src_type); + + if ((new_readmask & readmask) != readmask) + return 0; + + if (src_type & RC_SOURCE_RGB) { + memset(&inst->U.P.RGB.Src[source], 0, + sizeof(struct rc_pair_instruction_source)); + } + + if (src_type & RC_SOURCE_ALPHA) { + memset(&inst->U.P.Alpha.Src[source], 0, + sizeof(struct rc_pair_instruction_source)); + } + + return 1; +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h index dd0f6c66156..43ef8772092 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.h @@ -3,7 +3,10 @@ #ifndef RADEON_PROGRAM_UTIL_H #define RADEON_PROGRAM_UTIL_H +struct radeon_compiler; struct rc_instruction; +struct rc_pair_instruction; +struct rc_pair_sub_instruction; struct rc_src_register; unsigned int rc_swizzle_to_writemask(unsigned int swz); @@ -22,6 +25,18 @@ rc_swizzle rc_mask_to_swizzle(unsigned int mask); unsigned swizzle_mask(unsigned swizzle, unsigned mask); +void rc_pair_rewrite_writemask( + struct rc_pair_sub_instruction * sub, + unsigned int conversion_swizzle); + +void rc_normal_rewrite_writemask( + struct rc_instruction * inst, + unsigned int conversion_swizzle); + +unsigned int rc_rewrite_swizzle( + unsigned int swizzle, + unsigned int new_mask); + struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg); void reset_srcreg(struct rc_src_register* reg); @@ -46,4 +61,14 @@ unsigned int rc_inst_can_use_presub( struct rc_src_register presub_src0, struct rc_src_register presub_src1); +int rc_get_max_index( + struct radeon_compiler * c, + rc_register_file file); + +unsigned int rc_pair_remove_src( + struct rc_instruction * inst, + unsigned int src_type, + unsigned int source, + unsigned int new_readmask); + #endif /* RADEON_PROGRAM_UTIL_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c index 3c0ab10aa56..966b7f825f8 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c @@ -151,6 +151,7 @@ static void pair_sub_for_all_args( unsigned int presub_src_count; struct rc_pair_instruction_source * src_array; unsigned int j; +// fprintf(stderr, "Presubtract reader\n"); if (src_type & RC_SOURCE_RGB) { presub_type = fullinst-> U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Index; @@ -165,7 +166,9 @@ static void pair_sub_for_all_args( for(j = 0; j < presub_src_count; j++) { cb(userdata, fullinst, &sub->Arg[i], &src_array[j]); +// fprintf(stderr, "Callback for presub %u type=%u\n", j, src_type); } +// fprintf(stderr, "Done presubtract reader\n"); } else { struct rc_pair_instruction_source * src = rc_pair_get_src(&fullinst->U.P, &sub->Arg[i]); @@ -586,6 +589,8 @@ static void get_readers_pair_read_callback( 0 /*Pair Instructions don't use RelAddr*/, src->File, src->Index, arg->Swizzle); +// fprintf(stderr, "Shared mask = %u for [%u].%u writemask=%u abort=%u exit=%u\n", +// shared_mask, src->Index, arg->Swizzle, d->AliveWriteMask,d->ReaderData->Abort, d->ReaderData->ExitOnAbort); if (shared_mask == RC_MASK_NONE) return; @@ -775,6 +780,26 @@ static void get_readers_for_single_write( } } +static void init_get_readers_callback_data( + struct get_readers_callback_data * d, + struct rc_reader_data * reader_data, + struct radeon_compiler * c, + rc_read_src_fn read_normal_cb, + rc_pair_read_arg_fn read_pair_cb, + rc_read_write_mask_fn write_cb) +{ + reader_data->Abort = 0; + reader_data->ReaderCount = 0; + reader_data->ReadersReserved = 0; + reader_data->Readers = NULL; + + d->C = c; + d->ReaderData = reader_data; + d->ReadNormalCB = read_normal_cb; + d->ReadPairCB = read_pair_cb; + d->WriteCB = write_cb; +} + /** * This function will create a list of readers via the rc_reader_data struct. * This function will abort (set the flag data->Abort) and return if it @@ -823,16 +848,28 @@ void rc_get_readers( { struct get_readers_callback_data d; - data->Abort = 0; - data->ReaderCount = 0; - data->ReadersReserved = 0; - data->Readers = NULL; - - d.C = c; - d.ReaderData = data; - d.ReadNormalCB = read_normal_cb; - d.ReadPairCB = read_pair_cb; - d.WriteCB = write_cb; + init_get_readers_callback_data(&d, data, c, read_normal_cb, + read_pair_cb, write_cb); rc_for_all_writes_mask(writer, get_readers_for_single_write, &d); } + +void rc_get_readers_sub( + struct radeon_compiler * c, + struct rc_instruction * writer, + struct rc_pair_sub_instruction * sub_writer, + struct rc_reader_data * data, + rc_read_src_fn read_normal_cb, + rc_pair_read_arg_fn read_pair_cb, + rc_read_write_mask_fn write_cb) +{ + struct get_readers_callback_data d; + + init_get_readers_callback_data(&d, data, c, read_normal_cb, + read_pair_cb, write_cb); + + if (sub_writer->WriteMask) { + get_readers_for_single_write(&d, writer, RC_FILE_TEMPORARY, + sub_writer->DestIndex, sub_writer->WriteMask); + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h index 1e30cc69695..6667ae1c4f3 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h @@ -37,6 +37,7 @@ struct rc_swizzle_caps; struct rc_src_register; struct rc_pair_instruction_arg; struct rc_pair_instruction_source; +struct rc_pair_sub_instruction; struct rc_compiler; @@ -107,6 +108,15 @@ void rc_get_readers( rc_read_src_fn read_normal_cb, rc_pair_read_arg_fn read_pair_cb, rc_read_write_mask_fn write_cb); + +void rc_get_readers_sub( + struct radeon_compiler * c, + struct rc_instruction * writer, + struct rc_pair_sub_instruction * sub_writer, + struct rc_reader_data * data, + rc_read_src_fn read_normal_cb, + rc_pair_read_arg_fn read_pair_cb, + rc_read_write_mask_fn write_cb); /** * Compiler passes based on dataflow analysis. */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_list.c b/src/mesa/drivers/dri/r300/compiler/radeon_list.c new file mode 100644 index 00000000000..9b2ba80a8fa --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_list.c @@ -0,0 +1,88 @@ +/* + * Copyright 2011 Tom Stellard + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 "radeon_list.h" + +#include +#include + +#include "memory_pool.h" + +struct rc_list * rc_list(struct memory_pool * pool, void * item) +{ + struct rc_list * new = memory_pool_malloc(pool, sizeof(struct rc_list)); + new->Item = item; + new->Next = NULL; + new->Prev = NULL; +} + +void rc_list_add(struct rc_list ** list, struct rc_list * new_value) +{ + struct rc_list * temp; + + if (*list == NULL) { + *list = new_value; + return; + } + + for (temp = *list; temp->Next; temp = temp->Next); + + temp->Next = new_value; + new_value->Prev = temp; +} + +void rc_list_remove(struct rc_list ** list, struct rc_list * rm_value) +{ + if (*list == rm_value) { + *list = rm_value->Next; + return; + } + + rm_value->Prev->Next = rm_value->Next; + if (rm_value->Next) { + rm_value->Next->Prev = rm_value->Prev; + } +} + +unsigned int rc_list_count(struct rc_list * list) +{ + unsigned int count = 0; + while (list) { + count++; + list = list->Next; + } + return count; +} + +void rc_list_print(struct rc_list * list) +{ + while(list) { + fprintf(stderr, "%p->", list->Item); + list = list->Next; + } + fprintf(stderr, "\n"); +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_list.h b/src/mesa/drivers/dri/r300/compiler/radeon_list.h new file mode 100644 index 00000000000..b3c8f89cc68 --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_list.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Tom Stellard + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 RADEON_LIST_H +#define RADEON_LIST_H + +struct memory_pool; + +struct rc_list { + void * Item; + struct rc_list * Prev; + struct rc_list * Next; +}; + +struct rc_list * rc_list(struct memory_pool * pool, void * item); +void rc_list_add(struct rc_list ** list, struct rc_list * new_value); +void rc_list_remove(struct rc_list ** list, struct rc_list * rm_value); +unsigned int rc_list_count(struct rc_list * list); +void rc_list_print(struct rc_list * list); + +#endif /* RADEON_LIST_H */ + diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c index d53181e1f75..52c0216b64b 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Nicolai Haehnle. + * Copyright 2011 Tom Stellard * * All Rights Reserved. * @@ -29,125 +30,125 @@ #include +#include "main/glheader.h" +#include "program/register_allocate.h" +#include "ralloc.h" + #include "radeon_compiler.h" +#include "radeon_compiler_util.h" #include "radeon_dataflow.h" - +#include "radeon_list.h" +#include "radeon_variable.h" #define VERBOSE 0 #define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) -struct live_intervals { - int Start; - int End; - struct live_intervals * Next; -}; struct register_info { - struct live_intervals Live; + struct live_intervals Live[4]; unsigned int Used:1; unsigned int Allocated:1; unsigned int File:3; unsigned int Index:RC_REGISTER_INDEX_BITS; -}; - -struct hardware_register { - struct live_intervals * Used; + unsigned int Writemask; }; struct regalloc_state { struct radeon_compiler * C; - struct register_info Input[RC_REGISTER_MAX_INDEX]; - struct register_info Temporary[RC_REGISTER_MAX_INDEX]; - - struct hardware_register * HwTemporary; - unsigned int NumHwTemporaries; - /** - * If an instruction is inside of a loop, EndLoop will be the - * IP of the ENDLOOP instruction, and BeginLoop will be the IP - * of the BGNLOOP instruction. Otherwise, EndLoop and BeginLoop - * will be -1. - */ - int EndLoop; - int BeginLoop; + struct register_info * Input; + unsigned int NumInputs; + + struct register_info * Temporary; + unsigned int NumTemporaries; + + unsigned int Simple; + unsigned int HasLoop; +}; + +enum rc_reg_class { + RC_REG_CLASS_SINGLE, + RC_REG_CLASS_DOUBLE, + RC_REG_CLASS_TRIPLE, + RC_REG_CLASS_ALPHA, + RC_REG_CLASS_SINGLE_PLUS_ALPHA, + RC_REG_CLASS_DOUBLE_PLUS_ALPHA, + RC_REG_CLASS_TRIPLE_PLUS_ALPHA, + RC_REG_CLASS_X, + RC_REG_CLASS_Y, + RC_REG_CLASS_Z, + RC_REG_CLASS_XY, + RC_REG_CLASS_YZ, + RC_REG_CLASS_XZ, + RC_REG_CLASS_XW, + RC_REG_CLASS_YW, + RC_REG_CLASS_ZW, + RC_REG_CLASS_XYW, + RC_REG_CLASS_YZW, + RC_REG_CLASS_XZW, + RC_REG_CLASS_COUNT +}; + +struct rc_class { + enum rc_reg_class Class; + + unsigned int WritemaskCount; + + /** This is 1 if this class is being used by the register allocator + * and 0 otherwise */ + unsigned int Used; + + /** This is the ID number assigned to this class by ra. */ + unsigned int Id; + + /** List of writemasks that belong to this class */ + unsigned int Writemasks[3]; + + }; static void print_live_intervals(struct live_intervals * src) { - if (!src) { + if (!src || !src->Used) { DBG("(null)"); return; } - while(src) { - DBG("(%i,%i)", src->Start, src->End); - src = src->Next; - } + DBG("(%i,%i)", src->Start, src->End); } -static void add_live_intervals(struct regalloc_state * s, - struct live_intervals ** dst, struct live_intervals * src) +static int overlap_live_intervals(struct live_intervals * a, struct live_intervals * b) { - struct live_intervals ** dst_backup = dst; - if (VERBOSE) { - DBG("add_live_intervals: "); - print_live_intervals(*dst); + DBG("overlap_live_intervals: "); + print_live_intervals(a); DBG(" to "); - print_live_intervals(src); + print_live_intervals(b); DBG("\n"); } - while(src) { - if (*dst && (*dst)->End < src->Start) { - dst = &(*dst)->Next; - } else if (!*dst || (*dst)->Start > src->End) { - struct live_intervals * li = memory_pool_malloc(&s->C->Pool, sizeof(*li)); - li->Start = src->Start; - li->End = src->End; - li->Next = *dst; - *dst = li; - src = src->Next; - } else { - if (src->End > (*dst)->End) - (*dst)->End = src->End; - if (src->Start < (*dst)->Start) - (*dst)->Start = src->Start; - src = src->Next; - } - } - - if (VERBOSE) { - DBG(" result: "); - print_live_intervals(*dst_backup); - DBG("\n"); - } -} - -static int overlap_live_intervals(struct live_intervals * dst, struct live_intervals * src) -{ - if (VERBOSE) { - DBG("overlap_live_intervals: "); - print_live_intervals(dst); - DBG(" to "); - print_live_intervals(src); - DBG("\n"); + if (!a->Used || !b->Used) { + DBG(" unused interval\n"); + return 0; } - while(src && dst) { - if (dst->End <= src->Start) { - dst = dst->Next; - } else if (dst->End <= src->End) { + if (a->Start > b->Start) { + if (a->Start < b->End) { DBG(" overlap\n"); return 1; - } else if (dst->Start < src->End) { + } + } else if (b->Start > a->Start) { + if (b->Start < a->End) { + DBG(" overlap\n"); + return 1; + } + } else { /* a->Start == b->Start */ + if (a->Start != a->End && b->Start != b->End) { DBG(" overlap\n"); return 1; - } else { - src = src->Next; } } @@ -156,92 +157,26 @@ static int overlap_live_intervals(struct live_intervals * dst, struct live_inter return 0; } -static int try_add_live_intervals(struct regalloc_state * s, - struct live_intervals ** dst, struct live_intervals * src) -{ - if (overlap_live_intervals(*dst, src)) - return 0; - - add_live_intervals(s, dst, src); - return 1; -} - -static void scan_callback(void * data, struct rc_instruction * inst, +static void scan_read_callback(void * data, struct rc_instruction * inst, rc_register_file file, unsigned int index, unsigned int mask) { struct regalloc_state * s = data; struct register_info * reg; + unsigned int i; - if (file == RC_FILE_TEMPORARY) - reg = &s->Temporary[index]; - else if (file == RC_FILE_INPUT) - reg = &s->Input[index]; - else + if (file != RC_FILE_INPUT) return; - if (!reg->Used) { - reg->Used = 1; - if (file == RC_FILE_INPUT) - reg->Live.Start = -1; - else if (s->BeginLoop >= 0) - reg->Live.Start = s->BeginLoop; - else - reg->Live.Start = inst->IP; - reg->Live.End = inst->IP; - } else if (s->EndLoop >= 0) - reg->Live.End = s->EndLoop; - else if (inst->IP > reg->Live.End) - reg->Live.End = inst->IP; -} - -static void compute_live_intervals(struct radeon_compiler *c, - struct regalloc_state *s) -{ - memset(s, 0, sizeof(*s)); - s->C = c; - s->NumHwTemporaries = c->max_temp_regs; - s->BeginLoop = -1; - s->EndLoop = -1; - s->HwTemporary = - memory_pool_malloc(&c->Pool, - s->NumHwTemporaries * sizeof(struct hardware_register)); - memset(s->HwTemporary, 0, s->NumHwTemporaries * sizeof(struct hardware_register)); - - rc_recompute_ips(s->C); - - for(struct rc_instruction * inst = s->C->Program.Instructions.Next; - inst != &s->C->Program.Instructions; - inst = inst->Next) { - - /* For all instructions inside of a loop, the ENDLOOP - * instruction is used as the end of the live interval and - * the BGNLOOP instruction is used as the beginning. */ - if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && s->EndLoop < 0) { - int loops = 1; - struct rc_instruction * tmp; - s->BeginLoop = inst->IP; - for(tmp = inst->Next; - tmp != &s->C->Program.Instructions; - tmp = tmp->Next) { - if (tmp->U.I.Opcode == RC_OPCODE_BGNLOOP) { - loops++; - } else if (tmp->U.I.Opcode - == RC_OPCODE_ENDLOOP) { - if(!--loops) { - s->EndLoop = tmp->IP; - break; - } - } - } - } + s->Input[index].Used = 1; + reg = &s->Input[index]; - if (inst->IP == s->EndLoop) { - s->EndLoop = -1; - s->BeginLoop = -1; + for (i = 0; i < 4; i++) { + if (!((mask >> i) & 0x1)) { + continue; } - - rc_for_all_reads_mask(inst, scan_callback, s); - rc_for_all_writes_mask(inst, scan_callback, s); + reg->Live[i].Used = 1; + reg->Live[i].Start = 0; + reg->Live[i].End = inst->IP; } } @@ -251,7 +186,7 @@ static void remap_register(void * data, struct rc_instruction * inst, struct regalloc_state * s = data; const struct register_info * reg; - if (*file == RC_FILE_TEMPORARY) + if (*file == RC_FILE_TEMPORARY && s->Simple) reg = &s->Temporary[*index]; else if (*file == RC_FILE_INPUT) reg = &s->Input[*index]; @@ -259,106 +194,473 @@ static void remap_register(void * data, struct rc_instruction * inst, return; if (reg->Allocated) { - *file = reg->File; *index = reg->Index; } } -static void do_regalloc(struct regalloc_state * s) +static void alloc_input_simple(void * data, unsigned int input, + unsigned int hwreg) { - /* Simple and stupid greedy register allocation */ - for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) { - struct register_info * reg = &s->Temporary[index]; + struct regalloc_state * s = data; - if (!reg->Used) - continue; + if (input >= s->NumInputs) + return; + + s->Input[input].Allocated = 1; + s->Input[input].File = RC_FILE_TEMPORARY; + s->Input[input].Index = hwreg; +} - for(unsigned int hwreg = 0; hwreg < s->NumHwTemporaries; ++hwreg) { - if (try_add_live_intervals(s, &s->HwTemporary[hwreg].Used, ®->Live)) { - reg->Allocated = 1; - reg->File = RC_FILE_TEMPORARY; - reg->Index = hwreg; - goto success; +/* This functions offsets the temporary register indices by the number + * of input registers, because input registers are actually temporaries and + * should not occupy the same space. + * + * This pass is supposed to be used to maintain correct allocation of inputs + * if the standard register allocation is disabled. */ +static void do_regalloc_inputs_only(struct regalloc_state * s) +{ + for (unsigned i = 0; i < s->NumTemporaries; i++) { + s->Temporary[i].Allocated = 1; + s->Temporary[i].File = RC_FILE_TEMPORARY; + s->Temporary[i].Index = i + s->NumInputs; + } +} + +static unsigned int is_derivative(rc_opcode op) +{ + return (op == RC_OPCODE_DDX || op == RC_OPCODE_DDY); +} + +static enum rc_reg_class variable_get_class( + struct rc_variable * variable, + struct rc_class * classes) +{ + unsigned int i; + unsigned int can_change_writemask= 1; + unsigned int writemask = rc_variable_writemask_sum(variable); + struct rc_list * readers = rc_variable_readers_union(variable); + + if (!variable->C->is_r500) { + unsigned int mask_count = 0; + /* The assumption here is that if an instruction has type + * RC_INSTRUCTION_NORMAL then it is a TEX instruction. + * r300 and r400 can't swizzle the result of a TEX lookup. */ + if (variable->Inst->Type == RC_INSTRUCTION_NORMAL) { + writemask = RC_MASK_XYZW; + } + for (i = 0; i < 4; i++) { + if (GET_BIT(writemask, i)) { + mask_count++; } } + /* XXX We should do swizzle packing for r300 and r400 here. + * We need to figure out how not to create non-native + * swizzles. */ + if (mask_count > 1) { + can_change_writemask = 0; + } + } - rc_error(s->C, "Ran out of hardware temporaries\n"); - return; - - success:; + if (variable->Inst->Type == RC_INSTRUCTION_PAIR) { + /* DDX/DDY seem to always fail when their writemasks are + * changed.*/ + if (is_derivative(variable->Inst->U.P.RGB.Opcode) + || is_derivative(variable->Inst->U.P.Alpha.Opcode)) { + can_change_writemask = 0; + } } + for ( ; readers; readers = readers->Next) { + struct rc_reader * r = readers->Item; + if (r->Inst->Type == RC_INSTRUCTION_PAIR) { + if (r->U.P.Arg->Source == RC_PAIR_PRESUB_SRC) { + can_change_writemask = 0; + break; + } + /* DDX/DDY also fail when their swizzles are changed. */ + if (is_derivative(r->Inst->U.P.RGB.Opcode) + || is_derivative(r->Inst->U.P.Alpha.Opcode)) { + can_change_writemask = 0; + break; + } + } + } + for (i = 0; i < RC_REG_CLASS_COUNT; i++) { + unsigned int j; + if (!can_change_writemask && classes[i].WritemaskCount > 1) { + continue; + } + for (j = 0; j < 3; j++) { + if (classes[i].Writemasks[j] == writemask) { + return classes[i].Class; + } + } + } + rc_error(variable->C, "Could not find class for index=%u mask=%u\n", + variable->Dst.Index, writemask); + return 0; +} - /* Rewrite all instructions based on the translation table we built */ - for(struct rc_instruction * inst = s->C->Program.Instructions.Next; - inst != &s->C->Program.Instructions; - inst = inst->Next) { - rc_remap_registers(inst, &remap_register, s); +static unsigned int overlap_live_intervals_array( + struct live_intervals * a, + struct live_intervals * b) +{ + unsigned int a_chan, b_chan; + for (a_chan = 0; a_chan < 4; a_chan++) { + for (b_chan = 0; b_chan < 4; b_chan++) { + if (overlap_live_intervals(&a[a_chan], &b[b_chan])) { + return 1; + } + } } + return 0; } -static void alloc_input(void * data, unsigned int input, unsigned int hwreg) +static unsigned int reg_get_index(int reg) { - struct regalloc_state * s = data; + return reg / RC_MASK_XYZW; +} - if (!s->Input[input].Used) - return; +static unsigned int reg_get_writemask(int reg) +{ + return (reg % RC_MASK_XYZW) + 1; +} - add_live_intervals(s, &s->HwTemporary[hwreg].Used, &s->Input[input].Live); +static int get_reg_id(unsigned int index, unsigned int writemask) +{ + assert(writemask); + if (writemask == 0) { + return 0; + } + return (index * RC_MASK_XYZW) + (writemask - 1); +} - s->Input[input].Allocated = 1; - s->Input[input].File = RC_FILE_TEMPORARY; - s->Input[input].Index = hwreg; +#if VERBOSE +static void print_reg(int reg) +{ + unsigned int index = reg_get_index(reg); + unsigned int mask = reg_get_writemask(reg); + fprintf(stderr, "Temp[%u].%c%c%c%c", index, + mask & RC_MASK_X ? 'x' : '_', + mask & RC_MASK_Y ? 'y' : '_', + mask & RC_MASK_Z ? 'z' : '_', + mask & RC_MASK_W ? 'w' : '_'); +} +#endif +static void add_register_conflicts( + struct ra_regs * regs, + unsigned int max_temp_regs) +{ + unsigned int index, a_mask, b_mask; + for (index = 0; index < max_temp_regs; index++) { + for(a_mask = 1; a_mask <= RC_MASK_XYZW; a_mask++) { + for (b_mask = a_mask + 1; b_mask <= RC_MASK_XYZW; + b_mask++) { + if (a_mask & b_mask) { + ra_add_reg_conflict(regs, + get_reg_id(index, a_mask), + get_reg_id(index, b_mask)); + } + } + } + } } -void rc_pair_regalloc(struct radeon_compiler *cc, void *user) +static void do_advanced_regalloc(struct regalloc_state * s) { - struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc; - struct regalloc_state s; + struct rc_class rc_class_list [] = { + {RC_REG_CLASS_SINGLE, 3, 0, 0, + {RC_MASK_X, + RC_MASK_Y, + RC_MASK_Z}}, + {RC_REG_CLASS_DOUBLE, 3, 0, 0, + {RC_MASK_X | RC_MASK_Y, + RC_MASK_X | RC_MASK_Z, + RC_MASK_Y | RC_MASK_Z}}, + {RC_REG_CLASS_TRIPLE, 1, 0, 0, + {RC_MASK_X | RC_MASK_Y | RC_MASK_Z, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_ALPHA, 1, 0, 0, + {RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_SINGLE_PLUS_ALPHA, 3, 0, 0, + {RC_MASK_X | RC_MASK_W, + RC_MASK_Y | RC_MASK_W, + RC_MASK_Z | RC_MASK_W}}, + {RC_REG_CLASS_DOUBLE_PLUS_ALPHA, 3, 0, 0, + {RC_MASK_X | RC_MASK_Y | RC_MASK_W, + RC_MASK_X | RC_MASK_Z | RC_MASK_W, + RC_MASK_Y | RC_MASK_Z | RC_MASK_W}}, + {RC_REG_CLASS_TRIPLE_PLUS_ALPHA, 1, 0, 0, + {RC_MASK_X | RC_MASK_Y | RC_MASK_Z | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_X, 1, 0, 0, + {RC_MASK_X, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_Y, 1, 0, 0, + {RC_MASK_Y, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_Z, 1, 0, 0, + {RC_MASK_Z, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_XY, 1, 0, 0, + {RC_MASK_X | RC_MASK_Y, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_YZ, 1, 0, 0, + {RC_MASK_Y | RC_MASK_Z, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_XZ, 1, 0, 0, + {RC_MASK_X | RC_MASK_Z, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_XW, 1, 0, 0, + {RC_MASK_X | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_YW, 1, 0, 0, + {RC_MASK_Y | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_ZW, 1, 0, 0, + {RC_MASK_Z | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_XYW, 1, 0, 0, + {RC_MASK_X | RC_MASK_Y | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_YZW, 1, 0, 0, + {RC_MASK_Y | RC_MASK_Z | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}}, + {RC_REG_CLASS_XZW, 1, 0, 0, + {RC_MASK_X | RC_MASK_Z | RC_MASK_W, + RC_MASK_NONE, + RC_MASK_NONE}} + }; + + unsigned int i, j, index, input_node, node_count, node_index; + unsigned int * node_classes; + unsigned int * input_classes; + struct rc_instruction * inst; + struct rc_list * var_ptr; + struct rc_list * variables; + struct ra_regs * regs; + struct ra_graph * graph; + + /* Allocate the main ra data structure */ + regs = ra_alloc_reg_set(s->C->max_temp_regs * RC_MASK_XYZW); + + /* Get list of program variables */ + variables = rc_get_variables(s->C); + node_count = rc_list_count(variables); + node_classes = memory_pool_malloc(&s->C->Pool, + node_count * sizeof(unsigned int)); + input_classes = memory_pool_malloc(&s->C->Pool, + s->NumInputs * sizeof(unsigned int)); + + for (var_ptr = variables, node_index = 0; var_ptr; + var_ptr = var_ptr->Next, node_index++) { + unsigned int class_index; + /* Compute the live intervals */ + rc_variable_compute_live_intervals(var_ptr->Item); + + class_index = variable_get_class(var_ptr->Item, rc_class_list); + + /* If we haven't used this register class yet, mark it + * as used and allocate space for it. */ + if (!rc_class_list[class_index].Used) { + rc_class_list[class_index].Used = 1; + rc_class_list[class_index].Id = ra_alloc_reg_class(regs); + } - compute_live_intervals(cc, &s); + node_classes[node_index] = rc_class_list[class_index].Id; + } - c->AllocateHwInputs(c, &alloc_input, &s); - do_regalloc(&s); -} + /* Assign registers to the classes */ + for (i = 0; i < RC_REG_CLASS_COUNT; i++) { + struct rc_class class = rc_class_list[i]; + if (!class.Used) { + continue; + } -/* This functions offsets the temporary register indices by the number - * of input registers, because input registers are actually temporaries and - * should not occupy the same space. - * - * This pass is supposed to be used to maintain correct allocation of inputs - * if the standard register allocation is disabled. */ -void rc_pair_regalloc_inputs_only(struct radeon_compiler *cc, void *user) -{ - struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc; - struct regalloc_state s; - int temp_reg_offset; + for (index = 0; index < s->C->max_temp_regs; index++) { + for (j = 0; j < class.WritemaskCount; j++) { + int reg_id = get_reg_id(index, + class.Writemasks[j]); + ra_class_add_reg(regs, class.Id, reg_id); + } + } + } + + /* Add register conflicts */ + add_register_conflicts(regs, s->C->max_temp_regs); + + /* Calculate live intervals for input registers */ + for (inst = s->C->Program.Instructions.Next; + inst != &s->C->Program.Instructions; + inst = inst->Next) { + rc_for_all_reads_mask(inst, scan_read_callback, s); + } + + /* Create classes for input registers */ + for (i = 0; i < s->NumInputs; i++) { + unsigned int chan, class_id, writemask = 0; + for (chan = 0; chan < 4; chan++) { + if (s->Input[i].Live[chan].Used) { + writemask |= (1 << chan); + } + } + s->Input[i].Writemask = writemask; + if (!writemask) { + continue; + } + + class_id = ra_alloc_reg_class(regs); + input_classes[i] = class_id; + ra_class_add_reg(regs, class_id, + get_reg_id(s->Input[i].Index, writemask)); + } + + ra_set_finalize(regs); + + graph = ra_alloc_interference_graph(regs, node_count + s->NumInputs); - compute_live_intervals(cc, &s); + /* Build the interference graph */ + for (var_ptr = variables, node_index = 0; var_ptr; + var_ptr = var_ptr->Next,node_index++) { + struct rc_list * a, * b; + unsigned int b_index; - c->AllocateHwInputs(c, &alloc_input, &s); + ra_set_node_class(graph, node_index, node_classes[node_index]); - temp_reg_offset = 0; - for (unsigned i = 0; i < RC_REGISTER_MAX_INDEX; i++) { - if (s.Input[i].Allocated && temp_reg_offset <= s.Input[i].Index) - temp_reg_offset = s.Input[i].Index + 1; + for (a = var_ptr, b = var_ptr->Next, b_index = node_index + 1; + b; b = b->Next, b_index++) { + struct rc_variable * var_a = a->Item; + while (var_a) { + struct rc_variable * var_b = b->Item; + while (var_b) { + if (overlap_live_intervals_array(var_a->Live, var_b->Live)) { + ra_add_node_interference(graph, + node_index, b_index); + } + var_b = var_b->Friend; + } + var_a = var_a->Friend; + } + } } - if (temp_reg_offset) { - for (unsigned i = 0; i < RC_REGISTER_MAX_INDEX; i++) { - if (s.Temporary[i].Used) { - s.Temporary[i].Allocated = 1; - s.Temporary[i].File = RC_FILE_TEMPORARY; - s.Temporary[i].Index = i + temp_reg_offset; + /* Add input registers to the interference graph */ + for (i = 0, input_node = 0; i< s->NumInputs; i++) { + if (!s->Input[i].Writemask) { + continue; + } + ra_set_node_class(graph, node_count + input_node, + input_classes[i]); + for (var_ptr = variables, node_index = 0; + var_ptr; var_ptr = var_ptr->Next, node_index++) { + struct rc_variable * var = var_ptr->Item; + if (overlap_live_intervals_array(s->Input[i].Live, + var->Live)) { + ra_add_node_interference(graph, node_index, + node_count + input_node); } } + /* Manually allocate a register for this input */ + ra_set_node_reg(graph, node_count + input_node, get_reg_id( + s->Input[i].Index, s->Input[i].Writemask)); + input_node++; + } + + if (!ra_allocate_no_spills(graph)) { + rc_error(s->C, "Ran out of hardware temporaries\n"); + return; + } + + /* Rewrite the registers */ + for (var_ptr = variables, node_index = 0; var_ptr; + var_ptr = var_ptr->Next, node_index++) { + int reg = ra_get_node_reg(graph, node_index); + unsigned int writemask = reg_get_writemask(reg); + unsigned int index = reg_get_index(reg); + struct rc_variable * var = var_ptr->Item; + + if (!s->C->is_r500 && var->Inst->Type == RC_INSTRUCTION_NORMAL) { + writemask = rc_variable_writemask_sum(var); + } + + if (var->Dst.File == RC_FILE_INPUT) { + continue; + } + rc_variable_change_dst(var, index, writemask); + } + + ralloc_free(graph); + ralloc_free(regs); +} + +/** + * @param user This parameter should be a pointer to an integer value. If this + * integer value is zero, then a simple register allocator will be used that + * only allocates space for input registers (\sa do_regalloc_inputs_only). If + * user is non-zero, then the regular register allocator will be used + * (\sa do_regalloc). + */ +void rc_pair_regalloc(struct radeon_compiler *cc, void *user) +{ + struct r300_fragment_program_compiler *c = + (struct r300_fragment_program_compiler*)cc; + struct regalloc_state s; + int do_full_regalloc = (int)user; + struct rc_instruction * inst; + + memset(&s, 0, sizeof(s)); + s.C = cc; + s.NumInputs = rc_get_max_index(cc, RC_FILE_INPUT) + 1; + s.Input = memory_pool_malloc(&cc->Pool, + s.NumInputs * sizeof(struct register_info)); + memset(s.Input, 0, s.NumInputs * sizeof(struct register_info)); + + s.NumTemporaries = rc_get_max_index(cc, RC_FILE_TEMPORARY) + 1; + s.Temporary = memory_pool_malloc(&cc->Pool, + s.NumTemporaries * sizeof(struct register_info)); + memset(s.Temporary, 0, s.NumTemporaries * sizeof(struct register_info)); + + for(inst = cc->Program.Instructions.Next; + inst != &cc->Program.Instructions; + inst = inst->Next) { - /* Rewrite all registers. */ - for (struct rc_instruction *inst = cc->Program.Instructions.Next; - inst != &cc->Program.Instructions; - inst = inst->Next) { - rc_remap_registers(inst, &remap_register, &s); + if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP) { + s.HasLoop = 1; + break; } } + + rc_recompute_ips(s.C); + + c->AllocateHwInputs(c, &alloc_input_simple, &s); + if (!s.HasLoop && do_full_regalloc) { + do_advanced_regalloc(&s); + } else { + s.Simple = 1; + do_regalloc_inputs_only(&s); + } + + /* Rewrite inputs and if we are doing the simple allocation, rewrite + * temporaries too. */ + for (struct rc_instruction *inst = s.C->Program.Instructions.Next; + inst != &s.C->Program.Instructions; + inst = inst->Next) { + rc_remap_registers(inst, &remap_register, &s); + } } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.h b/src/mesa/drivers/dri/r300/compiler/radeon_program.h index a07f6b63c6e..b899eccbf53 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.h @@ -108,6 +108,9 @@ struct rc_sub_instruction { /** True if tex instruction should do shadow comparison */ unsigned int TexShadow:1; + + /**R500 Only. How to swizzle the result of a TEX lookup*/ + unsigned int TexSwizzle:12; /*@}*/ /** This holds information about the presubtract operation used by diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h index 45f79ece5ba..24577333450 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h @@ -129,6 +129,7 @@ typedef enum { #define RC_SWIZZLE_0000 RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_ZERO) #define RC_SWIZZLE_1111 RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_ONE) #define RC_SWIZZLE_HHHH RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF) +#define RC_SWIZZLE_UUUU RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_UNUSED) /** * \name Bitmasks for components of vectors. diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c index 68874795b8a..52315957520 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c @@ -223,3 +223,17 @@ struct rc_pair_instruction_source * rc_pair_get_src( return NULL; } } + +int rc_pair_get_src_index( + struct rc_pair_instruction * pair_inst, + struct rc_pair_instruction_source * src) +{ + int i; + for (i = 0; i < 3; i++) { + if (&pair_inst->RGB.Src[i] == src + || &pair_inst->Alpha.Src[i] == src) { + return i; + } + } + return -1; +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h index 82d7815aa78..a957ea9f7a0 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h @@ -114,6 +114,10 @@ void rc_pair_foreach_source_that_rgb_reads( struct rc_pair_instruction_source * rc_pair_get_src( struct rc_pair_instruction * pair_inst, struct rc_pair_instruction_arg * arg); + +int rc_pair_get_src_index( + struct rc_pair_instruction * pair_inst, + struct rc_pair_instruction_source * src); /*@}*/ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_variable.c b/src/mesa/drivers/dri/r300/compiler/radeon_variable.c new file mode 100644 index 00000000000..91a4d45dc0d --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_variable.c @@ -0,0 +1,434 @@ +/* + * Copyright 2011 Tom Stellard + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 "radeon_variable.h" + +#include "memory_pool.h" +#include "radeon_compiler_util.h" +#include "radeon_dataflow.h" +#include "radeon_list.h" +#include "radeon_opcodes.h" +#include "radeon_program.h" + +/** + * Rewrite the index and writemask for the destination register of var + * and its friends to new_index and new_writemask. This function also takes + * care of rewriting the swizzles for the sources of var. + */ +void rc_variable_change_dst( + struct rc_variable * var, + unsigned int new_index, + unsigned int new_writemask) +{ + unsigned int new_idx, old_idx; + unsigned int conversion_swizzle = rc_init_swizzle(RC_SWIZZLE_UNUSED, 0); + struct rc_variable * var_ptr; + struct rc_list * readers; + unsigned int old_mask = rc_variable_writemask_sum(var); + + new_idx = 0; + for (old_idx = 0; old_idx < 4; old_idx++) { + if (!GET_BIT(old_mask, old_idx)) + continue; + for ( ; new_idx < 4; new_idx++) { + if (GET_BIT(new_writemask, new_idx)) { + SET_SWZ(conversion_swizzle, old_idx, new_idx); + new_idx++; + break; + } + } + } + + for (var_ptr = var; var_ptr; var_ptr = var_ptr->Friend) { + if (var_ptr->Inst->Type == RC_INSTRUCTION_NORMAL) { + rc_normal_rewrite_writemask(var_ptr->Inst, + conversion_swizzle); + var_ptr->Inst->U.I.DstReg.Index = new_index; + } else { + struct rc_pair_sub_instruction * sub; + if (var_ptr->Dst.WriteMask == RC_MASK_W) { + assert(new_writemask & RC_MASK_W); + sub = &var_ptr->Inst->U.P.Alpha; + } else { + sub = &var_ptr->Inst->U.P.RGB; + rc_pair_rewrite_writemask(sub, + conversion_swizzle); + } + sub->DestIndex = new_index; + } + } + + readers = rc_variable_readers_union(var); + + for ( ; readers; readers = readers->Next) { + struct rc_reader * reader = readers->Item; + if (reader->Inst->Type == RC_INSTRUCTION_NORMAL) { + reader->U.I.Src->Index = new_index; + reader->U.I.Src->Swizzle = rc_rewrite_swizzle( + reader->U.I.Src->Swizzle, conversion_swizzle); + } else { + struct rc_pair_instruction * pair_inst = + &reader->Inst->U.P; + unsigned int src_type = rc_source_type_swz( + reader->U.P.Arg->Swizzle); + + int src_index = reader->U.P.Arg->Source; + if (src_index == RC_PAIR_PRESUB_SRC) { + src_index = rc_pair_get_src_index( + pair_inst, reader->U.P.Src); + } + /* Try to delete the old src, it is OK if this fails, + * because rc_pair_alloc_source might be able to + * find a source the ca be reused. + */ + if (rc_pair_remove_src(reader->Inst, src_type, + src_index, old_mask)) { + /* Reuse the source index of the source that + * was just deleted and set its register + * index. We can't use rc_pair_alloc_source + * for this becuase it might return a source + * index that is already being used. */ + if (src_type & RC_SOURCE_RGB) { + pair_inst->RGB.Src[src_index] + .Used = 1; + pair_inst->RGB.Src[src_index] + .Index = new_index; + pair_inst->RGB.Src[src_index] + .File = RC_FILE_TEMPORARY; + } + if (src_type & RC_SOURCE_ALPHA) { + pair_inst->Alpha.Src[src_index] + .Used = 1; + pair_inst->Alpha.Src[src_index] + .Index = new_index; + pair_inst->Alpha.Src[src_index] + .File = RC_FILE_TEMPORARY; + } + } else { + src_index = rc_pair_alloc_source( + &reader->Inst->U.P, + src_type & RC_SOURCE_RGB, + src_type & RC_SOURCE_ALPHA, + RC_FILE_TEMPORARY, + new_index); + if (src_index < 0) { + rc_error(var->C, "Rewrite of inst %u failed " + "Can't allocate source for " + "Inst %u src_type=%x " + "new_index=%u new_mask=%u\n", + var->Inst->IP, reader->Inst->IP, src_type, new_index, new_writemask); + continue; + } + } + reader->U.P.Arg->Swizzle = rc_rewrite_swizzle( + reader->U.P.Arg->Swizzle, conversion_swizzle); + if (reader->U.P.Arg->Source != RC_PAIR_PRESUB_SRC) { + reader->U.P.Arg->Source = src_index; + } + } + } +} + +/** + * Compute the live intervals for var and its friends. + */ +void rc_variable_compute_live_intervals(struct rc_variable * var) +{ + while(var) { + unsigned int i; + unsigned int start = var->Inst->IP; + + for (i = 0; i < var->ReaderCount; i++) { + unsigned int chan; + unsigned int mask = var->Readers[i].WriteMask; + for (chan = 0; chan < 4; chan++) { + if ((mask >> chan) & 0x1) { + var->Live[chan].Start = start; + var->Live[chan].End = + var->Readers[i].Inst->IP; + var->Live[chan].Used = 1; + } + } + } + var = var->Friend; + } +} + +/** + * @return 1 if a and b share a reader + * @return 0 if they do not + */ +static unsigned int readers_intersect( + struct rc_variable * a, + struct rc_variable * b) +{ + unsigned int a_index, b_index; + for (a_index = 0; a_index < a->ReaderCount; a_index++) { + struct rc_reader reader_a = a->Readers[a_index]; + for (b_index = 0; b_index < b->ReaderCount; b_index++) { + struct rc_reader reader_b = b->Readers[b_index]; + if (reader_a.Inst->Type == RC_INSTRUCTION_NORMAL + && reader_b.Inst->Type == RC_INSTRUCTION_NORMAL + && reader_a.U.I.Src == reader_b.U.I.Src) { + + return 1; + } + + if (reader_a.Inst->Type == RC_INSTRUCTION_PAIR + && reader_b.Inst->Type == RC_INSTRUCTION_PAIR + && reader_a.U.P.Arg == reader_b.U.P.Arg) { + + return 1; + } + } + } + return 0; +} + +void rc_variable_add_friend( + struct rc_variable * var, + struct rc_variable * friend) +{ + while(var->Friend) { + var = var->Friend; + } + var->Friend = friend; +} + +struct rc_variable * rc_variable( + struct radeon_compiler * c, + unsigned int DstFile, + unsigned int DstIndex, + unsigned int DstWriteMask, + struct rc_reader_data * reader_data) +{ + struct rc_variable * new = + memory_pool_malloc(&c->Pool, sizeof(struct rc_variable)); + memset(new, 0, sizeof(struct rc_variable)); + new->C = c; + new->Dst.File = DstFile; + new->Dst.Index = DstIndex; + new->Dst.WriteMask = DstWriteMask; + if (reader_data) { + new->Inst = reader_data->Writer; + new->ReaderCount = reader_data->ReaderCount; + new->Readers = reader_data->Readers; + } + return new; +} + +static void get_variable_helper( + struct rc_list ** aborted_list, + struct rc_list ** variable_list, + unsigned int aborted, + struct rc_variable * variable) +{ + if (aborted) { + rc_list_add(aborted_list, rc_list(&variable->C->Pool, variable)); + } else { + rc_list_add(variable_list, rc_list(&variable->C->Pool, variable)); + } +} + +static void get_variable_pair_helper( + struct rc_list ** aborted_list, + struct rc_list ** variable_list, + struct radeon_compiler * c, + struct rc_instruction * inst, + struct rc_pair_sub_instruction * sub_inst) +{ + struct rc_reader_data reader_data; + struct rc_variable * new_var; + rc_register_file file; + unsigned int writemask; + + if (sub_inst->Opcode == RC_OPCODE_NOP) { + return; + } + memset(&reader_data, 0, sizeof(struct rc_reader_data)); + rc_get_readers_sub(c, inst, sub_inst, &reader_data, NULL, NULL, NULL); + + if (reader_data.ReaderCount == 0) { + return; + } + + if (sub_inst->WriteMask) { + file = RC_FILE_TEMPORARY; + writemask = sub_inst->WriteMask; + } else if (sub_inst->OutputWriteMask) { + file = RC_FILE_OUTPUT; + writemask = sub_inst->OutputWriteMask; + } else { + writemask = 0; + file = RC_FILE_NONE; + } + new_var = rc_variable(c, file, sub_inst->DestIndex, writemask, + &reader_data); + get_variable_helper(aborted_list, variable_list, reader_data.Abort, + new_var); +} + +/** + * Generate a list of variables used by the shader program. Each instruction + * that writes to a register is considered a variable. The struct rc_variable + * data structure includes a list of readers and is essentially a + * definition-use chain. Any two variables that share a reader are considered + * "friends" and they are linked together via the Friend attribute. + */ +struct rc_list * rc_get_variables(struct radeon_compiler * c) +{ + struct rc_instruction * inst; + struct rc_list * aborted_list = NULL; + struct rc_list * variable_list = NULL; + struct rc_list * var_ptr; + struct rc_list * search_ptr; + + for (inst = c->Program.Instructions.Next; + inst != &c->Program.Instructions; + inst = inst->Next) { + struct rc_reader_data reader_data; + struct rc_variable * new_var; + memset(&reader_data, 0, sizeof(reader_data)); + + if (inst->Type == RC_INSTRUCTION_NORMAL) { + rc_get_readers(c, inst, &reader_data, NULL, NULL, NULL); + if (reader_data.ReaderCount == 0) { + continue; + } + new_var = rc_variable(c, inst->U.I.DstReg.File, + inst->U.I.DstReg.Index, + inst->U.I.DstReg.WriteMask, &reader_data); + get_variable_helper(&aborted_list, &variable_list, + reader_data.Abort, new_var); + } else { + get_variable_pair_helper(&aborted_list, &variable_list, + c, inst, &inst->U.P.RGB); + get_variable_pair_helper(&aborted_list, &variable_list, + c, inst, &inst->U.P.Alpha); + } + } + + /* The aborted_list contains a list of variables that might share a + * reader with another variable. We need to search through this list + * and pair together variables that do share the same reader. + */ + while (aborted_list) { + struct rc_list * search_ptr_next; + var_ptr = aborted_list; + + search_ptr = var_ptr->Next; + while(search_ptr) { + search_ptr_next = search_ptr->Next; + if (readers_intersect(var_ptr->Item, search_ptr->Item)){ + rc_list_remove(&aborted_list, search_ptr); + rc_variable_add_friend(var_ptr->Item, + search_ptr->Item); + } + search_ptr = search_ptr_next; + } + rc_list_remove(&aborted_list, var_ptr); + rc_list_add(&variable_list, rc_list( + &((struct rc_variable*)(var_ptr->Item))->C->Pool, + var_ptr->Item)); + } + return variable_list; +} + +/** + * @return The bitwise or of the writemasks of a variable and all of its + * friends. + */ +unsigned int rc_variable_writemask_sum(struct rc_variable * var) +{ + unsigned int writemask = 0; + while(var) { + writemask |= var->Dst.WriteMask; + var = var->Friend; + } + return writemask; +} + +/* + * @return A list of readers for a variable and its friends. Readers + * that read from two different variable friends are only included once in + * this list. + */ +struct rc_list * rc_variable_readers_union(struct rc_variable * var) +{ + struct rc_list * list = NULL; + while (var) { + unsigned int i; + for (i = 0; i < var->ReaderCount; i++) { + struct rc_list * temp; + struct rc_reader * a = &var->Readers[i]; + unsigned int match = 0; + for (temp = list; temp; temp = temp->Next) { + struct rc_reader * b = temp->Item; + if (a->Inst->Type != b->Inst->Type) { + continue; + } + if (a->Inst->Type == RC_INSTRUCTION_NORMAL) { + if (a->U.I.Src == b->U.I.Src) { + match = 1; + break; + } + } + if (a->Inst->Type == RC_INSTRUCTION_PAIR) { + if (a->U.P.Arg == b->U.P.Arg + && a->U.P.Src == b->U.P.Src) { + match = 1; + break; + } + } + } + if (match) { + continue; + } + rc_list_add(&list, rc_list(&var->C->Pool, a)); + } + var = var->Friend; + } + return list; +} + +void rc_variable_print(struct rc_variable * var) +{ + unsigned int i; + while (var) { + fprintf(stderr, "%u: TEMP[%u].%u: ", + var->Inst->IP, var->Dst.Index, var->Dst.WriteMask); + for (i = 0; i < 4; i++) { + fprintf(stderr, "chan %u: start=%u end=%u ", i, + var->Live[i].Start, var->Live[i].End); + } + fprintf(stderr, "%u readers\n", var->ReaderCount); + if (var->Friend) { + fprintf(stderr, "Friend: \n\t"); + } + var = var->Friend; + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_variable.h b/src/mesa/drivers/dri/r300/compiler/radeon_variable.h new file mode 100644 index 00000000000..b8fbcaa4029 --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_variable.h @@ -0,0 +1,84 @@ +/* + * Copyright 2011 Tom Stellard + * + * All Rights Reserved. + * + * 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 the rights to use, copy, modify, merge, publish, + * distribute, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 RADEON_VARIABLE_H +#define RADEON_VARIABLE_H + +#include "radeon_compiler.h" + +struct radeon_compiler; +struct rc_list; +struct rc_reader_data; +struct rc_readers; + +struct live_intervals { + int Start; + int End; + int Used; +}; + +struct rc_variable { + struct radeon_compiler * C; + struct rc_dst_register Dst; + + struct rc_instruction * Inst; + unsigned int ReaderCount; + struct rc_reader * Readers; + struct live_intervals Live[4]; + + /* A friend is a variable that shares a reader with another variable. + */ + struct rc_variable * Friend; +}; + +void rc_variable_change_dst( + struct rc_variable * var, + unsigned int new_index, + unsigned int new_writemask); + +void rc_variable_compute_live_intervals(struct rc_variable * var); + +void rc_variable_add_friend( + struct rc_variable * var, + struct rc_variable * friend); + +struct rc_variable * rc_variable( + struct radeon_compiler * c, + unsigned int DstFile, + unsigned int DstIndex, + unsigned int DstWriteMask, + struct rc_reader_data * reader_data); + +struct rc_list * rc_get_variables(struct radeon_compiler * c); + +unsigned int rc_variable_writemask_sum(struct rc_variable * var); + +struct rc_list * rc_variable_readers_union(struct rc_variable * var); + +void rc_variable_print(struct rc_variable * var); + +#endif /* RADEON_VARIABLE_H */ -- cgit v1.2.3 From 899b786b193ec4ee3eadd7c9c33c610cc115a3fe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 30 Apr 2011 20:40:42 +0200 Subject: i915g: enable X-tiling for s3tc textures Tested-by: Christopher Egert Signed-off-by: Daniel Vetter --- src/gallium/drivers/i915/i915_resource_texture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 7816925d230..e05b059706d 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -181,8 +181,7 @@ i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex) return I915_TILE_NONE; if (util_format_is_s3tc(tex->b.b.format)) - /* XXX X-tiling might make sense */ - return I915_TILE_NONE; + return I915_TILE_X; if (is->debug.use_blitter) return I915_TILE_X; -- cgit v1.2.3 From e9d2ef79de4d4a28365c5283dd025e182a0e7d6f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 1 May 2011 00:04:06 +0200 Subject: r600g: remove FIXME comment DONTBLOCK is correctly handled in r600_bo_map. --- src/gallium/drivers/r600/r600_buffer.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index b89901d6248..9f545f14699 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -87,9 +87,6 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, if (rbuffer->r.b.user_ptr) return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x; - if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { - /* FIXME */ - } if (transfer->usage & PIPE_TRANSFER_WRITE) { write = 1; } -- cgit v1.2.3 From 56e83b4aa245c2e22b3b4cf17b79651b9e03dffb Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 1 May 2011 13:25:52 +0200 Subject: r600g: remove set-but-unused variable --- src/gallium/drivers/r600/r600_buffer.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 9f545f14699..72f352df3c3 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -81,15 +81,11 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource); - int write = 0; uint8_t *data; if (rbuffer->r.b.user_ptr) return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x; - if (transfer->usage & PIPE_TRANSFER_WRITE) { - write = 1; - } data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe); if (!data) return NULL; -- cgit v1.2.3 From 425cfa139b36b4ac01db248de3dc8ad4799cec5c Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 1 May 2011 14:01:59 +0200 Subject: rbug: remove set-but-unused variables --- src/gallium/auxiliary/rbug/rbug_context.c | 7 ------- src/gallium/auxiliary/rbug/rbug_core.c | 14 -------------- src/gallium/auxiliary/rbug/rbug_texture.c | 7 ------- 3 files changed, 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rbug/rbug_context.c b/src/gallium/auxiliary/rbug/rbug_context.c index 36824058c7d..1188dd966e4 100644 --- a/src/gallium/auxiliary/rbug/rbug_context.c +++ b/src/gallium/auxiliary/rbug/rbug_context.c @@ -470,9 +470,6 @@ int rbug_send_context_draw_blocked(struct rbug_connection *__con, struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_context_list *ret; if (!header) @@ -480,9 +477,6 @@ struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_h if (header->opcode != (int32_t)RBUG_OP_CONTEXT_LIST) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -490,7 +484,6 @@ struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_h ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_core.c b/src/gallium/auxiliary/rbug/rbug_core.c index 1d47d13c9f3..514a10932bc 100644 --- a/src/gallium/auxiliary/rbug/rbug_core.c +++ b/src/gallium/auxiliary/rbug/rbug_core.c @@ -226,9 +226,6 @@ int rbug_send_error_reply(struct rbug_connection *__con, struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_noop *ret; if (!header) @@ -236,9 +233,6 @@ struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) if (header->opcode != (int32_t)RBUG_OP_NOOP) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -246,15 +240,11 @@ struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_ping *ret; if (!header) @@ -262,9 +252,6 @@ struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) if (header->opcode != (int32_t)RBUG_OP_PING) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -272,7 +259,6 @@ struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_texture.c b/src/gallium/auxiliary/rbug/rbug_texture.c index 2ad577915e8..017c8d0b99b 100644 --- a/src/gallium/auxiliary/rbug/rbug_texture.c +++ b/src/gallium/auxiliary/rbug/rbug_texture.c @@ -410,9 +410,6 @@ int rbug_send_texture_read_reply(struct rbug_connection *__con, struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_texture_list *ret; if (!header) @@ -420,9 +417,6 @@ struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_h if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -430,7 +424,6 @@ struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_h ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } -- cgit v1.2.3 From cacdc42e36d27d49b6deb0f1ea57f564ad31c88f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 1 May 2011 14:12:47 +0200 Subject: draw: remove set-but-unused variable --- src/gallium/auxiliary/draw/draw_vertex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index a4f5e882c0a..a1b2b8ff975 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -60,10 +60,9 @@ draw_compute_vertex_size(struct vertex_info *vinfo) void draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { - unsigned i, j; + unsigned i; for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->attrib[i].src_index; switch (vinfo->attrib[i].emit) { case EMIT_OMIT: debug_printf("EMIT_OMIT:"); -- cgit v1.2.3 From 08520bdea2db623044e2e46c21402039fd8fe5e2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 1 May 2011 14:13:09 +0200 Subject: tgsi: remove set-but-unused variables --- src/gallium/auxiliary/tgsi/tgsi_build.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index d2cb98e84af..269940ec840 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -917,7 +917,6 @@ tgsi_build_full_instruction( for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; struct tgsi_dst_register *dst_register; - struct tgsi_token *prev_token; if( maxsize <= size ) return 0; @@ -932,7 +931,6 @@ tgsi_build_full_instruction( reg->Register.Index, instruction, header ); - prev_token = (struct tgsi_token *) dst_register; if( reg->Register.Indirect ) { struct tgsi_src_register *ind; @@ -1001,7 +999,6 @@ tgsi_build_full_instruction( for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { const struct tgsi_full_src_register *reg = &full_inst->Src[i]; struct tgsi_src_register *src_register; - struct tgsi_token *prev_token; if( maxsize <= size ) return 0; @@ -1021,7 +1018,6 @@ tgsi_build_full_instruction( reg->Register.Index, instruction, header ); - prev_token = (struct tgsi_token *) src_register; if( reg->Register.Indirect ) { struct tgsi_src_register *ind; -- cgit v1.2.3 From 72c6a748b9ffdaa893f82faf911f22a241a5e4f5 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 01:10:19 +0200 Subject: Revert "r600g: truncate point sampled texture coordinates" This reverts commit 1dc204d145dc8c0b19473a7814c201a8954b6274. MC_COORD_TRUNCATE is for MPEG and produces quite an interesting behavior on regular textures. Anyway that commit broke filtering in demos/cubemap. --- src/gallium/drivers/r600/evergreen_state.c | 6 ------ src/gallium/drivers/r600/r600_state.c | 9 +-------- 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 89a8d942a54..e316ffdfe10 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -307,16 +307,11 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; - uint32_t coord_trunc = 0; if (rstate == NULL) { return NULL; } - if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) || - (state->min_img_filter == PIPE_TEX_FILTER_NEAREST)) - coord_trunc = 1; - rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -335,7 +330,6 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | - S_03C008_MC_COORD_TRUNCATE(coord_trunc) | S_03C008_TYPE(1), 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 1e3f81548a2..f23c19628de 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -366,16 +366,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; - uint32_t coord_trunc = 0; if (rstate == NULL) { return NULL; } - if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) || - (state->min_img_filter == PIPE_TEX_FILTER_NEAREST)) - coord_trunc = 1; - rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -392,9 +387,7 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, - S_03C008_MC_COORD_TRUNCATE(coord_trunc) | - S_03C008_TYPE(1), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_TYPE(1), 0xFFFFFFFF, NULL); if (uc.ui) { r600_pipe_state_add_reg(rstate, R_00A400_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color[0]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color[1]), 0xFFFFFFFF, NULL); -- cgit v1.2.3 From 0d5ceb5891185600e73e10db9832207fdbaaab80 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 01:43:33 +0200 Subject: r600g: remove some FIXME comments All texture LOD tests pass. --- src/gallium/drivers/r600/evergreen_state.c | 1 - src/gallium/drivers/r600/r600_state.c | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index e316ffdfe10..e3cbf59a2f7 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -323,7 +323,6 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); - /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)), diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index f23c19628de..3284f92f410 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -382,7 +382,6 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); - /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | -- cgit v1.2.3 From 16549885625ceee16a8616042b24db73f937ea6b Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 25 Apr 2011 23:57:11 +0200 Subject: targets/xorg-nouveau: add libnvc0.a to nouveau libs --- src/gallium/targets/xorg-nouveau/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/targets/xorg-nouveau/Makefile b/src/gallium/targets/xorg-nouveau/Makefile index 2fcd9ffb7d6..5a2cdb1b0ef 100644 --- a/src/gallium/targets/xorg-nouveau/Makefile +++ b/src/gallium/targets/xorg-nouveau/Makefile @@ -15,6 +15,7 @@ DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/rbug/librbug.a -- cgit v1.2.3 From eb0a9e9a5a3e1d86bce24cf4839be60ce72d89e3 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 25 Apr 2011 23:59:40 +0200 Subject: targets/xorg-nouveau: load nouveau_dri.so instead of i915_dri.so --- src/gallium/targets/xorg-nouveau/nouveau_xorg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c index 699af09029f..f0d64925c73 100644 --- a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c +++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c @@ -136,7 +136,7 @@ nouveau_xorg_pci_probe(DriverPtr driver, NULL, NULL, NULL, NULL, NULL); if (scrn != NULL) { scrn->driverVersion = 1; - scrn->driverName = "i915"; + scrn->driverName = "nouveau"; scrn->name = "modesetting"; scrn->Probe = NULL; -- cgit v1.2.3 From 951244c4cde0855bcdd9b66f1290de1227f4b827 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 1 May 2011 23:51:10 +0200 Subject: st/xorg: fix typos --- src/gallium/state_trackers/xorg/xorg_driver.c | 6 +++--- src/gallium/state_trackers/xorg/xorg_exa.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 19e9bf84656..063ae92f6be 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -831,9 +831,9 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "#################################\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Useful debugging info follows #\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "#################################\n"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n", ms->screen ? "Gallium3D" : "libkms"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n", diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index e7d6a93e5ca..e1172db3d20 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -336,7 +336,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) return FALSE; if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); if (!priv || !priv->tex) XORG_FALLBACK("%s", !priv ? "!priv" : "!priv->tex"); -- cgit v1.2.3 From 5815d06ac5a49a99a3659ba970a2f8df92c87a57 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 2 May 2011 09:36:49 +0200 Subject: st/xorg: Fix two more instances of typo 'accle'. --- src/gallium/state_trackers/xorg/xorg_exa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index e1172db3d20..91c206f1872 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -414,7 +414,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, return FALSE; if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); if (!priv || !priv->tex) XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex"); @@ -622,7 +622,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, pDstPicture ? render_format_name(pDstPicture->format) : "none"); #endif if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); priv = exaGetPixmapDriverPrivate(pDst); if (!priv || !priv->tex) -- cgit v1.2.3 From 929b3d82334e217641c3f39e7914a90dadc6e6b2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 11:39:47 +0200 Subject: r600g: remove some more FIXME comments --- src/gallium/drivers/r600/evergreen_state.c | 1 - src/gallium/drivers/r600/r600_state.c | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index e3cbf59a2f7..e325361b6c2 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -402,7 +402,6 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte array_mode = tmp->array_mode[0]; tile_type = tmp->tile_type; - /* FIXME properly handle first level != 0 */ r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, S_030000_DIM(r600_tex_dim(texture->target)) | S_030000_PITCH((pitch / 8) - 1) | diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 3284f92f410..1c27f880751 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -464,7 +464,6 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c depth = texture->array_size; } - /* FIXME properly handle first level != 0 */ r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, S_038000_DIM(r600_tex_dim(texture->target)) | S_038000_TILE_MODE(array_mode) | -- cgit v1.2.3 From ca6896ba1452687ee35791c7e48afae3b2b657fd Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 17:11:46 +0200 Subject: r600g: document some new evergreen formats --- src/gallium/drivers/r600/r600_formats.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_formats.h b/src/gallium/drivers/r600/r600_formats.h index c9af631da41..ae0bc432ad2 100644 --- a/src/gallium/drivers/r600/r600_formats.h +++ b/src/gallium/drivers/r600/r600_formats.h @@ -54,6 +54,9 @@ #define FMT_BC3 0x00000033 #define FMT_BC4 0x00000034 #define FMT_BC5 0x00000035 +#define FMT_BC6 0x00000036 +#define FMT_BC7 0x00000037 +#define FMT_32_AS_32_32_32_32 0x00000038 #define ENDIAN_NONE 0 #define ENDIAN_8IN16 1 -- cgit v1.2.3 From 02b352e2ace126e880d7df6a8c669e181b76e05f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 02:04:17 +0200 Subject: gallium: reorder fields of pipe_rasterizer_state to pack it more tightly sizeof(struct pipe_rasterizer_state): Before: 32 bytes After: 28 bytes Reviewed-by: Brian Paul --- src/gallium/include/pipe/p_state.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index f6ad4560f16..0c1f509a159 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -94,24 +94,21 @@ struct pipe_rasterizer_state unsigned poly_smooth:1; unsigned poly_stipple_enable:1; unsigned point_smooth:1; - unsigned sprite_coord_enable:PIPE_MAX_SHADER_OUTPUTS; unsigned sprite_coord_mode:1; /**< PIPE_SPRITE_COORD_ */ unsigned point_quad_rasterization:1; /** points rasterized as quads or points */ unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ unsigned multisample:1; /* XXX maybe more ms state in future */ unsigned line_smooth:1; unsigned line_stipple_enable:1; - unsigned line_stipple_factor:8; /**< [1..256] actually */ - unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; - /** + /** * Use the first vertex of a primitive as the provoking vertex for * flat shading. */ - unsigned flatshade_first:1; + unsigned flatshade_first:1; - /** + /** * When true, triangle rasterization uses (0.5, 0.5) pixel centers * for determining pixel ownership. * @@ -124,6 +121,11 @@ struct pipe_rasterizer_state */ unsigned gl_rasterization_rules:1; + unsigned line_stipple_factor:8; /**< [1..256] actually */ + unsigned line_stipple_pattern:16; + + unsigned sprite_coord_enable:PIPE_MAX_SHADER_OUTPUTS; + float line_width; float point_size; /**< used when no per-vertex size */ float offset_units; -- cgit v1.2.3 From 220abb7adf61872ddfb5b250be8085ee0fc2416d Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Mon, 2 May 2011 23:55:05 +0200 Subject: nv50,nvc0: advertise GL_FIXED vertex buffers as supported We'll handle them like f64 vertex buffers, by falling back to copying vertex data to the command buffer through translate. --- src/gallium/drivers/nv50/nv50_formats.c | 18 ++++++++++++++++++ src/gallium/drivers/nvc0/nvc0_formats.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_formats.c b/src/gallium/drivers/nv50/nv50_formats.c index c65189d0671..96ed9a7d6d4 100644 --- a/src/gallium/drivers/nv50/nv50_formats.c +++ b/src/gallium/drivers/nv50/nv50_formats.c @@ -571,4 +571,22 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = [PIPE_FORMAT_A8B8G8R8_UNORM] = { 0, B_(C3, C2, C1, C0, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW }, + + /* FIXED FORMATS - hw doesn't support these, convert on vbo push for now */ + + [PIPE_FORMAT_R32G32B32A32_FIXED] = { 0, + B_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32B32_FIXED] = { 0, + B_(C0, C1, C2, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32_FIXED] = { 0, + B_(C0, C1, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32_FIXED] = { 0, + B_(C0, ZERO, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), + VERTEX_BUFFER }, }; diff --git a/src/gallium/drivers/nvc0/nvc0_formats.c b/src/gallium/drivers/nvc0/nvc0_formats.c index 678e9b563ee..81077a7fa80 100644 --- a/src/gallium/drivers/nvc0/nvc0_formats.c +++ b/src/gallium/drivers/nvc0/nvc0_formats.c @@ -576,4 +576,22 @@ const struct nvc0_format nvc0_format_table[PIPE_FORMAT_COUNT] = [PIPE_FORMAT_A8B8G8R8_UNORM] = { 0, B_(C3, C2, C1, C0, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW }, + + /* FIXED FORMATS - hw doesn't support these, convert on vbo push for now */ + + [PIPE_FORMAT_R32G32B32A32_FIXED] = { 0, + B_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32B32_FIXED] = { 0, + B_(C0, C1, C2, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32_FIXED] = { 0, + B_(C0, C1, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32_FIXED] = { 0, + B_(C0, ZERO, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), + VERTEX_BUFFER }, }; -- cgit v1.2.3 From 320adb93a137a733da4b44f41e2d8ba01f164568 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 3 May 2011 11:54:07 +0200 Subject: r600g: set correct PIPE_CAP_MAX_COMBINED_SAMPLERS --- src/gallium/drivers/r600/r600_pipe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index e28d834dfee..9a5f172369d 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -404,11 +404,10 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) else return 14; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - /* FIXME allow this once infrastructure is there */ - return 16; case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - case PIPE_CAP_MAX_COMBINED_SAMPLERS: return 16; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 32; /* Render targets. */ case PIPE_CAP_MAX_RENDER_TARGETS: -- cgit v1.2.3 From 93754d8499934a4c38e9a934d0a934c1484b707c Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 3 May 2011 11:54:40 +0200 Subject: r600g: reorder caps --- src/gallium/drivers/r600/r600_pipe.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 9a5f172369d..779507cdc03 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -373,23 +373,24 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; + + /* Supported except the original R600. */ case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_FUNC: /* R600 doesn't support per-MRT blends */ - if (family == CHIP_R600) - return 0; - else - return 1; + return family == CHIP_R600 ? 0 : 1; - case PIPE_CAP_TGSI_INSTANCEID: - return 0; - - /* Unsupported features (boolean caps). */ + /* Unsupported features. */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - return 0; + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; case PIPE_CAP_ARRAY_TEXTURES: /* fix once the CS checker upstream is fixed */ @@ -414,14 +415,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* FIXME some r6xx are buggy and can only do 4 */ return 8; - /* Fragment coordinate conventions. */ - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; - /* Timer queries, present when the clock frequency is non zero. */ case PIPE_CAP_TIMER_QUERY: return r600_get_clock_crystal_freq(rscreen->radeon) != 0; -- cgit v1.2.3 From 5829332a9b814c5922f45b570c83565f8d35752d Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Tue, 3 May 2011 13:23:14 +0200 Subject: gallium/draw: Fix enum type taken by draw_get_shader_param(). Pointed out by clang: src/gallium/auxiliary/draw/draw_context.h:251:41: warning: implicit conversion from enumeration type 'enum pipe_cap' to different enumeration type 'enum pipe_shader_cap' [-Wconversion] return tgsi_exec_get_shader_param(param); ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~ --- src/gallium/auxiliary/draw/draw_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 7db75b71b43..5523e44563b 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -243,7 +243,7 @@ boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); static INLINE int -draw_get_shader_param(unsigned shader, enum pipe_cap param) +draw_get_shader_param(unsigned shader, enum pipe_shader_cap param) { switch(shader) { case PIPE_SHADER_VERTEX: -- cgit v1.2.3 From a8bbce8d6d894d482094fdac1e8823f838db6a94 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Tue, 3 May 2011 11:45:01 +0200 Subject: st/xorg: flush after loading the cursor We need cursor data to land in destination buffer before drmModeSetCursor. It fixes "cursor lag" on nv50. --- src/gallium/state_trackers/xorg/xorg_crtc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index d751ac18704..40b8434636b 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -210,6 +210,9 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) modesettingPtr ms = modesettingPTR(crtc->scrn); struct crtc_private *crtcp = crtc->driver_private; struct pipe_transfer *transfer; + struct pipe_fence_handle *fence = NULL; + struct pipe_context *ctx = ms->ctx; + struct pipe_screen *screen = ms->screen; if (!crtcp->cursor_tex) { struct pipe_resource templat; @@ -229,23 +232,28 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_KMS; - crtcp->cursor_tex = ms->screen->resource_create(ms->screen, - &templat); - ms->screen->resource_get_handle(ms->screen, crtcp->cursor_tex, &whandle); + crtcp->cursor_tex = screen->resource_create(screen, &templat); + screen->resource_get_handle(screen, crtcp->cursor_tex, &whandle); crtcp->cursor_handle = whandle.handle; } - transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex, + transfer = pipe_get_transfer(ctx, crtcp->cursor_tex, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, 64, 64); - ptr = ms->ctx->transfer_map(ms->ctx, transfer); + ptr = ctx->transfer_map(ctx, transfer); util_copy_rect(ptr, crtcp->cursor_tex->format, transfer->stride, 0, 0, 64, 64, (void*)image, 64 * 4, 0, 0); - ms->ctx->transfer_unmap(ms->ctx, transfer); - ms->ctx->transfer_destroy(ms->ctx, transfer); + ctx->transfer_unmap(ctx, transfer); + ctx->transfer_destroy(ctx, transfer); + ctx->flush(ctx, &fence); + + if (fence) { + screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE); + screen->fence_reference(screen, &fence, NULL); + } if (crtc->cursor_shown) drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, -- cgit v1.2.3 From c120d9d1cc9c03f73a8ac9d844bad7e7b1c4ea82 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 3 May 2011 15:26:07 -0400 Subject: r600g: add some new pci ids Signed-off-by: Alex Deucher --- src/gallium/winsys/r600/drm/radeon_pciid.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/radeon_pciid.c b/src/gallium/winsys/r600/drm/radeon_pciid.c index 146d6bd3100..455fb518fa9 100644 --- a/src/gallium/winsys/r600/drm/radeon_pciid.c +++ b/src/gallium/winsys/r600/drm/radeon_pciid.c @@ -177,6 +177,7 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x688A, CHIP_CYPRESS}, {0x1002, 0x6898, CHIP_CYPRESS}, {0x1002, 0x6899, CHIP_CYPRESS}, + {0x1002, 0x689b, CHIP_CYPRESS}, {0x1002, 0x689c, CHIP_HEMLOCK}, {0x1002, 0x689d, CHIP_HEMLOCK}, {0x1002, 0x689e, CHIP_CYPRESS}, @@ -187,7 +188,9 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x68b0, CHIP_JUNIPER}, {0x1002, 0x68b8, CHIP_JUNIPER}, {0x1002, 0x68b9, CHIP_JUNIPER}, + {0x1002, 0x68ba, CHIP_JUNIPER}, {0x1002, 0x68be, CHIP_JUNIPER}, + {0x1002, 0x68bf, CHIP_JUNIPER}, {0x1002, 0x68c0, CHIP_REDWOOD}, {0x1002, 0x68c1, CHIP_REDWOOD}, {0x1002, 0x68c8, CHIP_REDWOOD}, @@ -459,6 +462,7 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x6729, CHIP_BARTS}, {0x1002, 0x6738, CHIP_BARTS}, {0x1002, 0x6739, CHIP_BARTS}, + {0x1002, 0x673e, CHIP_BARTS}, {0x1002, 0x6740, CHIP_TURKS}, {0x1002, 0x6741, CHIP_TURKS}, {0x1002, 0x6742, CHIP_TURKS}, -- cgit v1.2.3 From fc30910c65e7ab078b900c29d2066e45d3edd8c2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 3 May 2011 18:56:20 -0600 Subject: i915g: add const qualifier to silence warning --- src/gallium/winsys/i915/drm/i915_drm_winsys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h index dae53c3e801..7f0d718bdb7 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_winsys.h +++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h @@ -18,7 +18,7 @@ struct i915_drm_winsys struct i915_winsys base; boolean dump_cmd; - char *dump_raw_file; + const char *dump_raw_file; boolean send_cmd; int fd; /**< Drm file discriptor */ -- cgit v1.2.3 From c636daa1455121d1db5b98bba09dd8004498c3b8 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Apr 2011 16:41:25 +0100 Subject: st/wgl: Cope with zero width/height windows. While ensuring the framebuffer area is never zero. --- src/gallium/state_trackers/wgl/stw_framebuffer.c | 50 ++++++++++++++++++------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c index d8b1440a688..4033365bfbe 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -117,13 +117,26 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb ) RECT window_rect; POINT client_pos; + /* + * Sanity checking. + */ + assert(fb->hWnd); - - /* Get the client area size. */ - GetClientRect( fb->hWnd, &client_rect ); + assert(fb->width && fb->height); + assert(fb->client_rect.right == fb->client_rect.left + fb->width); + assert(fb->client_rect.bottom == fb->client_rect.top + fb->height); + + /* + * Get the client area size. + */ + + if (!GetClientRect(fb->hWnd, &client_rect)) { + return; + } + assert(client_rect.left == 0); assert(client_rect.top == 0); - width = client_rect.right - client_rect.left; + width = client_rect.right - client_rect.left; height = client_rect.bottom - client_rect.top; if (width <= 0 || height <= 0) { @@ -138,7 +151,7 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb ) return; } - if(width != fb->width || height != fb->height) { + if (width != fb->width || height != fb->height) { fb->must_resize = TRUE; fb->width = width; fb->height = height; @@ -146,14 +159,14 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb ) client_pos.x = 0; client_pos.y = 0; - ClientToScreen(fb->hWnd, &client_pos); - - GetWindowRect(fb->hWnd, &window_rect); + if (ClientToScreen(fb->hWnd, &client_pos) && + GetWindowRect(fb->hWnd, &window_rect)) { + fb->client_rect.left = client_pos.x - window_rect.left; + fb->client_rect.top = client_pos.y - window_rect.top; + } - fb->client_rect.left = client_pos.x - window_rect.left; - fb->client_rect.top = client_pos.y - window_rect.top; - fb->client_rect.right = fb->client_rect.left + fb->width; - fb->client_rect.bottom = fb->client_rect.top + fb->height; + fb->client_rect.right = fb->client_rect.left + fb->width; + fb->client_rect.bottom = fb->client_rect.top + fb->height; #if 0 debug_printf("\n"); @@ -253,6 +266,19 @@ stw_framebuffer_create( fb->refcnt = 1; + /* + * Windows can be sometimes have zero width and or height, but we ensure + * a non-zero framebuffer size at all times. + */ + + fb->must_resize = TRUE; + fb->width = 1; + fb->height = 1; + fb->client_rect.left = 0; + fb->client_rect.top = 0; + fb->client_rect.right = fb->client_rect.left + fb->width; + fb->client_rect.bottom = fb->client_rect.top + fb->height; + stw_framebuffer_get_size(fb); pipe_mutex_init( fb->mutex ); -- cgit v1.2.3 From 9fbd708932d151b6ababbca1e23d01fb22154446 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 3 May 2011 19:09:53 +0100 Subject: st/wgl: Allow to create pbuffers bigger than the desktop. We use a hidden window for pbuffer contexts, but Windows limits window sizes to the desktop size by default. This means that creating a big pbuffer on a small resolution single monitor would truncate the pbuffer size to the desktop. This change overrides the windows maximum size, allow to create windows arbitrarily large. --- src/gallium/state_trackers/wgl/stw_ext_pbuffer.c | 26 +++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c index fb5d5e8b929..424d8daccb3 100644 --- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c +++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c @@ -40,6 +40,30 @@ #include "stw_framebuffer.h" +#define LARGE_WINDOW_SIZE 60000 + + +static LRESULT CALLBACK +WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MINMAXINFO *pMMI; + switch (uMsg) { + case WM_GETMINMAXINFO: + // Allow to create a window bigger than the desktop + pMMI = (MINMAXINFO *)lParam; + pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE; + pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE; + pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE; + pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE; + break; + default: + break; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + HPBUFFERARB WINAPI wglCreatePbufferARB(HDC _hDC, int iPixelFormat, @@ -109,7 +133,7 @@ wglCreatePbufferARB(HDC _hDC, wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.lpfnWndProc = DefWindowProc; + wc.lpfnWndProc = WndProc; wc.lpszClassName = "wglpbuffer"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); -- cgit v1.2.3 From ae7abf080b5c43e3736db2ed0d0e03ed59eb5ea4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 May 2011 20:45:39 +0200 Subject: r600g: do RV6xx base updates inline with state updates. This seems more in line with what the documentation suggests we should be doing. It doesn't fix the rv635 regression, though I thought it might, so it means I've no idea whats actually going wrong there. Signed-off-by: Dave Airlie Reviewed-by: Alex Deucher --- src/gallium/winsys/r600/drm/r600_hw_context.c | 75 ++++++++------------------- src/gallium/winsys/r600/drm/r600_priv.h | 1 + 2 files changed, 22 insertions(+), 54 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index e28ef1f162d..150485d3fe1 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -127,10 +127,20 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, block->pm4_bo_index[j] = block->nbo; block->pm4[block->pm4_ndwords++] = PKT3(PKT3_NOP, 0, 0); block->pm4[block->pm4_ndwords++] = 0x00000000; - block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags; - block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask; + if (reg[i+j].flags & REG_FLAG_RV6XX_SBU) { + block->reloc[block->nbo].flush_flags = 0; + block->reloc[block->nbo].flush_mask = 0; + } else { + block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags; + block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask; + } block->reloc[block->nbo].bo_pm4_index = block->pm4_ndwords - 1; } + if ((ctx->radeon->family > CHIP_R600) && + (ctx->radeon->family < CHIP_RV770) && reg[i+j].flags & REG_FLAG_RV6XX_SBU) { + block->pm4[block->pm4_ndwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); + block->pm4[block->pm4_ndwords++] = reg[i+j].flush_flags; + } } for (j = 0; j < n; j++) { if (reg[i+j].flush_flags) { @@ -197,7 +207,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028028_DB_STENCIL_CLEAR, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02802C_DB_DEPTH_CLEAR, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028040_CB_COLOR0_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028040_CB_COLOR0_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(0), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A0_CB_COLOR0_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028060_CB_COLOR0_SIZE, 0, 0, 0}, @@ -208,7 +218,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C0_CB_COLOR0_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028100_CB_COLOR0_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028044_CB_COLOR1_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028044_CB_COLOR1_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(1), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A4_CB_COLOR1_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028064_CB_COLOR1_SIZE, 0, 0, 0}, @@ -219,7 +229,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C4_CB_COLOR1_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028104_CB_COLOR1_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028048_CB_COLOR2_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028048_CB_COLOR2_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(2), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A8_CB_COLOR2_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028068_CB_COLOR2_SIZE, 0, 0, 0}, @@ -230,7 +240,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C8_CB_COLOR2_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028108_CB_COLOR2_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02804C_CB_COLOR3_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02804C_CB_COLOR3_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(3), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280AC_CB_COLOR3_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02806C_CB_COLOR3_SIZE, 0, 0, 0}, @@ -241,7 +251,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280CC_CB_COLOR3_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02810C_CB_COLOR3_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028050_CB_COLOR4_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028050_CB_COLOR4_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(4), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B0_CB_COLOR4_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028070_CB_COLOR4_SIZE, 0, 0, 0}, @@ -252,7 +262,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D0_CB_COLOR4_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028110_CB_COLOR4_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028054_CB_COLOR5_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028054_CB_COLOR5_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(5), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B4_CB_COLOR5_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028074_CB_COLOR5_SIZE, 0, 0, 0}, @@ -262,7 +272,7 @@ static const struct r600_reg r600_context_reg_list[] = { {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D4_CB_COLOR5_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028114_CB_COLOR5_MASK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028058_CB_COLOR6_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028058_CB_COLOR6_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(6), 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B8_CB_COLOR6_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028078_CB_COLOR6_SIZE, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028098_CB_COLOR6_VIEW, 0, 0, 0}, @@ -272,7 +282,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D8_CB_COLOR6_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028118_CB_COLOR6_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02805C_CB_COLOR7_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02805C_CB_COLOR7_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(7), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280BC_CB_COLOR7_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02807C_CB_COLOR7_SIZE, 0, 0, 0}, @@ -327,7 +337,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C48_PA_SC_AA_MASK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D2C_DB_SRESULTS_COMPARE_STATE1, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D44_DB_ALPHA_TO_MASK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02800C_DB_DEPTH_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02800C_DB_DEPTH_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_DEPTH, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028000_DB_DEPTH_SIZE, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028004_DB_DEPTH_VIEW, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, @@ -766,17 +776,6 @@ out_err: return r; } -static void rv6xx_context_surface_base_update(struct r600_context *ctx, - unsigned base_update_flags) -{ - /* need to emit surface base update on rv6xx */ - if ((ctx->radeon->family > CHIP_R600) && - (ctx->radeon->family < CHIP_RV770)) { - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); - ctx->pm4[ctx->pm4_cdwords++] = base_update_flags; - } -} - /* Flushes all surfaces */ void r600_context_flush_all(struct r600_context *ctx, unsigned flush_flags) { @@ -1192,7 +1191,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) unsigned ndwords = 7; struct r600_block *dirty_block = NULL; struct r600_block *next_block; - unsigned rv6xx_surface_base_update = 0; if (draw->indices) { ndwords = 11; @@ -1202,33 +1200,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) } } - /* rv6xx surface base update */ - if ((ctx->radeon->family > CHIP_R600) && - (ctx->radeon->family < CHIP_RV770)) { - struct r600_bo *cb[8]; - struct r600_bo *db; - - db = r600_context_reg_bo(ctx, R_02800C_DB_DEPTH_BASE); - cb[0] = r600_context_reg_bo(ctx, R_028040_CB_COLOR0_BASE); - cb[1] = r600_context_reg_bo(ctx, R_028044_CB_COLOR1_BASE); - cb[2] = r600_context_reg_bo(ctx, R_028048_CB_COLOR2_BASE); - cb[3] = r600_context_reg_bo(ctx, R_02804C_CB_COLOR3_BASE); - cb[4] = r600_context_reg_bo(ctx, R_028050_CB_COLOR4_BASE); - cb[5] = r600_context_reg_bo(ctx, R_028054_CB_COLOR5_BASE); - cb[6] = r600_context_reg_bo(ctx, R_028058_CB_COLOR6_BASE); - cb[7] = r600_context_reg_bo(ctx, R_02805C_CB_COLOR7_BASE); - for (int i = 0; i < 8; i++) { - if (cb[i]) { - rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_COLOR(i); - } - } - if (db) { - rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_DEPTH; - } - } - - /* XXX also need to update SURFACE_BASE_UPDATE_STRMOUT when we support it */ - /* queries need some special values */ if (ctx->num_query_running) { if (ctx->radeon->family >= CHIP_RV770) { @@ -1261,10 +1232,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) r600_context_block_emit_dirty(ctx, dirty_block); } - /* rv6xx surface base udpate */ - if (rv6xx_surface_base_update) - rv6xx_context_surface_base_update(ctx, rv6xx_surface_base_update); - /* draw packet */ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type; diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 27bdf2b1df8..f8363f9272b 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -64,6 +64,7 @@ struct radeon { #define REG_FLAG_NEED_BO 1 #define REG_FLAG_DIRTY_ALWAYS 2 +#define REG_FLAG_RV6XX_SBU 4 struct r600_reg { unsigned opcode; -- cgit v1.2.3 From f60235e73a5260f92630ce472e06d8c5c00414fb Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 5 May 2011 20:54:36 +0200 Subject: r600g: Match alpha ref precision to color format precision. This fixes piglit fbo-alphatest-formats on Evergreen. Signed-off-by: Henri Verbeet --- src/gallium/drivers/r600/evergreen_state.c | 20 +++++++++---- src/gallium/drivers/r600/r600_pipe.h | 10 ++++++- src/gallium/drivers/r600/r600_state.c | 11 ++++--- src/gallium/drivers/r600/r600_state_common.c | 44 +++++++++++++++++++++------- 4 files changed, 64 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index e325361b6c2..d60c153b482 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -143,14 +143,17 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx, static void *evergreen_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -190,6 +193,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -206,7 +210,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL); /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE, @@ -709,10 +712,17 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state /* we can only set the export size if any thing is snorm/unorm component is > 11 bits, if we aren't a float, sint or uint */ + /* FIXME: This should probably be the same for all CBs if we want + * useful alpha tests. */ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && - ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) + ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) { color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC); + rctx->export_16bpc = true; + } else { + rctx->export_16bpc = false; + } + rctx->alpha_ref_dirty = true; if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) { tile_type = rtex->tile_type; @@ -914,7 +924,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index ae2a57e1416..aa5ef4efb3b 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -97,6 +97,11 @@ struct r600_pipe_blend { unsigned cb_target_mask; }; +struct r600_pipe_dsa { + struct r600_pipe_state rstate; + unsigned alpha_ref; +}; + struct r600_vertex_element { unsigned count; @@ -186,6 +191,9 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; + bool export_16bpc; + unsigned alpha_ref; + bool alpha_ref_dirty; struct r600_textures_info ps_samplers; struct r600_pipe_fences fences; @@ -283,11 +291,11 @@ void *r600_create_vertex_elements(struct pipe_context *ctx, const struct pipe_vertex_element *elements); void r600_delete_vertex_element(struct pipe_context *ctx, void *state); void r600_bind_blend_state(struct pipe_context *ctx, void *state); +void r600_bind_dsa_state(struct pipe_context *ctx, void *state); void r600_bind_rs_state(struct pipe_context *ctx, void *state); void r600_delete_rs_state(struct pipe_context *ctx, void *state); void r600_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *state); -void r600_bind_state(struct pipe_context *ctx, void *state); void r600_delete_state(struct pipe_context *ctx, void *state); void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); void *r600_create_shader_state(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 1c27f880751..90c5ba2b31e 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -199,14 +199,17 @@ static void *r600_create_blend_state(struct pipe_context *ctx, static void *r600_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -246,6 +249,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -262,7 +266,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E0_SPI_FOG_FUNC_SCALE, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); @@ -964,7 +967,7 @@ void r600_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index cf605e11ade..de1b811ce89 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -86,6 +86,21 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state) r600_context_pipe_state_set(&rctx->ctx, rstate); } +void r600_bind_dsa_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_dsa *dsa = state; + struct r600_pipe_state *rstate; + + if (state == NULL) + return; + rstate = &dsa->rstate; + rctx->states[rstate->id] = rstate; + rctx->alpha_ref = dsa->alpha_ref; + rctx->alpha_ref_dirty = true; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + void r600_bind_rs_state(struct pipe_context *ctx, void *state) { struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; @@ -131,17 +146,6 @@ void r600_sampler_view_destroy(struct pipe_context *ctx, FREE(resource); } -void r600_bind_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (state == NULL) - return; - rctx->states[rstate->id] = rstate; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - void r600_delete_state(struct pipe_context *ctx, void *state) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -316,6 +320,23 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) free(shader); } +static void r600_update_alpha_ref(struct r600_pipe_context *rctx) +{ + unsigned alpha_ref = rctx->alpha_ref; + struct r600_pipe_state rstate; + + if (!rctx->alpha_ref_dirty) + return; + + rstate.nregs = 0; + if (rctx->export_16bpc) + alpha_ref &= ~0x1FFF; + r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); + + r600_context_pipe_state_set(&rctx->ctx, &rstate); + rctx->alpha_ref_dirty = false; +} + /* FIXME optimize away spi update when it's not needed */ static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim) { @@ -554,6 +575,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; } + r600_update_alpha_ref(rctx); r600_spi_update(rctx, draw.info.mode); mask = 0; -- cgit v1.2.3 From d116fe51c1aee3453290ac30ffe993bc131c53f7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 May 2011 03:17:16 -0400 Subject: r600g: fix cache flushes on r6xx r6xx asics have some problems with the surface sync logic for the CB and DB. It's recommended to use the event write interface for flushing the DB/CB caches rather than the sync packets. A single event write flush flushes all dst caches, so we only need one for all CBs and DB. Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=35312 Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600.h | 1 + src/gallium/winsys/r600/drm/r600_hw_context.c | 36 ++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 0b0df9d019b..33aa45088a8 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -235,6 +235,7 @@ struct r600_query { #define R600_CONTEXT_DRAW_PENDING (1 << 0) #define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1) +#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2) struct r600_context { struct radeon *radeon; diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 150485d3fe1..b8a8108fb12 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -797,19 +797,33 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, unsigned flush_mask, struct r600_bo *rbo) { struct radeon_bo *bo; + boolean use_event_flush = FALSE; + bo = rbo->bo; /* if bo has already been flushed */ if (!(~bo->last_flush & flush_flags)) { bo->last_flush &= flush_mask; return; } - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = flush_flags; - ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8; - ctx->pm4[ctx->pm4_cdwords++] = 0x00000000; - ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A; - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id; + + if ((ctx->radeon->family < CHIP_RV770) && + (G_0085F0_CB_ACTION_ENA(flush_flags) || + G_0085F0_DB_ACTION_ENA(flush_flags))) + use_event_flush = TRUE; + + if (use_event_flush && (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH)) { + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; + } else { + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = flush_flags; + ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8; + ctx->pm4[ctx->pm4_cdwords++] = 0x00000000; + ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A; + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id; + } bo->last_flush = (bo->last_flush | flush_flags) & flush_mask; } @@ -1119,6 +1133,7 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block * goto out; } + ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH; for (int j = 0; j < block->nreg; j++) { if (block->pm4_bo_index[j]) { /* find relocation */ @@ -1132,6 +1147,7 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block * block->reloc[id].bo); } } + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; memcpy(&ctx->pm4[ctx->pm4_cdwords], block->pm4, block->pm4_ndwords * 4); ctx->pm4_cdwords += block->pm4_ndwords; @@ -1155,6 +1171,7 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) { struct r600_bo *cb[8]; struct r600_bo *db; + int i; if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY)) return; @@ -1169,8 +1186,9 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) cb[6] = r600_context_reg_bo(ctx, R_028058_CB_COLOR6_BASE); cb[7] = r600_context_reg_bo(ctx, R_02805C_CB_COLOR7_BASE); + ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH; /* flush the color buffers */ - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { if (!cb[i]) continue; @@ -1182,7 +1200,7 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) if (db) { r600_context_bo_flush(ctx, S_0085F0_DB_ACTION_ENA(1), 0, db); } - + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY; } -- cgit v1.2.3 From 5066f7cd0e010db46b42f8f08a33c10cb34f8726 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 6 May 2011 08:40:08 +1000 Subject: r600g: add rv670 flushing workaround. Hopefully we can find out the proper fix for this, but for now this makes the fbo mipmap tests pass on my rv670 (x2 card). Signed-off-by: Dave Airlie --- src/gallium/winsys/r600/drm/r600_hw_context.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index b8a8108fb12..ff99143485b 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -812,6 +812,10 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, use_event_flush = TRUE; if (use_event_flush && (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH)) { + /* the rv670 seems to fail fbo-generatemipmap unless we flush the CB1 dest base ena */ + if (ctx->radeon->family == CHIP_RV670) + r600_context_flush_all(ctx, S_0085F0_CB1_DEST_BASE_ENA(1)); + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing); ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; -- cgit v1.2.3 From bf7a3ddca6fcc73eebdd9afdc45a485b38477bd9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 May 2011 18:45:55 -0400 Subject: r600g: further r6xx cache flush fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't emit sync packets for additional CBs or DB. Spotted by Fredrik Höglund. Signed-off-by: Alex Deucher --- src/gallium/winsys/r600/drm/r600_hw_context.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index ff99143485b..24538825273 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -797,7 +797,6 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, unsigned flush_mask, struct r600_bo *rbo) { struct radeon_bo *bo; - boolean use_event_flush = FALSE; bo = rbo->bo; /* if bo has already been flushed */ @@ -808,17 +807,16 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, if ((ctx->radeon->family < CHIP_RV770) && (G_0085F0_CB_ACTION_ENA(flush_flags) || - G_0085F0_DB_ACTION_ENA(flush_flags))) - use_event_flush = TRUE; - - if (use_event_flush && (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH)) { - /* the rv670 seems to fail fbo-generatemipmap unless we flush the CB1 dest base ena */ - if (ctx->radeon->family == CHIP_RV670) - r600_context_flush_all(ctx, S_0085F0_CB1_DEST_BASE_ENA(1)); - - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); - ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; + G_0085F0_DB_ACTION_ENA(flush_flags))) { + if (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH) { + /* the rv670 seems to fail fbo-generatemipmap unless we flush the CB1 dest base ena */ + if (ctx->radeon->family == CHIP_RV670) + r600_context_flush_all(ctx, S_0085F0_CB1_DEST_BASE_ENA(1)); + + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; + } } else { ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); ctx->pm4[ctx->pm4_cdwords++] = flush_flags; -- cgit v1.2.3 From 5939bc03bc15b9b1131463ffad04a7b2d987074d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 May 2011 18:54:03 -0400 Subject: r600g: fix up the rules for enabling SOURCE_FORMAT(EXPORT_NORM) Setting SOURCE_FORMAT to EXPORT_NORM is an optimization. Leaving SOURCE_FORMAT at 0 will work in all cases, but is less efficient. The conditions for the setting the EXPORT_NORM optimization are as follows: R600/RV6xx: BLEND_CLAMP is enabled BLEND_FLOAT32 is disabled 11-bit or smaller UNORM/SNORM/SRGB R7xx/evergreen: 11-bit or smaller UNORM/SNORM/SRGB 16-bit or smaller FLOAT Signed-off-by: Alex Deucher --- src/gallium/drivers/r600/evergreen_state.c | 16 +++++++++----- src/gallium/drivers/r600/r600_state.c | 35 +++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index d60c153b482..9757811e8b6 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -710,14 +710,20 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state S_028C70_ENDIAN(endian); - /* we can only set the export size if any thing is snorm/unorm component is > 11 bits, - if we aren't a float, sint or uint */ + /* EXPORT_NORM is an optimzation that can be enabled for better + * performance in certain cases. + * EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - 16-bit or smaller FLOAT + */ /* FIXME: This should probably be the same for all CBs if we want * useful alpha tests. */ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && - desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && - ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) { - color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC); + ((desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) || + (desc->channel[i].size < 17 && + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) { rctx->export_16bpc = true; } else { rctx->export_16bpc = false; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 90c5ba2b31e..3f979cf170f 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -770,11 +770,36 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta S_0280A0_NUMBER_TYPE(ntype) | S_0280A0_ENDIAN(endian); - /* on R600 this can't be set if BLEND_CLAMP isn't set, - if BLEND_FLOAT32 is set of > 11 bits in a UNORM or SNORM */ - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && - desc->channel[i].size < 12) - color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + /* EXPORT_NORM is an optimzation that can be enabled for better + * performance in certain cases + */ + if (rctx->family < CHIP_RV770) { + /* EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - BLEND_CLAMP is enabled + * - BLEND_FLOAT32 is disabled + */ + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && + (desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_0280A0_NUMBER_UINT && + ntype != V_0280A0_NUMBER_SINT) && + G_0280A0_BLEND_CLAMP(color_info) && + !G_0280A0_BLEND_FLOAT32(color_info)) + color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + } else { + /* EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - 16-bit or smaller FLOAT + */ + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && + ((desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_0280A0_NUMBER_UINT && ntype != V_0280A0_NUMBER_SINT) || + (desc->channel[i].size < 17 && + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) + color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + } r600_pipe_state_add_reg(rstate, R_028040_CB_COLOR0_BASE + cb * 4, -- cgit v1.2.3 From 31d27259b6d682f69866ace89ffaac5294e8bf62 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 5 May 2011 19:30:30 -0400 Subject: r600g: add back SOURCE_FORMAT setting that get accidently dropped Spotted by Henri Verbeet Signed-off-by: Alex Deucher --- src/gallium/drivers/r600/evergreen_state.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 9757811e8b6..3384a76803c 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -724,6 +724,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) || (desc->channel[i].size < 17 && desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) { + color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC); rctx->export_16bpc = true; } else { rctx->export_16bpc = false; -- cgit v1.2.3 From 8c3226be9004657db6c850b3164caf70deafa822 Mon Sep 17 00:00:00 2001 From: Kostas Georgiou Date: Fri, 6 May 2011 17:44:24 +0100 Subject: Add pci id for FirePro 2270 Signed-off-by: Kostas Georgiou --- src/egl/drivers/dri2/platform_drm.c | 1 + src/gallium/winsys/r600/drm/radeon_pciid.c | 1 + src/mesa/drivers/dri/radeon/radeon_chipset.h | 1 + src/mesa/drivers/dri/radeon/radeon_screen.c | 1 + 4 files changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index f50177574ec..68912e36732 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -488,6 +488,7 @@ const int r600_chip_ids[] = { 0x68E8, /* PCI_CHIP_CEDAR_68E8 */ 0x68E9, /* PCI_CHIP_CEDAR_68E9 */ 0x68F1, /* PCI_CHIP_CEDAR_68F1 */ + 0x68F2, /* PCI_CHIP_CEDAR_68F2 */ 0x68F8, /* PCI_CHIP_CEDAR_68F8 */ 0x68F9, /* PCI_CHIP_CEDAR_68F9 */ 0x68FE, /* PCI_CHIP_CEDAR_68FE */ diff --git a/src/gallium/winsys/r600/drm/radeon_pciid.c b/src/gallium/winsys/r600/drm/radeon_pciid.c index 455fb518fa9..35db37aa1fd 100644 --- a/src/gallium/winsys/r600/drm/radeon_pciid.c +++ b/src/gallium/winsys/r600/drm/radeon_pciid.c @@ -206,6 +206,7 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x68e8, CHIP_CEDAR}, {0x1002, 0x68e9, CHIP_CEDAR}, {0x1002, 0x68f1, CHIP_CEDAR}, + {0x1002, 0x68f2, CHIP_CEDAR}, {0x1002, 0x68f8, CHIP_CEDAR}, {0x1002, 0x68f9, CHIP_CEDAR}, {0x1002, 0x68fe, CHIP_CEDAR}, diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h index dd50202081a..9145023826e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_chipset.h +++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h @@ -406,6 +406,7 @@ #define PCI_CHIP_CEDAR_68E8 0x68E8 #define PCI_CHIP_CEDAR_68E9 0x68E9 #define PCI_CHIP_CEDAR_68F1 0x68F1 +#define PCI_CHIP_CEDAR_68F2 0x68F2 #define PCI_CHIP_CEDAR_68F8 0x68F8 #define PCI_CHIP_CEDAR_68F9 0x68F9 #define PCI_CHIP_CEDAR_68FE 0x68FE diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 3ee5050f6c4..6449229e088 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1106,6 +1106,7 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) case PCI_CHIP_CEDAR_68E8: case PCI_CHIP_CEDAR_68E9: case PCI_CHIP_CEDAR_68F1: + case PCI_CHIP_CEDAR_68F2: case PCI_CHIP_CEDAR_68F8: case PCI_CHIP_CEDAR_68F9: case PCI_CHIP_CEDAR_68FE: -- cgit v1.2.3 From 3b2bc4ac5b63429738687fd296180149b54e67a4 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Fri, 6 May 2011 19:06:20 +0200 Subject: gallium/xorg st/nv50: add PIPE_BIND_CURSOR We need to distinguish surfaces for mouse cursors from scanouts, because nv50 hardware display engine ignores tiling flags. --- src/gallium/drivers/nv50/nv50_miptree.c | 10 +++++++++- src/gallium/include/pipe/p_defines.h | 3 ++- src/gallium/state_trackers/xorg/xorg_crtc.c | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 9eeca05ada3..486b368ae98 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -158,6 +158,9 @@ nv50_miptree_create(struct pipe_screen *pscreen, tile_flags = 0x6000; break; default: + if (pt->bind & PIPE_BIND_CURSOR) + tile_flags = 0; + else if ((pt->bind & PIPE_BIND_SCANOUT) && util_format_get_blocksizebits(pt->format) == 32) tile_flags = 0x7a00; @@ -165,6 +168,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, tile_flags = 0x7000; break; } + if (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR)) + tile_flags |= NOUVEAU_BO_TILE_SCANOUT; /* For 3D textures, a mipmap is spanned by all the layers, for array * textures and cube maps, each layer contains its own mipmaps. @@ -176,7 +181,10 @@ nv50_miptree_create(struct pipe_screen *pscreen, unsigned blocksize = util_format_get_blocksize(pt->format); lvl->offset = mt->total_size; - lvl->tile_mode = get_tile_dims(nbx, nby, d); + + if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) + lvl->tile_mode = get_tile_dims(nbx, nby, d); + lvl->pitch = align(nbx * blocksize, NV50_TILE_PITCH(lvl->tile_mode)); mt->total_size += lvl->pitch * diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 431a7fb6695..5f7dd96516c 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -300,7 +300,8 @@ enum pipe_transfer_usage { #define PIPE_BIND_TRANSFER_WRITE (1 << 9) /* get_transfer */ #define PIPE_BIND_TRANSFER_READ (1 << 10) /* get_transfer */ #define PIPE_BIND_STREAM_OUTPUT (1 << 11) /* set_stream_output_buffers */ -#define PIPE_BIND_CUSTOM (1 << 16) /* state-tracker/winsys usages */ +#define PIPE_BIND_CURSOR (1 << 16) /* mouse cursor */ +#define PIPE_BIND_CUSTOM (1 << 17) /* state-tracker/winsys usages */ /* The first two flags above were previously part of the amorphous * TEXTURE_USAGE, most of which are now descriptions of the ways a diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 40b8434636b..0499ed1ea0b 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -221,6 +221,7 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) memset(&templat, 0, sizeof(templat)); templat.bind |= PIPE_BIND_RENDER_TARGET; templat.bind |= PIPE_BIND_SCANOUT; + templat.bind |= PIPE_BIND_CURSOR; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth0 = 1; -- cgit v1.2.3 From 3b20a89941fe9c7b5ad10e13cb035d0508c43bbd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 6 May 2011 13:18:00 -0400 Subject: r600g: avoid recursion in rv670 flush workaround Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=36914 Signed-off-by: Alex Deucher --- src/gallium/winsys/r600/drm/r600_hw_context.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 24538825273..0514bbeaba3 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -810,8 +810,13 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, G_0085F0_DB_ACTION_ENA(flush_flags))) { if (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH) { /* the rv670 seems to fail fbo-generatemipmap unless we flush the CB1 dest base ena */ - if (ctx->radeon->family == CHIP_RV670) - r600_context_flush_all(ctx, S_0085F0_CB1_DEST_BASE_ENA(1)); + if (ctx->radeon->family == CHIP_RV670) { + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = S_0085F0_CB1_DEST_BASE_ENA(1); /* CP_COHER_CNTL */ + ctx->pm4[ctx->pm4_cdwords++] = 0xffffffff; /* CP_COHER_SIZE */ + ctx->pm4[ctx->pm4_cdwords++] = 0; /* CP_COHER_BASE */ + ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A; /* POLL_INTERVAL */ + } ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing); ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); -- cgit v1.2.3 From a5f0a11477ae90f47f3adb59a93c5576dc8c7325 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 02:37:46 +0200 Subject: gallium: implement seamless cubemap extensions Reviewed-by: Brian Paul --- src/gallium/docs/source/cso/sampler.rst | 4 ++++ src/gallium/include/pipe/p_defines.h | 2 ++ src/gallium/include/pipe/p_state.h | 1 + src/mesa/state_tracker/st_atom_sampler.c | 3 +++ src/mesa/state_tracker/st_extensions.c | 8 ++++++++ 5 files changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst index 9bbb784de8e..648b5cc60ea 100644 --- a/src/gallium/docs/source/cso/sampler.rst +++ b/src/gallium/docs/source/cso/sampler.rst @@ -107,3 +107,7 @@ max_anisotropy Set to zero to disable anisotropic filtering. Any other setting enables anisotropic filtering, however it's not unexpected some drivers only will change their filtering with a setting of 2 and higher. +seamless_cube_map + If set, the bilinear filter of a cube map may take samples from adjacent + cube map faces when sampled near a texture border to produce a seamless + look. \ No newline at end of file diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 5f7dd96516c..c0c2a7c7fd2 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -466,6 +466,8 @@ enum pipe_cap { PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR = 44, PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL = 45, PIPE_CAP_MIXED_COLORBUFFER_FORMATS = 46, + PIPE_CAP_SEAMLESS_CUBE_MAP = 47, + PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE = 48, }; /* Shader caps not specific to any single stage */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 0c1f509a159..86ef255cd2e 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -269,6 +269,7 @@ struct pipe_sampler_state unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ unsigned max_anisotropy:6; + unsigned seamless_cube_map:1; float lod_bias; /**< LOD/lambda bias */ float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 56da010b385..e3d6cbb8e12 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -201,6 +201,9 @@ update_samplers(struct st_context *st) = st_compare_func_to_pipe(msamp->CompareFunc); } + sampler->seamless_cube_map = + st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; + st->state.num_samplers = su + 1; /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/ diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 030bbc797fb..ad8e6bb9ec9 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -595,4 +595,12 @@ void st_init_extensions(struct st_context *st) PIPE_BIND_SAMPLER_VIEW)) { ctx->Extensions.EXT_packed_float = GL_TRUE; } + + if (screen->get_param(screen, PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE)) { + ctx->Extensions.ARB_seamless_cube_map = GL_TRUE; + ctx->Extensions.AMD_seamless_cubemap_per_texture = GL_TRUE; + } + else if (screen->get_param(screen, PIPE_CAP_SEAMLESS_CUBE_MAP)) { + ctx->Extensions.ARB_seamless_cube_map = GL_TRUE; + } } -- cgit v1.2.3 From d931b0d8b360fc0222d295eca38aaee3e4e5d0be Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 2 May 2011 02:38:20 +0200 Subject: r600g: implement seamless_cube_map for evergreen The r600/r700 support will follow soon. --- src/gallium/drivers/r600/evergreen_state.c | 1 + src/gallium/drivers/r600/evergreend.h | 9 +++++++++ src/gallium/drivers/r600/r600_pipe.c | 5 +++++ 3 files changed, 15 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 3384a76803c..502f2663e8b 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -332,6 +332,7 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | + (state->seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) | S_03C008_TYPE(1), 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index de445b879a1..670606d9b07 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1194,6 +1194,15 @@ #define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 21) #define G_03C008_FORCE_DEGAMMA(x) (((x) >> 21) & 0x1) #define C_03C008_FORCE_DEGAMMA 0xFFDFFFFF +#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22) +#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f) +#define C_03C008_ANISO_BIAS (~(0x3f << 22)) +#define S_03C008_TRUNCATE_COORD(x) (((x) & 0x1) << 28) +#define G_03C008_TRUNCATE_COORD(x) (((x) >> 28) & 0x1) +#define C_03C008_TRUNCATE_COORD (~(1 << 28)) +#define S_03C008_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 29) +#define G_03C008_DISABLE_CUBE_WRAP(x) (((x) >> 29) & 0x1) +#define C_03C008_DISABLE_CUBE_WRAP (~(1 << 29)) #define S_03C008_TYPE(x) (((x) & 0x1) << 31) #define G_03C008_TYPE(x) (((x) >> 31) & 0x1) #define C_03C008_TYPE 0x7FFFFFFF diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 779507cdc03..080180ffea3 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -383,6 +383,11 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* R600 doesn't support per-MRT blends */ return family == CHIP_R600 ? 0 : 1; + /* Supported on Evergreen. */ + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return family >= CHIP_CEDAR ? 1 : 0; + /* Unsupported features. */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: -- cgit v1.2.3 From 531b12af35a832bcd8928a4919d76f8e9405cde0 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 6 May 2011 21:11:03 +0200 Subject: nv50,nvc0: activate seamless cube map filtering --- src/gallium/drivers/nv50/nv50_screen.c | 10 +++++++++- src/gallium/drivers/nv50/nv50_state.c | 30 ++++++++++++++++++++++++++++++ src/gallium/drivers/nvc0/nvc0_screen.c | 5 +++++ 3 files changed, 44 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index a2f13e3d703..4dad8599870 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -89,7 +89,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; + case PIPE_CAP_SEAMLESS_CUBE_MAP: + return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D; + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: @@ -417,6 +420,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1); OUT_RING (chan, 1); + if (tesla_class >= NVA0_3D) { + BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1); + OUT_RING (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); + } + BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 799f49619d2..8d75dd07c4d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -34,6 +34,36 @@ #include "nouveau/nouveau_gldefs.h" +/* Caveats: + * ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will + * use non-normalized coordinates, everything else won't + * (The relevant bit is in the TIC entry and not the TSC entry.) + * + * ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is + * always activated on NVA0 + + * (Give me the global bit, otherwise it's not worth the CPU work.) + * + * ! pipe_sampler_state.border_color is not swizzled according to the texture + * swizzle in pipe_sampler_view + * (This will be ugly with indirect independent texture/sampler access, + * we'd have to emulate the logic in the shader. GL doesn't have that, + * D3D doesn't have swizzle, if we knew what we were implementing we'd be + * good.) + * + * ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn + * + * ! pipe_rasterizer_state.flatshade_first also applies to QUADS + * (There's a GL query for that, forcing an exception is just ridiculous.) + * + * ! pipe_rasterizer_state.gl_rasterization_rules is ignored - pixel centers + * are always at half integer coordinates and the top-left rule applies + * (There does not seem to be a hardware switch for this.) + * + * ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC0 + * (The hardware only has 8 slots meant for TexCoord and we have to assign + * in advance to maintain elegant separate shader objects.) + */ + static INLINE uint32_t nv50_colormask(unsigned mask) { diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index ca0691d2aee..34bf0f0a2ad 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -74,7 +74,10 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: + case PIPE_CAP_SEAMLESS_CUBE_MAP: return 1; + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: @@ -441,6 +444,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RING (chan, 1); BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1); OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(TEX_MISC), 1); + OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); nvc0_magic_3d_init(chan); -- cgit v1.2.3 From d8e222d8877cf8b236bb24eb520521ff2e2ce32f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 6 May 2011 21:57:52 +0200 Subject: r300g: handle seamless_cube_map caps --- src/gallium/drivers/r300/r300_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index e8e16e08172..7a1366a4f8f 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -140,6 +140,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: return 0; /* SWTCL-only features. */ -- cgit v1.2.3