From fc427d23439a2702068209957f08990ea29fe21b Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 19 Feb 2010 04:23:06 +0100 Subject: r300g: remove L8_UNORM from colorbuffer formats Not renderable in OpenGL anyway. --- src/gallium/drivers/r300/r300_screen.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 5fa1ea0850e..036736ccc46 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -230,7 +230,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* Supported formats. */ /* Colorbuffer */ case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: -- cgit v1.2.3 From 71214c640c8b20020ead13897c76b9b6773126ba Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 19 Feb 2010 03:12:14 -0800 Subject: Revert "r300g: remove L8_UNORM from colorbuffer formats" This reverts commit fc427d23439a2702068209957f08990ea29fe21b. At least xorg uses this, and just because something is not used in OpenGL is *never* a valid reason to remove functionality from Gallium. If something lacks a test, go add a test, don't remove features. --- src/gallium/drivers/r300/r300_screen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 036736ccc46..5fa1ea0850e 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -230,6 +230,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* Supported formats. */ /* Colorbuffer */ case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: -- cgit v1.2.3 From f0c50345d13372e81805d9d176881b981a008123 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 19 Feb 2010 20:01:11 +0100 Subject: r300g: fix rendering into the L8 and A8 texture formats RB3D_COLORPITCH.COLORFORMAT.I8 stores the C2 component. --- src/gallium/drivers/r300/r300_state_inlines.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index a6083925326..c990be40b9e 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -422,11 +422,11 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) /* 8-bit outputs */ case PIPE_FORMAT_A8_UNORM: return R300_US_OUT_FMT_C4_8 | - R300_C0_SEL_A; + R300_C2_SEL_A; case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: return R300_US_OUT_FMT_C4_8 | - R300_C0_SEL_R; + R300_C2_SEL_R; /* R300_OUT_SIGN(x) */ default: debug_printf("r300: Implementation error: " -- cgit v1.2.3 From 2a30c268bdddf02300913c79ffbbb779c5399815 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 20 Feb 2010 18:52:20 +0100 Subject: r300g: re-enable SRGB formats Ouch. --- src/gallium/drivers/r300/r300_texture.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 153f4eebdaf..e2c10325fa9 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -208,7 +208,8 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) switch (desc->channel[0].type) { case UTIL_FORMAT_TYPE_UNSIGNED: case UTIL_FORMAT_TYPE_SIGNED: - if (!desc->channel[0].normalized) { + if (!desc->channel[0].normalized && + desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { return ~0; } -- cgit v1.2.3 From 5c14fd1743701776d128c2c1d25244f4de371ebe Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 20 Feb 2010 21:33:53 +0100 Subject: r300g: make r300_translate_texformat private Unlikely to increase performance from inlining. And partially expose it through r300_is_sampler_format_supported. --- src/gallium/drivers/r300/r300_screen.c | 2 +- src/gallium/drivers/r300/r300_texture.c | 244 ++++++++++++++++++++++++++++++++ src/gallium/drivers/r300/r300_texture.h | 235 +----------------------------- 3 files changed, 246 insertions(+), 235 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 5fa1ea0850e..0b3b96def79 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -222,7 +222,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* Check sampler format support. */ if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) && (is_r500 || !is_z24) && /* Z24 cannot be sampled from on non-r5xx. */ - r300_translate_texformat(format) != ~0) { + r300_is_sampler_format_supported(format)) { retval |= PIPE_TEXTURE_USAGE_SAMPLER; } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 34a49bec34c..5b7afc6eb9e 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -44,6 +44,250 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; +/* Translate a pipe_format into a useful texture format for sampling. + * + * Some special formats are translated directly using R300_EASY_TX_FORMAT, + * but the majority of them is translated in a generic way, automatically + * supporting all the formats hw can support. + * + * R300_EASY_TX_FORMAT swizzles the texture. + * Note the signature of R300_EASY_TX_FORMAT: + * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT); + * + * The FORMAT specifies how the texture sampler will treat the texture, and + * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ +static uint32_t r300_translate_texformat(enum pipe_format format) +{ + uint32_t result = 0; + const struct util_format_description *desc; + unsigned components = 0, i; + boolean uniform = TRUE; + const uint32_t swizzle_shift[4] = { + R300_TX_FORMAT_R_SHIFT, + R300_TX_FORMAT_G_SHIFT, + R300_TX_FORMAT_B_SHIFT, + R300_TX_FORMAT_A_SHIFT + }; + const uint32_t sign_bit[4] = { + R300_TX_FORMAT_SIGNED_X, + R300_TX_FORMAT_SIGNED_Y, + R300_TX_FORMAT_SIGNED_Z, + R300_TX_FORMAT_SIGNED_W, + }; + + desc = util_format_description(format); + + /* Colorspace (return non-RGB formats directly). */ + switch (desc->colorspace) { + /* Depth stencil formats. */ + case UTIL_FORMAT_COLORSPACE_ZS: + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return R300_EASY_TX_FORMAT(X, X, X, X, X16); + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); + default: + return ~0; /* Unsupported. */ + } + + /* YUV formats. */ + case UTIL_FORMAT_COLORSPACE_YUV: + result |= R300_TX_FORMAT_YUV_TO_RGB; + + switch (format) { + case PIPE_FORMAT_YCBCR: + return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; + case PIPE_FORMAT_YCBCR_REV: + return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; + default: + return ~0; /* Unsupported/unknown. */ + } + + /* Add gamma correction. */ + case UTIL_FORMAT_COLORSPACE_SRGB: + result |= R300_TX_FORMAT_GAMMA; + break; + + default:; + } + + /* Add swizzle. */ + for (i = 0; i < 4; i++) { + switch (desc->swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_X: + case UTIL_FORMAT_SWIZZLE_NONE: + result |= R300_TX_FORMAT_X << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Y: + result |= R300_TX_FORMAT_Y << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + result |= R300_TX_FORMAT_Z << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + result |= R300_TX_FORMAT_W << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_0: + result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_1: + result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; + break; + default: + return ~0; /* Unsupported. */ + } + } + + /* Compressed formats. */ + if (desc->layout == UTIL_FORMAT_LAYOUT_DXT) { + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT1_SRGB: + case PIPE_FORMAT_DXT1_SRGBA: + return R300_TX_FORMAT_DXT1 | result; + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT3_SRGBA: + return R300_TX_FORMAT_DXT3 | result; + case PIPE_FORMAT_DXT5_RGBA: + case PIPE_FORMAT_DXT5_SRGBA: + return R300_TX_FORMAT_DXT5 | result; + default: + return ~0; /* Unsupported/unknown. */ + } + } + + /* Get the number of components. */ + for (i = 0; i < 4; i++) { + if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { + ++components; + } + } + + /* Add sign. */ + for (i = 0; i < components; i++) { + if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { + result |= sign_bit[i]; + } + } + + /* See whether the components are of the same size. */ + for (i = 1; i < components; i++) { + uniform = uniform && desc->channel[0].size == desc->channel[i].size; + } + + /* Non-uniform formats. */ + if (!uniform) { + switch (components) { + case 3: + if (desc->channel[0].size == 5 && + desc->channel[1].size == 6 && + desc->channel[2].size == 5) { + return R300_TX_FORMAT_Z5Y6X5 | result; + } + if (desc->channel[0].size == 5 && + desc->channel[1].size == 5 && + desc->channel[2].size == 6) { + return R300_TX_FORMAT_Z6Y5X5 | result; + } + return ~0; /* Unsupported/unknown. */ + + case 4: + if (desc->channel[0].size == 5 && + desc->channel[1].size == 5 && + desc->channel[2].size == 5 && + desc->channel[3].size == 1) { + return R300_TX_FORMAT_W1Z5Y5X5 | result; + } + if (desc->channel[0].size == 10 && + desc->channel[1].size == 10 && + desc->channel[2].size == 10 && + desc->channel[3].size == 2) { + return R300_TX_FORMAT_W2Z10Y10X10 | result; + } + } + return ~0; /* Unsupported/unknown. */ + } + + /* And finally, uniform formats. */ + switch (desc->channel[0].type) { + case UTIL_FORMAT_TYPE_UNSIGNED: + case UTIL_FORMAT_TYPE_SIGNED: + if (!desc->channel[0].normalized && + desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { + return ~0; + } + + switch (desc->channel[0].size) { + case 4: + switch (components) { + case 2: + return R300_TX_FORMAT_Y4X4 | result; + case 4: + return R300_TX_FORMAT_W4Z4Y4X4 | result; + } + return ~0; + + case 8: + switch (components) { + case 1: + return R300_TX_FORMAT_X8 | result; + case 2: + return R300_TX_FORMAT_Y8X8 | result; + case 4: + return R300_TX_FORMAT_W8Z8Y8X8 | result; + } + return ~0; + + case 16: + switch (components) { + case 1: + return R300_TX_FORMAT_X16 | result; + case 2: + return R300_TX_FORMAT_Y16X16 | result; + case 4: + return R300_TX_FORMAT_W16Z16Y16X16 | result; + } + } + return ~0; + +/* XXX Enable float textures here. */ +#if 0 + case UTIL_FORMAT_TYPE_FLOAT: + switch (desc->channel[0].size) { + case 16: + switch (components) { + case 1: + return R300_TX_FORMAT_16F | result; + case 2: + return R300_TX_FORMAT_16F_16F | result; + case 4: + return R300_TX_FORMAT_16F_16F_16F_16F | result; + } + return ~0; + + case 32: + switch (components) { + case 1: + return R300_TX_FORMAT_32F | result; + case 2: + return R300_TX_FORMAT_32F_32F | result; + case 4: + return R300_TX_FORMAT_32F_32F_32F_32F | result; + } + } +#endif + } + + return ~0; /* Unsupported/unknown. */ +} + +boolean r300_is_sampler_format_supported(enum pipe_format format) +{ + return r300_translate_texformat(format) != ~0; +} + static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex) { struct r300_texture_state* state = &tex->state; diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index e2c10325fa9..01209efe3ce 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -42,240 +42,7 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen, struct pipe_texture *tex, enum pipe_format new_format); -/* Translate a pipe_format into a useful texture format for sampling. - * - * R300_EASY_TX_FORMAT swizzles the texture. - * Note the signature of R300_EASY_TX_FORMAT: - * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT); - * - * The FORMAT specifies how the texture sampler will treat the texture, and - * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ -static INLINE uint32_t r300_translate_texformat(enum pipe_format format) -{ - uint32_t result = 0; - const struct util_format_description *desc; - unsigned components = 0, i; - boolean uniform = TRUE; - const uint32_t swizzle_shift[4] = { - R300_TX_FORMAT_R_SHIFT, - R300_TX_FORMAT_G_SHIFT, - R300_TX_FORMAT_B_SHIFT, - R300_TX_FORMAT_A_SHIFT - }; - const uint32_t sign_bit[4] = { - R300_TX_FORMAT_SIGNED_X, - R300_TX_FORMAT_SIGNED_Y, - R300_TX_FORMAT_SIGNED_Z, - R300_TX_FORMAT_SIGNED_W, - }; - - desc = util_format_description(format); - - /* Colorspace (return non-RGB formats directly). */ - switch (desc->colorspace) { - /* Depth stencil formats. */ - case UTIL_FORMAT_COLORSPACE_ZS: - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, X16); - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); - default: - return ~0; /* Unsupported. */ - } - - /* YUV formats. */ - case UTIL_FORMAT_COLORSPACE_YUV: - result |= R300_TX_FORMAT_YUV_TO_RGB; - - switch (format) { - case PIPE_FORMAT_YCBCR: - return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; - case PIPE_FORMAT_YCBCR_REV: - return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; - default: - return ~0; /* Unsupported/unknown. */ - } - - /* Add gamma correction. */ - case UTIL_FORMAT_COLORSPACE_SRGB: - result |= R300_TX_FORMAT_GAMMA; - break; - - default:; - } - - /* Add swizzle. */ - for (i = 0; i < 4; i++) { - switch (desc->swizzle[i]) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_NONE: - result |= R300_TX_FORMAT_X << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Y: - result |= R300_TX_FORMAT_Y << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Z: - result |= R300_TX_FORMAT_Z << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_W: - result |= R300_TX_FORMAT_W << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_0: - result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_1: - result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; - break; - default: - return ~0; /* Unsupported. */ - } - } - - /* Compressed formats. */ - if (desc->layout == UTIL_FORMAT_LAYOUT_DXT) { - switch (format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT1_SRGB: - case PIPE_FORMAT_DXT1_SRGBA: - return R300_TX_FORMAT_DXT1 | result; - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT3_SRGBA: - return R300_TX_FORMAT_DXT3 | result; - case PIPE_FORMAT_DXT5_RGBA: - case PIPE_FORMAT_DXT5_SRGBA: - return R300_TX_FORMAT_DXT5 | result; - default: - return ~0; /* Unsupported/unknown. */ - } - } - - /* Get the number of components. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - ++components; - } - } - - /* Add sign. */ - for (i = 0; i < components; i++) { - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - result |= sign_bit[i]; - } - } - - /* See whether the components are of the same size. */ - for (i = 1; i < components; i++) { - uniform = uniform && desc->channel[0].size == desc->channel[i].size; - } - - /* Non-uniform formats. */ - if (!uniform) { - switch (components) { - case 3: - if (desc->channel[0].size == 5 && - desc->channel[1].size == 6 && - desc->channel[2].size == 5) { - return R300_TX_FORMAT_Z5Y6X5 | result; - } - if (desc->channel[0].size == 5 && - desc->channel[1].size == 5 && - desc->channel[2].size == 6) { - return R300_TX_FORMAT_Z6Y5X5 | result; - } - return ~0; /* Unsupported/unknown. */ - - case 4: - if (desc->channel[0].size == 5 && - desc->channel[1].size == 5 && - desc->channel[2].size == 5 && - desc->channel[3].size == 1) { - return R300_TX_FORMAT_W1Z5Y5X5 | result; - } - if (desc->channel[0].size == 10 && - desc->channel[1].size == 10 && - desc->channel[2].size == 10 && - desc->channel[3].size == 2) { - return R300_TX_FORMAT_W2Z10Y10X10 | result; - } - } - return ~0; /* Unsupported/unknown. */ - } - - /* And finally, uniform formats. */ - switch (desc->channel[0].type) { - case UTIL_FORMAT_TYPE_UNSIGNED: - case UTIL_FORMAT_TYPE_SIGNED: - if (!desc->channel[0].normalized && - desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { - return ~0; - } - - switch (desc->channel[0].size) { - case 4: - switch (components) { - case 2: - return R300_TX_FORMAT_Y4X4 | result; - case 4: - return R300_TX_FORMAT_W4Z4Y4X4 | result; - } - return ~0; - - case 8: - switch (components) { - case 1: - return R300_TX_FORMAT_X8 | result; - case 2: - return R300_TX_FORMAT_Y8X8 | result; - case 4: - return R300_TX_FORMAT_W8Z8Y8X8 | result; - } - return ~0; - - case 16: - switch (components) { - case 1: - return R300_TX_FORMAT_X16 | result; - case 2: - return R300_TX_FORMAT_Y16X16 | result; - case 4: - return R300_TX_FORMAT_W16Z16Y16X16 | result; - } - } - return ~0; - -/* XXX Enable float textures here. */ -#if 0 - case UTIL_FORMAT_TYPE_FLOAT: - switch (desc->channel[0].size) { - case 16: - switch (components) { - case 1: - return R300_TX_FORMAT_16F | result; - case 2: - return R300_TX_FORMAT_16F_16F | result; - case 4: - return R300_TX_FORMAT_16F_16F_16F_16F | result; - } - return ~0; - - case 32: - switch (components) { - case 1: - return R300_TX_FORMAT_32F | result; - case 2: - return R300_TX_FORMAT_32F_32F | result; - case 4: - return R300_TX_FORMAT_32F_32F_32F_32F | result; - } - } -#endif - } - - return ~0; /* Unsupported/unknown. */ -} +boolean r300_is_sampler_format_supported(enum pipe_format format); struct r300_video_surface { -- cgit v1.2.3 From 7a087e1d6f6eb3ff4b78e34ba7b59b6fc5082bc1 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 21 Feb 2010 00:17:04 +0100 Subject: r300g: add all missing colorbuffer formats --- src/gallium/drivers/r300/r300_screen.c | 60 +++----- src/gallium/drivers/r300/r300_state_inlines.h | 188 ++++++++++++++++++++------ 2 files changed, 165 insertions(+), 83 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 0b3b96def79..4bb4e5a7852 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -27,6 +27,7 @@ #include "r300_context.h" #include "r300_screen.h" +#include "r300_state_inlines.h" #include "r300_texture.h" #include "radeon_winsys.h" @@ -212,6 +213,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, boolean is_r500 = r300_screen(screen)->caps->is_r500; boolean is_z24 = format == PIPE_FORMAT_Z24X8_UNORM || format == PIPE_FORMAT_Z24S8_UNORM; + boolean is_color2101010 = format == PIPE_FORMAT_A2B10G10R10_UNORM; if (target >= PIPE_MAX_TEXTURE_TYPES) { debug_printf("r300: Implementation error: Received bogus texture " @@ -221,50 +223,32 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* Check sampler format support. */ if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) && - (is_r500 || !is_z24) && /* Z24 cannot be sampled from on non-r5xx. */ + /* Z24 cannot be sampled from on non-r5xx. */ + (is_r500 || !is_z24) && r300_is_sampler_format_supported(format)) { retval |= PIPE_TEXTURE_USAGE_SAMPLER; } - switch (format) { - /* Supported formats. */ - /* Colorbuffer */ - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_I8_UNORM: - retval |= usage & - (PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY); - break; - - /* ZS buffer */ - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - retval = usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL; - break; - - /* XXX Add all remaining gallium-supported formats, - * see util/u_format.csv. */ - - default:; + /* Check colorbuffer format support. */ + if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_PRIMARY)) && + /* 2101010 cannot be rendered to on non-r5xx. */ + (is_r500 || !is_color2101010) && + r300_is_colorbuffer_format_supported(format)) { + retval |= usage & + (PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_PRIMARY); } - /* If usage was a mask that contained multiple bits, and not all of them - * are supported, this will catch that and return FALSE. - * e.g. usage = 2 | 4; retval = 4; (retval >= usage) == FALSE - * - * This also returns FALSE for any unknown formats. - */ - return (retval >= usage); + /* Check depth-stencil format support. */ + if (usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL && + r300_is_zs_format_supported(format)) { + retval |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + } + + return retval == usage; } static struct pipe_transfer* diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index c990be40b9e..63f5ff60450 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -334,43 +334,66 @@ static INLINE uint32_t r300_anisotropy(unsigned max_aniso) static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) { switch (format) { - /* 8-bit buffers */ + /* 8-bit buffers. */ case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_L8_SRGB: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: return R300_COLOR_FORMAT_I8; - /* 16-bit buffers */ + + /* 16-bit buffers. */ case PIPE_FORMAT_R5G6B5_UNORM: return R300_COLOR_FORMAT_RGB565; case PIPE_FORMAT_A1R5G5B5_UNORM: return R300_COLOR_FORMAT_ARGB1555; case PIPE_FORMAT_A4R4G4B4_UNORM: return R300_COLOR_FORMAT_ARGB4444; - /* 32-bit buffers */ + + /* 32-bit buffers. */ case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_SRGB: case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_SRGB: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8X8_SRGB: case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_R8G8B8X8_SRGB: + case PIPE_FORMAT_R8G8B8X8_SNORM: + case PIPE_FORMAT_A8B8G8R8_SNORM: + case PIPE_FORMAT_X8B8G8R8_SNORM: + case PIPE_FORMAT_X8UB8UG8SR8S_NORM: return R300_COLOR_FORMAT_ARGB8888; - /* XXX Not in pipe_format - case PIPE_FORMAT_A32R32G32B32: - return R300_COLOR_FORMAT_ARGB32323232; - case PIPE_FORMAT_A16R16G16B16: + case PIPE_FORMAT_A2B10G10R10_UNORM: + return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */ + + /* 64-bit buffers. */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ return R300_COLOR_FORMAT_ARGB16161616; - case PIPE_FORMAT_A10R10G10B10_UNORM: - return R500_COLOR_FORMAT_ARGB10101010; - case PIPE_FORMAT_A2R10G10B10_UNORM: - return R500_COLOR_FORMAT_ARGB2101010; - case PIPE_FORMAT_I10_UNORM: - return R500_COLOR_FORMAT_I10; */ + +/* XXX Enable float textures here. */ +#if 0 + /* 128-bit buffers. */ + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return R300_COLOR_FORMAT_ARGB32323232; +#endif + + /* YUV buffers. */ + case PIPE_FORMAT_YCBCR: + return R300_COLOR_FORMAT_YVYU; + case PIPE_FORMAT_YCBCR_REV: + return R300_COLOR_FORMAT_VYUY; default: - debug_printf("r300: Implementation error: " - "Got unsupported color format %s in %s\n", - util_format_name(format), __FUNCTION__); - assert(0); - break; + return ~0; /* Unsupported. */ } - return 0; } /* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */ @@ -386,13 +409,8 @@ static INLINE uint32_t r300_translate_zsformat(enum pipe_format format) case PIPE_FORMAT_Z24S8_UNORM: return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; default: - debug_printf("r300: Implementation error: " - "Got unsupported ZS format %s in %s\n", - util_format_name(format), __FUNCTION__); - assert(0); - break; + return ~0; /* Unsupported. */ } - return 0; } /* Shader output formats. This is essentially the swizzle from the shader @@ -401,41 +419,121 @@ static INLINE uint32_t r300_translate_zsformat(enum pipe_format format) * Note that formats are stored from C3 to C0. */ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) { + uint32_t modifier = 0; + unsigned i; + const struct util_format_description *desc; + static const uint32_t sign_bit[4] = { + R300_OUT_SIGN(0x1), + R300_OUT_SIGN(0x2), + R300_OUT_SIGN(0x4), + R300_OUT_SIGN(0x8), + }; + + desc = util_format_description(format); + + /* Specifies how the shader output is written to the fog unit. */ + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { + /* The gamma correction causes precision loss so we need + * higher precision to maintain reasonable quality. + * It has nothing to do with the colorbuffer format. */ + modifier |= R300_US_OUT_FMT_C4_10_GAMMA; + } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { + if (desc->channel[0].size == 32) { + modifier |= R300_US_OUT_FMT_C4_32_FP; + } else { + modifier |= R300_US_OUT_FMT_C4_16_FP; + } + } else { + if (desc->channel[0].size == 16) { + modifier |= R300_US_OUT_FMT_C4_16; + } else { + /* C4_8 seems to be used for the formats whose pixel size + * is <= 32 bits. */ + modifier |= R300_US_OUT_FMT_C4_8; + } + } + + /* Add sign. */ + for (i = 0; i < 4; i++) + if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { + modifier |= sign_bit[i]; + } + + /* Add swizzles and return. */ switch (format) { + /* 8-bit outputs. + * COLORFORMAT_I8 stores the C2 component. */ + case PIPE_FORMAT_A8_UNORM: + return modifier | R300_C2_SEL_A; + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_L8_SRGB: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return modifier | R300_C2_SEL_R; + + /* ARGB 32-bit outputs. */ case PIPE_FORMAT_R5G6B5_UNORM: - /* C_5_6_5 is missing in US_OUT_FMT, but C4_8 works just fine. */ case PIPE_FORMAT_A1R5G5B5_UNORM: - /* C_1_5_5_5 is missing in US_OUT_FMT, but C4_8 works just fine. */ case PIPE_FORMAT_A4R4G4B4_UNORM: - /* C4_4 is missing in US_OUT_FMT, but C4_8 works just fine. */ case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_SRGB: case PIPE_FORMAT_X8R8G8B8_UNORM: - return R300_US_OUT_FMT_C4_8 | + case PIPE_FORMAT_X8R8G8B8_SRGB: + return modifier | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; + + /* BGRA 32-bit outputs. */ + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8X8_SRGB: + return modifier | + R300_C0_SEL_A | R300_C1_SEL_R | + R300_C2_SEL_G | R300_C3_SEL_B; + + /* RGBA 32-bit outputs. */ case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: - return R300_US_OUT_FMT_C4_8 | + case PIPE_FORMAT_R8G8B8X8_SRGB: + case PIPE_FORMAT_R8G8B8X8_SNORM: + return modifier | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; - /* 8-bit outputs */ - case PIPE_FORMAT_A8_UNORM: - return R300_US_OUT_FMT_C4_8 | - R300_C2_SEL_A; - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_L8_UNORM: - return R300_US_OUT_FMT_C4_8 | - R300_C2_SEL_R; - /* R300_OUT_SIGN(x) */ + /* ABGR 32-bit outputs. */ + case PIPE_FORMAT_A8B8G8R8_SNORM: + case PIPE_FORMAT_X8B8G8R8_SNORM: + case PIPE_FORMAT_X8UB8UG8SR8S_NORM: + case PIPE_FORMAT_A2B10G10R10_UNORM: + /* RGBA high precision outputs (same swizzles as ABGR low precision) */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return modifier | + R300_C0_SEL_R | R300_C1_SEL_G | + R300_C2_SEL_B | R300_C3_SEL_A; + default: - debug_printf("r300: Implementation error: " - "Got unsupported output format %s in %s\n", - util_format_name(format), __FUNCTION__); - assert(0); - return R300_US_OUT_FMT_UNUSED; + return ~0; /* Unsupported. */ } - return 0; +} + +static INLINE +boolean r300_is_zs_format_supported(enum pipe_format format) +{ + return r300_translate_zsformat(format) != ~0; +} + +static INLINE +boolean r300_is_colorbuffer_format_supported(enum pipe_format format) +{ + return r300_translate_colorformat(format) != ~0 && + r300_translate_out_fmt(format) != ~0; } /* Non-CSO state. (For now.) */ -- cgit v1.2.3 From 3c244dac47195cce3fdcb05176e38d33b2cad8ed Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 20 Feb 2010 21:12:45 +0100 Subject: r300g: precompute framebuffer register values --- src/gallium/drivers/r300/r300_context.h | 11 ++ src/gallium/drivers/r300/r300_emit.c | 14 +- src/gallium/drivers/r300/r300_screen.c | 1 - src/gallium/drivers/r300/r300_state_inlines.h | 209 ----------------------- src/gallium/drivers/r300/r300_texture.c | 231 ++++++++++++++++++++++++++ src/gallium/drivers/r300/r300_texture.h | 4 + 6 files changed, 250 insertions(+), 220 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 1eba8a8ed12..443af4ec2e3 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -125,6 +125,16 @@ struct r300_texture_state { uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */ }; +struct r300_texture_fb_state { + /* Colorbuffer. */ + uint32_t colorpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/ + uint32_t us_out_fmt; /* R300_US_OUT_FMT[0-3] */ + + /* Zbuffer. */ + uint32_t depthpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */ + uint32_t zb_format; /* R300_ZB_FORMAT */ +}; + struct r300_viewport_state { float xscale; /* R300_VAP_VPORT_XSCALE: 0x2098 */ float xoffset; /* R300_VAP_VPORT_XOFFSET: 0x209c */ @@ -232,6 +242,7 @@ struct r300_texture { /* Registers carrying texture format data. */ struct r300_texture_state state; + struct r300_texture_fb_state fb_state; /* Buffer tiling */ enum r300_buffer_tiling microtile, macrotile; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 88fe166359b..5a2865887f2 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -422,14 +422,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | - r300_translate_colorformat(tex->tex.format) | - R300_COLOR_TILE(tex->mip_macrotile[surf->level]) | - R300_COLOR_MICROTILE(tex->microtile), + OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), - r300_translate_out_fmt(surf->format)); + OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); } /* Set up a zbuffer. */ @@ -441,12 +437,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format)); + OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | - R300_DEPTHMACROTILE(tex->mip_macrotile[surf->level]) | - R300_DEPTHMICROTILE(tex->microtile), + OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 4bb4e5a7852..6a55570571a 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -27,7 +27,6 @@ #include "r300_context.h" #include "r300_screen.h" -#include "r300_state_inlines.h" #include "r300_texture.h" #include "radeon_winsys.h" diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 63f5ff60450..0e1cb328d17 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -327,215 +327,6 @@ static INLINE uint32_t r300_anisotropy(unsigned max_aniso) } } -/* Buffer formats. */ - -/* Colorbuffer formats. This is the unswizzled format of the RB3D block's - * output. For the swizzling of the targets, check the shader's format. */ -static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) -{ - switch (format) { - /* 8-bit buffers. */ - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_L8_SRGB: - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R8_SNORM: - return R300_COLOR_FORMAT_I8; - - /* 16-bit buffers. */ - case PIPE_FORMAT_R5G6B5_UNORM: - return R300_COLOR_FORMAT_RGB565; - case PIPE_FORMAT_A1R5G5B5_UNORM: - return R300_COLOR_FORMAT_ARGB1555; - case PIPE_FORMAT_A4R4G4B4_UNORM: - return R300_COLOR_FORMAT_ARGB4444; - - /* 32-bit buffers. */ - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_SRGB: - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_B8G8R8X8_SRGB: - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SRGB: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_R8G8B8X8_SRGB: - case PIPE_FORMAT_R8G8B8X8_SNORM: - case PIPE_FORMAT_A8B8G8R8_SNORM: - case PIPE_FORMAT_X8B8G8R8_SNORM: - case PIPE_FORMAT_X8UB8UG8SR8S_NORM: - return R300_COLOR_FORMAT_ARGB8888; - case PIPE_FORMAT_A2B10G10R10_UNORM: - return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */ - - /* 64-bit buffers. */ - case PIPE_FORMAT_R16G16B16A16_UNORM: - case PIPE_FORMAT_R16G16B16A16_SNORM: - //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ - return R300_COLOR_FORMAT_ARGB16161616; - -/* XXX Enable float textures here. */ -#if 0 - /* 128-bit buffers. */ - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return R300_COLOR_FORMAT_ARGB32323232; -#endif - - /* YUV buffers. */ - case PIPE_FORMAT_YCBCR: - return R300_COLOR_FORMAT_YVYU; - case PIPE_FORMAT_YCBCR_REV: - return R300_COLOR_FORMAT_VYUY; - default: - return ~0; /* Unsupported. */ - } -} - -/* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */ -static INLINE uint32_t r300_translate_zsformat(enum pipe_format format) -{ - switch (format) { - /* 16-bit depth, no stencil */ - case PIPE_FORMAT_Z16_UNORM: - return R300_DEPTHFORMAT_16BIT_INT_Z; - /* 24-bit depth, ignored stencil */ - case PIPE_FORMAT_Z24X8_UNORM: - /* 24-bit depth, 8-bit stencil */ - case PIPE_FORMAT_Z24S8_UNORM: - return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; - default: - return ~0; /* Unsupported. */ - } -} - -/* Shader output formats. This is essentially the swizzle from the shader - * to the RB3D block. - * - * Note that formats are stored from C3 to C0. */ -static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) -{ - uint32_t modifier = 0; - unsigned i; - const struct util_format_description *desc; - static const uint32_t sign_bit[4] = { - R300_OUT_SIGN(0x1), - R300_OUT_SIGN(0x2), - R300_OUT_SIGN(0x4), - R300_OUT_SIGN(0x8), - }; - - desc = util_format_description(format); - - /* Specifies how the shader output is written to the fog unit. */ - if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { - /* The gamma correction causes precision loss so we need - * higher precision to maintain reasonable quality. - * It has nothing to do with the colorbuffer format. */ - modifier |= R300_US_OUT_FMT_C4_10_GAMMA; - } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { - if (desc->channel[0].size == 32) { - modifier |= R300_US_OUT_FMT_C4_32_FP; - } else { - modifier |= R300_US_OUT_FMT_C4_16_FP; - } - } else { - if (desc->channel[0].size == 16) { - modifier |= R300_US_OUT_FMT_C4_16; - } else { - /* C4_8 seems to be used for the formats whose pixel size - * is <= 32 bits. */ - modifier |= R300_US_OUT_FMT_C4_8; - } - } - - /* Add sign. */ - for (i = 0; i < 4; i++) - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - modifier |= sign_bit[i]; - } - - /* Add swizzles and return. */ - switch (format) { - /* 8-bit outputs. - * COLORFORMAT_I8 stores the C2 component. */ - case PIPE_FORMAT_A8_UNORM: - return modifier | R300_C2_SEL_A; - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_L8_SRGB: - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R8_SNORM: - return modifier | R300_C2_SEL_R; - - /* ARGB 32-bit outputs. */ - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_SRGB: - return modifier | - R300_C0_SEL_B | R300_C1_SEL_G | - R300_C2_SEL_R | R300_C3_SEL_A; - - /* BGRA 32-bit outputs. */ - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_B8G8R8X8_SRGB: - return modifier | - R300_C0_SEL_A | R300_C1_SEL_R | - R300_C2_SEL_G | R300_C3_SEL_B; - - /* RGBA 32-bit outputs. */ - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SRGB: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_R8G8B8X8_SRGB: - case PIPE_FORMAT_R8G8B8X8_SNORM: - return modifier | - R300_C0_SEL_A | R300_C1_SEL_B | - R300_C2_SEL_G | R300_C3_SEL_R; - - /* ABGR 32-bit outputs. */ - case PIPE_FORMAT_A8B8G8R8_SNORM: - case PIPE_FORMAT_X8B8G8R8_SNORM: - case PIPE_FORMAT_X8UB8UG8SR8S_NORM: - case PIPE_FORMAT_A2B10G10R10_UNORM: - /* RGBA high precision outputs (same swizzles as ABGR low precision) */ - case PIPE_FORMAT_R16G16B16A16_UNORM: - case PIPE_FORMAT_R16G16B16A16_SNORM: - //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return modifier | - R300_C0_SEL_R | R300_C1_SEL_G | - R300_C2_SEL_B | R300_C3_SEL_A; - - default: - return ~0; /* Unsupported. */ - } -} - -static INLINE -boolean r300_is_zs_format_supported(enum pipe_format format) -{ - return r300_translate_zsformat(format) != ~0; -} - -static INLINE -boolean r300_is_colorbuffer_format_supported(enum pipe_format format) -{ - return r300_translate_colorformat(format) != ~0 && - r300_translate_out_fmt(format) != ~0; -} - /* Non-CSO state. (For now.) */ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count) diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 5b7afc6eb9e..ed2be06254a 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson + * Copyright 2010 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"), @@ -29,6 +30,7 @@ #include "r300_context.h" #include "r300_texture.h" #include "r300_screen.h" +#include "r300_state_inlines.h" #include "radeon_winsys.h" @@ -283,6 +285,213 @@ static uint32_t r300_translate_texformat(enum pipe_format format) return ~0; /* Unsupported/unknown. */ } +/* Buffer formats. */ + +/* Colorbuffer formats. This is the unswizzled format of the RB3D block's + * output. For the swizzling of the targets, check the shader's format. */ +static uint32_t r300_translate_colorformat(enum pipe_format format) +{ + switch (format) { + /* 8-bit buffers. */ + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_L8_SRGB: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return R300_COLOR_FORMAT_I8; + + /* 16-bit buffers. */ + case PIPE_FORMAT_R5G6B5_UNORM: + return R300_COLOR_FORMAT_RGB565; + case PIPE_FORMAT_A1R5G5B5_UNORM: + return R300_COLOR_FORMAT_ARGB1555; + case PIPE_FORMAT_A4R4G4B4_UNORM: + return R300_COLOR_FORMAT_ARGB4444; + + /* 32-bit buffers. */ + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_SRGB: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_SRGB: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8X8_SRGB: + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_SRGB: + case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_R8G8B8X8_SRGB: + case PIPE_FORMAT_R8G8B8X8_SNORM: + case PIPE_FORMAT_A8B8G8R8_SNORM: + case PIPE_FORMAT_X8B8G8R8_SNORM: + case PIPE_FORMAT_X8UB8UG8SR8S_NORM: + return R300_COLOR_FORMAT_ARGB8888; + case PIPE_FORMAT_A2B10G10R10_UNORM: + return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */ + + /* 64-bit buffers. */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ + return R300_COLOR_FORMAT_ARGB16161616; + +/* XXX Enable float textures here. */ +#if 0 + /* 128-bit buffers. */ + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return R300_COLOR_FORMAT_ARGB32323232; +#endif + + /* YUV buffers. */ + case PIPE_FORMAT_YCBCR: + return R300_COLOR_FORMAT_YVYU; + case PIPE_FORMAT_YCBCR_REV: + return R300_COLOR_FORMAT_VYUY; + default: + return ~0; /* Unsupported. */ + } +} + +/* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */ +static uint32_t r300_translate_zsformat(enum pipe_format format) +{ + switch (format) { + /* 16-bit depth, no stencil */ + case PIPE_FORMAT_Z16_UNORM: + return R300_DEPTHFORMAT_16BIT_INT_Z; + /* 24-bit depth, ignored stencil */ + case PIPE_FORMAT_Z24X8_UNORM: + /* 24-bit depth, 8-bit stencil */ + case PIPE_FORMAT_Z24S8_UNORM: + return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; + default: + return ~0; /* Unsupported. */ + } +} + +/* Shader output formats. This is essentially the swizzle from the shader + * to the RB3D block. + * + * Note that formats are stored from C3 to C0. */ +static uint32_t r300_translate_out_fmt(enum pipe_format format) +{ + uint32_t modifier = 0; + unsigned i; + const struct util_format_description *desc; + static const uint32_t sign_bit[4] = { + R300_OUT_SIGN(0x1), + R300_OUT_SIGN(0x2), + R300_OUT_SIGN(0x4), + R300_OUT_SIGN(0x8), + }; + + desc = util_format_description(format); + + /* Specifies how the shader output is written to the fog unit. */ + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { + /* The gamma correction causes precision loss so we need + * higher precision to maintain reasonable quality. + * It has nothing to do with the colorbuffer format. */ + modifier |= R300_US_OUT_FMT_C4_10_GAMMA; + } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { + if (desc->channel[0].size == 32) { + modifier |= R300_US_OUT_FMT_C4_32_FP; + } else { + modifier |= R300_US_OUT_FMT_C4_16_FP; + } + } else { + if (desc->channel[0].size == 16) { + modifier |= R300_US_OUT_FMT_C4_16; + } else { + /* C4_8 seems to be used for the formats whose pixel size + * is <= 32 bits. */ + modifier |= R300_US_OUT_FMT_C4_8; + } + } + + /* Add sign. */ + for (i = 0; i < 4; i++) + if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { + modifier |= sign_bit[i]; + } + + /* Add swizzles and return. */ + switch (format) { + /* 8-bit outputs. + * COLORFORMAT_I8 stores the C2 component. */ + case PIPE_FORMAT_A8_UNORM: + return modifier | R300_C2_SEL_A; + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_L8_SRGB: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return modifier | R300_C2_SEL_R; + + /* ARGB 32-bit outputs. */ + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_SRGB: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_SRGB: + return modifier | + R300_C0_SEL_B | R300_C1_SEL_G | + R300_C2_SEL_R | R300_C3_SEL_A; + + /* BGRA 32-bit outputs. */ + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8X8_SRGB: + return modifier | + R300_C0_SEL_A | R300_C1_SEL_R | + R300_C2_SEL_G | R300_C3_SEL_B; + + /* RGBA 32-bit outputs. */ + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_SRGB: + case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_R8G8B8X8_SRGB: + case PIPE_FORMAT_R8G8B8X8_SNORM: + return modifier | + R300_C0_SEL_A | R300_C1_SEL_B | + R300_C2_SEL_G | R300_C3_SEL_R; + + /* ABGR 32-bit outputs. */ + case PIPE_FORMAT_A8B8G8R8_SNORM: + case PIPE_FORMAT_X8B8G8R8_SNORM: + case PIPE_FORMAT_X8UB8UG8SR8S_NORM: + case PIPE_FORMAT_A2B10G10R10_UNORM: + /* RGBA high precision outputs (same swizzles as ABGR low precision) */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return modifier | + R300_C0_SEL_R | R300_C1_SEL_G | + R300_C2_SEL_B | R300_C3_SEL_A; + + default: + return ~0; /* Unsupported. */ + } +} + +boolean r300_is_colorbuffer_format_supported(enum pipe_format format) +{ + return r300_translate_colorformat(format) != ~0 && + r300_translate_out_fmt(format) != ~0; +} + +boolean r300_is_zs_format_supported(enum pipe_format format) +{ + return r300_translate_zsformat(format) != ~0; +} + boolean r300_is_sampler_format_supported(enum pipe_format format) { return r300_translate_texformat(format) != ~0; @@ -292,8 +501,10 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex { struct r300_texture_state* state = &tex->state; struct pipe_texture *pt = &tex->tex; + unsigned i; boolean is_r500 = screen->caps->is_r500; + /* Set sampler state. */ state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) | R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff); @@ -327,6 +538,26 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n", pt->width0, pt->height0, pt->last_level); + + /* Set framebuffer state. */ + if (util_format_is_depth_or_stencil(tex->tex.format)) { + for (i = 0; i <= tex->tex.last_level; i++) { + tex->fb_state.depthpitch[i] = + tex->pitch[i] | + R300_DEPTHMACROTILE(tex->mip_macrotile[i]) | + R300_DEPTHMICROTILE(tex->microtile); + } + tex->fb_state.zb_format = r300_translate_zsformat(tex->tex.format); + } else { + for (i = 0; i <= tex->tex.last_level; i++) { + tex->fb_state.colorpitch[i] = + tex->pitch[i] | + r300_translate_colorformat(tex->tex.format) | + R300_COLOR_TILE(tex->mip_macrotile[i]) | + R300_COLOR_MICROTILE(tex->microtile); + } + tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->tex.format); + } } void r300_texture_reinterpret_format(struct pipe_screen *screen, diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 01209efe3ce..46a5fb6188b 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -42,6 +42,10 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen, struct pipe_texture *tex, enum pipe_format new_format); +boolean r300_is_colorbuffer_format_supported(enum pipe_format format); + +boolean r300_is_zs_format_supported(enum pipe_format format); + boolean r300_is_sampler_format_supported(enum pipe_format format); struct r300_video_surface -- cgit v1.2.3 From 8ff6790afb9c1b5a53a22fed9d5159581ba42a8f Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Sun, 21 Feb 2010 14:26:53 -0800 Subject: r300g: Remove unnecessary header. --- src/gallium/drivers/r300/r300_emit.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 5a2865887f2..f7dcd8dc52f 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,7 +32,6 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" -#include "r300_state_inlines.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) -- cgit v1.2.3 From 233290f2031057b37fdadb650873b02be307ebc8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 21 Feb 2010 20:49:29 +0100 Subject: r3OOg: support rendering of more than 65535 vertices per draw call (almost) The path for VAP_ALT_NUM_VERTICES is also in place (and tested) but not enabled by default due to the missing support of this reg in the upstream kernel. Also, a non-zero BUFFER_BASE in the INDX_BUFFER packet3 hangs the machine. Am I missing something? Because of this, only draw_arrays can render more than 65535 vertices without the use of VAP_ALT_NUM_VERTICES. --- src/gallium/drivers/r300/r300_reg.h | 3 + src/gallium/drivers/r300/r300_render.c | 109 ++++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 29 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index a049da69e2e..a249e8b36be 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -113,11 +113,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* index size - when not set the indices are assumed to be 16 bit */ # define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11) +# define R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS (1<<14) /* number of vertices */ # define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16 #define R500_VAP_INDEX_OFFSET 0x208c +#define R500_VAP_ALT_NUM_VERTICES 0x2088 + #define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 # define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) # define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT (1<<1) diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cd4971ae136..754eb4dc769 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -42,6 +42,9 @@ /* r300_render: Vertex and index buffer primitive emission. */ #define R300_MAX_VBO_SIZE (1024 * 1024) +/* XXX The DRM rejects VAP_ALT_NUM_VERTICES.. */ +//#define ENABLE_ALT_NUM_VERTS + uint32_t r300_translate_primitive(unsigned prim) { switch (prim) { @@ -210,16 +213,28 @@ static void r300_emit_draw_arrays(struct r300_context *r300, unsigned mode, unsigned count) { +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = count > 65535; +#else + boolean alt_num_verts = FALSE; +#endif CS_LOCALS(r300); - BEGIN_CS(8); + if (alt_num_verts) { + assert(count < (1 << 24)); + BEGIN_CS(10); + OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); + } else { + BEGIN_CS(8); + } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | - r300_translate_primitive(mode)); + r300_translate_primitive(mode) | + (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); END_CS; } @@ -234,14 +249,27 @@ static void r300_emit_draw_elements(struct r300_context *r300, { uint32_t count_dwords; uint32_t offset_dwords = indexSize * start / sizeof(uint32_t); +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = count > 65535; +#else + boolean alt_num_verts = FALSE; +#endif CS_LOCALS(r300); - /* XXX most of these are stupid */ - assert(indexSize == 4 || indexSize == 2); assert((start * indexSize) % 4 == 0); - assert(offset_dwords == 0); - BEGIN_CS(14); + /* XXX Non-zero offset locks up. */ + if (offset_dwords != 0) { + return; + } + + if (alt_num_verts) { + assert(count < (1 << 24)); + BEGIN_CS(16); + OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); + } else { + BEGIN_CS(14); + } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex); @@ -251,24 +279,24 @@ static void r300_emit_draw_elements(struct r300_context *r300, count_dwords = count + start; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | R300_VAP_VF_CNTL__INDEX_SIZE_32bit | - r300_translate_primitive(mode)); + r300_translate_primitive(mode) | + (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); } else { count_dwords = (count + start + 1) / 2; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | - r300_translate_primitive(mode)); + r300_translate_primitive(mode) | + (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); } /* INDX_BUFFER is a truly special packet3. * Unlike most other packet3, where the offset is after the count, * the order is reversed, so the relocation ends up carrying the * size of the indexbuf instead of the offset. - * - * XXX Fix offset */ OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2); OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | (0 << R300_INDX_BUFFER_SKIP_SHIFT)); - OUT_CS(offset_dwords); + OUT_CS(offset_dwords << 2); OUT_CS_RELOC(indexBuffer, count_dwords, RADEON_GEM_DOMAIN_GTT, 0, 0); @@ -343,18 +371,18 @@ void r300_draw_range_elements(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); struct pipe_buffer* orgIndexBuffer = indexBuffer; +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = r300_screen(pipe->screen)->caps->is_r500 && + count > 65536; +#else + boolean alt_num_verts = FALSE; +#endif + unsigned short_count; if (!u_trim_pipe_prim(mode, &count)) { return; } - if (count > 65535) { - /* XXX: use aux/indices functions to split this into smaller - * primitives. - */ - return; - } - r300_update_derived_state(r300); r300_emit_buffer_validate(r300); @@ -381,8 +409,19 @@ void r300_draw_range_elements(struct pipe_context* pipe, r300_emit_aos(r300, 0); - r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, - mode, start, count); + if (alt_num_verts || count <= 65535) { + r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, + maxIndex, mode, start, count); + } else { + do { + short_count = MIN2(count, 65534); + r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, + maxIndex, mode, start, short_count); + + start += short_count; + count -= short_count; + } while (count); + } cleanup: if (indexBuffer != orgIndexBuffer) { @@ -404,18 +443,18 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, unsigned start, unsigned count) { struct r300_context* r300 = r300_context(pipe); +#if defined(ENABLE_ALT_NUM_VERTS) + boolean alt_num_verts = r300_screen(pipe->screen)->caps->is_r500 && + count > 65536; +#else + boolean alt_num_verts = FALSE; +#endif + unsigned short_count; if (!u_trim_pipe_prim(mode, &count)) { return; } - if (count > 65535) { - /* XXX: driver needs to handle this -- use the functions in - * aux/indices to split this into several smaller primitives. - */ - return; - } - r300_update_derived_state(r300); r300_emit_buffer_validate(r300); @@ -428,8 +467,20 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, } r300_emit_dirty_state(r300); - r300_emit_aos(r300, start); - r300_emit_draw_arrays(r300, mode, count); + + if (alt_num_verts || count <= 65535) { + r300_emit_aos(r300, start); + r300_emit_draw_arrays(r300, mode, count); + } else { + do { + short_count = MIN2(count, 65535); + r300_emit_aos(r300, start); + r300_emit_draw_arrays(r300, mode, short_count); + + start += short_count; + count -= short_count; + } while (count); + } } } -- cgit v1.2.3 From fff5be8e7b4557c221f2425dcafc2e7cbbba76ba Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 12 Feb 2010 15:39:51 +1000 Subject: r300g: rebuild winsys/pipe buffer handling and add buffer map This creates a cleaner winsys and drop the simple screen stuff. It makes r300g use pb_bufmgr structs and adds usage of the cached bufmgr for vertex/index buffers. It also avoids mapping too often. I'm not 100% sure this is perfect but it won't find its own bugs. Signed-off-by: Dave Airlie --- src/gallium/drivers/r300/Makefile | 1 + src/gallium/drivers/r300/r300_context.c | 38 ++- src/gallium/drivers/r300/r300_context.h | 9 +- src/gallium/drivers/r300/r300_cs.h | 22 +- src/gallium/drivers/r300/r300_emit.c | 54 +-- src/gallium/drivers/r300/r300_render.c | 33 +- src/gallium/drivers/r300/r300_screen.c | 38 ++- src/gallium/drivers/r300/r300_screen.h | 2 +- src/gallium/drivers/r300/r300_screen_buffer.c | 222 +++++++++++++ src/gallium/drivers/r300/r300_screen_buffer.h | 85 +++++ src/gallium/drivers/r300/r300_state.c | 25 +- src/gallium/drivers/r300/r300_texture.c | 41 +-- src/gallium/drivers/r300/r300_texture.h | 4 +- src/gallium/drivers/r300/r300_winsys.h | 127 +++++++- src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h | 2 - src/gallium/winsys/drm/radeon/core/Makefile | 2 +- src/gallium/winsys/drm/radeon/core/radeon_buffer.h | 60 ++-- src/gallium/winsys/drm/radeon/core/radeon_drm.c | 134 +++----- src/gallium/winsys/drm/radeon/core/radeon_drm.h | 5 - .../winsys/drm/radeon/core/radeon_drm_buffer.c | 361 +++++++++++++++++++++ src/gallium/winsys/drm/radeon/core/radeon_r300.c | 237 ++++++++++---- src/gallium/winsys/drm/radeon/core/radeon_r300.h | 6 +- src/gallium/winsys/drm/radeon/core/radeon_winsys.h | 86 ++--- 23 files changed, 1247 insertions(+), 347 deletions(-) create mode 100644 src/gallium/drivers/r300/r300_screen_buffer.c create mode 100644 src/gallium/drivers/r300/r300_screen_buffer.h create mode 100644 src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index afddcb161fa..5707309bdf9 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -14,6 +14,7 @@ C_SOURCES = \ r300_query.c \ r300_render.c \ r300_screen.c \ + r300_screen_buffer.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index f631b4ed27f..a8a6a07a841 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -24,6 +24,7 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" +#include "util/u_upload_mgr.h" #include "r300_blit.h" #include "r300_context.h" @@ -54,6 +55,9 @@ static void r300_destroy_context(struct pipe_context* context) FREE(query); } + u_upload_destroy(r300->upload_vb); + u_upload_destroy(r300->upload_ib); + FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); FREE(r300->fb_state.state); @@ -70,11 +74,7 @@ r300_is_texture_referenced(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level) { - struct pipe_buffer* buf = 0; - - r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); - - return pipe->is_buffer_referenced(pipe, buf); + return 0; } static unsigned int @@ -136,14 +136,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, { struct r300_context* r300 = CALLOC_STRUCT(r300_context); struct r300_screen* r300screen = r300_screen(screen); - struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys; + struct r300_winsys_screen *rws = r300screen->rws; if (!r300) return NULL; - r300->winsys = radeon_winsys; + r300->rws = rws; - r300->context.winsys = (struct pipe_winsys*)radeon_winsys; + r300->context.winsys = (struct pipe_winsys*)rws; r300->context.screen = screen; r300->context.priv = priv; @@ -201,11 +201,31 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->invariant_state.dirty = TRUE; - r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); + rws->set_flush_cb(r300->rws, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw++; r300->blitter = util_blitter_create(&r300->context); + r300->upload_ib = u_upload_create(screen, + 32 * 1024, 16, + PIPE_BUFFER_USAGE_INDEX); + + if (r300->upload_ib == NULL) + goto no_upload_ib; + + r300->upload_vb = u_upload_create(screen, + 128 * 1024, 16, + PIPE_BUFFER_USAGE_VERTEX); + if (r300->upload_vb == NULL) + goto no_upload_vb; + return &r300->context; + + // u_upload_destroy(r300->upload_vb); + no_upload_ib: + u_upload_destroy(r300->upload_ib); + no_upload_vb: + FREE(r300); + return NULL; } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 443af4ec2e3..749bac04987 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -32,6 +32,7 @@ #include "r300_screen.h" +struct u_upload_mgr; struct r300_context; struct r300_fragment_shader; @@ -238,7 +239,7 @@ struct r300_texture { boolean is_npot; /* Pipe buffer backing this texture. */ - struct pipe_buffer* buffer; + struct r300_winsys_buffer *buffer; /* Registers carrying texture format data. */ struct r300_texture_state state; @@ -265,7 +266,7 @@ struct r300_context { struct pipe_context context; /* The interface to the windowing system, etc. */ - struct radeon_winsys* winsys; + struct r300_winsys_screen *rws; /* Draw module. Used mostly for SW TCL. */ struct draw_context* draw; /* Accelerated blit support. */ @@ -330,6 +331,7 @@ struct r300_context { /* Vertex elements for Gallium. */ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; + bool any_user_vbs; struct pipe_stencil_ref stencil_ref; @@ -343,6 +345,9 @@ struct r300_context { boolean polygon_offset_enabled; /* Z buffer bit depth. */ uint32_t zbuffer_bpp; + + struct u_upload_mgr *upload_vb; + struct u_upload_mgr *upload_ib; }; /* Convenience cast wrapper. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 151f72b0fe4..ad07efbffdb 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -51,7 +51,7 @@ #define CS_LOCALS(context) \ struct r300_context* const cs_context_copy = (context); \ - struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \ + struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \ int cs_count = 0; (void) cs_count; #define CHECK_CS(size) \ @@ -105,22 +105,34 @@ cs_count--; \ } while (0) -#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ +#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \ "domains (%d, %d, %d)\n", \ bo, offset, rd, wd, flags); \ assert(bo); \ cs_winsys->write_cs_dword(cs_winsys, offset); \ - cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ + r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ cs_count -= 3; \ } while (0) -#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ + +#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \ + DBG(cs_context_copy, DBG_CS, "r300: writing relocation for texture %p, offset %d, " \ + "domains (%d, %d, %d)\n", \ + tex, offset, rd, wd, flags); \ + assert(tex); \ + cs_winsys->write_cs_dword(cs_winsys, offset); \ + r300_texture_write_reloc(cs_winsys, tex, rd, wd, flags); \ + cs_count -= 3; \ +} while (0) + + +#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \ "domains (%d, %d, %d)\n", \ bo, rd, wd, flags); \ assert(bo); \ - cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ + r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ cs_count -= 2; \ } while (0) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f7dcd8dc52f..6fb1d7bd922 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,6 +32,8 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" +#include "r300_screen_buffer.h" +#include "r300_state_inlines.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) @@ -418,10 +420,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "cbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level], + OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); @@ -434,12 +436,12 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level], + OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); } @@ -489,13 +491,13 @@ static void r300_emit_query_finish(struct r300_context *r300, /* pipe 3 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), 0, RADEON_GEM_DOMAIN_GTT, 0); case 3: /* pipe 2 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), 0, RADEON_GEM_DOMAIN_GTT, 0); case 2: /* pipe 1 only */ @@ -503,13 +505,13 @@ static void r300_emit_query_finish(struct r300_context *r300, OUT_CS_REG(R300_SU_REG_DEST, 1 << (caps->high_second_pipe ? 3 : 1)); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), 0, RADEON_GEM_DOMAIN_GTT, 0); case 1: /* pipe 0 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), 0, RADEON_GEM_DOMAIN_GTT, 0); break; default: @@ -531,7 +533,7 @@ static void rv530_emit_query_single(struct r300_context *r300, BEGIN_CS(8); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -544,10 +546,10 @@ static void rv530_emit_query_double(struct r300_context *r300, BEGIN_CS(14); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -759,7 +761,7 @@ void r300_emit_texture(struct r300_context* r300, OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1); OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2); OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1); - OUT_CS_RELOC(tex->buffer, + OUT_CS_TEX_RELOC(tex, R300_TXO_MACRO_TILE(tex->macrotile) | R300_TXO_MICRO_TILE(tex->microtile), RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); @@ -800,7 +802,7 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) } for (i = 0; i < aos_count; i++) { - OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, + OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, RADEON_GEM_DOMAIN_GTT, 0, 0); } END_CS; @@ -1012,15 +1014,15 @@ void r300_emit_buffer_validate(struct r300_context *r300) boolean invalid = FALSE; /* Clean out BOs. */ - r300->winsys->reset_bos(r300->winsys); + r300->rws->reset_bos(r300->rws); validate: /* Color buffers... */ for (i = 0; i < fb->nr_cbufs; i++) { tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300_add_texture(r300->rws, tex, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1029,8 +1031,8 @@ validate: if (fb->zsbuf) { tex = (struct r300_texture*)fb->zsbuf->texture; assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300_add_texture(r300->rws, tex, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1040,31 +1042,31 @@ validate: tex = r300->textures[i]; if (!tex) continue; - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { + if (!r300_add_texture(r300->rws, tex, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...occlusion query buffer... */ if (r300->dirty_state & R300_NEW_QUERY) { - if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, - 0, RADEON_GEM_DOMAIN_GTT)) { + if (!r300_add_buffer(r300->rws, r300->oqbo, + 0, RADEON_GEM_DOMAIN_GTT)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...and vertex buffer. */ if (r300->vbo) { - if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300_add_buffer(r300->rws, r300->vbo, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } else { /* debug_printf("No VBO while emitting dirty state!\n"); */ } - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { /* Well, hell. */ @@ -1096,7 +1098,7 @@ void r300_emit_dirty_state(struct r300_context* r300) /* Make sure we have at least 2*1024 spare dwords. */ /* XXX It would be nice to know the number of dwords we really need to * XXX emit. */ - while (!r300->winsys->check_cs(r300->winsys, dwords)) { + while (!r300->rws->check_cs(r300->rws, dwords)) { r300->context.flush(&r300->context, 0, NULL); } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 754eb4dc769..47f5d6f7f16 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -30,10 +30,12 @@ #include "util/u_format.h" #include "util/u_memory.h" +#include "util/u_upload_mgr.h" #include "util/u_prim.h" #include "r300_cs.h" #include "r300_context.h" +#include "r300_screen_buffer.h" #include "r300_emit.h" #include "r300_reg.h" #include "r300_render.h" @@ -297,7 +299,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | (0 << R300_INDX_BUFFER_SKIP_SHIFT)); OUT_CS(offset_dwords << 2); - OUT_CS_RELOC(indexBuffer, count_dwords, + OUT_CS_BUF_RELOC(indexBuffer, count_dwords, RADEON_GEM_DOMAIN_GTT, 0, 0); END_CS; @@ -308,21 +310,28 @@ static boolean r300_setup_vertex_buffers(struct r300_context *r300) struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_buffer *pbuf; + int ret; + + /* upload buffers first */ + if (r300->any_user_vbs) { + ret = r300_upload_user_buffers(r300); + r300->any_user_vbs = false; + } validate: for (int i = 0; i < r300->vertex_element_count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300_add_buffer(r300->rws, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { r300->context.flush(&r300->context, 0, NULL); - return r300->winsys->validate(r300->winsys); + return r300->rws->validate(r300->rws); } return TRUE; @@ -396,15 +405,20 @@ void r300_draw_range_elements(struct pipe_context* pipe, indexSize = 2; } - if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + r300_upload_index_buffer(r300, &indexBuffer, + indexSize, start, count); + + if (!r300_add_buffer(r300->rws, indexBuffer, + RADEON_GEM_DOMAIN_GTT, 0)) { goto cleanup; } - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { goto cleanup; } + u_upload_flush(r300->upload_vb); + u_upload_flush(r300->upload_ib); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); @@ -425,7 +439,7 @@ void r300_draw_range_elements(struct pipe_context* pipe, cleanup: if (indexBuffer != orgIndexBuffer) { - pipe->screen->buffer_destroy(indexBuffer); + pipe_buffer_reference( &indexBuffer, NULL ); } } @@ -466,6 +480,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return; } + u_upload_flush(r300->upload_vb); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 6a55570571a..3b70312c829 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -23,7 +23,6 @@ #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" -#include "util/u_simple_screen.h" #include "r300_context.h" #include "r300_screen.h" @@ -32,6 +31,8 @@ #include "radeon_winsys.h" #include "r300_winsys.h" +#include "r300_screen_buffer.h" + /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. * @@ -292,10 +293,11 @@ static void* r300_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; + struct r300_winsys_screen *rws = r300_winsys_screen(screen); char* map; enum pipe_format format = tex->tex.format; - map = pipe_buffer_map(screen, tex->buffer, + map = rws->buffer_map(rws, tex->buffer, pipe_transfer_buffer_flags(transfer)); if (!map) { @@ -311,21 +313,26 @@ static void r300_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; - pipe_buffer_unmap(screen, tex->buffer); + struct r300_winsys_screen *rws = r300_winsys_screen(screen); + rws->buffer_unmap(rws, tex->buffer); } static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); + struct r300_winsys_screen *rws = r300_winsys_screen(pscreen); + + if (rws) + rws->destroy(rws); FREE(r300screen->caps); FREE(r300screen); } -struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) +struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) { - struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); - struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); + struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen); + struct r300_capabilities *caps = CALLOC_STRUCT(r300_capabilities); if (!r300screen || !caps) { FREE(r300screen); @@ -333,16 +340,16 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) return NULL; } - caps->pci_id = radeon_winsys->pci_id; - caps->num_frag_pipes = radeon_winsys->gb_pipes; - caps->num_z_pipes = radeon_winsys->z_pipes; + caps->pci_id = rws->get_value(rws, R300_VID_PCI_ID); + caps->num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES); + caps->num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES); r300_init_debug(r300screen); r300_parse_chipset(caps); r300screen->caps = caps; - r300screen->radeon_winsys = radeon_winsys; - r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys; + r300screen->rws = rws; + r300screen->screen.winsys = (struct pipe_winsys*)rws; r300screen->screen.destroy = r300_destroy_screen; r300screen->screen.get_name = r300_get_name; r300screen->screen.get_vendor = r300_get_vendor; @@ -356,7 +363,12 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) r300screen->screen.transfer_unmap = r300_transfer_unmap; r300_init_screen_texture_functions(&r300screen->screen); - u_simple_screen_init(&r300screen->screen); - + r300_screen_init_buffer_functions(r300screen); return &r300screen->screen; } + +struct r300_winsys_screen * +r300_winsys_screen(struct pipe_screen *screen) +{ + return r300_screen(screen)->rws; +} diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 502fbfa5a24..87fc6190ce6 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -33,7 +33,7 @@ struct r300_screen { /* Parent class */ struct pipe_screen screen; - struct radeon_winsys* radeon_winsys; + struct r300_winsys_screen *rws; /* Chipset capabilities */ struct r300_capabilities* caps; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c new file mode 100644 index 00000000000..358582ea211 --- /dev/null +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -0,0 +1,222 @@ +#include + +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" +#include "util/u_upload_mgr.h" + +#include "r300_screen_buffer.h" + +#include "r300_winsys.h" + +int r300_upload_index_buffer(struct r300_context *r300, + struct pipe_buffer **index_buffer, + unsigned index_size, + unsigned start, + unsigned count) +{ + struct pipe_buffer *upload_buffer = NULL; + unsigned index_offset = start * index_size; + int ret = 0; + + if (r300_buffer_is_user_buffer(*index_buffer)) { + ret = u_upload_buffer(r300->upload_ib, + index_offset, + count * index_size, + *index_buffer, + &index_offset, + &upload_buffer); + if (ret) { + goto done; + } + *index_buffer = upload_buffer; + } + done: + // if (upload_buffer) + // pipe_buffer_reference(&upload_buffer, NULL); + return ret; +} + +int r300_upload_user_buffers(struct r300_context *r300) +{ + enum pipe_error ret = PIPE_OK; + int i, nr; + + nr = r300->vertex_buffer_count; + + for (i = 0; i < nr; i++) { + + if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) { + struct pipe_buffer *upload_buffer = NULL; + unsigned offset = 0; + unsigned size = r300->vertex_buffer[i].buffer->size; + unsigned upload_offset; + + ret = u_upload_buffer(r300->upload_vb, + offset, size, + r300->vertex_buffer[i].buffer, + &upload_offset, &upload_buffer); + if (ret) + return ret; + + pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); + r300->vertex_buffer[i].buffer = upload_buffer; + r300->vertex_buffer[i].buffer_offset = upload_offset; + } + } + return ret; +} + +static struct r300_winsys_buffer * +r300_winsys_buffer_create(struct r300_screen *r300screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_winsys_buffer *buf; + + buf = rws->buffer_create(rws, alignment, usage, size); + return buf; +} + +static void r300_winsys_buffer_destroy(struct r300_screen *r300screen, + struct r300_buffer *rbuf) +{ + struct r300_winsys_screen *rws = r300screen->rws; + + if (rbuf->buf) { + rws->buffer_destroy(rbuf->buf); + rbuf->buf = NULL; + } +} + +static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_buffer *rbuf; + + rbuf = CALLOC_STRUCT(r300_buffer); + if (!rbuf) + goto error1; + + rbuf->magic = R300_BUFFER_MAGIC; + + pipe_reference_init(&rbuf->base.reference, 1); + rbuf->base.screen = screen; + rbuf->base.alignment = alignment; + rbuf->base.usage = usage; + rbuf->base.size = size; + + rbuf->buf = r300_winsys_buffer_create(r300screen, + alignment, + usage, + size); + + if (!rbuf->buf) + goto error2; + + return &rbuf->base; +error2: + FREE(rbuf); +error1: + return NULL; +} + + +static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes) +{ + struct r300_buffer *rbuf; + + rbuf = CALLOC_STRUCT(r300_buffer); + if (!rbuf) + goto no_rbuf; + + rbuf->magic = R300_BUFFER_MAGIC; + + pipe_reference_init(&rbuf->base.reference, 1); + rbuf->base.screen = screen; + rbuf->base.alignment = 1; + rbuf->base.usage = 0; + rbuf->base.size = bytes; + + rbuf->user_buffer = ptr; + return &rbuf->base; + +no_rbuf: + return NULL; +} + +static void r300_buffer_destroy(struct pipe_buffer *buf) +{ + struct r300_screen *r300screen = r300_screen(buf->screen); + struct r300_buffer *rbuf = r300_buffer(buf); + + r300_winsys_buffer_destroy(r300screen, rbuf); + FREE(rbuf); +} + +static void * +r300_buffer_map_range(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned length, + unsigned usage ) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_buffer *rbuf = r300_buffer(buf); + void *map; + + if (rbuf->user_buffer) + return rbuf->user_buffer; + + map = rws->buffer_map(rws, rbuf->buf, usage); + + return map; +} + +static void * +r300_buffer_map(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned usage) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_buffer *rbuf = r300_buffer(buf); + void *map; + + if (rbuf->user_buffer) + return rbuf->user_buffer; + + map = rws->buffer_map(rws, rbuf->buf, usage); + + return map; +} + +static void +r300_buffer_unmap(struct pipe_screen *screen, + struct pipe_buffer *buf) +{ + struct r300_screen *r300screen = r300_screen(screen); + struct r300_winsys_screen *rws = r300screen->rws; + struct r300_buffer *rbuf = r300_buffer(buf); + + if (rbuf->buf) + rws->buffer_unmap(rws, rbuf->buf); +} + +void r300_screen_init_buffer_functions(struct r300_screen *r300screen) +{ + r300screen->screen.buffer_create = r300_buffer_create; + r300screen->screen.user_buffer_create = r300_user_buffer_create; + r300screen->screen.buffer_map = r300_buffer_map; + r300screen->screen.buffer_map_range = r300_buffer_map_range; +// r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range; + r300screen->screen.buffer_unmap = r300_buffer_unmap; + r300screen->screen.buffer_destroy = r300_buffer_destroy; +} diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h new file mode 100644 index 00000000000..7c026508b59 --- /dev/null +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -0,0 +1,85 @@ +#ifndef R300_SCREEN_BUFFER_H +#define R300_SCREEN_BUFFER_H +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "r300_screen.h" + +#include "r300_winsys.h" +#include "r300_context.h" + +#define R300_BUFFER_MAGIC 0xabcd1234 + +struct r300_buffer +{ + struct pipe_buffer base; + + uint32_t magic; + + struct r300_winsys_buffer *buf; + + void *user_buffer; +}; + +static INLINE struct r300_buffer * +r300_buffer(struct pipe_buffer *buffer) +{ + if (buffer) { + assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC); + return (struct r300_buffer *)buffer; + } + return NULL; +} + +static INLINE boolean +r300_buffer_is_user_buffer(struct pipe_buffer *buffer) +{ + return r300_buffer(buffer)->user_buffer ? true : false; +} + +static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws, + struct pipe_buffer *buffer, + int rd, int wr) +{ + struct r300_buffer *buf = r300_buffer(buffer); + + if (!buf->buf) + return true; + + return rws->add_buffer(rws, buf->buf, rd, wr); +} + + +static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws, + struct r300_texture *tex, + int rd, int wr) +{ + return rws->add_buffer(rws, tex->buffer, rd, wr); +} + +void r300_screen_init_buffer_functions(struct r300_screen *r300screen); + +static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws, + struct r300_buffer *buf, + uint32_t rd, uint32_t wd, uint32_t flags) +{ + if (!buf->buf) + return; + + rws->write_cs_reloc(rws, buf->buf, rd, wd, flags); +} + +static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws, + struct r300_texture *texture, + uint32_t rd, uint32_t wd, uint32_t flags) +{ + rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags); +} + +int r300_upload_user_buffers(struct r300_context *r300); + +int r300_upload_index_buffer(struct r300_context *r300, + struct pipe_buffer **index_buffer, + unsigned index_size, + unsigned start, + unsigned count); +#endif diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c1930..d8a87dec151 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -34,6 +34,7 @@ #include "r300_context.h" #include "r300_reg.h" #include "r300_screen.h" +#include "r300_screen_buffer.h" #include "r300_state_inlines.h" #include "r300_fs.h" #include "r300_vs.h" @@ -521,7 +522,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->cbufs[i]->texture; if (tex) { - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -533,7 +534,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->zsbuf->texture; if (tex) { - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -545,7 +546,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->cbufs[i]->texture; level = new_state->cbufs[i]->level; - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -554,7 +555,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->zsbuf->texture; level = new_state->zsbuf->level; - r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + r300->rws->buffer_set_tiling(r300->rws, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -1028,10 +1029,26 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); + boolean any_user_buffer = false; + int i; + + if (count == r300->vertex_buffer_count && + memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0) + return; + + for (i = 0; i < count; i++) { + pipe_buffer_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer); + if (r300_buffer_is_user_buffer(buffers[i].buffer)) + any_user_buffer = true; + } + + for ( ; i < r300->vertex_buffer_count; i++) + pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); memcpy(r300->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); r300->vertex_buffer_count = count; + r300->any_user_vbs = any_user_buffer; if (r300->draw) { draw_flush(r300->draw); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index ed2be06254a..9016e86ccd7 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -731,7 +731,7 @@ static struct pipe_texture* { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); struct r300_screen* rscreen = r300_screen(screen); - struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; if (!tex) { return NULL; @@ -745,13 +745,13 @@ static struct pipe_texture* r300_setup_miptree(rscreen, tex); r300_setup_texture_state(rscreen, tex); - tex->buffer = screen->buffer_create(screen, 2048, - PIPE_BUFFER_USAGE_PIXEL, - tex->size); - winsys->buffer_set_tiling(winsys, tex->buffer, - tex->pitch[0], - tex->microtile != R300_BUFFER_LINEAR, - tex->macrotile != R300_BUFFER_LINEAR); + tex->buffer = rws->buffer_create(rws, 2048, + PIPE_BUFFER_USAGE_PIXEL, + tex->size); + rws->buffer_set_tiling(rws, tex->buffer, + tex->pitch[0], + tex->microtile != R300_BUFFER_LINEAR, + tex->macrotile != R300_BUFFER_LINEAR); if (!tex->buffer) { FREE(tex); @@ -764,9 +764,9 @@ static struct pipe_texture* static void r300_texture_destroy(struct pipe_texture* texture) { struct r300_texture* tex = (struct r300_texture*)texture; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; - pipe_buffer_reference(&tex->buffer, NULL); - + rws->buffer_reference(rws, &tex->buffer, NULL); FREE(tex); } @@ -806,14 +806,14 @@ static void r300_tex_surface_destroy(struct pipe_surface* s) FREE(s); } -static struct pipe_texture* - r300_texture_blanket(struct pipe_screen* screen, - const struct pipe_texture* base, - const unsigned* stride, - struct pipe_buffer* buffer) +struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, + const struct pipe_texture *base, + const unsigned *stride, + struct r300_winsys_buffer *buffer) { struct r300_texture* tex; struct r300_screen* rscreen = r300_screen(screen); + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || @@ -837,7 +837,7 @@ static struct pipe_texture* r300_setup_flags(tex); r300_setup_texture_state(rscreen, tex); - pipe_buffer_reference(&tex->buffer, buffer); + rws->buffer_reference(rws, &tex->buffer, buffer); return (struct pipe_texture*)tex; } @@ -896,7 +896,6 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; screen->tex_surface_destroy = r300_tex_surface_destroy; - screen->texture_blanket = r300_texture_blanket; screen->video_surface_create = r300_video_surface_create; screen->video_surface_destroy= r300_video_surface_destroy; @@ -904,19 +903,23 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct pipe_buffer** buffer, + struct r300_winsys_buffer** buffer, unsigned* stride) { struct r300_texture* tex = (struct r300_texture*)texture; + struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; + struct r300_winsys_buffer *buf; + if (!tex) { return FALSE; } - pipe_buffer_reference(buffer, tex->buffer); + rws->buffer_reference(rws, &buf, tex->buffer); if (stride) { *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); } + *buffer = buf; return TRUE; } diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 46a5fb6188b..97724f790c8 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -63,8 +63,8 @@ r300_video_surface(struct pipe_video_surface *pvs) #ifndef R300_WINSYS_H boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, + struct pipe_texture *texture, + struct r300_winsys_buffer** buffer, unsigned* stride); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 40fb8a95ca5..c6f9174496b 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -23,10 +23,6 @@ #ifndef R300_WINSYS_H #define R300_WINSYS_H -#ifdef __cplusplus -extern "C" { -#endif - /* The public interface header for the r300 pipe driver. * Any winsys hosting this pipe needs to implement r300_winsys and then * call r300_create_screen to start things. */ @@ -34,19 +30,128 @@ extern "C" { #include "pipe/p_defines.h" #include "pipe/p_state.h" -struct radeon_winsys; +struct r300_winsys_screen; /* Creates a new r300 screen. */ -struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); +struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws); + +struct r300_winsys_buffer; boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride); + struct r300_winsys_buffer** buffer, + unsigned *stride); + +enum r300_value_id { + R300_VID_PCI_ID, + R300_VID_GB_PIPES, + R300_VID_Z_PIPES, +}; + +struct r300_winsys_screen { + void (*destroy)(struct r300_winsys_screen *ws); + + /** + * Buffer management. Buffer attributes are mostly fixed over its lifetime. + * + * Remember that gallium gets to choose the interface it needs, and the + * window systems must then implement that interface (rather than the + * other way around...). + * + * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This + * usage argument is only an optimization hint, not a guarantee, therefore + * proper behavior must be observed in all circumstances. + * + * alignment indicates the client's alignment requirements, eg for + * SSE instructions. + */ + struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws, + unsigned alignment, + unsigned usage, + unsigned size); + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags. + */ + void *(*buffer_map)( struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf, + unsigned usage ); + + void (*buffer_unmap)( struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf ); + + void (*buffer_destroy)( struct r300_winsys_buffer *buf ); + + + void (*buffer_reference)(struct r300_winsys_screen *rws, + struct r300_winsys_buffer **pdst, + struct r300_winsys_buffer *src); + + boolean (*buffer_references)(struct r300_winsys_buffer *a, + struct r300_winsys_buffer *b); + + /* Add a pipe_buffer to the list of buffer objects to validate. */ + boolean (*add_buffer)(struct r300_winsys_screen *winsys, + struct r300_winsys_buffer *buf, + uint32_t rd, + uint32_t wd); + + /* Revalidate all currently setup pipe_buffers. + * Returns TRUE if a flush is required. */ + boolean (*validate)(struct r300_winsys_screen* winsys); + + /* Check to see if there's room for commands. */ + boolean (*check_cs)(struct r300_winsys_screen* winsys, int size); + + /* Start a command emit. */ + void (*begin_cs)(struct r300_winsys_screen* winsys, + int size, + const char* file, + const char* function, + int line); + + /* Write a dword to the command buffer. */ + void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword); + + /* Write a relocated dword to the command buffer. */ + void (*write_cs_reloc)(struct r300_winsys_screen *winsys, + struct r300_winsys_buffer *buf, + uint32_t rd, + uint32_t wd, + uint32_t flags); + + /* Finish a command emit. */ + void (*end_cs)(struct r300_winsys_screen* winsys, + const char* file, + const char* function, + int line); + + /* Flush the CS. */ + void (*flush_cs)(struct r300_winsys_screen* winsys); + + /* winsys flush - callback from winsys when flush required */ + void (*set_flush_cb)(struct r300_winsys_screen *winsys, + void (*flush_cb)(void *), void *data); + + void (*reset_bos)(struct r300_winsys_screen *winsys); + + void (*buffer_set_tiling)(struct r300_winsys_screen *winsys, + struct r300_winsys_buffer *buffer, + uint32_t pitch, + boolean microtiled, + boolean macrotiled); + + uint32_t (*get_value)(struct r300_winsys_screen *winsys, + enum r300_value_id vid); +}; -#ifdef __cplusplus -} -#endif +struct r300_winsys_screen * +r300_winsys_screen(struct pipe_screen *screen); +struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, + const struct pipe_texture *base, + const unsigned *stride, + struct r300_winsys_buffer *buffer); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h index c6a7d4a8c51..b36680eb667 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h @@ -32,8 +32,6 @@ i965_libdrm_winsys(struct brw_winsys_screen *iws) return (struct i965_libdrm_winsys *)iws; } -struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id); - void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws); diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/drm/radeon/core/Makefile index 860cbb6dbf8..13bbbf730d6 100644 --- a/src/gallium/winsys/drm/radeon/core/Makefile +++ b/src/gallium/winsys/drm/radeon/core/Makefile @@ -5,7 +5,7 @@ include $(TOP)/configs/current LIBNAME = radeonwinsys C_SOURCES = \ - radeon_buffer.c \ + radeon_drm_buffer.c \ radeon_drm.c \ radeon_r300.c diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index f1c8fc2a3b1..8e0274e33d5 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -32,11 +32,11 @@ #include -#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "pipebuffer/pb_buffer.h" +#include "pipebuffer/pb_bufmgr.h" #include "util/u_memory.h" @@ -47,41 +47,41 @@ #include "radeon_winsys.h" -struct radeon_pipe_buffer { - struct pipe_buffer base; - /* Pointer to GPU-backed BO. */ - struct radeon_bo *bo; - /* Pointer to fallback PB buffer. */ - struct pb_buffer *pb; - boolean flinked; - uint32_t flink; -}; #define RADEON_MAX_BOS 24 -struct radeon_winsys_priv { - /* DRM FD */ - int fd; +static INLINE struct pb_buffer * +radeon_pb_buffer(struct r300_winsys_buffer *buffer) +{ + return (struct pb_buffer *)buffer; +} - /* Radeon BO manager. */ - struct radeon_bo_manager* bom; +static INLINE struct r300_winsys_buffer * +radeon_libdrm_winsys_buffer(struct pb_buffer *buffer) +{ + return (struct r300_winsys_buffer *)buffer; +} - /* Radeon CS manager. */ - struct radeon_cs_manager* csm; +struct pb_manager * +radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws); - /* Current CS. */ - struct radeon_cs* cs; +boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd); - /* Flush CB */ - void (*flush_cb)(void *); - void *flush_data; -}; -struct radeon_winsys* radeon_pipe_winsys(int fb); -#if 0 -struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, - uint32_t handle, - enum pipe_format format, - int w, int h, int pitch); -#endif +void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd, + uint32_t flags); + +struct radeon_libdrm_winsys* radeon_pipe_winsys(int fd); + +boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, + uint32_t *handle); +uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf); +struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, + uint32_t handle); + +void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch); + +void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr); #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index 0c0e118ba3a..f886fda2f27 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -31,8 +31,22 @@ #include "radeon_drm.h" +static struct radeon_libdrm_winsys * +radeon_winsys_create(int fd) +{ + struct radeon_libdrm_winsys *rws; + + rws = CALLOC_STRUCT(radeon_libdrm_winsys); + if (rws == NULL) { + return NULL; + } + + rws->fd = fd; + return rws; +} + /* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(int fd, struct radeon_winsys* winsys) +static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) { struct drm_radeon_gem_info gem_info = {0}; struct drm_radeon_info info = {0}; @@ -123,62 +137,26 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg) { - struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB); - do_ioctls(drmFB, rwinsys); + struct radeon_libdrm_winsys* rws; + + rws = radeon_winsys_create(drmFB); + if (!rws) + return NULL; + + do_ioctls(drmFB, rws); /* The state tracker can organize a softpipe fallback if no hw * driver is found. */ - if (is_r3xx(rwinsys->pci_id)) { - radeon_setup_winsys(drmFB, rwinsys); - return r300_create_screen(rwinsys); + if (is_r3xx(rws->pci_id)) { + radeon_setup_winsys(drmFB, rws); + return r300_create_screen(&rws->base); } else { - FREE(rwinsys); + FREE(rws); return NULL; } } - -boolean radeon_buffer_from_texture(struct drm_api* api, - struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride) -{ - /* XXX fix this */ - return r300_get_texture_buffer(screen, texture, buffer, stride); -} - -/* Create a buffer from a handle. */ -/* XXX what's up with name? */ -struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, - struct pipe_screen* screen, - const char* name, - unsigned handle) -{ - struct radeon_bo_manager* bom = - ((struct radeon_winsys*)screen->winsys)->priv->bom; - struct radeon_pipe_buffer* radeon_buffer; - struct radeon_bo* bo = NULL; - - bo = radeon_bo_open(bom, handle, 0, 0, 0, 0); - if (bo == NULL) { - return NULL; - } - - radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); - if (radeon_buffer == NULL) { - radeon_bo_unref(bo); - return NULL; - } - - pipe_reference_init(&radeon_buffer->base.reference, 1); - radeon_buffer->base.screen = screen; - radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; - radeon_buffer->bo = bo; - return &radeon_buffer->base; -} - static struct pipe_texture* radeon_texture_from_shared_handle(struct drm_api *api, struct pipe_screen *screen, @@ -187,18 +165,20 @@ radeon_texture_from_shared_handle(struct drm_api *api, unsigned stride, unsigned handle) { - struct pipe_buffer *buffer; + struct pb_buffer *_buf; + struct r300_winsys_buffer *buf; struct pipe_texture *blanket; + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(r300_winsys_screen(screen)); - buffer = radeon_buffer_from_handle(api, screen, name, handle); - if (!buffer) { - return NULL; + _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle); + if (!_buf) { + return NULL; } - blanket = screen->texture_blanket(screen, templ, &stride, buffer); - - pipe_buffer_reference(&buffer, NULL); + buf = radeon_libdrm_winsys_buffer(_buf); + blanket = r300_texture_blanket_winsys_buffer(screen, templ, &stride, buf); + pb_reference(&_buf, NULL); return blanket; } @@ -208,34 +188,14 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - int retval, fd; - struct drm_gem_flink flink; - struct radeon_pipe_buffer* radeon_buffer; - struct pipe_buffer *buffer = NULL; - - if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { + struct r300_winsys_buffer *radeon_buffer; + struct pb_buffer *_buf; + if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { return FALSE; } - radeon_buffer = (struct radeon_pipe_buffer*)buffer; - if (!radeon_buffer->flinked) { - fd = ((struct radeon_winsys*)screen->winsys)->priv->fd; - - flink.handle = radeon_buffer->bo->handle; - - retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - if (retval) { - debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", - retval); - return FALSE; - } - - radeon_buffer->flink = flink.name; - radeon_buffer->flinked = TRUE; - } - - *handle = radeon_buffer->flink; - return TRUE; + _buf = radeon_pb_buffer(radeon_buffer); + return radeon_drm_bufmgr_shared_handle_from_buffer(_buf, handle); } static boolean radeon_local_handle_from_texture(struct drm_api *api, @@ -244,16 +204,18 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - struct pipe_buffer *buffer = NULL; - if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { + struct r300_winsys_buffer *radeon_buffer; + struct pb_buffer *_buf; + + if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { return FALSE; } - *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle; - - pipe_buffer_reference(&buffer, NULL); + _buf = radeon_pb_buffer(radeon_buffer); + *handle = radeon_drm_bufmgr_handle_from_buffer(_buf); - return TRUE; + pb_reference(&_buf, NULL); + return true; } static void radeon_drm_api_destroy(struct drm_api *api) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 8d74cbafc2f..2f550613307 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -59,11 +59,6 @@ boolean radeon_buffer_from_texture(struct drm_api* api, struct pipe_buffer** buffer, unsigned* stride); -struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, - struct pipe_screen* screen, - const char* name, - unsigned handle); - boolean radeon_handle_from_buffer(struct drm_api* api, struct pipe_screen* screen, struct pipe_buffer* buffer, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c new file mode 100644 index 00000000000..5f2fd2d7fc8 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c @@ -0,0 +1,361 @@ + +#include "radeon_drm.h" +#include "radeon_bo_gem.h" +#include "radeon_cs_gem.h" + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" +#include "pipebuffer/pb_buffer.h" +#include "pipebuffer/pb_bufmgr.h" + +#include "radeon_winsys.h" +struct radeon_drm_bufmgr; + +struct radeon_drm_buffer { + struct pb_buffer base; + struct radeon_drm_bufmgr *mgr; + + struct radeon_bo *bo; + + boolean flinked; + uint32_t flink; + + boolean mapped; + struct radeon_drm_buffer *next, *prev; +}; + +extern const struct pb_vtbl radeon_drm_buffer_vtbl; + + +static INLINE struct radeon_drm_buffer * +radeon_drm_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &radeon_drm_buffer_vtbl); + return (struct radeon_drm_buffer *)buf; +} + +struct radeon_drm_bufmgr { + struct pb_manager base; + struct radeon_libdrm_winsys *rws; + struct radeon_drm_buffer buffer_map_list; +}; + +static INLINE struct radeon_drm_bufmgr * +radeon_drm_bufmgr(struct pb_manager *mgr) +{ + assert(mgr); + return (struct radeon_drm_bufmgr *)mgr; +} + +static void +radeon_drm_buffer_destroy(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + + if (buf->mapped) { + remove_from_list(buf); + radeon_bo_unmap(buf->bo); + buf->mapped = false; + } + radeon_bo_unref(buf->bo); + + FREE(buf); +} + +static void * +radeon_drm_buffer_map(struct pb_buffer *_buf, + unsigned flags) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + int write; + + if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { + uint32_t domain; + + if (radeon_bo_is_busy(buf->bo, &domain)) + return NULL; + } + + if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) { + buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data); + } + + if (buf->mapped) + return buf->bo->ptr; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { + write = 1; + } + + if (radeon_bo_map(buf->bo, write)) { + return NULL; + } + buf->mapped = true; + insert_at_tail(&buf->mgr->buffer_map_list, buf); + return buf->bo->ptr; +} + +static void +radeon_drm_buffer_unmap(struct pb_buffer *_buf) +{ + (void)_buf; +} + +static void +radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + + +static enum pipe_error +radeon_drm_buffer_validate(struct pb_buffer *_buf, + struct pb_validate *vl, + unsigned flags) +{ + /* Always pinned */ + return PIPE_OK; +} + +static void +radeon_drm_buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ +} + +const struct pb_vtbl radeon_drm_buffer_vtbl = { + radeon_drm_buffer_destroy, + radeon_drm_buffer_map, + radeon_drm_buffer_unmap, + radeon_drm_buffer_validate, + radeon_drm_buffer_fence, + radeon_drm_buffer_get_base_buffer, +}; + + +static uint32_t radeon_domain_from_usage(unsigned usage) +{ + uint32_t domain = 0; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + return domain; +} + +struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, + uint32_t handle) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + struct radeon_libdrm_winsys *rws = mgr->rws; + struct radeon_drm_buffer *buf; + struct radeon_bo *bo; + + bo = radeon_bo_open(rws->bom, handle, 0, + 0, 0, 0); + if (bo == NULL) + return NULL; + + buf = CALLOC_STRUCT(radeon_drm_buffer); + if (!buf) { + radeon_bo_unref(bo); + return NULL; + } + + make_empty_list(buf); + + pipe_reference_init(&buf->base.base.reference, 1); + buf->base.base.alignment = 0; + buf->base.base.usage = PIPE_BUFFER_USAGE_PIXEL; + buf->base.base.size = 0; + buf->base.vtbl = &radeon_drm_buffer_vtbl; + buf->mgr = mgr; + + buf->bo = bo; + + // fprintf(stderr,"hand %p : %d\n", &buf->base, handle); + return &buf->base; + +} + +static struct pb_buffer * +radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr, + pb_size size, + const struct pb_desc *desc) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + struct radeon_libdrm_winsys *rws = mgr->rws; + struct radeon_drm_buffer *buf; + uint32_t domain; + + buf = CALLOC_STRUCT(radeon_drm_buffer); + if (!buf) + goto error1; + + pipe_reference_init(&buf->base.base.reference, 1); + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + buf->base.base.size = size; + buf->base.vtbl = &radeon_drm_buffer_vtbl; + buf->mgr = mgr; + + make_empty_list(buf); + domain = radeon_domain_from_usage(desc->usage); + buf->bo = radeon_bo_open(rws->bom, 0, size, + desc->alignment, domain, 0); + if (buf->bo == NULL) + goto error2; + + // fprintf(stderr,"%p : %d\n", &buf->base, size); + return &buf->base; + + error2: + FREE(buf); + error1: + return NULL; +} + +static void +radeon_drm_bufmgr_flush(struct pb_manager *mgr) +{ + /* NOP */ +} + +static void +radeon_drm_bufmgr_destroy(struct pb_manager *_mgr) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + FREE(mgr); +} + +struct pb_manager * +radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws) +{ + struct radeon_drm_bufmgr *mgr; + + mgr = CALLOC_STRUCT(radeon_drm_bufmgr); + if (!mgr) + return NULL; + + mgr->base.destroy = radeon_drm_bufmgr_destroy; + mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer; + mgr->base.flush = radeon_drm_bufmgr_flush; + + mgr->rws = rws; + make_empty_list(&mgr->buffer_map_list); + return &mgr->base; +} + +uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + + return buf->bo->handle; +} + +boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, + uint32_t *handle) +{ + struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); + struct drm_gem_flink flink; + int retval, fd; + if (!buf->flinked) { + fd = buf->mgr->rws->fd; + flink.handle = buf->bo->handle; + + retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (retval) { + return false; + } + + buf->flinked = TRUE; + buf->flink = flink.name; + } + *handle = buf->flink; + return TRUE; +} + +static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) +{ + struct radeon_drm_buffer *buf; + if (_buf->vtbl == &radeon_drm_buffer_vtbl) { + buf = radeon_drm_buffer(_buf); + } else { + struct pb_buffer *base_buf; + pb_size offset; + pb_get_base_buffer(_buf, &base_buf, &offset); + + buf = radeon_drm_buffer(base_buf); + } + return buf; +} + +void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + uint32_t flags = 0; + + if (microtiled) + flags |= RADEON_BO_FLAGS_MICRO_TILE; + if (macrotiled) + flags |= RADEON_BO_FLAGS_MACRO_TILE; + + radeon_bo_set_tiling(buf->bo, flags, pitch); + +} + +boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo, + rd, wd); + + return true; +} + +void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, + uint32_t rd, uint32_t wd, + uint32_t flags) +{ + struct radeon_drm_buffer *buf = get_drm_buffer(_buf); + int retval; + + retval = radeon_cs_write_reloc(buf->mgr->rws->cs, + buf->bo, rd, wd, flags); + if (retval) { + debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", + buf, rd, wd, flags); + } +} + +void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) +{ + struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); + struct radeon_drm_buffer *rpb, *t_rpb; + + foreach_s(rpb, t_rpb, &mgr->buffer_map_list) { + rpb->mapped = 0; + radeon_bo_unmap(rpb->bo); + remove_from_list(rpb); + } + + make_empty_list(&mgr->buffer_map_list); + + +} diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index d759beaba13..997abb8f5cb 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,29 +22,104 @@ #include "radeon_r300.h" -static void radeon_set_flush_cb(struct radeon_winsys *winsys, +static struct r300_winsys_buffer * +radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct pb_desc desc; + struct pb_manager *provider; + struct pb_buffer *buffer; + + memset(&desc, 0, sizeof(desc)); + desc.alignment = alignment; + desc.usage = usage; + + if (usage == PIPE_BUFFER_USAGE_CONSTANT) + provider = ws->mman; + else if (usage == PIPE_BUFFER_USAGE_VERTEX || + usage == PIPE_BUFFER_USAGE_INDEX) + provider = ws->cman; + else + provider = ws->kman; + buffer = provider->create_buffer(provider, size, &desc); + if (!buffer) + return NULL; + + return radeon_libdrm_winsys_buffer(buffer); +} + +static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + + pb_destroy(_buf); +} +static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, + uint32_t pitch, + boolean microtiled, + boolean macrotiled) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch); +} + +static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf, + unsigned usage) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + + return pb_map(_buf, 0); +} + +static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws, + struct r300_winsys_buffer *buf) +{ + struct pb_buffer *_buf = radeon_pb_buffer(buf); + + pb_unmap(_buf); +} + +static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, + struct r300_winsys_buffer **pdst, + struct r300_winsys_buffer *src) +{ + struct pb_buffer *_src = radeon_pb_buffer(src); + struct pb_buffer *_dst = radeon_pb_buffer(*pdst); + + pb_reference(&_dst, _src); + + *pdst = radeon_libdrm_winsys_buffer(_dst); +} + +static void radeon_set_flush_cb(struct r300_winsys_screen *rws, void (*flush_cb)(void *), void *data) { - winsys->priv->flush_cb = flush_cb; - winsys->priv->flush_data = data; - radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + ws->flush_cb = flush_cb; + ws->flush_data = data; + radeon_cs_space_set_flush(ws->cs, flush_cb, data); } -static boolean radeon_add_buffer(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, +static boolean radeon_add_buffer(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, uint32_t rd, uint32_t wd) { - struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; + struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd); - return TRUE; + return radeon_drm_bufmgr_add_buffer(_buf, rd, wd); } -static boolean radeon_validate(struct radeon_winsys* winsys) +static boolean radeon_validate(struct r300_winsys_screen *rws) { - if (radeon_cs_space_check(winsys->priv->cs) < 0) { + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + if (radeon_cs_space_check(ws->cs) < 0) { return FALSE; } @@ -52,108 +127,146 @@ static boolean radeon_validate(struct radeon_winsys* winsys) return TRUE; } -static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) +static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size) { - struct radeon_cs* cs = winsys->priv->cs; + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + struct radeon_cs *cs = ws->cs; - return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; + return radeon_validate(rws) && cs->cdw + size <= cs->ndw; } -static void radeon_begin_cs(struct radeon_winsys* winsys, +static void radeon_begin_cs(struct r300_winsys_screen *rws, int size, const char* file, const char* function, int line) { - radeon_cs_begin(winsys->priv->cs, size, file, function, line); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_begin(ws->cs, size, file, function, line); } -static void radeon_write_cs_dword(struct radeon_winsys* winsys, +static void radeon_write_cs_dword(struct r300_winsys_screen *rws, uint32_t dword) { - radeon_cs_write_dword(winsys->priv->cs, dword); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_write_dword(ws->cs, dword); } -static void radeon_write_cs_reloc(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, +static void radeon_write_cs_reloc(struct r300_winsys_screen *rws, + struct r300_winsys_buffer *buf, uint32_t rd, uint32_t wd, uint32_t flags) { - int retval = 0; - struct radeon_pipe_buffer* radeon_buffer = - (struct radeon_pipe_buffer*)pbuffer; - - assert(!radeon_buffer->pb); - - retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, - rd, wd, flags); - - if (retval) { - debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", - pbuffer, rd, wd, flags); - } + struct pb_buffer *_buf = radeon_pb_buffer(buf); + radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags); } -static void radeon_reset_bos(struct radeon_winsys *winsys) +static void radeon_reset_bos(struct r300_winsys_screen *rws) { - radeon_cs_space_reset_bos(winsys->priv->cs); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_space_reset_bos(ws->cs); } -static void radeon_end_cs(struct radeon_winsys* winsys, +static void radeon_end_cs(struct r300_winsys_screen *rws, const char* file, const char* function, int line) { - radeon_cs_end(winsys->priv->cs, file, function, line); + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); + radeon_cs_end(ws->cs, file, function, line); } -static void radeon_flush_cs(struct radeon_winsys* winsys) +static void radeon_flush_cs(struct r300_winsys_screen *rws) { + struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); int retval; /* Don't flush a zero-sized CS. */ - if (!winsys->priv->cs->cdw) { + if (!ws->cs->cdw) { return; } + radeon_drm_bufmgr_flush_maps(ws->kman); /* Emit the CS. */ - retval = radeon_cs_emit(winsys->priv->cs); + retval = radeon_cs_emit(ws->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); - radeon_cs_print(winsys->priv->cs, stderr); + radeon_cs_print(ws->cs, stderr); } /* Reset CS. * Someday, when we care about performance, we should really find a way * to rotate between two or three CS objects so that the GPU can be * spinning through one CS while another one is being filled. */ - radeon_cs_erase(winsys->priv->cs); + radeon_cs_erase(ws->cs); +} + +static uint32_t radeon_get_value(struct r300_winsys_screen *rws, + enum r300_value_id id) +{ + struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; + + switch(id) { + case R300_VID_PCI_ID: + return ws->pci_id; + case R300_VID_GB_PIPES: + return ws->gb_pipes; + case R300_VID_Z_PIPES: + return ws->z_pipes; + } + return 0; +} + +static void +radeon_winsys_destroy(struct r300_winsys_screen *rws) +{ + struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; + radeon_cs_destroy(ws->cs); + + ws->cman->destroy(ws->cman); + ws->kman->destroy(ws->kman); + ws->mman->destroy(ws->mman); + + radeon_bo_manager_gem_dtor(ws->bom); + radeon_cs_manager_gem_dtor(ws->csm); } void -radeon_setup_winsys(int fd, struct radeon_winsys* winsys) +radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) { - struct radeon_winsys_priv* priv = winsys->priv; + ws->csm = radeon_cs_manager_gem_ctor(fd); + + ws->bom = radeon_bo_manager_gem_ctor(fd); + ws->kman = radeon_drm_bufmgr_create(ws); - priv->csm = radeon_cs_manager_gem_ctor(fd); + ws->cman = pb_cache_manager_create(ws->kman, 100000); + ws->mman = pb_malloc_bufmgr_create(); /* Size limit on IBs is 64 kibibytes. */ - priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4); - radeon_cs_set_limit(priv->cs, - RADEON_GEM_DOMAIN_GTT, winsys->gart_size); - radeon_cs_set_limit(priv->cs, - RADEON_GEM_DOMAIN_VRAM, winsys->vram_size); - - winsys->add_buffer = radeon_add_buffer; - winsys->validate = radeon_validate; - - winsys->check_cs = radeon_check_cs; - winsys->begin_cs = radeon_begin_cs; - winsys->write_cs_dword = radeon_write_cs_dword; - winsys->write_cs_reloc = radeon_write_cs_reloc; - winsys->end_cs = radeon_end_cs; - winsys->flush_cs = radeon_flush_cs; - winsys->reset_bos = radeon_reset_bos; - winsys->set_flush_cb = radeon_set_flush_cb; + ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); + radeon_cs_set_limit(ws->cs, + RADEON_GEM_DOMAIN_GTT, ws->gart_size); + radeon_cs_set_limit(ws->cs, + RADEON_GEM_DOMAIN_VRAM, ws->vram_size); + + ws->base.add_buffer = radeon_add_buffer; + ws->base.validate = radeon_validate; + ws->base.destroy = radeon_winsys_destroy; + ws->base.check_cs = radeon_check_cs; + ws->base.begin_cs = radeon_begin_cs; + ws->base.write_cs_dword = radeon_write_cs_dword; + ws->base.write_cs_reloc = radeon_write_cs_reloc; + ws->base.end_cs = radeon_end_cs; + ws->base.flush_cs = radeon_flush_cs; + ws->base.reset_bos = radeon_reset_bos; + ws->base.set_flush_cb = radeon_set_flush_cb; + ws->base.get_value = radeon_get_value; + + ws->base.buffer_create = radeon_r300_winsys_buffer_create; + ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy; + ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling; + ws->base.buffer_map = radeon_r300_winsys_buffer_map; + ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; + ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index cfbdb302661..82a8aad715a 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -28,12 +28,12 @@ #include #include "drm.h" #include "radeon_drm.h" +#include "radeon_bo_gem.h" #include "radeon_cs_gem.h" -#include "r300_winsys.h" - +#include "radeon_winsys.h" #include "radeon_buffer.h" -void radeon_setup_winsys(int fd, struct radeon_winsys* winsys); +void radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys); #endif /* RADEON_R300_H */ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index 4901080ca7b..c8e725cff07 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -30,16 +30,17 @@ #ifndef RADEON_WINSYS_H #define RADEON_WINSYS_H -#include "util/u_simple_screen.h" +#include "r300_winsys.h" -struct radeon_winsys_priv; - -struct radeon_winsys { +struct radeon_libdrm_winsys { /* Parent class. */ - struct pipe_winsys base; + struct r300_winsys_screen base; + + struct pb_manager *kman; - /* Winsys private */ - struct radeon_winsys_priv* priv; + struct pb_manager *mman; + + struct pb_manager *cman; /* PCI ID */ uint32_t pci_id; @@ -56,56 +57,27 @@ struct radeon_winsys { /* VRAM size. */ uint32_t vram_size; - /* Add a pipe_buffer to the list of buffer objects to validate. */ - boolean (*add_buffer)(struct radeon_winsys* winsys, - struct pipe_buffer* pbuffer, - uint32_t rd, - uint32_t wd); - - /* Revalidate all currently setup pipe_buffers. - * Returns TRUE if a flush is required. */ - boolean (*validate)(struct radeon_winsys* winsys); - - /* Check to see if there's room for commands. */ - boolean (*check_cs)(struct radeon_winsys* winsys, int size); - - /* Start a command emit. */ - void (*begin_cs)(struct radeon_winsys* winsys, - int size, - const char* file, - const char* function, - int line); - - /* Write a dword to the command buffer. */ - void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword); - - /* Write a relocated dword to the command buffer. */ - void (*write_cs_reloc)(struct radeon_winsys* winsys, - struct pipe_buffer* bo, - uint32_t rd, - uint32_t wd, - uint32_t flags); - - /* Finish a command emit. */ - void (*end_cs)(struct radeon_winsys* winsys, - const char* file, - const char* function, - int line); - - /* Flush the CS. */ - void (*flush_cs)(struct radeon_winsys* winsys); - - /* winsys flush - callback from winsys when flush required */ - void (*set_flush_cb)(struct radeon_winsys *winsys, - void (*flush_cb)(void *), void *data); - - void (*reset_bos)(struct radeon_winsys *winsys); - - void (*buffer_set_tiling)(struct radeon_winsys* winsys, - struct pipe_buffer* buffer, - uint32_t pitch, - boolean microtiled, - boolean macrotiled); + /* DRM FD */ + int fd; + + /* Radeon BO manager. */ + struct radeon_bo_manager *bom; + + /* Radeon CS manager. */ + struct radeon_cs_manager *csm; + + /* Current CS. */ + struct radeon_cs *cs; + + /* Flush CB */ + void (*flush_cb)(void *); + void *flush_data; }; +static INLINE struct radeon_libdrm_winsys * +radeon_winsys_screen(struct r300_winsys_screen *base) +{ + return (struct radeon_libdrm_winsys *)base; +} + #endif -- cgit v1.2.3 From b14548ea32000459f4f0c4b49f3fa11d1ee9c003 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 22 Feb 2010 17:26:30 +1000 Subject: Revert "r300g: rebuild winsys/pipe buffer handling and add buffer map" This reverts commit fff5be8e7b4557c221f2425dcafc2e7cbbba76ba. Probably went too soon with this, dileX reported OA not working for him it works here fine, but the optimisations I wanted aren't working properly yet so I'll fix that now. Signed-off-by: Dave Airlie --- src/gallium/drivers/r300/Makefile | 1 - src/gallium/drivers/r300/r300_context.c | 38 +-- src/gallium/drivers/r300/r300_context.h | 9 +- src/gallium/drivers/r300/r300_cs.h | 22 +- src/gallium/drivers/r300/r300_emit.c | 54 ++- src/gallium/drivers/r300/r300_render.c | 33 +- src/gallium/drivers/r300/r300_screen.c | 38 +-- src/gallium/drivers/r300/r300_screen.h | 2 +- src/gallium/drivers/r300/r300_screen_buffer.c | 222 ------------- src/gallium/drivers/r300/r300_screen_buffer.h | 85 ----- src/gallium/drivers/r300/r300_state.c | 25 +- src/gallium/drivers/r300/r300_texture.c | 41 ++- src/gallium/drivers/r300/r300_texture.h | 4 +- src/gallium/drivers/r300/r300_winsys.h | 127 +------- src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h | 2 + src/gallium/winsys/drm/radeon/core/Makefile | 2 +- src/gallium/winsys/drm/radeon/core/radeon_buffer.h | 60 ++-- src/gallium/winsys/drm/radeon/core/radeon_drm.c | 134 +++++--- src/gallium/winsys/drm/radeon/core/radeon_drm.h | 5 + .../winsys/drm/radeon/core/radeon_drm_buffer.c | 361 --------------------- src/gallium/winsys/drm/radeon/core/radeon_r300.c | 237 ++++---------- src/gallium/winsys/drm/radeon/core/radeon_r300.h | 6 +- src/gallium/winsys/drm/radeon/core/radeon_winsys.h | 86 +++-- 23 files changed, 347 insertions(+), 1247 deletions(-) delete mode 100644 src/gallium/drivers/r300/r300_screen_buffer.c delete mode 100644 src/gallium/drivers/r300/r300_screen_buffer.h delete mode 100644 src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 5707309bdf9..afddcb161fa 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -14,7 +14,6 @@ C_SOURCES = \ r300_query.c \ r300_render.c \ r300_screen.c \ - r300_screen_buffer.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index a8a6a07a841..f631b4ed27f 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -24,7 +24,6 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" -#include "util/u_upload_mgr.h" #include "r300_blit.h" #include "r300_context.h" @@ -55,9 +54,6 @@ static void r300_destroy_context(struct pipe_context* context) FREE(query); } - u_upload_destroy(r300->upload_vb); - u_upload_destroy(r300->upload_ib); - FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); FREE(r300->fb_state.state); @@ -74,7 +70,11 @@ r300_is_texture_referenced(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level) { - return 0; + struct pipe_buffer* buf = 0; + + r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); + + return pipe->is_buffer_referenced(pipe, buf); } static unsigned int @@ -136,14 +136,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, { struct r300_context* r300 = CALLOC_STRUCT(r300_context); struct r300_screen* r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; + struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys; if (!r300) return NULL; - r300->rws = rws; + r300->winsys = radeon_winsys; - r300->context.winsys = (struct pipe_winsys*)rws; + r300->context.winsys = (struct pipe_winsys*)radeon_winsys; r300->context.screen = screen; r300->context.priv = priv; @@ -201,31 +201,11 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->invariant_state.dirty = TRUE; - rws->set_flush_cb(r300->rws, r300_flush_cb, r300); + r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw++; r300->blitter = util_blitter_create(&r300->context); - r300->upload_ib = u_upload_create(screen, - 32 * 1024, 16, - PIPE_BUFFER_USAGE_INDEX); - - if (r300->upload_ib == NULL) - goto no_upload_ib; - - r300->upload_vb = u_upload_create(screen, - 128 * 1024, 16, - PIPE_BUFFER_USAGE_VERTEX); - if (r300->upload_vb == NULL) - goto no_upload_vb; - return &r300->context; - - // u_upload_destroy(r300->upload_vb); - no_upload_ib: - u_upload_destroy(r300->upload_ib); - no_upload_vb: - FREE(r300); - return NULL; } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 749bac04987..443af4ec2e3 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -32,7 +32,6 @@ #include "r300_screen.h" -struct u_upload_mgr; struct r300_context; struct r300_fragment_shader; @@ -239,7 +238,7 @@ struct r300_texture { boolean is_npot; /* Pipe buffer backing this texture. */ - struct r300_winsys_buffer *buffer; + struct pipe_buffer* buffer; /* Registers carrying texture format data. */ struct r300_texture_state state; @@ -266,7 +265,7 @@ struct r300_context { struct pipe_context context; /* The interface to the windowing system, etc. */ - struct r300_winsys_screen *rws; + struct radeon_winsys* winsys; /* Draw module. Used mostly for SW TCL. */ struct draw_context* draw; /* Accelerated blit support. */ @@ -331,7 +330,6 @@ struct r300_context { /* Vertex elements for Gallium. */ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; - bool any_user_vbs; struct pipe_stencil_ref stencil_ref; @@ -345,9 +343,6 @@ struct r300_context { boolean polygon_offset_enabled; /* Z buffer bit depth. */ uint32_t zbuffer_bpp; - - struct u_upload_mgr *upload_vb; - struct u_upload_mgr *upload_ib; }; /* Convenience cast wrapper. */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index ad07efbffdb..151f72b0fe4 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -51,7 +51,7 @@ #define CS_LOCALS(context) \ struct r300_context* const cs_context_copy = (context); \ - struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \ + struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \ int cs_count = 0; (void) cs_count; #define CHECK_CS(size) \ @@ -105,34 +105,22 @@ cs_count--; \ } while (0) -#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \ +#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \ "domains (%d, %d, %d)\n", \ bo, offset, rd, wd, flags); \ assert(bo); \ cs_winsys->write_cs_dword(cs_winsys, offset); \ - r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ - cs_count -= 3; \ -} while (0) - - -#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \ - DBG(cs_context_copy, DBG_CS, "r300: writing relocation for texture %p, offset %d, " \ - "domains (%d, %d, %d)\n", \ - tex, offset, rd, wd, flags); \ - assert(tex); \ - cs_winsys->write_cs_dword(cs_winsys, offset); \ - r300_texture_write_reloc(cs_winsys, tex, rd, wd, flags); \ + cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ cs_count -= 3; \ } while (0) - -#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ +#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \ "domains (%d, %d, %d)\n", \ bo, rd, wd, flags); \ assert(bo); \ - r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \ + cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ cs_count -= 2; \ } while (0) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 6fb1d7bd922..f7dcd8dc52f 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,8 +32,6 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" -#include "r300_screen_buffer.h" -#include "r300_state_inlines.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) @@ -420,10 +418,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "cbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); - OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); - OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level], + OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); @@ -436,12 +434,12 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level], + OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); } @@ -491,13 +489,13 @@ static void r300_emit_query_finish(struct r300_context *r300, /* pipe 3 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), 0, RADEON_GEM_DOMAIN_GTT, 0); case 3: /* pipe 2 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), 0, RADEON_GEM_DOMAIN_GTT, 0); case 2: /* pipe 1 only */ @@ -505,13 +503,13 @@ static void r300_emit_query_finish(struct r300_context *r300, OUT_CS_REG(R300_SU_REG_DEST, 1 << (caps->high_second_pipe ? 3 : 1)); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), 0, RADEON_GEM_DOMAIN_GTT, 0); case 1: /* pipe 0 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), + OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), 0, RADEON_GEM_DOMAIN_GTT, 0); break; default: @@ -533,7 +531,7 @@ static void rv530_emit_query_single(struct r300_context *r300, BEGIN_CS(8); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -546,10 +544,10 @@ static void rv530_emit_query_double(struct r300_context *r300, BEGIN_CS(14); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -761,7 +759,7 @@ void r300_emit_texture(struct r300_context* r300, OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1); OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2); OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1); - OUT_CS_TEX_RELOC(tex, + OUT_CS_RELOC(tex->buffer, R300_TXO_MACRO_TILE(tex->macrotile) | R300_TXO_MICRO_TILE(tex->microtile), RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); @@ -802,7 +800,7 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) } for (i = 0; i < aos_count; i++) { - OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, + OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, RADEON_GEM_DOMAIN_GTT, 0, 0); } END_CS; @@ -1014,15 +1012,15 @@ void r300_emit_buffer_validate(struct r300_context *r300) boolean invalid = FALSE; /* Clean out BOs. */ - r300->rws->reset_bos(r300->rws); + r300->winsys->reset_bos(r300->winsys); validate: /* Color buffers... */ for (i = 0; i < fb->nr_cbufs; i++) { tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); - if (!r300_add_texture(r300->rws, tex, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1031,8 +1029,8 @@ validate: if (fb->zsbuf) { tex = (struct r300_texture*)fb->zsbuf->texture; assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); - if (!r300_add_texture(r300->rws, tex, - 0, RADEON_GEM_DOMAIN_VRAM)) { + if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1042,31 +1040,31 @@ validate: tex = r300->textures[i]; if (!tex) continue; - if (!r300_add_texture(r300->rws, tex, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...occlusion query buffer... */ if (r300->dirty_state & R300_NEW_QUERY) { - if (!r300_add_buffer(r300->rws, r300->oqbo, - 0, RADEON_GEM_DOMAIN_GTT)) { + if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, + 0, RADEON_GEM_DOMAIN_GTT)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...and vertex buffer. */ if (r300->vbo) { - if (!r300_add_buffer(r300->rws, r300->vbo, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } else { /* debug_printf("No VBO while emitting dirty state!\n"); */ } - if (!r300->rws->validate(r300->rws)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { /* Well, hell. */ @@ -1098,7 +1096,7 @@ void r300_emit_dirty_state(struct r300_context* r300) /* Make sure we have at least 2*1024 spare dwords. */ /* XXX It would be nice to know the number of dwords we really need to * XXX emit. */ - while (!r300->rws->check_cs(r300->rws, dwords)) { + while (!r300->winsys->check_cs(r300->winsys, dwords)) { r300->context.flush(&r300->context, 0, NULL); } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 47f5d6f7f16..754eb4dc769 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -30,12 +30,10 @@ #include "util/u_format.h" #include "util/u_memory.h" -#include "util/u_upload_mgr.h" #include "util/u_prim.h" #include "r300_cs.h" #include "r300_context.h" -#include "r300_screen_buffer.h" #include "r300_emit.h" #include "r300_reg.h" #include "r300_render.h" @@ -299,7 +297,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | (0 << R300_INDX_BUFFER_SKIP_SHIFT)); OUT_CS(offset_dwords << 2); - OUT_CS_BUF_RELOC(indexBuffer, count_dwords, + OUT_CS_RELOC(indexBuffer, count_dwords, RADEON_GEM_DOMAIN_GTT, 0, 0); END_CS; @@ -310,28 +308,21 @@ static boolean r300_setup_vertex_buffers(struct r300_context *r300) struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; struct pipe_buffer *pbuf; - int ret; - - /* upload buffers first */ - if (r300->any_user_vbs) { - ret = r300_upload_user_buffers(r300); - r300->any_user_vbs = false; - } validate: for (int i = 0; i < r300->vertex_element_count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - if (!r300_add_buffer(r300->rws, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } - if (!r300->rws->validate(r300->rws)) { + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); - return r300->rws->validate(r300->rws); + return r300->winsys->validate(r300->winsys); } return TRUE; @@ -405,20 +396,15 @@ void r300_draw_range_elements(struct pipe_context* pipe, indexSize = 2; } - r300_upload_index_buffer(r300, &indexBuffer, - indexSize, start, count); - - if (!r300_add_buffer(r300->rws, indexBuffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, + RADEON_GEM_DOMAIN_GTT, 0)) { goto cleanup; } - if (!r300->rws->validate(r300->rws)) { + if (!r300->winsys->validate(r300->winsys)) { goto cleanup; } - u_upload_flush(r300->upload_vb); - u_upload_flush(r300->upload_ib); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); @@ -439,7 +425,7 @@ void r300_draw_range_elements(struct pipe_context* pipe, cleanup: if (indexBuffer != orgIndexBuffer) { - pipe_buffer_reference( &indexBuffer, NULL ); + pipe->screen->buffer_destroy(indexBuffer); } } @@ -480,7 +466,6 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return; } - u_upload_flush(r300->upload_vb); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 3b70312c829..6a55570571a 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -23,6 +23,7 @@ #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" +#include "util/u_simple_screen.h" #include "r300_context.h" #include "r300_screen.h" @@ -31,8 +32,6 @@ #include "radeon_winsys.h" #include "r300_winsys.h" -#include "r300_screen_buffer.h" - /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. * @@ -293,11 +292,10 @@ static void* r300_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; - struct r300_winsys_screen *rws = r300_winsys_screen(screen); char* map; enum pipe_format format = tex->tex.format; - map = rws->buffer_map(rws, tex->buffer, + map = pipe_buffer_map(screen, tex->buffer, pipe_transfer_buffer_flags(transfer)); if (!map) { @@ -313,26 +311,21 @@ static void r300_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer) { struct r300_texture* tex = (struct r300_texture*)transfer->texture; - struct r300_winsys_screen *rws = r300_winsys_screen(screen); - rws->buffer_unmap(rws, tex->buffer); + pipe_buffer_unmap(screen, tex->buffer); } static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); - struct r300_winsys_screen *rws = r300_winsys_screen(pscreen); - - if (rws) - rws->destroy(rws); FREE(r300screen->caps); FREE(r300screen); } -struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) +struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) { - struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen); - struct r300_capabilities *caps = CALLOC_STRUCT(r300_capabilities); + struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); + struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); if (!r300screen || !caps) { FREE(r300screen); @@ -340,16 +333,16 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) return NULL; } - caps->pci_id = rws->get_value(rws, R300_VID_PCI_ID); - caps->num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES); - caps->num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES); + caps->pci_id = radeon_winsys->pci_id; + caps->num_frag_pipes = radeon_winsys->gb_pipes; + caps->num_z_pipes = radeon_winsys->z_pipes; r300_init_debug(r300screen); r300_parse_chipset(caps); r300screen->caps = caps; - r300screen->rws = rws; - r300screen->screen.winsys = (struct pipe_winsys*)rws; + r300screen->radeon_winsys = radeon_winsys; + r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys; r300screen->screen.destroy = r300_destroy_screen; r300screen->screen.get_name = r300_get_name; r300screen->screen.get_vendor = r300_get_vendor; @@ -363,12 +356,7 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws) r300screen->screen.transfer_unmap = r300_transfer_unmap; r300_init_screen_texture_functions(&r300screen->screen); - r300_screen_init_buffer_functions(r300screen); - return &r300screen->screen; -} + u_simple_screen_init(&r300screen->screen); -struct r300_winsys_screen * -r300_winsys_screen(struct pipe_screen *screen) -{ - return r300_screen(screen)->rws; + return &r300screen->screen; } diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 87fc6190ce6..502fbfa5a24 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -33,7 +33,7 @@ struct r300_screen { /* Parent class */ struct pipe_screen screen; - struct r300_winsys_screen *rws; + struct radeon_winsys* radeon_winsys; /* Chipset capabilities */ struct r300_capabilities* caps; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c deleted file mode 100644 index 358582ea211..00000000000 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ /dev/null @@ -1,222 +0,0 @@ -#include - -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_memory.h" -#include "util/u_upload_mgr.h" - -#include "r300_screen_buffer.h" - -#include "r300_winsys.h" - -int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_buffer **index_buffer, - unsigned index_size, - unsigned start, - unsigned count) -{ - struct pipe_buffer *upload_buffer = NULL; - unsigned index_offset = start * index_size; - int ret = 0; - - if (r300_buffer_is_user_buffer(*index_buffer)) { - ret = u_upload_buffer(r300->upload_ib, - index_offset, - count * index_size, - *index_buffer, - &index_offset, - &upload_buffer); - if (ret) { - goto done; - } - *index_buffer = upload_buffer; - } - done: - // if (upload_buffer) - // pipe_buffer_reference(&upload_buffer, NULL); - return ret; -} - -int r300_upload_user_buffers(struct r300_context *r300) -{ - enum pipe_error ret = PIPE_OK; - int i, nr; - - nr = r300->vertex_buffer_count; - - for (i = 0; i < nr; i++) { - - if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) { - struct pipe_buffer *upload_buffer = NULL; - unsigned offset = 0; - unsigned size = r300->vertex_buffer[i].buffer->size; - unsigned upload_offset; - - ret = u_upload_buffer(r300->upload_vb, - offset, size, - r300->vertex_buffer[i].buffer, - &upload_offset, &upload_buffer); - if (ret) - return ret; - - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); - r300->vertex_buffer[i].buffer = upload_buffer; - r300->vertex_buffer[i].buffer_offset = upload_offset; - } - } - return ret; -} - -static struct r300_winsys_buffer * -r300_winsys_buffer_create(struct r300_screen *r300screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_winsys_buffer *buf; - - buf = rws->buffer_create(rws, alignment, usage, size); - return buf; -} - -static void r300_winsys_buffer_destroy(struct r300_screen *r300screen, - struct r300_buffer *rbuf) -{ - struct r300_winsys_screen *rws = r300screen->rws; - - if (rbuf->buf) { - rws->buffer_destroy(rbuf->buf); - rbuf->buf = NULL; - } -} - -static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_buffer *rbuf; - - rbuf = CALLOC_STRUCT(r300_buffer); - if (!rbuf) - goto error1; - - rbuf->magic = R300_BUFFER_MAGIC; - - pipe_reference_init(&rbuf->base.reference, 1); - rbuf->base.screen = screen; - rbuf->base.alignment = alignment; - rbuf->base.usage = usage; - rbuf->base.size = size; - - rbuf->buf = r300_winsys_buffer_create(r300screen, - alignment, - usage, - size); - - if (!rbuf->buf) - goto error2; - - return &rbuf->base; -error2: - FREE(rbuf); -error1: - return NULL; -} - - -static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct r300_buffer *rbuf; - - rbuf = CALLOC_STRUCT(r300_buffer); - if (!rbuf) - goto no_rbuf; - - rbuf->magic = R300_BUFFER_MAGIC; - - pipe_reference_init(&rbuf->base.reference, 1); - rbuf->base.screen = screen; - rbuf->base.alignment = 1; - rbuf->base.usage = 0; - rbuf->base.size = bytes; - - rbuf->user_buffer = ptr; - return &rbuf->base; - -no_rbuf: - return NULL; -} - -static void r300_buffer_destroy(struct pipe_buffer *buf) -{ - struct r300_screen *r300screen = r300_screen(buf->screen); - struct r300_buffer *rbuf = r300_buffer(buf); - - r300_winsys_buffer_destroy(r300screen, rbuf); - FREE(rbuf); -} - -static void * -r300_buffer_map_range(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned offset, unsigned length, - unsigned usage ) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); - void *map; - - if (rbuf->user_buffer) - return rbuf->user_buffer; - - map = rws->buffer_map(rws, rbuf->buf, usage); - - return map; -} - -static void * -r300_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned usage) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); - void *map; - - if (rbuf->user_buffer) - return rbuf->user_buffer; - - map = rws->buffer_map(rws, rbuf->buf, usage); - - return map; -} - -static void -r300_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) -{ - struct r300_screen *r300screen = r300_screen(screen); - struct r300_winsys_screen *rws = r300screen->rws; - struct r300_buffer *rbuf = r300_buffer(buf); - - if (rbuf->buf) - rws->buffer_unmap(rws, rbuf->buf); -} - -void r300_screen_init_buffer_functions(struct r300_screen *r300screen) -{ - r300screen->screen.buffer_create = r300_buffer_create; - r300screen->screen.user_buffer_create = r300_user_buffer_create; - r300screen->screen.buffer_map = r300_buffer_map; - r300screen->screen.buffer_map_range = r300_buffer_map_range; -// r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range; - r300screen->screen.buffer_unmap = r300_buffer_unmap; - r300screen->screen.buffer_destroy = r300_buffer_destroy; -} diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h deleted file mode 100644 index 7c026508b59..00000000000 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef R300_SCREEN_BUFFER_H -#define R300_SCREEN_BUFFER_H -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" -#include "r300_screen.h" - -#include "r300_winsys.h" -#include "r300_context.h" - -#define R300_BUFFER_MAGIC 0xabcd1234 - -struct r300_buffer -{ - struct pipe_buffer base; - - uint32_t magic; - - struct r300_winsys_buffer *buf; - - void *user_buffer; -}; - -static INLINE struct r300_buffer * -r300_buffer(struct pipe_buffer *buffer) -{ - if (buffer) { - assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC); - return (struct r300_buffer *)buffer; - } - return NULL; -} - -static INLINE boolean -r300_buffer_is_user_buffer(struct pipe_buffer *buffer) -{ - return r300_buffer(buffer)->user_buffer ? true : false; -} - -static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws, - struct pipe_buffer *buffer, - int rd, int wr) -{ - struct r300_buffer *buf = r300_buffer(buffer); - - if (!buf->buf) - return true; - - return rws->add_buffer(rws, buf->buf, rd, wr); -} - - -static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws, - struct r300_texture *tex, - int rd, int wr) -{ - return rws->add_buffer(rws, tex->buffer, rd, wr); -} - -void r300_screen_init_buffer_functions(struct r300_screen *r300screen); - -static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws, - struct r300_buffer *buf, - uint32_t rd, uint32_t wd, uint32_t flags) -{ - if (!buf->buf) - return; - - rws->write_cs_reloc(rws, buf->buf, rd, wd, flags); -} - -static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws, - struct r300_texture *texture, - uint32_t rd, uint32_t wd, uint32_t flags) -{ - rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags); -} - -int r300_upload_user_buffers(struct r300_context *r300); - -int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_buffer **index_buffer, - unsigned index_size, - unsigned start, - unsigned count); -#endif diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index d8a87dec151..34bf81c1930 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -34,7 +34,6 @@ #include "r300_context.h" #include "r300_reg.h" #include "r300_screen.h" -#include "r300_screen_buffer.h" #include "r300_state_inlines.h" #include "r300_fs.h" #include "r300_vs.h" @@ -522,7 +521,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->cbufs[i]->texture; if (tex) { - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -534,7 +533,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)old_state->zsbuf->texture; if (tex) { - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[0], tex->microtile != 0, tex->macrotile != 0); @@ -546,7 +545,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->cbufs[i]->texture; level = new_state->cbufs[i]->level; - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -555,7 +554,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, tex = (struct r300_texture*)new_state->zsbuf->texture; level = new_state->zsbuf->level; - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, tex->pitch[level], tex->microtile != 0, tex->mip_macrotile[level] != 0); @@ -1029,26 +1028,10 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); - boolean any_user_buffer = false; - int i; - - if (count == r300->vertex_buffer_count && - memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0) - return; - - for (i = 0; i < count; i++) { - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer); - if (r300_buffer_is_user_buffer(buffers[i].buffer)) - any_user_buffer = true; - } - - for ( ; i < r300->vertex_buffer_count; i++) - pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL); memcpy(r300->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); r300->vertex_buffer_count = count; - r300->any_user_vbs = any_user_buffer; if (r300->draw) { draw_flush(r300->draw); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 9016e86ccd7..ed2be06254a 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -731,7 +731,7 @@ static struct pipe_texture* { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); struct r300_screen* rscreen = r300_screen(screen); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; + struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; if (!tex) { return NULL; @@ -745,13 +745,13 @@ static struct pipe_texture* r300_setup_miptree(rscreen, tex); r300_setup_texture_state(rscreen, tex); - tex->buffer = rws->buffer_create(rws, 2048, - PIPE_BUFFER_USAGE_PIXEL, - tex->size); - rws->buffer_set_tiling(rws, tex->buffer, - tex->pitch[0], - tex->microtile != R300_BUFFER_LINEAR, - tex->macrotile != R300_BUFFER_LINEAR); + tex->buffer = screen->buffer_create(screen, 2048, + PIPE_BUFFER_USAGE_PIXEL, + tex->size); + winsys->buffer_set_tiling(winsys, tex->buffer, + tex->pitch[0], + tex->microtile != R300_BUFFER_LINEAR, + tex->macrotile != R300_BUFFER_LINEAR); if (!tex->buffer) { FREE(tex); @@ -764,9 +764,9 @@ static struct pipe_texture* static void r300_texture_destroy(struct pipe_texture* texture) { struct r300_texture* tex = (struct r300_texture*)texture; - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; - rws->buffer_reference(rws, &tex->buffer, NULL); + pipe_buffer_reference(&tex->buffer, NULL); + FREE(tex); } @@ -806,14 +806,14 @@ static void r300_tex_surface_destroy(struct pipe_surface* s) FREE(s); } -struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, - const struct pipe_texture *base, - const unsigned *stride, - struct r300_winsys_buffer *buffer) +static struct pipe_texture* + r300_texture_blanket(struct pipe_screen* screen, + const struct pipe_texture* base, + const unsigned* stride, + struct pipe_buffer* buffer) { struct r300_texture* tex; struct r300_screen* rscreen = r300_screen(screen); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || @@ -837,7 +837,7 @@ struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *scre r300_setup_flags(tex); r300_setup_texture_state(rscreen, tex); - rws->buffer_reference(rws, &tex->buffer, buffer); + pipe_buffer_reference(&tex->buffer, buffer); return (struct pipe_texture*)tex; } @@ -896,6 +896,7 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; screen->tex_surface_destroy = r300_tex_surface_destroy; + screen->texture_blanket = r300_texture_blanket; screen->video_surface_create = r300_video_surface_create; screen->video_surface_destroy= r300_video_surface_destroy; @@ -903,23 +904,19 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct r300_winsys_buffer** buffer, + struct pipe_buffer** buffer, unsigned* stride) { struct r300_texture* tex = (struct r300_texture*)texture; - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - struct r300_winsys_buffer *buf; - if (!tex) { return FALSE; } - rws->buffer_reference(rws, &buf, tex->buffer); + pipe_buffer_reference(buffer, tex->buffer); if (stride) { *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); } - *buffer = buf; return TRUE; } diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 97724f790c8..46a5fb6188b 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -63,8 +63,8 @@ r300_video_surface(struct pipe_video_surface *pvs) #ifndef R300_WINSYS_H boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture *texture, - struct r300_winsys_buffer** buffer, + struct pipe_texture* texture, + struct pipe_buffer** buffer, unsigned* stride); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index c6f9174496b..40fb8a95ca5 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -23,6 +23,10 @@ #ifndef R300_WINSYS_H #define R300_WINSYS_H +#ifdef __cplusplus +extern "C" { +#endif + /* The public interface header for the r300 pipe driver. * Any winsys hosting this pipe needs to implement r300_winsys and then * call r300_create_screen to start things. */ @@ -30,128 +34,19 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" -struct r300_winsys_screen; +struct radeon_winsys; /* Creates a new r300 screen. */ -struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws); - -struct r300_winsys_buffer; +struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, - struct r300_winsys_buffer** buffer, - unsigned *stride); - -enum r300_value_id { - R300_VID_PCI_ID, - R300_VID_GB_PIPES, - R300_VID_Z_PIPES, -}; - -struct r300_winsys_screen { - void (*destroy)(struct r300_winsys_screen *ws); - - /** - * Buffer management. Buffer attributes are mostly fixed over its lifetime. - * - * Remember that gallium gets to choose the interface it needs, and the - * window systems must then implement that interface (rather than the - * other way around...). - * - * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This - * usage argument is only an optimization hint, not a guarantee, therefore - * proper behavior must be observed in all circumstances. - * - * alignment indicates the client's alignment requirements, eg for - * SSE instructions. - */ - struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws, - unsigned alignment, - unsigned usage, - unsigned size); - - /** - * Map the entire data store of a buffer object into the client's address. - * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags. - */ - void *(*buffer_map)( struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf, - unsigned usage ); - - void (*buffer_unmap)( struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf ); - - void (*buffer_destroy)( struct r300_winsys_buffer *buf ); - - - void (*buffer_reference)(struct r300_winsys_screen *rws, - struct r300_winsys_buffer **pdst, - struct r300_winsys_buffer *src); - - boolean (*buffer_references)(struct r300_winsys_buffer *a, - struct r300_winsys_buffer *b); - - /* Add a pipe_buffer to the list of buffer objects to validate. */ - boolean (*add_buffer)(struct r300_winsys_screen *winsys, - struct r300_winsys_buffer *buf, - uint32_t rd, - uint32_t wd); - - /* Revalidate all currently setup pipe_buffers. - * Returns TRUE if a flush is required. */ - boolean (*validate)(struct r300_winsys_screen* winsys); - - /* Check to see if there's room for commands. */ - boolean (*check_cs)(struct r300_winsys_screen* winsys, int size); - - /* Start a command emit. */ - void (*begin_cs)(struct r300_winsys_screen* winsys, - int size, - const char* file, - const char* function, - int line); - - /* Write a dword to the command buffer. */ - void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword); - - /* Write a relocated dword to the command buffer. */ - void (*write_cs_reloc)(struct r300_winsys_screen *winsys, - struct r300_winsys_buffer *buf, - uint32_t rd, - uint32_t wd, - uint32_t flags); - - /* Finish a command emit. */ - void (*end_cs)(struct r300_winsys_screen* winsys, - const char* file, - const char* function, - int line); - - /* Flush the CS. */ - void (*flush_cs)(struct r300_winsys_screen* winsys); - - /* winsys flush - callback from winsys when flush required */ - void (*set_flush_cb)(struct r300_winsys_screen *winsys, - void (*flush_cb)(void *), void *data); - - void (*reset_bos)(struct r300_winsys_screen *winsys); - - void (*buffer_set_tiling)(struct r300_winsys_screen *winsys, - struct r300_winsys_buffer *buffer, - uint32_t pitch, - boolean microtiled, - boolean macrotiled); - - uint32_t (*get_value)(struct r300_winsys_screen *winsys, - enum r300_value_id vid); -}; + struct pipe_buffer** buffer, + unsigned* stride); -struct r300_winsys_screen * -r300_winsys_screen(struct pipe_screen *screen); +#ifdef __cplusplus +} +#endif -struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen, - const struct pipe_texture *base, - const unsigned *stride, - struct r300_winsys_buffer *buffer); #endif /* R300_WINSYS_H */ diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h index b36680eb667..c6a7d4a8c51 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h @@ -32,6 +32,8 @@ i965_libdrm_winsys(struct brw_winsys_screen *iws) return (struct i965_libdrm_winsys *)iws; } +struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id); + void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws); diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/drm/radeon/core/Makefile index 13bbbf730d6..860cbb6dbf8 100644 --- a/src/gallium/winsys/drm/radeon/core/Makefile +++ b/src/gallium/winsys/drm/radeon/core/Makefile @@ -5,7 +5,7 @@ include $(TOP)/configs/current LIBNAME = radeonwinsys C_SOURCES = \ - radeon_drm_buffer.c \ + radeon_buffer.c \ radeon_drm.c \ radeon_r300.c diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index 8e0274e33d5..f1c8fc2a3b1 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -32,11 +32,11 @@ #include +#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "pipebuffer/pb_buffer.h" -#include "pipebuffer/pb_bufmgr.h" #include "util/u_memory.h" @@ -47,41 +47,41 @@ #include "radeon_winsys.h" +struct radeon_pipe_buffer { + struct pipe_buffer base; + /* Pointer to GPU-backed BO. */ + struct radeon_bo *bo; + /* Pointer to fallback PB buffer. */ + struct pb_buffer *pb; + boolean flinked; + uint32_t flink; +}; #define RADEON_MAX_BOS 24 -static INLINE struct pb_buffer * -radeon_pb_buffer(struct r300_winsys_buffer *buffer) -{ - return (struct pb_buffer *)buffer; -} +struct radeon_winsys_priv { + /* DRM FD */ + int fd; -static INLINE struct r300_winsys_buffer * -radeon_libdrm_winsys_buffer(struct pb_buffer *buffer) -{ - return (struct r300_winsys_buffer *)buffer; -} + /* Radeon BO manager. */ + struct radeon_bo_manager* bom; -struct pb_manager * -radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws); + /* Radeon CS manager. */ + struct radeon_cs_manager* csm; -boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd); + /* Current CS. */ + struct radeon_cs* cs; + /* Flush CB */ + void (*flush_cb)(void *); + void *flush_data; +}; -void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd, - uint32_t flags); - -struct radeon_libdrm_winsys* radeon_pipe_winsys(int fd); - -boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, - uint32_t *handle); -uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf); -struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, - uint32_t handle); - -void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch); - -void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr); +struct radeon_winsys* radeon_pipe_winsys(int fb); +#if 0 +struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch); +#endif #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index f886fda2f27..0c0e118ba3a 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -31,22 +31,8 @@ #include "radeon_drm.h" -static struct radeon_libdrm_winsys * -radeon_winsys_create(int fd) -{ - struct radeon_libdrm_winsys *rws; - - rws = CALLOC_STRUCT(radeon_libdrm_winsys); - if (rws == NULL) { - return NULL; - } - - rws->fd = fd; - return rws; -} - /* Helper function to do the ioctls needed for setup and init. */ -static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) +static void do_ioctls(int fd, struct radeon_winsys* winsys) { struct drm_radeon_gem_info gem_info = {0}; struct drm_radeon_info info = {0}; @@ -137,26 +123,62 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg) { - struct radeon_libdrm_winsys* rws; - - rws = radeon_winsys_create(drmFB); - if (!rws) - return NULL; - - do_ioctls(drmFB, rws); + struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB); + do_ioctls(drmFB, rwinsys); /* The state tracker can organize a softpipe fallback if no hw * driver is found. */ - if (is_r3xx(rws->pci_id)) { - radeon_setup_winsys(drmFB, rws); - return r300_create_screen(&rws->base); + if (is_r3xx(rwinsys->pci_id)) { + radeon_setup_winsys(drmFB, rwinsys); + return r300_create_screen(rwinsys); } else { - FREE(rws); + FREE(rwinsys); return NULL; } } + +boolean radeon_buffer_from_texture(struct drm_api* api, + struct pipe_screen* screen, + struct pipe_texture* texture, + struct pipe_buffer** buffer, + unsigned* stride) +{ + /* XXX fix this */ + return r300_get_texture_buffer(screen, texture, buffer, stride); +} + +/* Create a buffer from a handle. */ +/* XXX what's up with name? */ +struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, + struct pipe_screen* screen, + const char* name, + unsigned handle) +{ + struct radeon_bo_manager* bom = + ((struct radeon_winsys*)screen->winsys)->priv->bom; + struct radeon_pipe_buffer* radeon_buffer; + struct radeon_bo* bo = NULL; + + bo = radeon_bo_open(bom, handle, 0, 0, 0, 0); + if (bo == NULL) { + return NULL; + } + + radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); + if (radeon_buffer == NULL) { + radeon_bo_unref(bo); + return NULL; + } + + pipe_reference_init(&radeon_buffer->base.reference, 1); + radeon_buffer->base.screen = screen; + radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; + radeon_buffer->bo = bo; + return &radeon_buffer->base; +} + static struct pipe_texture* radeon_texture_from_shared_handle(struct drm_api *api, struct pipe_screen *screen, @@ -165,20 +187,18 @@ radeon_texture_from_shared_handle(struct drm_api *api, unsigned stride, unsigned handle) { - struct pb_buffer *_buf; - struct r300_winsys_buffer *buf; + struct pipe_buffer *buffer; struct pipe_texture *blanket; - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(r300_winsys_screen(screen)); - _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle); - if (!_buf) { - return NULL; + buffer = radeon_buffer_from_handle(api, screen, name, handle); + if (!buffer) { + return NULL; } - buf = radeon_libdrm_winsys_buffer(_buf); - blanket = r300_texture_blanket_winsys_buffer(screen, templ, &stride, buf); + blanket = screen->texture_blanket(screen, templ, &stride, buffer); + + pipe_buffer_reference(&buffer, NULL); - pb_reference(&_buf, NULL); return blanket; } @@ -188,14 +208,34 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - struct r300_winsys_buffer *radeon_buffer; - struct pb_buffer *_buf; - if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { + int retval, fd; + struct drm_gem_flink flink; + struct radeon_pipe_buffer* radeon_buffer; + struct pipe_buffer *buffer = NULL; + + if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { return FALSE; } - _buf = radeon_pb_buffer(radeon_buffer); - return radeon_drm_bufmgr_shared_handle_from_buffer(_buf, handle); + radeon_buffer = (struct radeon_pipe_buffer*)buffer; + if (!radeon_buffer->flinked) { + fd = ((struct radeon_winsys*)screen->winsys)->priv->fd; + + flink.handle = radeon_buffer->bo->handle; + + retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (retval) { + debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", + retval); + return FALSE; + } + + radeon_buffer->flink = flink.name; + radeon_buffer->flinked = TRUE; + } + + *handle = radeon_buffer->flink; + return TRUE; } static boolean radeon_local_handle_from_texture(struct drm_api *api, @@ -204,18 +244,16 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api, unsigned *stride, unsigned *handle) { - struct r300_winsys_buffer *radeon_buffer; - struct pb_buffer *_buf; - - if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) { + struct pipe_buffer *buffer = NULL; + if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { return FALSE; } - _buf = radeon_pb_buffer(radeon_buffer); - *handle = radeon_drm_bufmgr_handle_from_buffer(_buf); + *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle; + + pipe_buffer_reference(&buffer, NULL); - pb_reference(&_buf, NULL); - return true; + return TRUE; } static void radeon_drm_api_destroy(struct drm_api *api) diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index 2f550613307..8d74cbafc2f 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -59,6 +59,11 @@ boolean radeon_buffer_from_texture(struct drm_api* api, struct pipe_buffer** buffer, unsigned* stride); +struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, + struct pipe_screen* screen, + const char* name, + unsigned handle); + boolean radeon_handle_from_buffer(struct drm_api* api, struct pipe_screen* screen, struct pipe_buffer* buffer, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c deleted file mode 100644 index 5f2fd2d7fc8..00000000000 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.c +++ /dev/null @@ -1,361 +0,0 @@ - -#include "radeon_drm.h" -#include "radeon_bo_gem.h" -#include "radeon_cs_gem.h" - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_simple_list.h" -#include "pipebuffer/pb_buffer.h" -#include "pipebuffer/pb_bufmgr.h" - -#include "radeon_winsys.h" -struct radeon_drm_bufmgr; - -struct radeon_drm_buffer { - struct pb_buffer base; - struct radeon_drm_bufmgr *mgr; - - struct radeon_bo *bo; - - boolean flinked; - uint32_t flink; - - boolean mapped; - struct radeon_drm_buffer *next, *prev; -}; - -extern const struct pb_vtbl radeon_drm_buffer_vtbl; - - -static INLINE struct radeon_drm_buffer * -radeon_drm_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &radeon_drm_buffer_vtbl); - return (struct radeon_drm_buffer *)buf; -} - -struct radeon_drm_bufmgr { - struct pb_manager base; - struct radeon_libdrm_winsys *rws; - struct radeon_drm_buffer buffer_map_list; -}; - -static INLINE struct radeon_drm_bufmgr * -radeon_drm_bufmgr(struct pb_manager *mgr) -{ - assert(mgr); - return (struct radeon_drm_bufmgr *)mgr; -} - -static void -radeon_drm_buffer_destroy(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - - if (buf->mapped) { - remove_from_list(buf); - radeon_bo_unmap(buf->bo); - buf->mapped = false; - } - radeon_bo_unref(buf->bo); - - FREE(buf); -} - -static void * -radeon_drm_buffer_map(struct pb_buffer *_buf, - unsigned flags) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - int write; - - if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { - uint32_t domain; - - if (radeon_bo_is_busy(buf->bo, &domain)) - return NULL; - } - - if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) { - buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data); - } - - if (buf->mapped) - return buf->bo->ptr; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { - write = 1; - } - - if (radeon_bo_map(buf->bo, write)) { - return NULL; - } - buf->mapped = true; - insert_at_tail(&buf->mgr->buffer_map_list, buf); - return buf->bo->ptr; -} - -static void -radeon_drm_buffer_unmap(struct pb_buffer *_buf) -{ - (void)_buf; -} - -static void -radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - *base_buf = buf; - *offset = 0; -} - - -static enum pipe_error -radeon_drm_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - /* Always pinned */ - return PIPE_OK; -} - -static void -radeon_drm_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ -} - -const struct pb_vtbl radeon_drm_buffer_vtbl = { - radeon_drm_buffer_destroy, - radeon_drm_buffer_map, - radeon_drm_buffer_unmap, - radeon_drm_buffer_validate, - radeon_drm_buffer_fence, - radeon_drm_buffer_get_base_buffer, -}; - - -static uint32_t radeon_domain_from_usage(unsigned usage) -{ - uint32_t domain = 0; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BUFFER_USAGE_INDEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - - return domain; -} - -struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr, - uint32_t handle) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_libdrm_winsys *rws = mgr->rws; - struct radeon_drm_buffer *buf; - struct radeon_bo *bo; - - bo = radeon_bo_open(rws->bom, handle, 0, - 0, 0, 0); - if (bo == NULL) - return NULL; - - buf = CALLOC_STRUCT(radeon_drm_buffer); - if (!buf) { - radeon_bo_unref(bo); - return NULL; - } - - make_empty_list(buf); - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = 0; - buf->base.base.usage = PIPE_BUFFER_USAGE_PIXEL; - buf->base.base.size = 0; - buf->base.vtbl = &radeon_drm_buffer_vtbl; - buf->mgr = mgr; - - buf->bo = bo; - - // fprintf(stderr,"hand %p : %d\n", &buf->base, handle); - return &buf->base; - -} - -static struct pb_buffer * -radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr, - pb_size size, - const struct pb_desc *desc) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_libdrm_winsys *rws = mgr->rws; - struct radeon_drm_buffer *buf; - uint32_t domain; - - buf = CALLOC_STRUCT(radeon_drm_buffer); - if (!buf) - goto error1; - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = desc->alignment; - buf->base.base.usage = desc->usage; - buf->base.base.size = size; - buf->base.vtbl = &radeon_drm_buffer_vtbl; - buf->mgr = mgr; - - make_empty_list(buf); - domain = radeon_domain_from_usage(desc->usage); - buf->bo = radeon_bo_open(rws->bom, 0, size, - desc->alignment, domain, 0); - if (buf->bo == NULL) - goto error2; - - // fprintf(stderr,"%p : %d\n", &buf->base, size); - return &buf->base; - - error2: - FREE(buf); - error1: - return NULL; -} - -static void -radeon_drm_bufmgr_flush(struct pb_manager *mgr) -{ - /* NOP */ -} - -static void -radeon_drm_bufmgr_destroy(struct pb_manager *_mgr) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - FREE(mgr); -} - -struct pb_manager * -radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws) -{ - struct radeon_drm_bufmgr *mgr; - - mgr = CALLOC_STRUCT(radeon_drm_bufmgr); - if (!mgr) - return NULL; - - mgr->base.destroy = radeon_drm_bufmgr_destroy; - mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer; - mgr->base.flush = radeon_drm_bufmgr_flush; - - mgr->rws = rws; - make_empty_list(&mgr->buffer_map_list); - return &mgr->base; -} - -uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - - return buf->bo->handle; -} - -boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf, - uint32_t *handle) -{ - struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf); - struct drm_gem_flink flink; - int retval, fd; - if (!buf->flinked) { - fd = buf->mgr->rws->fd; - flink.handle = buf->bo->handle; - - retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - if (retval) { - return false; - } - - buf->flinked = TRUE; - buf->flink = flink.name; - } - *handle = buf->flink; - return TRUE; -} - -static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf) -{ - struct radeon_drm_buffer *buf; - if (_buf->vtbl == &radeon_drm_buffer_vtbl) { - buf = radeon_drm_buffer(_buf); - } else { - struct pb_buffer *base_buf; - pb_size offset; - pb_get_base_buffer(_buf, &base_buf, &offset); - - buf = radeon_drm_buffer(base_buf); - } - return buf; -} - -void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - uint32_t flags = 0; - - if (microtiled) - flags |= RADEON_BO_FLAGS_MICRO_TILE; - if (macrotiled) - flags |= RADEON_BO_FLAGS_MACRO_TILE; - - radeon_bo_set_tiling(buf->bo, flags, pitch); - -} - -boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo, - rd, wd); - - return true; -} - -void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf, - uint32_t rd, uint32_t wd, - uint32_t flags) -{ - struct radeon_drm_buffer *buf = get_drm_buffer(_buf); - int retval; - - retval = radeon_cs_write_reloc(buf->mgr->rws->cs, - buf->bo, rd, wd, flags); - if (retval) { - debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", - buf, rd, wd, flags); - } -} - -void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr) -{ - struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr); - struct radeon_drm_buffer *rpb, *t_rpb; - - foreach_s(rpb, t_rpb, &mgr->buffer_map_list) { - rpb->mapped = 0; - radeon_bo_unmap(rpb->bo); - remove_from_list(rpb); - } - - make_empty_list(&mgr->buffer_map_list); - - -} diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index 997abb8f5cb..d759beaba13 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -22,104 +22,29 @@ #include "radeon_r300.h" -static struct r300_winsys_buffer * -radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - struct pb_desc desc; - struct pb_manager *provider; - struct pb_buffer *buffer; - - memset(&desc, 0, sizeof(desc)); - desc.alignment = alignment; - desc.usage = usage; - - if (usage == PIPE_BUFFER_USAGE_CONSTANT) - provider = ws->mman; - else if (usage == PIPE_BUFFER_USAGE_VERTEX || - usage == PIPE_BUFFER_USAGE_INDEX) - provider = ws->cman; - else - provider = ws->kman; - buffer = provider->create_buffer(provider, size, &desc); - if (!buffer) - return NULL; - - return radeon_libdrm_winsys_buffer(buffer); -} - -static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_destroy(_buf); -} -static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, - uint32_t pitch, - boolean microtiled, - boolean macrotiled) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch); -} - -static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf, - unsigned usage) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - return pb_map(_buf, 0); -} - -static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws, - struct r300_winsys_buffer *buf) -{ - struct pb_buffer *_buf = radeon_pb_buffer(buf); - - pb_unmap(_buf); -} - -static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, - struct r300_winsys_buffer **pdst, - struct r300_winsys_buffer *src) -{ - struct pb_buffer *_src = radeon_pb_buffer(src); - struct pb_buffer *_dst = radeon_pb_buffer(*pdst); - - pb_reference(&_dst, _src); - - *pdst = radeon_libdrm_winsys_buffer(_dst); -} - -static void radeon_set_flush_cb(struct r300_winsys_screen *rws, +static void radeon_set_flush_cb(struct radeon_winsys *winsys, void (*flush_cb)(void *), void *data) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - ws->flush_cb = flush_cb; - ws->flush_data = data; - radeon_cs_space_set_flush(ws->cs, flush_cb, data); + winsys->priv->flush_cb = flush_cb; + winsys->priv->flush_data = data; + radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data); } -static boolean radeon_add_buffer(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, +static boolean radeon_add_buffer(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, uint32_t rd, uint32_t wd) { - struct pb_buffer *_buf = radeon_pb_buffer(buf); + struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo; - return radeon_drm_bufmgr_add_buffer(_buf, rd, wd); + radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd); + return TRUE; } -static boolean radeon_validate(struct r300_winsys_screen *rws) +static boolean radeon_validate(struct radeon_winsys* winsys) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - if (radeon_cs_space_check(ws->cs) < 0) { + if (radeon_cs_space_check(winsys->priv->cs) < 0) { return FALSE; } @@ -127,146 +52,108 @@ static boolean radeon_validate(struct r300_winsys_screen *rws) return TRUE; } -static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size) +static boolean radeon_check_cs(struct radeon_winsys* winsys, int size) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - struct radeon_cs *cs = ws->cs; + struct radeon_cs* cs = winsys->priv->cs; - return radeon_validate(rws) && cs->cdw + size <= cs->ndw; + return radeon_validate(winsys) && cs->cdw + size <= cs->ndw; } -static void radeon_begin_cs(struct r300_winsys_screen *rws, +static void radeon_begin_cs(struct radeon_winsys* winsys, int size, const char* file, const char* function, int line) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_begin(ws->cs, size, file, function, line); + radeon_cs_begin(winsys->priv->cs, size, file, function, line); } -static void radeon_write_cs_dword(struct r300_winsys_screen *rws, +static void radeon_write_cs_dword(struct radeon_winsys* winsys, uint32_t dword) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_write_dword(ws->cs, dword); + radeon_cs_write_dword(winsys->priv->cs, dword); } -static void radeon_write_cs_reloc(struct r300_winsys_screen *rws, - struct r300_winsys_buffer *buf, +static void radeon_write_cs_reloc(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, uint32_t rd, uint32_t wd, uint32_t flags) { - struct pb_buffer *_buf = radeon_pb_buffer(buf); - radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags); + int retval = 0; + struct radeon_pipe_buffer* radeon_buffer = + (struct radeon_pipe_buffer*)pbuffer; + + assert(!radeon_buffer->pb); + + retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, + rd, wd, flags); + + if (retval) { + debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", + pbuffer, rd, wd, flags); + } } -static void radeon_reset_bos(struct r300_winsys_screen *rws) +static void radeon_reset_bos(struct radeon_winsys *winsys) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_space_reset_bos(ws->cs); + radeon_cs_space_reset_bos(winsys->priv->cs); } -static void radeon_end_cs(struct r300_winsys_screen *rws, +static void radeon_end_cs(struct radeon_winsys* winsys, const char* file, const char* function, int line) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); - radeon_cs_end(ws->cs, file, function, line); + radeon_cs_end(winsys->priv->cs, file, function, line); } -static void radeon_flush_cs(struct r300_winsys_screen *rws) +static void radeon_flush_cs(struct radeon_winsys* winsys) { - struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws); int retval; /* Don't flush a zero-sized CS. */ - if (!ws->cs->cdw) { + if (!winsys->priv->cs->cdw) { return; } - radeon_drm_bufmgr_flush_maps(ws->kman); /* Emit the CS. */ - retval = radeon_cs_emit(ws->cs); + retval = radeon_cs_emit(winsys->priv->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); - radeon_cs_print(ws->cs, stderr); + radeon_cs_print(winsys->priv->cs, stderr); } /* Reset CS. * Someday, when we care about performance, we should really find a way * to rotate between two or three CS objects so that the GPU can be * spinning through one CS while another one is being filled. */ - radeon_cs_erase(ws->cs); -} - -static uint32_t radeon_get_value(struct r300_winsys_screen *rws, - enum r300_value_id id) -{ - struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; - - switch(id) { - case R300_VID_PCI_ID: - return ws->pci_id; - case R300_VID_GB_PIPES: - return ws->gb_pipes; - case R300_VID_Z_PIPES: - return ws->z_pipes; - } - return 0; -} - -static void -radeon_winsys_destroy(struct r300_winsys_screen *rws) -{ - struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws; - radeon_cs_destroy(ws->cs); - - ws->cman->destroy(ws->cman); - ws->kman->destroy(ws->kman); - ws->mman->destroy(ws->mman); - - radeon_bo_manager_gem_dtor(ws->bom); - radeon_cs_manager_gem_dtor(ws->csm); + radeon_cs_erase(winsys->priv->cs); } void -radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws) +radeon_setup_winsys(int fd, struct radeon_winsys* winsys) { - ws->csm = radeon_cs_manager_gem_ctor(fd); - - ws->bom = radeon_bo_manager_gem_ctor(fd); - ws->kman = radeon_drm_bufmgr_create(ws); + struct radeon_winsys_priv* priv = winsys->priv; - ws->cman = pb_cache_manager_create(ws->kman, 100000); - ws->mman = pb_malloc_bufmgr_create(); + priv->csm = radeon_cs_manager_gem_ctor(fd); /* Size limit on IBs is 64 kibibytes. */ - ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4); - radeon_cs_set_limit(ws->cs, - RADEON_GEM_DOMAIN_GTT, ws->gart_size); - radeon_cs_set_limit(ws->cs, - RADEON_GEM_DOMAIN_VRAM, ws->vram_size); - - ws->base.add_buffer = radeon_add_buffer; - ws->base.validate = radeon_validate; - ws->base.destroy = radeon_winsys_destroy; - ws->base.check_cs = radeon_check_cs; - ws->base.begin_cs = radeon_begin_cs; - ws->base.write_cs_dword = radeon_write_cs_dword; - ws->base.write_cs_reloc = radeon_write_cs_reloc; - ws->base.end_cs = radeon_end_cs; - ws->base.flush_cs = radeon_flush_cs; - ws->base.reset_bos = radeon_reset_bos; - ws->base.set_flush_cb = radeon_set_flush_cb; - ws->base.get_value = radeon_get_value; - - ws->base.buffer_create = radeon_r300_winsys_buffer_create; - ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy; - ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling; - ws->base.buffer_map = radeon_r300_winsys_buffer_map; - ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap; - ws->base.buffer_reference = radeon_r300_winsys_buffer_reference; + priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4); + radeon_cs_set_limit(priv->cs, + RADEON_GEM_DOMAIN_GTT, winsys->gart_size); + radeon_cs_set_limit(priv->cs, + RADEON_GEM_DOMAIN_VRAM, winsys->vram_size); + + winsys->add_buffer = radeon_add_buffer; + winsys->validate = radeon_validate; + + winsys->check_cs = radeon_check_cs; + winsys->begin_cs = radeon_begin_cs; + winsys->write_cs_dword = radeon_write_cs_dword; + winsys->write_cs_reloc = radeon_write_cs_reloc; + winsys->end_cs = radeon_end_cs; + winsys->flush_cs = radeon_flush_cs; + winsys->reset_bos = radeon_reset_bos; + winsys->set_flush_cb = radeon_set_flush_cb; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index 82a8aad715a..cfbdb302661 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -28,12 +28,12 @@ #include #include "drm.h" #include "radeon_drm.h" -#include "radeon_bo_gem.h" #include "radeon_cs_gem.h" -#include "radeon_winsys.h" +#include "r300_winsys.h" + #include "radeon_buffer.h" -void radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys); +void radeon_setup_winsys(int fd, struct radeon_winsys* winsys); #endif /* RADEON_R300_H */ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index c8e725cff07..4901080ca7b 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -30,17 +30,16 @@ #ifndef RADEON_WINSYS_H #define RADEON_WINSYS_H -#include "r300_winsys.h" +#include "util/u_simple_screen.h" -struct radeon_libdrm_winsys { - /* Parent class. */ - struct r300_winsys_screen base; - - struct pb_manager *kman; +struct radeon_winsys_priv; - struct pb_manager *mman; +struct radeon_winsys { + /* Parent class. */ + struct pipe_winsys base; - struct pb_manager *cman; + /* Winsys private */ + struct radeon_winsys_priv* priv; /* PCI ID */ uint32_t pci_id; @@ -57,27 +56,56 @@ struct radeon_libdrm_winsys { /* VRAM size. */ uint32_t vram_size; - /* DRM FD */ - int fd; - - /* Radeon BO manager. */ - struct radeon_bo_manager *bom; - - /* Radeon CS manager. */ - struct radeon_cs_manager *csm; - - /* Current CS. */ - struct radeon_cs *cs; - - /* Flush CB */ - void (*flush_cb)(void *); - void *flush_data; + /* Add a pipe_buffer to the list of buffer objects to validate. */ + boolean (*add_buffer)(struct radeon_winsys* winsys, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd); + + /* Revalidate all currently setup pipe_buffers. + * Returns TRUE if a flush is required. */ + boolean (*validate)(struct radeon_winsys* winsys); + + /* Check to see if there's room for commands. */ + boolean (*check_cs)(struct radeon_winsys* winsys, int size); + + /* Start a command emit. */ + void (*begin_cs)(struct radeon_winsys* winsys, + int size, + const char* file, + const char* function, + int line); + + /* Write a dword to the command buffer. */ + void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword); + + /* Write a relocated dword to the command buffer. */ + void (*write_cs_reloc)(struct radeon_winsys* winsys, + struct pipe_buffer* bo, + uint32_t rd, + uint32_t wd, + uint32_t flags); + + /* Finish a command emit. */ + void (*end_cs)(struct radeon_winsys* winsys, + const char* file, + const char* function, + int line); + + /* Flush the CS. */ + void (*flush_cs)(struct radeon_winsys* winsys); + + /* winsys flush - callback from winsys when flush required */ + void (*set_flush_cb)(struct radeon_winsys *winsys, + void (*flush_cb)(void *), void *data); + + void (*reset_bos)(struct radeon_winsys *winsys); + + void (*buffer_set_tiling)(struct radeon_winsys* winsys, + struct pipe_buffer* buffer, + uint32_t pitch, + boolean microtiled, + boolean macrotiled); }; -static INLINE struct radeon_libdrm_winsys * -radeon_winsys_screen(struct r300_winsys_screen *base) -{ - return (struct radeon_libdrm_winsys *)base; -} - #endif -- cgit v1.2.3 From 63cb6f59eac91ba34cf80ff3736568e40b094fe1 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 22 Feb 2010 21:36:22 +0100 Subject: gallium: Remove bypass_vs_clip_and_viewport from rasteriser state. Needs testing. --- src/gallium/auxiliary/draw/draw_context.c | 8 +- src/gallium/auxiliary/draw/draw_pt.c | 4 +- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 3 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 15 +- src/gallium/auxiliary/util/u_blit.c | 15 +- src/gallium/auxiliary/util/u_blitter.c | 1 - src/gallium/auxiliary/util/u_dump_state.c | 1 - src/gallium/auxiliary/util/u_gen_mipmap.c | 39 ++- src/gallium/docs/source/cso/rasterizer.rst | 12 - src/gallium/drivers/nv30/nv30_context.h | 1 - src/gallium/drivers/nv30/nv30_state_viewport.c | 58 +---- src/gallium/drivers/nv40/nv40_context.h | 1 - src/gallium/drivers/nv40/nv40_state_viewport.c | 57 +---- src/gallium/drivers/nv50/nv50_context.h | 1 - src/gallium/drivers/nv50/nv50_state_validate.c | 62 ++--- src/gallium/drivers/r300/r300_context.h | 2 - src/gallium/drivers/r300/r300_emit.c | 46 ++-- src/gallium/drivers/r300/r300_state.c | 5 +- src/gallium/drivers/r300/r300_state_derived.c | 8 +- src/gallium/drivers/softpipe/sp_video_context.c | 1 - src/gallium/drivers/svga/svga_state_framebuffer.c | 285 ++++++++++----------- src/gallium/drivers/svga/svga_state_need_swtnl.c | 3 +- src/gallium/drivers/trace/tr_dump_state.c | 1 - src/gallium/include/pipe/p_state.h | 10 - src/mesa/state_tracker/st_cb_clear.c | 44 ++-- 25 files changed, 271 insertions(+), 412 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index d5ddc4a6a92..bb0988543f5 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -128,9 +128,7 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->rasterizer = raster; - draw->bypass_clipping = - ((draw->rasterizer && draw->rasterizer->bypass_vs_clip_and_viewport) || - draw->driver.bypass_clipping); + draw->bypass_clipping = draw->driver.bypass_clipping; } @@ -140,9 +138,7 @@ void draw_set_driver_clipping( struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->driver.bypass_clipping = bypass_clipping; - draw->bypass_clipping = - ((draw->rasterizer && draw->rasterizer->bypass_vs_clip_and_viewport) || - draw->driver.bypass_clipping); + draw->bypass_clipping = draw->driver.bypass_clipping; } diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 341353f6289..6d90a6c42fd 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -87,9 +87,7 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_CLIPTEST; } - if (!draw->rasterizer->bypass_vs_clip_and_viewport) { - opt |= PT_SHADE; - } + opt |= PT_SHADE; } if (opt == 0) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index c5dfbcfa3cb..1aecb510777 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -100,8 +100,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.nr_elements = MAX2(fse->key.nr_outputs, /* outputs - translate to hw format */ fse->key.nr_inputs); /* inputs - fetch from api format */ - fse->key.viewport = (!draw->rasterizer->bypass_vs_clip_and_viewport && - !draw->identity_viewport); + fse->key.viewport = !draw->identity_viewport; fse->key.clip = !draw->bypass_clipping; fse->key.const_vbuffers = 0; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 56b69354b21..da5106463a7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -96,8 +96,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, */ draw_pt_post_vs_prepare( fpme->post_vs, (boolean)draw->bypass_clipping, - (boolean)(draw->identity_viewport || - draw->rasterizer->bypass_vs_clip_and_viewport), + (boolean)draw->identity_viewport, (boolean)draw->rasterizer->gl_rasterization_rules, (draw->vs.edgeflag_output ? true : false) ); @@ -154,9 +153,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of - * the pipeline verts. If there is no shader, eg if - * bypass_vs_clip_and_viewport, then the inputs == outputs, and are - * already in the correct place. + * the pipeline verts. */ if (opt & PT_SHADE) { @@ -239,9 +236,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of - * the pipeline verts. If there is no shader, ie if - * bypass_vs_clip_and_viewport, then the inputs == outputs, and are - * already in the correct place. + * the pipeline verts. */ if (opt & PT_SHADE) { @@ -319,9 +314,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of - * the pipeline verts. If there is no shader, ie if - * bypass_vs_clip_and_viewport, then the inputs == outputs, and are - * already in the correct place. + * the pipeline verts. */ if (opt & PT_SHADE) { diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index f0bc58a558f..90a3230a0f5 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -101,7 +101,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_vs_clip_and_viewport = 1; ctx->rasterizer.gl_rasterization_rules = 1; /* samplers */ @@ -114,7 +113,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->sampler.mag_img_filter = 0; /* set later */ ctx->sampler.normalized_coords = 1; - /* vertex shader - still required to provide the linkage between * fragment shader input semantics and vertex_element/buffers. */ @@ -407,6 +405,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); + cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); @@ -422,6 +421,17 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); + /* viewport */ + ctx->viewport.scale[0] = 0.5f * dst->width; + ctx->viewport.scale[1] = 0.5f * dst->height; + ctx->viewport.scale[2] = 1.0f; + ctx->viewport.scale[3] = 1.0f; + ctx->viewport.translate[0] = 0.5f * dst->width; + ctx->viewport.translate[1] = 0.5f * dst->height; + ctx->viewport.translate[2] = 0.0f; + ctx->viewport.translate[3] = 0.0f; + cso_set_viewport(ctx->cso, &ctx->viewport); + /* texture */ cso_set_sampler_textures(ctx->cso, 1, &tex); @@ -461,6 +471,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_rasterizer(ctx->cso); cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); + cso_restore_viewport(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 18f86068183..50877f6b01a 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -160,7 +160,6 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) memset(&rs_state, 0, sizeof(rs_state)); rs_state.front_winding = PIPE_WINDING_CW; rs_state.cull_mode = PIPE_WINDING_NONE; - rs_state.bypass_vs_clip_and_viewport = 1; rs_state.gl_rasterization_rules = 1; rs_state.flatshade = 1; ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index eaf4ec90f25..ae7afd7311e 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -318,7 +318,6 @@ util_dump_rasterizer_state(struct os_stream *stream, const struct pipe_rasterize util_dump_member(stream, uint, state, line_stipple_factor); util_dump_member(stream, uint, state, line_stipple_pattern); util_dump_member(stream, bool, state, line_last_pixel); - util_dump_member(stream, bool, state, bypass_vs_clip_and_viewport); util_dump_member(stream, bool, state, flatshade_first); util_dump_member(stream, bool, state, gl_rasterization_rules); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 1d7329d422b..4f9ff1d9612 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1296,7 +1296,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_vs_clip_and_viewport = 1; ctx->rasterizer.gl_rasterization_rules = 1; /* sampler state */ @@ -1361,25 +1360,25 @@ get_next_slot(struct gen_mipmap_state *ctx) static unsigned set_vertex_data(struct gen_mipmap_state *ctx, enum pipe_texture_target tex_target, - uint face, float width, float height) + uint face) { unsigned offset; /* vert[0].position */ - ctx->vertices[0][0][0] = 0.0f; /*x*/ - ctx->vertices[0][0][1] = 0.0f; /*y*/ + ctx->vertices[0][0][0] = -1.0f; /*x*/ + ctx->vertices[0][0][1] = -1.0f; /*y*/ /* vert[1].position */ - ctx->vertices[1][0][0] = width; - ctx->vertices[1][0][1] = 0.0f; + ctx->vertices[1][0][0] = 1.0f; + ctx->vertices[1][0][1] = -1.0f; /* vert[2].position */ - ctx->vertices[2][0][0] = width; - ctx->vertices[2][0][1] = height; + ctx->vertices[2][0][0] = 1.0f; + ctx->vertices[2][0][1] = 1.0f; /* vert[3].position */ - ctx->vertices[3][0][0] = 0.0f; - ctx->vertices[3][0][1] = height; + ctx->vertices[3][0][0] = -1.0f; + ctx->vertices[3][0][1] = 1.0f; /* Setup vertex texcoords. This is a little tricky for cube maps. */ if (tex_target == PIPE_TEXTURE_CUBE) { @@ -1499,6 +1498,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); + cso_save_viewport(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); @@ -1522,6 +1522,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, */ for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; + struct pipe_viewport_state vp; struct pipe_surface *surf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, @@ -1535,6 +1536,17 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, fb.height = u_minify(pt->height0, dstLevel); cso_set_framebuffer(ctx->cso, &fb); + /* viewport */ + vp.scale[0] = 0.5f * fb.width; + vp.scale[1] = 0.5f * fb.height; + vp.scale[2] = 1.0f; + vp.scale[3] = 1.0f; + vp.translate[0] = 0.5f * fb.width; + vp.translate[1] = 0.5f * fb.height; + vp.translate[2] = 0.0f; + vp.translate[3] = 0.0f; + cso_set_viewport(ctx->cso, &vp); + /* * Setup sampler state * Note: we should only have to set the min/max LOD clamps to ensure @@ -1549,12 +1561,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_sampler_textures(ctx->cso, 1, &pt); - /* quad coords in window coords (bypassing vs, clip and viewport) */ + /* quad coords in clip coords */ offset = set_vertex_data(ctx, pt->target, - face, - (float) u_minify(pt->width0, dstLevel), - (float) u_minify(pt->height0, dstLevel)); + face); util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, @@ -1578,4 +1588,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); + cso_restore_viewport(ctx->cso); } diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst index 24cc78c68de..ccd9136a2eb 100644 --- a/src/gallium/docs/source/cso/rasterizer.rst +++ b/src/gallium/docs/source/cso/rasterizer.rst @@ -10,18 +10,6 @@ multisample state, scissoring and flat/smooth shading. Members ------- -bypass_vs_clip_and_viewport -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Whether the entire TCL pipeline should be bypassed. This implies that -vertices are pre-transformed for the viewport, and will not be run -through the vertex shader. - -.. note:: - - Implementations may still clip away vertices that are not in the viewport - when this is set. - flatshade ^^^^^^^^^ diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index ca3d6aca7fa..ea259aadf35 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -101,7 +101,6 @@ struct nv30_blend_state { struct nv30_state { unsigned scissor_enabled; unsigned stipple_enabled; - unsigned viewport_bypass; unsigned fp_samplers; uint64_t dirty; diff --git a/src/gallium/drivers/nv30/nv30_state_viewport.c b/src/gallium/drivers/nv30/nv30_state_viewport.c index 2d7781292bd..6fccd6b60e7 100644 --- a/src/gallium/drivers/nv30/nv30_state_viewport.c +++ b/src/gallium/drivers/nv30/nv30_state_viewport.c @@ -5,55 +5,25 @@ nv30_state_viewport_validate(struct nv30_context *nv30) { struct pipe_viewport_state *vpt = &nv30->viewport; struct nouveau_stateobj *so; - unsigned bypass; - - if (/*nv30->render_mode == HW &&*/ - !nv30->rasterizer->pipe.bypass_vs_clip_and_viewport) - bypass = 0; - else - bypass = 1; if (nv30->state.hw[NV30_STATE_VIEWPORT] && - (bypass || !(nv30->dirty & NV30_NEW_VIEWPORT)) && - nv30->state.viewport_bypass == bypass) + !(nv30->dirty & NV30_NEW_VIEWPORT)) return FALSE; - nv30->state.viewport_bypass = bypass; so = so_new(3, 10, 0); - if (!bypass) { - so_method(so, nv30->screen->rankine, - NV34TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(vpt->translate[0])); - so_data (so, fui(vpt->translate[1])); - so_data (so, fui(vpt->translate[2])); - so_data (so, fui(vpt->translate[3])); - so_data (so, fui(vpt->scale[0])); - so_data (so, fui(vpt->scale[1])); - so_data (so, fui(vpt->scale[2])); - so_data (so, fui(vpt->scale[3])); -/* so_method(so, nv30->screen->rankine, 0x1d78, 1); - so_data (so, 1); -*/ } else { - so_method(so, nv30->screen->rankine, - NV34TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(0.0)); - so_data (so, fui(0.0)); - so_data (so, fui(0.0)); - so_data (so, fui(0.0)); - so_data (so, fui(1.0)); - so_data (so, fui(1.0)); - so_data (so, fui(1.0)); - so_data (so, fui(0.0)); - /* Not entirely certain what this is yet. The DDX uses this - * value also as it fixes rendering when you pass - * pre-transformed vertices to the GPU. My best gusss is that - * this bypasses some culling/clipping stage. Might be worth - * noting that points/lines are uneffected by whatever this - * value fixes, only filled polygons are effected. - */ -/* so_method(so, nv30->screen->rankine, 0x1d78, 1); - so_data (so, 0x110); -*/ } + so_method(so, nv30->screen->rankine, + NV34TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); +/* so_method(so, nv30->screen->rankine, 0x1d78, 1); + so_data (so, 1); +*/ /* TODO/FIXME: never saw value 0x0110 in renouveau dumps, only 0x0001 */ so_method(so, nv30->screen->rankine, 0x1d78, 1); so_data (so, 1); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 4861924dac7..97fb6a2ef94 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -101,7 +101,6 @@ struct nv40_blend_state { struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; - unsigned viewport_bypass; unsigned fp_samplers; uint64_t dirty; diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9919ba1d0b0..3aacb00f996 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -5,55 +5,24 @@ nv40_state_viewport_validate(struct nv40_context *nv40) { struct pipe_viewport_state *vpt = &nv40->viewport; struct nouveau_stateobj *so; - unsigned bypass; - - if (nv40->render_mode == HW && - !nv40->rasterizer->pipe.bypass_vs_clip_and_viewport) - bypass = 0; - else - bypass = 1; if (nv40->state.hw[NV40_STATE_VIEWPORT] && - (bypass || !(nv40->dirty & NV40_NEW_VIEWPORT)) && - nv40->state.viewport_bypass == bypass) + !(nv40->dirty & NV40_NEW_VIEWPORT)) return FALSE; - nv40->state.viewport_bypass = bypass; so = so_new(2, 9, 0); - if (!bypass) { - so_method(so, nv40->screen->curie, - NV40TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(vpt->translate[0])); - so_data (so, fui(vpt->translate[1])); - so_data (so, fui(vpt->translate[2])); - so_data (so, fui(vpt->translate[3])); - so_data (so, fui(vpt->scale[0])); - so_data (so, fui(vpt->scale[1])); - so_data (so, fui(vpt->scale[2])); - so_data (so, fui(vpt->scale[3])); - so_method(so, nv40->screen->curie, 0x1d78, 1); - so_data (so, 1); - } else { - so_method(so, nv40->screen->curie, - NV40TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(0.0)); - so_data (so, fui(0.0)); - so_data (so, fui(0.0)); - so_data (so, fui(0.0)); - so_data (so, fui(1.0)); - so_data (so, fui(1.0)); - so_data (so, fui(1.0)); - so_data (so, fui(0.0)); - /* Not entirely certain what this is yet. The DDX uses this - * value also as it fixes rendering when you pass - * pre-transformed vertices to the GPU. My best gusss is that - * this bypasses some culling/clipping stage. Might be worth - * noting that points/lines are uneffected by whatever this - * value fixes, only filled polygons are effected. - */ - so_method(so, nv40->screen->curie, 0x1d78, 1); - so_data (so, 0x110); - } + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 1); so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); so_ref(NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index b4de3e2ba57..c540594b949 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -127,7 +127,6 @@ struct nv50_state { struct nouveau_stateobj *scissor; unsigned scissor_enabled; struct nouveau_stateobj *viewport; - unsigned viewport_bypass; struct nouveau_stateobj *tsc_upload; struct nouveau_stateobj *tic_upload; unsigned miptree_nr[PIPE_SHADER_TYPES]; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index efab94cab74..a91b31015e2 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -375,50 +375,32 @@ nv50_state_validate(struct nv50_context *nv50) scissor_uptodate: if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) { - unsigned bypass; - - if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport) - bypass = 0; - else - bypass = 1; - if (nv50->state.viewport && - (bypass || !(nv50->dirty & NV50_NEW_VIEWPORT)) && - nv50->state.viewport_bypass == bypass) + !(nv50->dirty & NV50_NEW_VIEWPORT)) goto viewport_uptodate; - nv50->state.viewport_bypass = bypass; so = so_new(5, 9, 0); - if (!bypass) { - so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3); - so_data (so, fui(nv50->viewport.translate[0])); - so_data (so, fui(nv50->viewport.translate[1])); - so_data (so, fui(nv50->viewport.translate[2])); - so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3); - so_data (so, fui(nv50->viewport.scale[0])); - so_data (so, fui(nv50->viewport.scale[1])); - so_data (so, fui(nv50->viewport.scale[2])); - - so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); - so_data (so, 1); - /* 0x0000 = remove whole primitive only (xyz) - * 0x1018 = remove whole primitive only (xy), clamp z - * 0x1080 = clip primitive (xyz) - * 0x1098 = clip primitive (xy), clamp z - */ - so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1); - so_data (so, 0x1080); - /* no idea what 0f90 does */ - so_method(so, tesla, 0x0f90, 1); - so_data (so, 0); - } else { - so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); - so_data (so, 0); - so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1); - so_data (so, 0x0000); - so_method(so, tesla, 0x0f90, 1); - so_data (so, 1); - } + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3); + so_data (so, fui(nv50->viewport.translate[0])); + so_data (so, fui(nv50->viewport.translate[1])); + so_data (so, fui(nv50->viewport.translate[2])); + so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3); + so_data (so, fui(nv50->viewport.scale[0])); + so_data (so, fui(nv50->viewport.scale[1])); + so_data (so, fui(nv50->viewport.scale[2])); + + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); + so_data (so, 1); + /* 0x0000 = remove whole primitive only (xyz) + * 0x1018 = remove whole primitive only (xy), clamp z + * 0x1080 = clip primitive (xyz) + * 0x1098 = clip primitive (xy), clamp z + */ + so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1); + so_data (so, 0x1080); + /* no idea what 0f90 does */ + so_method(so, tesla, 0x0f90, 1); + so_data (so, 0); so_ref(so, &nv50->state.viewport); so_ref(NULL, &so); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 443af4ec2e3..2f056aafcbf 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -337,8 +337,6 @@ struct r300_context { uint32_t dirty_state; /* Flag indicating whether or not the HW is dirty. */ uint32_t dirty_hw; - /* Whether the TCL engine should be in bypass mode. */ - boolean tcl_bypass; /* Whether polygon offset is enabled. */ boolean polygon_offset_enabled; /* Z buffer bit depth. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f7dcd8dc52f..37ebe6c49df 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -170,23 +170,15 @@ static const float * get_shader_constant( break; case RC_STATE_R300_VIEWPORT_SCALE: - if (r300->tcl_bypass) { - vec[0] = 1; - vec[1] = 1; - vec[2] = 1; - } else { - vec[0] = viewport->xscale; - vec[1] = viewport->yscale; - vec[2] = viewport->zscale; - } + vec[0] = viewport->xscale; + vec[1] = viewport->yscale; + vec[2] = viewport->zscale; break; case RC_STATE_R300_VIEWPORT_OFFSET: - if (!r300->tcl_bypass) { - vec[0] = viewport->xoffset; - vec[1] = viewport->yoffset; - vec[2] = viewport->zoffset; - } + vec[0] = viewport->xoffset; + vec[1] = viewport->yoffset; + vec[2] = viewport->zoffset; break; default: @@ -936,22 +928,16 @@ void r300_emit_viewport_state(struct r300_context* r300, void* state) struct r300_viewport_state* viewport = (struct r300_viewport_state*)state; CS_LOCALS(r300); - if (r300->tcl_bypass) { - BEGIN_CS(2); - OUT_CS_REG(R300_VAP_VTE_CNTL, 0); - END_CS; - } else { - BEGIN_CS(9); - OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); - OUT_CS_32F(viewport->xscale); - OUT_CS_32F(viewport->xoffset); - OUT_CS_32F(viewport->yscale); - OUT_CS_32F(viewport->yoffset); - OUT_CS_32F(viewport->zscale); - OUT_CS_32F(viewport->zoffset); - OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); - END_CS; - } + BEGIN_CS(9); + OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); + OUT_CS_32F(viewport->xscale); + OUT_CS_32F(viewport->xoffset); + OUT_CS_32F(viewport->yscale); + OUT_CS_32F(viewport->yoffset); + OUT_CS_32F(viewport->zscale); + OUT_CS_32F(viewport->zoffset); + OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); + END_CS; } void r300_emit_texture_count(struct r300_context* r300) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c1930..3550c69c46d 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -711,8 +711,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe, /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL. * Else, enable HW TCL and force Draw's TCL off. */ - if (state->bypass_vs_clip_and_viewport || - !r300screen->caps->has_tcl) { + if (!r300screen->caps->has_tcl) { rs->vap_control_status |= R300_VAP_TCL_BYPASS; } @@ -824,10 +823,8 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) } if (rs) { - r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport; r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; } else { - r300->tcl_bypass = FALSE; r300->polygon_offset_enabled = FALSE; } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2cbce9210a7..778eaaacd99 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -114,13 +114,7 @@ static void r300_vertex_psc(struct r300_context* r300) int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; int* stream_tab; - /* If TCL is bypassed, map vertex streams to equivalent VS output - * locations. */ - if (r300->tcl_bypass) { - stream_tab = r300->vs->stream_loc_notcl; - } else { - stream_tab = identity; - } + stream_tab = identity; /* Vertex shaders have no semantics on their inputs, * so PSC should just route stuff based on the vertex elements, diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index 7a3a6361670..8e4867a904e 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -174,7 +174,6 @@ init_pipe_state(struct sp_mpeg12_context *ctx) rast.line_stipple_factor = 0; rast.line_stipple_pattern = 0; rast.line_last_pixel = 0; - rast.bypass_vs_clip_and_viewport = 0; rast.line_width = 1; rast.point_smooth = 0; rast.point_quad_rasterization = 0; diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index b4cafb8f219..4d0c06bd77e 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -120,174 +120,153 @@ static int emit_viewport( struct svga_context *svga, float fb_width = svga->curr.framebuffer.width; float fb_height = svga->curr.framebuffer.height; - memset( &prescale, 0, sizeof(prescale) ); - - if (svga->curr.rast->templ.bypass_vs_clip_and_viewport) { - - /* Avoid POSITIONT as it has a non trivial implementation outside the D3D - * API. Always generate a vertex shader. - */ - rect.x = 0; - rect.y = 0; - rect.w = svga->curr.framebuffer.width; - rect.h = svga->curr.framebuffer.height; - - prescale.scale[0] = 2.0 / (float)rect.w; - prescale.scale[1] = - 2.0 / (float)rect.h; - prescale.scale[2] = 1.0; - prescale.scale[3] = 1.0; - prescale.translate[0] = -1.0f; - prescale.translate[1] = 1.0f; - prescale.translate[2] = 0; - prescale.translate[3] = 0; - prescale.enabled = TRUE; - } else { - - /* Examine gallium viewport transformation and produce a screen - * rectangle and possibly vertex shader pre-transformation to - * get the same results. - */ - float fx = viewport->scale[0] * -1.0 + viewport->translate[0]; - float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1]; - float fw = viewport->scale[0] * 2; - float fh = flip * viewport->scale[1] * 2; - - SVGA_DBG(DEBUG_VIEWPORT, - "\ninitial %f,%f %fx%f\n", - fx, - fy, - fw, - fh); - - prescale.scale[0] = 1.0; - prescale.scale[1] = 1.0; - prescale.scale[2] = 1.0; - prescale.scale[3] = 1.0; - prescale.translate[0] = 0; - prescale.translate[1] = 0; - prescale.translate[2] = 0; - prescale.translate[3] = 0; - prescale.enabled = TRUE; - - - - if (fw < 0) { - prescale.scale[0] *= -1.0; - prescale.translate[0] += -fw; - fw = -fw; - fx = viewport->scale[0] * 1.0 + viewport->translate[0]; - } + float fx = viewport->scale[0] * -1.0 + viewport->translate[0]; + float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1]; + float fw = viewport->scale[0] * 2; + float fh = flip * viewport->scale[1] * 2; - if (fh < 0) { - prescale.scale[1] *= -1.0; - prescale.translate[1] += -fh; - fh = -fh; - fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1]; - } + memset( &prescale, 0, sizeof(prescale) ); - if (fx < 0) { - prescale.translate[0] += fx; - prescale.scale[0] *= fw / (fw + fx); - fw += fx; - fx = 0; - } + /* Examine gallium viewport transformation and produce a screen + * rectangle and possibly vertex shader pre-transformation to + * get the same results. + */ - if (fy < 0) { - prescale.translate[1] += fy; - prescale.scale[1] *= fh / (fh + fy); - fh += fy; - fy = 0; - } + SVGA_DBG(DEBUG_VIEWPORT, + "\ninitial %f,%f %fx%f\n", + fx, + fy, + fw, + fh); + + prescale.scale[0] = 1.0; + prescale.scale[1] = 1.0; + prescale.scale[2] = 1.0; + prescale.scale[3] = 1.0; + prescale.translate[0] = 0; + prescale.translate[1] = 0; + prescale.translate[2] = 0; + prescale.translate[3] = 0; + prescale.enabled = TRUE; + + + + if (fw < 0) { + prescale.scale[0] *= -1.0; + prescale.translate[0] += -fw; + fw = -fw; + fx = viewport->scale[0] * 1.0 + viewport->translate[0]; + } - if (fx + fw > fb_width) { - prescale.scale[0] *= fw / (fb_width - fx); - prescale.translate[0] -= fx * (fw / (fb_width - fx)); - prescale.translate[0] += fx; - fw = fb_width - fx; - - } + if (fh < 0) { + prescale.scale[1] *= -1.0; + prescale.translate[1] += -fh; + fh = -fh; + fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1]; + } - if (fy + fh > fb_height) { - prescale.scale[1] *= fh / (fb_height - fy); - prescale.translate[1] -= fy * (fh / (fb_height - fy)); - prescale.translate[1] += fy; - fh = fb_height - fy; - } + if (fx < 0) { + prescale.translate[0] += fx; + prescale.scale[0] *= fw / (fw + fx); + fw += fx; + fx = 0; + } - if (fw < 0 || fh < 0) { - fw = fh = fx = fy = 0; - degenerate = TRUE; - goto out; - } + if (fy < 0) { + prescale.translate[1] += fy; + prescale.scale[1] *= fh / (fh + fy); + fh += fy; + fy = 0; + } + if (fx + fw > fb_width) { + prescale.scale[0] *= fw / (fb_width - fx); + prescale.translate[0] -= fx * (fw / (fb_width - fx)); + prescale.translate[0] += fx; + fw = fb_width - fx; + + } - /* D3D viewport is integer space. Convert fx,fy,etc. to - * integers. - * - * TODO: adjust pretranslate correct for any subpixel error - * introduced converting to integers. - */ - rect.x = fx; - rect.y = fy; - rect.w = fw; - rect.h = fh; + if (fy + fh > fb_height) { + prescale.scale[1] *= fh / (fb_height - fy); + prescale.translate[1] -= fy * (fh / (fb_height - fy)); + prescale.translate[1] += fy; + fh = fb_height - fy; + } - SVGA_DBG(DEBUG_VIEWPORT, - "viewport error %f,%f %fx%f\n", - fabs((float)rect.x - fx), - fabs((float)rect.y - fy), - fabs((float)rect.w - fw), - fabs((float)rect.h - fh)); + if (fw < 0 || fh < 0) { + fw = fh = fx = fy = 0; + degenerate = TRUE; + goto out; + } - SVGA_DBG(DEBUG_VIEWPORT, - "viewport %d,%d %dx%d\n", - rect.x, - rect.y, - rect.w, - rect.h); - - /* Finally, to get GL rasterization rules, need to tweak the - * screen-space coordinates slightly relative to D3D which is - * what hardware implements natively. - */ - if (svga->curr.rast->templ.gl_rasterization_rules) { - float adjust_x = 0.0; - float adjust_y = 0.0; - - switch (svga->curr.reduced_prim) { - case PIPE_PRIM_LINES: - adjust_x = -0.5; - adjust_y = 0; - break; - case PIPE_PRIM_POINTS: - case PIPE_PRIM_TRIANGLES: - adjust_x = -0.375; - adjust_y = -0.5; - break; - } - - prescale.translate[0] += adjust_x; - prescale.translate[1] += adjust_y; - prescale.translate[2] = 0.5; /* D3D clip space */ - prescale.scale[2] = 0.5; /* D3D clip space */ + /* D3D viewport is integer space. Convert fx,fy,etc. to + * integers. + * + * TODO: adjust pretranslate correct for any subpixel error + * introduced converting to integers. + */ + rect.x = fx; + rect.y = fy; + rect.w = fw; + rect.h = fh; + + SVGA_DBG(DEBUG_VIEWPORT, + "viewport error %f,%f %fx%f\n", + fabs((float)rect.x - fx), + fabs((float)rect.y - fy), + fabs((float)rect.w - fw), + fabs((float)rect.h - fh)); + + SVGA_DBG(DEBUG_VIEWPORT, + "viewport %d,%d %dx%d\n", + rect.x, + rect.y, + rect.w, + rect.h); + + + /* Finally, to get GL rasterization rules, need to tweak the + * screen-space coordinates slightly relative to D3D which is + * what hardware implements natively. + */ + if (svga->curr.rast->templ.gl_rasterization_rules) { + float adjust_x = 0.0; + float adjust_y = 0.0; + + switch (svga->curr.reduced_prim) { + case PIPE_PRIM_LINES: + adjust_x = -0.5; + adjust_y = 0; + break; + case PIPE_PRIM_POINTS: + case PIPE_PRIM_TRIANGLES: + adjust_x = -0.375; + adjust_y = -0.5; + break; } + prescale.translate[0] += adjust_x; + prescale.translate[1] += adjust_y; + prescale.translate[2] = 0.5; /* D3D clip space */ + prescale.scale[2] = 0.5; /* D3D clip space */ + } - range_min = viewport->scale[2] * -1.0 + viewport->translate[2]; - range_max = viewport->scale[2] * 1.0 + viewport->translate[2]; - /* D3D (and by implication SVGA) doesn't like dealing with zmax - * less than zmin. Detect that case, flip the depth range and - * invert our z-scale factor to achieve the same effect. - */ - if (range_min > range_max) { - float range_tmp; - range_tmp = range_min; - range_min = range_max; - range_max = range_tmp; - prescale.scale[2] = -prescale.scale[2]; - } + range_min = viewport->scale[2] * -1.0 + viewport->translate[2]; + range_max = viewport->scale[2] * 1.0 + viewport->translate[2]; + + /* D3D (and by implication SVGA) doesn't like dealing with zmax + * less than zmin. Detect that case, flip the depth range and + * invert our z-scale factor to achieve the same effect. + */ + if (range_min > range_max) { + float range_tmp; + range_tmp = range_min; + range_min = range_max; + range_max = range_tmp; + prescale.scale[2] = -prescale.scale[2]; } if (prescale.enabled) { diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c index dd13a89d24d..a6ed18599c4 100644 --- a/src/gallium/drivers/svga/svga_state_need_swtnl.c +++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c @@ -129,8 +129,7 @@ static int update_need_pipeline( struct svga_context *svga, /* SVGA_NEW_CLIP */ - if (!svga->curr.rast->templ.bypass_vs_clip_and_viewport && - svga->curr.clip.nr) { + if (svga->curr.clip.nr) { SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__); need_pipeline = TRUE; } diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 6da186a6555..f97d963dba6 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -112,7 +112,6 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) trace_dump_member(uint, state, line_stipple_factor); trace_dump_member(uint, state, line_stipple_pattern); trace_dump_member(bool, state, line_last_pixel); - trace_dump_member(bool, state, bypass_vs_clip_and_viewport); trace_dump_member(bool, state, flatshade_first); trace_dump_member(bool, state, gl_rasterization_rules); diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5ac5c878135..02558520bfe 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -113,16 +113,6 @@ struct pipe_rasterizer_state unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; - /** - * Vertex coordinates are pre-transformed to screen space. Skip - * the vertex shader, clipping and viewport processing. Note that - * a vertex shader is still needed though, to indicate the mapping - * from vertex elements to fragment shader input semantics. - * - * XXX: considered for removal. - */ - unsigned bypass_vs_clip_and_viewport:1; - /** * Use the first vertex of a primitive as the provoking vertex for * flat shading. diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 898c32293d1..5edab55ccab 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -65,9 +65,6 @@ st_init_clear(struct st_context *st) memset(&st->clear.raster, 0, sizeof(st->clear.raster)); st->clear.raster.gl_rasterization_rules = 1; - /* rasterizer state: bypass vertex shader, clipping and viewport */ - st->clear.raster.bypass_vs_clip_and_viewport = 1; - /* fragment shader state: color pass-through program */ st->clear.fs = util_make_fragment_passthrough_shader(pipe); @@ -104,9 +101,7 @@ st_destroy_clear(struct st_context *st) /** * Draw a screen-aligned quadrilateral. - * Coords are window coords with y=0=bottom. These will be passed - * through unmodified to the rasterizer as we have set - * rasterizer->bypass_vs_clip_and_viewport. + * Coords are clip coords with y=0=bottom. */ static void draw_quad(GLcontext *ctx, @@ -192,18 +187,13 @@ clear_with_quad(GLcontext *ctx, GLboolean color, GLboolean depth, GLboolean stencil) { struct st_context *st = ctx->st; - const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin; - const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax; - GLfloat y0, y1; - - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - y0 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax); - y1 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin); - } - else { - y0 = (GLfloat) ctx->DrawBuffer->_Ymin; - y1 = (GLfloat) ctx->DrawBuffer->_Ymax; - } + const struct gl_framebuffer *fb = ctx->DrawBuffer; + const GLfloat fb_width = (GLfloat) fb->Width; + const GLfloat fb_height = (GLfloat) fb->Height; + const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f; + const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f; + const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; + const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, @@ -218,6 +208,7 @@ clear_with_quad(GLcontext *ctx, cso_save_stencil_ref(st->cso_context); cso_save_depth_stencil_alpha(st->cso_context); cso_save_rasterizer(st->cso_context); + cso_save_viewport(st->cso_context); cso_save_fragment_shader(st->cso_context); cso_save_vertex_shader(st->cso_context); @@ -273,6 +264,21 @@ clear_with_quad(GLcontext *ctx, cso_set_rasterizer(st->cso_context, &st->clear.raster); + /* viewport state: viewport matching window dims */ + { + const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); + struct pipe_viewport_state vp; + vp.scale[0] = 0.5f * fb_width; + vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f); + vp.scale[2] = 1.0f; + vp.scale[3] = 1.0f; + vp.translate[0] = 0.5f * fb_width; + vp.translate[1] = 0.5f * fb_height; + vp.translate[2] = 0.0f; + vp.translate[3] = 0.0f; + cso_set_viewport(st->cso_context, &vp); + } + cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); @@ -284,9 +290,9 @@ clear_with_quad(GLcontext *ctx, cso_restore_stencil_ref(st->cso_context); cso_restore_depth_stencil_alpha(st->cso_context); cso_restore_rasterizer(st->cso_context); + cso_restore_viewport(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); - } -- cgit v1.2.3 From 902ccfcb40f21e1a5fca2f1bec1cbbabb053d8cf Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 22 Feb 2010 13:51:38 +0100 Subject: r300g: fix draw_elements for "start" != 0 Reported-by: Andre Maasikas --- src/gallium/drivers/r300/r300_render.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 754eb4dc769..648d884654f 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -258,11 +258,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, assert((start * indexSize) % 4 == 0); - /* XXX Non-zero offset locks up. */ - if (offset_dwords != 0) { - return; - } - if (alt_num_verts) { assert(count < (1 << 24)); BEGIN_CS(16); @@ -276,13 +271,13 @@ static void r300_emit_draw_elements(struct r300_context *r300, OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); if (indexSize == 4) { - count_dwords = count + start; + count_dwords = count; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | R300_VAP_VF_CNTL__INDEX_SIZE_32bit | r300_translate_primitive(mode) | (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); } else { - count_dwords = (count + start + 1) / 2; + count_dwords = (count + 1) / 2; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | r300_translate_primitive(mode) | (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); -- cgit v1.2.3 From 232f6e176192d112fbdf9bd7de2d0f36ee16a246 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 23 Feb 2010 09:08:28 +0100 Subject: r300g: fix texture swizzling for the SRGB formats --- src/gallium/drivers/r300/r300_texture.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index ed2be06254a..7b116b30e5e 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -70,6 +70,19 @@ static uint32_t r300_translate_texformat(enum pipe_format format) R300_TX_FORMAT_B_SHIFT, R300_TX_FORMAT_A_SHIFT }; + const uint32_t swizzle_arith[4] = { + R300_TX_FORMAT_X, + R300_TX_FORMAT_Y, + R300_TX_FORMAT_Z, + R300_TX_FORMAT_W + }; + const uint32_t swizzle_array[4] = { + R300_TX_FORMAT_W, + R300_TX_FORMAT_Z, + R300_TX_FORMAT_Y, + R300_TX_FORMAT_X + }; + const uint32_t *swizzle; const uint32_t sign_bit[4] = { R300_TX_FORMAT_SIGNED_X, R300_TX_FORMAT_SIGNED_Y, @@ -115,20 +128,23 @@ static uint32_t r300_translate_texformat(enum pipe_format format) } /* Add swizzle. */ + swizzle = desc->layout == UTIL_FORMAT_LAYOUT_ARITH ? + swizzle_arith : swizzle_array; + for (i = 0; i < 4; i++) { switch (desc->swizzle[i]) { case UTIL_FORMAT_SWIZZLE_X: case UTIL_FORMAT_SWIZZLE_NONE: - result |= R300_TX_FORMAT_X << swizzle_shift[i]; + result |= swizzle[0] << swizzle_shift[i]; break; case UTIL_FORMAT_SWIZZLE_Y: - result |= R300_TX_FORMAT_Y << swizzle_shift[i]; + result |= swizzle[1] << swizzle_shift[i]; break; case UTIL_FORMAT_SWIZZLE_Z: - result |= R300_TX_FORMAT_Z << swizzle_shift[i]; + result |= swizzle[2] << swizzle_shift[i]; break; case UTIL_FORMAT_SWIZZLE_W: - result |= R300_TX_FORMAT_W << swizzle_shift[i]; + result |= swizzle[3] << swizzle_shift[i]; break; case UTIL_FORMAT_SWIZZLE_0: result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; -- cgit v1.2.3 From f9f4f3df422334aee31f9041c374c72d0f97ba39 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 24 Feb 2010 16:11:08 +0000 Subject: r300: Update for UTIL_FORMAT_LAYOUT_xxx changes. --- src/gallium/drivers/r300/r300_state_inlines.h | 6 ++---- src/gallium/drivers/r300/r300_texture.c | 14 ++------------ 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 0e1cb328d17..2f3a56e1fbc 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -384,8 +384,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { desc = util_format_description(format); - if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH && - desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) { + if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { debug_printf("r300: Bad format %s in %s:%d\n", util_format_name(format), __FUNCTION__, __LINE__); assert(0); @@ -458,8 +457,7 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) { assert(format); - if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH && - desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) { + if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { debug_printf("r300: Bad format %s in %s:%d\n", util_format_name(format), __FUNCTION__, __LINE__); return 0; diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 7b116b30e5e..7c3b781c0bf 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -70,19 +70,12 @@ static uint32_t r300_translate_texformat(enum pipe_format format) R300_TX_FORMAT_B_SHIFT, R300_TX_FORMAT_A_SHIFT }; - const uint32_t swizzle_arith[4] = { + const uint32_t swizzle[4] = { R300_TX_FORMAT_X, R300_TX_FORMAT_Y, R300_TX_FORMAT_Z, R300_TX_FORMAT_W }; - const uint32_t swizzle_array[4] = { - R300_TX_FORMAT_W, - R300_TX_FORMAT_Z, - R300_TX_FORMAT_Y, - R300_TX_FORMAT_X - }; - const uint32_t *swizzle; const uint32_t sign_bit[4] = { R300_TX_FORMAT_SIGNED_X, R300_TX_FORMAT_SIGNED_Y, @@ -128,9 +121,6 @@ static uint32_t r300_translate_texformat(enum pipe_format format) } /* Add swizzle. */ - swizzle = desc->layout == UTIL_FORMAT_LAYOUT_ARITH ? - swizzle_arith : swizzle_array; - for (i = 0; i < 4; i++) { switch (desc->swizzle[i]) { case UTIL_FORMAT_SWIZZLE_X: @@ -158,7 +148,7 @@ static uint32_t r300_translate_texformat(enum pipe_format format) } /* Compressed formats. */ - if (desc->layout == UTIL_FORMAT_LAYOUT_DXT) { + if (desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED) { switch (format) { case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: -- cgit v1.2.3 From 778276a4dd30d97ca9b573b090a28b22d17a6801 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 24 Feb 2010 15:49:11 -0700 Subject: r300g: remove invalid .PHONY line The $(COMPILER_ARCHIVE) target is not a phony target. This solves the unconditional re-making of libr300.a --- src/gallium/drivers/r300/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index afddcb161fa..1f69daec819 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -32,7 +32,5 @@ EXTRA_OBJECTS = \ include ../../Makefile.template -.PHONY : $(COMPILER_ARCHIVE) - $(COMPILER_ARCHIVE): $(MAKE) -C $(TOP)/src/mesa/drivers/dri/r300/compiler -- cgit v1.2.3 From e6632b4bf7cba5fe8a77d54635a3b617fa67185f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 22 Feb 2010 15:11:29 +0100 Subject: r300g: prevent CS overflow when emitting the draw packets Signed-off-by: Corbin Simpson --- src/gallium/drivers/r300/r300_emit.c | 29 +++++++++++------------ src/gallium/drivers/r300/r300_emit.h | 2 ++ src/gallium/drivers/r300/r300_render.c | 42 ++++++++++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f7dcd8dc52f..2d8801c08ad 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1076,16 +1076,10 @@ validate: } } -/* Emit all dirty state. */ -void r300_emit_dirty_state(struct r300_context* r300) +unsigned r300_get_num_dirty_dwords(struct r300_context *r300) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_atom* atom; - unsigned i, dwords = 1024; - int dirty_tex = 0; - - /* Check the required number of dwords against the space remaining in the - * current CS object. If we need more, then flush. */ + unsigned dwords = 0; foreach(atom, &r300->atom_list) { if (atom->dirty || atom->always_dirty) { @@ -1093,12 +1087,19 @@ void r300_emit_dirty_state(struct r300_context* r300) } } - /* Make sure we have at least 2*1024 spare dwords. */ - /* XXX It would be nice to know the number of dwords we really need to - * XXX emit. */ - while (!r300->winsys->check_cs(r300->winsys, dwords)) { - r300->context.flush(&r300->context, 0, NULL); - } + /* XXX This is the compensation for the non-atomized states. */ + dwords += 2048; + + return dwords; +} + +/* Emit all dirty state. */ +void r300_emit_dirty_state(struct r300_context* r300) +{ + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_atom* atom; + unsigned i; + int dirty_tex = 0; if (r300->dirty_state & R300_NEW_QUERY) { r300_emit_query_start(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 6b96d9b57c0..ff709a05957 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -90,6 +90,8 @@ void r300_emit_ztop_state(struct r300_context* r300, void* state); void r300_flush_textures(struct r300_context* r300); +unsigned r300_get_num_dirty_dwords(struct r300_context *r300); + /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 648d884654f..ec72d6c3b52 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -118,6 +118,18 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, return color_control; } +/* Check if the requested number of dwords is available in the CS and + * if not, flush. Return TRUE if the flush occured. */ +static boolean r300_reserve_cs_space(struct r300_context *r300, + unsigned dwords) +{ + while (!r300->winsys->check_cs(r300->winsys, dwords)) { + r300->context.flush(&r300->context, 0, NULL); + return TRUE; + } + return FALSE; +} + static boolean immd_is_good_idea(struct r300_context *r300, unsigned count) { @@ -132,7 +144,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; unsigned vertex_element_count = r300->vertex_element_count; - unsigned i, v, vbi, dw, elem_offset; + unsigned i, v, vbi, dw, elem_offset, dwords; /* Size of the vertex, in dwords. */ unsigned vertex_size = 0; @@ -171,9 +183,12 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, } } + dwords = 10 + count * vertex_size; + + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_emit_dirty_state(r300); - BEGIN_CS(10 + count * vertex_size); + BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); @@ -400,8 +415,9 @@ void r300_draw_range_elements(struct pipe_context* pipe, goto cleanup; } + /* 128 dwords for emit_aos and emit_draw_elements */ + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); r300_emit_dirty_state(r300); - r300_emit_aos(r300, 0); if (alt_num_verts || count <= 65535) { @@ -415,6 +431,12 @@ void r300_draw_range_elements(struct pipe_context* pipe, start += short_count; count -= short_count; + + /* 16 spare dwords are enough for emit_draw_elements. */ + if (count && r300_reserve_cs_space(r300, 16)) { + r300_emit_dirty_state(r300); + r300_emit_aos(r300, 0); + } } while (count); } @@ -461,6 +483,9 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, return; } + /* Make sure there are at least 128 spare dwords in the command buffer. + * (most of it being consumed by emit_aos) */ + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { @@ -474,6 +499,12 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, start += short_count; count -= short_count; + + /* Again, we emit both AOS and draw_arrays so there should be + * at least 128 spare dwords. */ + if (count && r300_reserve_cs_space(r300, 128)) { + r300_emit_dirty_state(r300); + } } while (count); } } @@ -690,6 +721,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render, CS_LOCALS(r300); + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2); r300_emit_dirty_state(r300); DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); @@ -708,12 +740,14 @@ static void r300_render_draw(struct vbuf_render* render, struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; int i; + unsigned dwords = 2 + (count+1)/2; CS_LOCALS(r300); + r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_emit_dirty_state(r300); - BEGIN_CS(2 + (count+1)/2); + BEGIN_CS(dwords); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | r300render->hwprim); -- cgit v1.2.3 From f05d4526e31bfcf238d826582317312bf0d8572d Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 24 Feb 2010 19:53:47 -0800 Subject: r300g: Move CALLOCs to correct place. --- src/gallium/drivers/r300/r300_context.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index f631b4ed27f..925873ad53d 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -128,7 +128,14 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(vertex_format, 26); /* Some non-CSO atoms need explicit space to store the state locally. */ + r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); + r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state); r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); + r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); + r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); + r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info); + r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); + r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); } struct pipe_context* r300_create_context(struct pipe_screen* screen, @@ -178,14 +185,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300_setup_atoms(r300); - r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); - r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state); - r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); - r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); - r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info); - r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); - r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); - /* Open up the OQ BO. */ r300->oqbo = screen->buffer_create(screen, 4096, PIPE_BUFFER_USAGE_VERTEX, 4096); -- cgit v1.2.3 From 686f69bd13fd2aebaa40edeb7e25e4a49b12a2bd Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 24 Feb 2010 20:02:59 -0800 Subject: r300g: Atomize vertex shader. --- src/gallium/drivers/r300/r300_blit.c | 2 +- src/gallium/drivers/r300/r300_context.c | 1 + src/gallium/drivers/r300/r300_context.h | 3 +- src/gallium/drivers/r300/r300_emit.c | 62 ++++++++++++--------------- src/gallium/drivers/r300/r300_emit.h | 3 +- src/gallium/drivers/r300/r300_state.c | 18 ++++---- src/gallium/drivers/r300/r300_state_derived.c | 25 ++++++----- src/gallium/drivers/r300/r300_vs.c | 4 +- 8 files changed, 58 insertions(+), 60 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index eb9b0beeb5a..187b4bf384e 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -33,7 +33,7 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); - util_blitter_save_vertex_shader(r300->blitter, r300->vs); + util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); } /* Clear currently bound buffers. */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 925873ad53d..47883589a76 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -126,6 +126,7 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(viewport, 9); R300_INIT_ATOM(rs_block, 21); R300_INIT_ATOM(vertex_format, 26); + R300_INIT_ATOM(vs, 1031); /* Some non-CSO atoms need explicit space to store the state locally. */ r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 443af4ec2e3..3d4f6524e5b 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -155,7 +155,6 @@ struct r300_ztop_state { #define R300_ANY_NEW_SAMPLERS 0x0001fe00 #define R300_NEW_TEXTURE 0x00040000 #define R300_ANY_NEW_TEXTURES 0x03fc0000 -#define R300_NEW_VERTEX_SHADER 0x08000000 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 #define R300_NEW_KITCHEN_SINK 0x7fffffff @@ -315,7 +314,7 @@ struct r300_context { struct r300_texture* textures[8]; int texture_count; /* Vertex shader. */ - struct r300_vertex_shader* vs; + struct r300_atom vs_state; /* Viewport state. */ struct r300_atom viewport_state; /* ZTOP state. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 2d8801c08ad..3037a38989a 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -843,21 +843,31 @@ void r300_emit_vertex_format_state(struct r300_context* r300, void* state) END_CS; } +static void r300_flush_pvs(struct r300_context* r300) +{ + CS_LOCALS(r300); + + BEGIN_CS(2); + OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); + END_CS; +} -void r300_emit_vertex_program_code(struct r300_context* r300, - struct r300_vertex_program_code* code) +void r300_emit_vs_state(struct r300_context* r300, void* state) { - int i; + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)state; + struct r300_vertex_program_code* code = &vs->code; struct r300_screen* r300screen = r300_screen(r300->context.screen); unsigned instruction_count = code->length / 4; + unsigned i; + + unsigned vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72; + unsigned input_count = MAX2(util_bitcount(code->InputsRead), 1); + unsigned output_count = MAX2(util_bitcount(code->OutputsWritten), 1); + unsigned temp_count = MAX2(code->num_temporaries, 1); - int vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72; - int input_count = MAX2(util_bitcount(code->InputsRead), 1); - int output_count = MAX2(util_bitcount(code->OutputsWritten), 1); - int temp_count = MAX2(code->num_temporaries, 1); - int pvs_num_slots = MIN3(vtx_mem_size / input_count, - vtx_mem_size / output_count, 10); - int pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6); + unsigned pvs_num_slots = MIN3(vtx_mem_size / input_count, + vtx_mem_size / output_count, 10); + unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6); CS_LOCALS(r300); @@ -867,6 +877,8 @@ void r300_emit_vertex_program_code(struct r300_context* r300, return; } + r300_flush_pvs(r300); + BEGIN_CS(9 + code->length); /* R300_VAP_PVS_CODE_CNTL_0 * R300_VAP_PVS_CONST_CNTL @@ -881,8 +893,9 @@ void r300_emit_vertex_program_code(struct r300_context* r300, OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length); - for (i = 0; i < code->length; i++) + for (i = 0; i < code->length; i++) { OUT_CS(code->body.d[i]); + } OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(pvs_num_slots) | R300_PVS_NUM_CNTLRS(pvs_num_controllers) | @@ -892,12 +905,6 @@ void r300_emit_vertex_program_code(struct r300_context* r300, END_CS; } -void r300_emit_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs) -{ - r300_emit_vertex_program_code(r300, &vs->code); -} - void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants) { @@ -994,15 +1001,6 @@ void r300_flush_textures(struct r300_context* r300) END_CS; } -static void r300_flush_pvs(struct r300_context* r300) -{ - CS_LOCALS(r300); - - BEGIN_CS(2); - OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); - END_CS; -} - void r300_emit_buffer_validate(struct r300_context *r300) { struct pipe_framebuffer_state* fb = @@ -1088,7 +1086,7 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300) } /* XXX This is the compensation for the non-atomized states. */ - dwords += 2048; + dwords += 1024; return dwords; } @@ -1160,17 +1158,13 @@ void r300_emit_dirty_state(struct r300_context* r300) r300_flush_textures(r300); } - if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) { + if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS || r300->vs_state.dirty) { r300_flush_pvs(r300); } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER) { - r300_emit_vertex_shader(r300, r300->vs); - r300->dirty_state &= ~R300_NEW_VERTEX_SHADER; - } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { - r300_emit_vs_constant_buffer(r300, &r300->vs->code.constants); + struct r300_vertex_shader* vs = r300->vs_state.state; + r300_emit_vs_constant_buffer(r300, &vs->code.constants); r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index ff709a05957..f27cf5f32d2 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -79,8 +79,7 @@ void r300_emit_vertex_program_code(struct r300_context* r300, void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); -void r300_emit_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs); +void r300_emit_vs_state(struct r300_context* r300, void* state); void r300_emit_viewport_state(struct r300_context* r300, void* state); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c1930..0f14ccc53e5 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -658,9 +658,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300->fs = fs; r300_pick_fragment_shader(r300); - if (r300->vs && r300_vertex_shader_setup_wpos(r300)) { - r300->vertex_format_state.dirty = TRUE; - } + r300->vertex_format_state.dirty = TRUE; r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -1107,21 +1105,23 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; if (vs == NULL) { - r300->vs = NULL; + r300->vs_state.state = NULL; return; } else if (!vs->translated) { r300_translate_vertex_shader(r300, vs); } - r300->vs = vs; + r300->vs_state.state = vs; + r300->vs_state.size = vs->code.length + 11; + r300->vs_state.dirty = TRUE; + + r300->vertex_format_state.dirty = TRUE; + if (r300->fs) { r300_vertex_shader_setup_wpos(r300); } - r300->vertex_format_state.dirty = TRUE; - - r300->dirty_state |= - R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; + r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2cbce9210a7..b33d44990a9 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -42,7 +42,8 @@ static void r300_draw_emit_attrib(struct r300_context* r300, enum interp_mode interp, int index) { - struct tgsi_shader_info* info = &r300->vs->info; + struct r300_vertex_shader* vs = r300->vs_state.state; + struct tgsi_shader_info* info = &vs->info; int output; output = draw_find_shader_output(r300->draw, @@ -55,7 +56,8 @@ static void r300_draw_emit_attrib(struct r300_context* r300, static void r300_draw_emit_all_attribs(struct r300_context* r300) { - struct r300_shader_semantics* vs_outputs = &r300->vs->outputs; + struct r300_vertex_shader* vs = r300->vs_state.state; + struct r300_shader_semantics* vs_outputs = &vs->outputs; int i, gen_count; /* Position. */ @@ -106,6 +108,7 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) /* Update the PSC tables. */ static void r300_vertex_psc(struct r300_context* r300) { + struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_vertex_info *vformat = (struct r300_vertex_info*)r300->vertex_format_state.state; uint16_t type, swizzle; @@ -117,7 +120,7 @@ static void r300_vertex_psc(struct r300_context* r300) /* If TCL is bypassed, map vertex streams to equivalent VS output * locations. */ if (r300->tcl_bypass) { - stream_tab = r300->vs->stream_loc_notcl; + stream_tab = vs->stream_loc_notcl; } else { stream_tab = identity; } @@ -127,7 +130,7 @@ static void r300_vertex_psc(struct r300_context* r300) * and not on attrib information. */ DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" " in psc\n", - r300->vs->info.num_inputs, + vs->info.num_inputs, r300->vertex_element_count); for (i = 0; i < r300->vertex_element_count; i++) { @@ -159,13 +162,14 @@ static void r300_vertex_psc(struct r300_context* r300) /* Update the PSC tables for SW TCL, using Draw. */ static void r300_swtcl_vertex_psc(struct r300_context* r300) { + struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_vertex_info *vformat = (struct r300_vertex_info*)r300->vertex_format_state.state; struct vertex_info* vinfo = &vformat->vinfo; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; - int* vs_output_tab = r300->vs->stream_loc_notcl; + int* vs_output_tab = vs->stream_loc_notcl; /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ @@ -424,6 +428,7 @@ static void r300_update_rs_block(struct r300_context* r300, /* Update the shader-dependant states. */ static void r300_update_derived_shader_state(struct r300_context* r300) { + struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_vertex_info *vformat = (struct r300_vertex_info*)r300->vertex_format_state.state; @@ -431,9 +436,9 @@ static void r300_update_derived_shader_state(struct r300_context* r300) /* Mmm, delicious hax */ memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info)); - memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4); + memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4); - r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs); + r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); if (r300screen->caps->has_tcl) { r300_vertex_psc(r300); @@ -519,9 +524,9 @@ static void r300_update_ztop(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { /* XXX */ - if (r300->dirty_state & - (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER) || - r300->vertex_format_state.dirty || r300->rs_state.dirty) { + if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER || + r300->vs_state.dirty || r300->vertex_format_state.dirty || + r300->rs_state.dirty) { r300_update_derived_shader_state(r300); } diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index a6786c321c6..60a04bbfeda 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -368,8 +368,8 @@ void r300_translate_vertex_shader(struct r300_context* r300, boolean r300_vertex_shader_setup_wpos(struct r300_context* r300) { - struct r300_vertex_shader* vs = r300->vs; - int tex_output = r300->vs->wpos_tex_output; + struct r300_vertex_shader* vs = r300->vs_state.state; + int tex_output = vs->wpos_tex_output; uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output; uint32_t* hwfmt = vs->hwfmt; -- cgit v1.2.3 From dba7ad895333b9b0988239266a217edeebe6a3b3 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 26 Feb 2010 22:34:09 +0100 Subject: r300g: remove pointless "while" --- src/gallium/drivers/r300/r300_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index ec72d6c3b52..d604bfb7d75 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -123,7 +123,7 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, static boolean r300_reserve_cs_space(struct r300_context *r300, unsigned dwords) { - while (!r300->winsys->check_cs(r300->winsys, dwords)) { + if (!r300->winsys->check_cs(r300->winsys, dwords)) { r300->context.flush(&r300->context, 0, NULL); return TRUE; } -- cgit v1.2.3 From 93da1522098145f0e7ff9d4188050728b075b4a1 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 00:37:01 +0100 Subject: r300g: always emit the correct max vertex index to avoid DRM errors Fixing bizarre reports that a vertex buffer is not large enough. --- src/gallium/drivers/r300/r300_context.h | 1 + src/gallium/drivers/r300/r300_render.c | 7 +++++-- src/gallium/drivers/r300/r300_state.c | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 3d4f6524e5b..8704f185293 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -326,6 +326,7 @@ struct r300_context { /* Vertex buffers for Gallium. */ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; + int vertex_buffer_max_index; /* Vertex elements for Gallium. */ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index d604bfb7d75..e4f7615368d 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -452,8 +452,11 @@ void r300_draw_elements(struct pipe_context* pipe, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { - pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0, ~0, - mode, start, count); + struct r300_context *r300 = r300_context(pipe); + + pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0, + r300->vertex_buffer_max_index, + mode, start, count); } void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 0f14ccc53e5..ee4409c8899 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1026,10 +1026,17 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); + unsigned i, max_index = ~0; memcpy(r300->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); + + for (i = 0; i < count; i++) { + max_index = MIN2(buffers[i].max_index, max_index); + } + r300->vertex_buffer_count = count; + r300->vertex_buffer_max_index = max_index; if (r300->draw) { draw_flush(r300->draw); -- cgit v1.2.3 From f129a7dd686cb3d824253bffab8c8b32b8ef8b69 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 20:00:38 +0100 Subject: r300g: mark rasterizer_state as dirty only when it's not NULL --- src/gallium/drivers/r300/r300_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index ee4409c8899..0fbb9e77162 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -824,13 +824,13 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) if (rs) { r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport; r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; + r300->rs_state.dirty = TRUE; } else { r300->tcl_bypass = FALSE; r300->polygon_offset_enabled = FALSE; } r300->rs_state.state = rs; - r300->rs_state.dirty = TRUE; /* XXX Why is this still needed, dammit!? */ r300->scissor_state.dirty = TRUE; r300->viewport_state.dirty = TRUE; -- cgit v1.2.3 From a3d4d0dec2882e352dc9ddcc1572e36620a4d13e Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 20:03:34 +0100 Subject: r300g: put the emission of R300_US_OUT_FMT_UNUSED back It wasn't such a good idea to remove it. :/ --- src/gallium/drivers/r300/r300_emit.c | 6 +++++- src/gallium/drivers/r300/r300_state.c | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3037a38989a..1ea622f8507 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -387,7 +387,8 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) int i; CS_LOCALS(r300); - BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 6); + BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + + (fb->zsbuf ? 10 : 0) + 6); /* Flush and free renderbuffer caches. */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -426,6 +427,9 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); } + for (; i < 4; i++) { + OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), R300_US_OUT_FMT_UNUSED); + } /* Set up a zbuffer. */ if (fb->zsbuf) { diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 0fbb9e77162..2c4beee5ad6 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -598,7 +598,8 @@ static void memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); - r300->fb_state.size = (10 * state->nr_cbufs) + (state->zsbuf ? 10 : 0) + 6; + r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) + + (state->zsbuf ? 10 : 0) + 6; r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); -- cgit v1.2.3 From 74f94e8fdfe035fa68acdc19e6b0afc2957a4264 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 20:05:00 +0100 Subject: r300g: move the emission of GA_POINT_MINMAX into emit_fb_state The only practical limits are the ones derived from the currently-set framebuffer state. --- src/gallium/drivers/r300/r300_context.h | 1 - src/gallium/drivers/r300/r300_emit.c | 10 +++++----- src/gallium/drivers/r300/r300_state.c | 19 ++----------------- 3 files changed, 7 insertions(+), 23 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8704f185293..ac14e3f0df4 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -86,7 +86,6 @@ struct r300_rs_state { uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ uint32_t antialiasing_config; /* R300_GB_AA_CONFIG: 0x4020 */ uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ - uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */ uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ float depth_scale; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 1ea622f8507..7fc66dd2650 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -388,7 +388,7 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) CS_LOCALS(r300); BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + - (fb->zsbuf ? 10 : 0) + 6); + (fb->zsbuf ? 10 : 0) + 8); /* Flush and free renderbuffer caches. */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -447,6 +447,8 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) 0, RADEON_GEM_DOMAIN_VRAM, 0); } + OUT_CS_REG(R300_GA_POINT_MINMAX, + (MAX2(fb->width, fb->height) * 6) << R300_GA_POINT_MINMAX_MAX_SHIFT); END_CS; } @@ -582,15 +584,13 @@ void r300_emit_rs_state(struct r300_context* r300, void* state) float scale, offset; CS_LOCALS(r300); - BEGIN_CS(18 + (rs->polygon_offset_enable ? 5 : 0)); + BEGIN_CS(17 + (rs->polygon_offset_enable ? 5 : 0)); OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config); OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size); - OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2); - OUT_CS(rs->point_minmax); - OUT_CS(rs->line_control); + OUT_CS_REG(R300_GA_LINE_CNTL, rs->line_control); if (rs->polygon_offset_enable) { scale = rs->depth_scale * 12; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 2c4beee5ad6..f1f0de1a463 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -599,7 +599,7 @@ static void memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) + - (state->zsbuf ? 10 : 0) + 6; + (state->zsbuf ? 10 : 0) + 8; r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); @@ -718,22 +718,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->point_size = pack_float_16_6x(state->point_size) | (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); - /* Point minimum and maximum sizes. This register has to be emitted, - * and it'd be a step backwards to put it in invariant state. */ - if (r300screen->caps->is_r500) { - rs->point_minmax = - ((int)(0.0 * 6.0) << R300_GA_POINT_MINMAX_MIN_SHIFT) | - ((int)(4096.0 * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT); - } else if (r300screen->caps->is_r400) { - rs->point_minmax = - ((int)(0.0 * 6.0) << R300_GA_POINT_MINMAX_MIN_SHIFT) | - ((int)(4021.0 * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT); - } else { - rs->point_minmax = - ((int)(0.0 * 6.0) << R300_GA_POINT_MINMAX_MIN_SHIFT) | - ((int)(2560.0 * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT); - } - rs->line_control = pack_float_16_6x(state->line_width) | R300_GA_LINE_CNTL_END_TYPE_COMP; @@ -832,6 +816,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) } r300->rs_state.state = rs; + r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0); /* XXX Why is this still needed, dammit!? */ r300->scissor_state.dirty = TRUE; r300->viewport_state.dirty = TRUE; -- cgit v1.2.3 From 841122d0e8025290ff2691e13ade1099d2c3351c Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 21:54:16 +0100 Subject: r300g: add size parameter to the atom emit functions Maintaining a closer relationship between the atom size and what's passed in BEGIN_CS. --- src/gallium/drivers/r300/r300_context.h | 2 +- src/gallium/drivers/r300/r300_emit.c | 34 +++++++++++++++---------- src/gallium/drivers/r300/r300_emit.h | 33 +++++++++++++++--------- src/gallium/drivers/r300/r300_state_invariant.c | 3 ++- src/gallium/drivers/r300/r300_state_invariant.h | 3 ++- 5 files changed, 47 insertions(+), 28 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index ac14e3f0df4..e3ad5869213 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -45,7 +45,7 @@ struct r300_atom { /* Opaque state. */ void* state; /* Emit the state to the context. */ - void (*emit)(struct r300_context*, void*); + void (*emit)(struct r300_context*, unsigned, void*); /* Upper bound on number of dwords to emit. */ unsigned size; /* Whether this atom should be emitted. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 7fc66dd2650..a17ebb3ea87 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -34,7 +34,8 @@ #include "r300_screen.h" #include "r300_vs.h" -void r300_emit_blend_state(struct r300_context* r300, void* state) +void r300_emit_blend_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_blend_state* blend = (struct r300_blend_state*)state; struct pipe_framebuffer_state* fb = @@ -58,7 +59,8 @@ void r300_emit_blend_state(struct r300_context* r300, void* state) END_CS; } -void r300_emit_blend_color_state(struct r300_context* r300, void* state) +void r300_emit_blend_color_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_blend_color_state* bc = (struct r300_blend_color_state*)state; struct r300_screen* r300screen = r300_screen(r300->context.screen); @@ -77,7 +79,8 @@ void r300_emit_blend_color_state(struct r300_context* r300, void* state) } } -void r300_emit_clip_state(struct r300_context* r300, void* state) +void r300_emit_clip_state(struct r300_context* r300, + unsigned size, void* state) { struct pipe_clip_state* clip = (struct pipe_clip_state*)state; int i; @@ -107,7 +110,7 @@ void r300_emit_clip_state(struct r300_context* r300, void* state) } -void r300_emit_dsa_state(struct r300_context* r300, void* state) +void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state) { struct r300_dsa_state* dsa = (struct r300_dsa_state*)state; struct r300_screen* r300screen = r300_screen(r300->context.screen); @@ -378,7 +381,7 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300, END_CS; } -void r300_emit_fb_state(struct r300_context* r300, void* state) +void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_screen* r300screen = r300_screen(r300->context.screen); @@ -578,7 +581,7 @@ void r300_emit_query_end(struct r300_context* r300) r300_emit_query_finish(r300, query); } -void r300_emit_rs_state(struct r300_context* r300, void* state) +void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state) { struct r300_rs_state* rs = (struct r300_rs_state*)state; float scale, offset; @@ -621,7 +624,8 @@ void r300_emit_rs_state(struct r300_context* r300, void* state) END_CS; } -void r300_emit_rs_block_state(struct r300_context* r300, void* state) +void r300_emit_rs_block_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_rs_block* rs = (struct r300_rs_block*)state; unsigned i; @@ -663,7 +667,8 @@ void r300_emit_rs_block_state(struct r300_context* r300, void* state) END_CS; } -void r300_emit_scissor_state(struct r300_context* r300, void* state) +void r300_emit_scissor_state(struct r300_context* r300, + unsigned size, void* state) { unsigned minx, miny, maxx, maxy; uint32_t top_left, bottom_right; @@ -810,7 +815,8 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) END_CS; } -void r300_emit_vertex_format_state(struct r300_context* r300, void* state) +void r300_emit_vertex_format_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state; unsigned i; @@ -856,7 +862,7 @@ static void r300_flush_pvs(struct r300_context* r300) END_CS; } -void r300_emit_vs_state(struct r300_context* r300, void* state) +void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) { struct r300_vertex_shader* vs = (struct r300_vertex_shader*)state; struct r300_vertex_program_code* code = &vs->code; @@ -942,7 +948,8 @@ void r300_emit_vs_constant_buffer(struct r300_context* r300, END_CS; } -void r300_emit_viewport_state(struct r300_context* r300, void* state) +void r300_emit_viewport_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_viewport_state* viewport = (struct r300_viewport_state*)state; CS_LOCALS(r300); @@ -986,7 +993,8 @@ void r300_emit_texture_count(struct r300_context* r300) } -void r300_emit_ztop_state(struct r300_context* r300, void* state) +void r300_emit_ztop_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_ztop_state* ztop = (struct r300_ztop_state*)state; CS_LOCALS(r300); @@ -1110,7 +1118,7 @@ void r300_emit_dirty_state(struct r300_context* r300) foreach(atom, &r300->atom_list) { if (atom->dirty || atom->always_dirty) { - atom->emit(r300, atom->state); + atom->emit(r300, atom->size, atom->state); atom->dirty = FALSE; } } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index f27cf5f32d2..a9b75d5b37b 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -31,13 +31,17 @@ struct r300_vertex_program_code; void r300_emit_aos(struct r300_context* r300, unsigned offset); -void r300_emit_blend_state(struct r300_context* r300, void* state); +void r300_emit_blend_state(struct r300_context* r300, + unsigned size, void* state); -void r300_emit_blend_color_state(struct r300_context* r300, void* state); +void r300_emit_blend_color_state(struct r300_context* r300, + unsigned size, void* state); -void r300_emit_clip_state(struct r300_context* r300, void* state); +void r300_emit_clip_state(struct r300_context* r300, + unsigned size, void* state); -void r300_emit_dsa_state(struct r300_context* r300, void* state); +void r300_emit_dsa_state(struct r300_context* r300, + unsigned size, void* state); void r300_emit_fragment_program_code(struct r300_context* r300, struct rX00_fragment_program_code* generic_code); @@ -51,18 +55,20 @@ void r500_emit_fragment_program_code(struct r300_context* r300, void r500_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); -void r300_emit_fb_state(struct r300_context* r300, void* state); +void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state); void r300_emit_query_begin(struct r300_context* r300, struct r300_query* query); void r300_emit_query_end(struct r300_context* r300); -void r300_emit_rs_state(struct r300_context* r300, void* state); +void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_rs_block_state(struct r300_context* r300, void* state); +void r300_emit_rs_block_state(struct r300_context* r300, + unsigned size, void* state); -void r300_emit_scissor_state(struct r300_context* r300, void* state); +void r300_emit_scissor_state(struct r300_context* r300, + unsigned size, void* state); void r300_emit_texture(struct r300_context* r300, struct r300_sampler_state* sampler, @@ -71,7 +77,8 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_buffer(struct r300_context* r300); -void r300_emit_vertex_format_state(struct r300_context* r300, void* state); +void r300_emit_vertex_format_state(struct r300_context* r300, + unsigned size, void* state); void r300_emit_vertex_program_code(struct r300_context* r300, struct r300_vertex_program_code* code); @@ -79,13 +86,15 @@ void r300_emit_vertex_program_code(struct r300_context* r300, void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); -void r300_emit_vs_state(struct r300_context* r300, void* state); +void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_viewport_state(struct r300_context* r300, void* state); +void r300_emit_viewport_state(struct r300_context* r300, + unsigned size, void* state); void r300_emit_texture_count(struct r300_context* r300); -void r300_emit_ztop_state(struct r300_context* r300, void* state); +void r300_emit_ztop_state(struct r300_context* r300, + unsigned size, void* state); void r300_flush_textures(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index 97927acf1b4..4a2c68269b1 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -38,7 +38,8 @@ struct pipe_viewport_state r300_viewport_identity = { * * Note that eventually this should be empty, but it's useful for development * and general unduplication of code. */ -void r300_emit_invariant_state(struct r300_context* r300, void* state) +void r300_emit_invariant_state(struct r300_context* r300, + unsigned size, void* state) { struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h index 5d1a9636545..83d031c7fe9 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.h +++ b/src/gallium/drivers/r300/r300_state_invariant.h @@ -25,6 +25,7 @@ struct r300_context; -void r300_emit_invariant_state(struct r300_context* r300, void* state); +void r300_emit_invariant_state(struct r300_context* r300, + unsigned size, void* state); #endif /* R300_STATE_INVARIANT_H */ -- cgit v1.2.3 From fe6d3b9222ce184daab61ebb390a6af0b9889abf Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 23:26:19 +0100 Subject: r300g: atomize PVS flush The first non-state atom. It's better and cleaner to have it. --- src/gallium/drivers/r300/r300_context.c | 39 +++++++++++++++++---------------- src/gallium/drivers/r300/r300_context.h | 2 ++ src/gallium/drivers/r300/r300_emit.c | 8 +------ src/gallium/drivers/r300/r300_emit.h | 2 ++ src/gallium/drivers/r300/r300_state.c | 5 ++++- 5 files changed, 29 insertions(+), 27 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 47883589a76..5fc3a308043 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -96,12 +96,12 @@ static void r300_flush_cb(void *data) } #define R300_INIT_ATOM(atomname, atomsize) \ - r300->atomname##_state.name = #atomname; \ - r300->atomname##_state.state = NULL; \ - r300->atomname##_state.size = atomsize; \ - r300->atomname##_state.emit = r300_emit_##atomname##_state; \ - r300->atomname##_state.dirty = FALSE; \ - insert_at_tail(&r300->atom_list, &r300->atomname##_state); + r300->atomname.name = #atomname; \ + r300->atomname.state = NULL; \ + r300->atomname.size = atomsize; \ + r300->atomname.emit = r300_emit_##atomname; \ + r300->atomname.dirty = FALSE; \ + insert_at_tail(&r300->atom_list, &r300->atomname); static void r300_setup_atoms(struct r300_context* r300) { @@ -114,19 +114,20 @@ static void r300_setup_atoms(struct r300_context* r300) * an upper bound on each atom, to keep the emission machinery from * underallocating space. */ make_empty_list(&r300->atom_list); - R300_INIT_ATOM(invariant, 71); - R300_INIT_ATOM(ztop, 2); - R300_INIT_ATOM(blend, 8); - R300_INIT_ATOM(blend_color, 3); - R300_INIT_ATOM(clip, 29); - R300_INIT_ATOM(dsa, 8); - R300_INIT_ATOM(fb, 56); - R300_INIT_ATOM(rs, 25); - R300_INIT_ATOM(scissor, 3); - R300_INIT_ATOM(viewport, 9); - R300_INIT_ATOM(rs_block, 21); - R300_INIT_ATOM(vertex_format, 26); - R300_INIT_ATOM(vs, 1031); + R300_INIT_ATOM(invariant_state, 71); + R300_INIT_ATOM(ztop_state, 2); + R300_INIT_ATOM(blend_state, 8); + R300_INIT_ATOM(blend_color_state, 3); + R300_INIT_ATOM(clip_state, 29); + R300_INIT_ATOM(dsa_state, 8); + R300_INIT_ATOM(fb_state, 56); + R300_INIT_ATOM(rs_state, 25); + R300_INIT_ATOM(scissor_state, 3); + R300_INIT_ATOM(viewport_state, 9); + R300_INIT_ATOM(rs_block_state, 21); + R300_INIT_ATOM(vertex_format_state, 26); + R300_INIT_ATOM(pvs_flush, 2); + R300_INIT_ATOM(vs_state, 1031); /* Some non-CSO atoms need explicit space to store the state locally. */ r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index e3ad5869213..32b64b6b28a 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -318,6 +318,8 @@ struct r300_context { struct r300_atom viewport_state; /* ZTOP state. */ struct r300_atom ztop_state; + /* PVS flush. */ + struct r300_atom pvs_flush; /* Invariant state. This must be emitted to get the engine started. */ struct r300_atom invariant_state; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index a17ebb3ea87..6a0ede359b0 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -853,7 +853,7 @@ void r300_emit_vertex_format_state(struct r300_context* r300, END_CS; } -static void r300_flush_pvs(struct r300_context* r300) +void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state) { CS_LOCALS(r300); @@ -887,8 +887,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) return; } - r300_flush_pvs(r300); - BEGIN_CS(9 + code->length); /* R300_VAP_PVS_CODE_CNTL_0 * R300_VAP_PVS_CONST_CNTL @@ -1170,10 +1168,6 @@ void r300_emit_dirty_state(struct r300_context* r300) r300_flush_textures(r300); } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS || r300->vs_state.dirty) { - r300_flush_pvs(r300); - } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { struct r300_vertex_shader* vs = r300->vs_state.state; r300_emit_vs_constant_buffer(r300, &vs->code.constants); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index a9b75d5b37b..5809bf43405 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -96,6 +96,8 @@ void r300_emit_texture_count(struct r300_context* r300); void r300_emit_ztop_state(struct r300_context* r300, unsigned size, void* state); +void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state); + void r300_flush_textures(struct r300_context* r300); unsigned r300_get_num_dirty_dwords(struct r300_context *r300); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f1f0de1a463..79cd715af17 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1109,6 +1109,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->vs_state.dirty = TRUE; r300->vertex_format_state.dirty = TRUE; + r300->pvs_flush.dirty = TRUE; if (r300->fs) { r300_vertex_shader_setup_wpos(r300); @@ -1186,8 +1187,10 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, r300->shader_constants[shader].count = buf->size / (4 * sizeof(float)); pipe_buffer_unmap(pipe->screen, buf); - if (shader == PIPE_SHADER_VERTEX) + if (shader == PIPE_SHADER_VERTEX) { r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; + r300->pvs_flush.dirty = TRUE; + } else if (shader == PIPE_SHADER_FRAGMENT) r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; } -- cgit v1.2.3 From 279715e76e5385afaad2834191e8578cf3a5d233 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 23:37:01 +0100 Subject: r300g: atomize invalidation of texture caches --- src/gallium/drivers/r300/r300_context.c | 1 + src/gallium/drivers/r300/r300_context.h | 2 ++ src/gallium/drivers/r300/r300_emit.c | 8 +------- src/gallium/drivers/r300/r300_emit.h | 2 +- src/gallium/drivers/r300/r300_state.c | 6 ++++++ 5 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 5fc3a308043..5f50b60eab7 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -128,6 +128,7 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(vertex_format_state, 26); R300_INIT_ATOM(pvs_flush, 2); R300_INIT_ATOM(vs_state, 1031); + R300_INIT_ATOM(texture_cache_inval, 2); /* Some non-CSO atoms need explicit space to store the state locally. */ r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 32b64b6b28a..47f2aa5154a 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -320,6 +320,8 @@ struct r300_context { struct r300_atom ztop_state; /* PVS flush. */ struct r300_atom pvs_flush; + /* Texture cache invalidate. */ + struct r300_atom texture_cache_inval; /* Invariant state. This must be emitted to get the engine started. */ struct r300_atom invariant_state; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 6a0ede359b0..ad19725e60b 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1002,7 +1002,7 @@ void r300_emit_ztop_state(struct r300_context* r300, END_CS; } -void r300_flush_textures(struct r300_context* r300) +void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, void* state) { CS_LOCALS(r300); @@ -1107,7 +1107,6 @@ void r300_emit_dirty_state(struct r300_context* r300) struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_atom* atom; unsigned i; - int dirty_tex = 0; if (r300->dirty_state & R300_NEW_QUERY) { r300_emit_query_start(r300); @@ -1155,7 +1154,6 @@ void r300_emit_dirty_state(struct r300_context* r300) r300->sampler_states[i], r300->textures[i], i); - dirty_tex |= r300->dirty_state & (R300_NEW_TEXTURE << i); } r300->dirty_state &= ~((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i)); @@ -1164,10 +1162,6 @@ void r300_emit_dirty_state(struct r300_context* r300) r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES); } - if (dirty_tex) { - r300_flush_textures(r300); - } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { struct r300_vertex_shader* vs = r300->vs_state.state; r300_emit_vs_constant_buffer(r300, &vs->code.constants); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 5809bf43405..c73b016b76c 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -98,7 +98,7 @@ void r300_emit_ztop_state(struct r300_context* r300, void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state); -void r300_flush_textures(struct r300_context* r300); +void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, void* state); unsigned r300_get_num_dirty_dwords(struct r300_context *r300); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 79cd715af17..15e0a0ad358 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -922,6 +922,7 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; + boolean dirty_tex = FALSE; int i; /* XXX magic num */ @@ -934,6 +935,7 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, pipe_texture_reference((struct pipe_texture**)&r300->textures[i], texture[i]); r300->dirty_state |= (R300_NEW_TEXTURE << i); + dirty_tex = TRUE; /* R300-specific - set the texrect factor in a fragment shader */ if (!is_r500 && r300->textures[i]->is_npot) { @@ -953,6 +955,10 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, } r300->texture_count = count; + + if (dirty_tex) { + r300->texture_cache_inval.dirty = TRUE; + } } static void r300_set_scissor_state(struct pipe_context* pipe, -- cgit v1.2.3 From 4ed97f0a73db37f6105b6282d92646c3f66c2645 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 23:12:46 +0100 Subject: r300g: use the atom size directly during emission --- src/gallium/drivers/r300/r300_context.c | 22 +++++++++-------- src/gallium/drivers/r300/r300_emit.c | 35 +++++++++++++-------------- src/gallium/drivers/r300/r300_state.c | 2 +- src/gallium/drivers/r300/r300_state_derived.c | 2 +- 4 files changed, 31 insertions(+), 30 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 5f50b60eab7..3a84fc564d9 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -105,29 +105,31 @@ static void r300_flush_cb(void *data) static void r300_setup_atoms(struct r300_context* r300) { + boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; + boolean has_tcl = r300_screen(r300->context.screen)->caps->has_tcl; + /* Create the actual atom list. * * Each atom is examined and emitted in the order it appears here, which * can affect performance and conformance if not handled with care. * - * Some atoms never change size, others change every emit. This is just - * an upper bound on each atom, to keep the emission machinery from - * underallocating space. */ + * Some atoms never change size, others change every emit - those have + * the size of 0 here. */ make_empty_list(&r300->atom_list); R300_INIT_ATOM(invariant_state, 71); R300_INIT_ATOM(ztop_state, 2); R300_INIT_ATOM(blend_state, 8); - R300_INIT_ATOM(blend_color_state, 3); - R300_INIT_ATOM(clip_state, 29); - R300_INIT_ATOM(dsa_state, 8); - R300_INIT_ATOM(fb_state, 56); - R300_INIT_ATOM(rs_state, 25); + R300_INIT_ATOM(blend_color_state, is_r500 ? 3 : 2); + R300_INIT_ATOM(clip_state, has_tcl ? 5 + (6 * 4) : 2); + R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6); + R300_INIT_ATOM(fb_state, 0); + R300_INIT_ATOM(rs_state, 0); R300_INIT_ATOM(scissor_state, 3); R300_INIT_ATOM(viewport_state, 9); - R300_INIT_ATOM(rs_block_state, 21); + R300_INIT_ATOM(rs_block_state, 0); R300_INIT_ATOM(vertex_format_state, 26); R300_INIT_ATOM(pvs_flush, 2); - R300_INIT_ATOM(vs_state, 1031); + R300_INIT_ATOM(vs_state, 0); R300_INIT_ATOM(texture_cache_inval, 2); /* Some non-CSO atoms need explicit space to store the state locally. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index ad19725e60b..013611018b0 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -42,7 +42,7 @@ void r300_emit_blend_state(struct r300_context* r300, (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); - BEGIN_CS(8); + BEGIN_CS(size); OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop); OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3); if (fb->nr_cbufs) { @@ -67,13 +67,13 @@ void r300_emit_blend_color_state(struct r300_context* r300, CS_LOCALS(r300); if (r300screen->caps->is_r500) { - BEGIN_CS(3); + BEGIN_CS(size); OUT_CS_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2); OUT_CS(bc->blend_color_red_alpha); OUT_CS(bc->blend_color_green_blue); END_CS; } else { - BEGIN_CS(2); + BEGIN_CS(size); OUT_CS_REG(R300_RB3D_BLEND_COLOR, bc->blend_color); END_CS; } @@ -88,7 +88,7 @@ void r300_emit_clip_state(struct r300_context* r300, CS_LOCALS(r300); if (r300screen->caps->has_tcl) { - BEGIN_CS(5 + (6 * 4)); + BEGIN_CS(size); OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, (r300screen->caps->is_r500 ? R500_PVS_UCP_START : R300_PVS_UCP_START)); @@ -103,7 +103,7 @@ void r300_emit_clip_state(struct r300_context* r300, R300_PS_UCP_MODE_CLIP_AS_TRIFAN); END_CS; } else { - BEGIN_CS(2); + BEGIN_CS(size); OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE); END_CS; } @@ -119,7 +119,7 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state) struct pipe_stencil_ref stencil_ref = r300->stencil_ref; CS_LOCALS(r300); - BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6); + BEGIN_CS(size); OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); OUT_CS_REG_SEQ(R300_ZB_CNTL, 3); @@ -390,8 +390,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) int i; CS_LOCALS(r300); - BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + - (fb->zsbuf ? 10 : 0) + 8); + BEGIN_CS(size); /* Flush and free renderbuffer caches. */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -587,7 +586,7 @@ void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state) float scale, offset; CS_LOCALS(r300); - BEGIN_CS(17 + (rs->polygon_offset_enable ? 5 : 0)); + BEGIN_CS(size); OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config); @@ -636,7 +635,7 @@ void r300_emit_rs_block_state(struct r300_context* r300, DBG(r300, DBG_DRAW, "r300: RS emit:\n"); - BEGIN_CS(5 + count*2); + BEGIN_CS(size); if (r300screen->caps->is_r500) { OUT_CS_REG_SEQ(R500_RS_IP_0, count); } else { @@ -722,7 +721,7 @@ void r300_emit_scissor_state(struct r300_context* r300, (((maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); } - BEGIN_CS(3); + BEGIN_CS(size); OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); OUT_CS(top_left); OUT_CS(bottom_right); @@ -824,7 +823,7 @@ void r300_emit_vertex_format_state(struct r300_context* r300, DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n"); - BEGIN_CS(26); + BEGIN_CS(size); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size); OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); @@ -857,7 +856,7 @@ void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state) { CS_LOCALS(r300); - BEGIN_CS(2); + BEGIN_CS(size); OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); END_CS; } @@ -887,7 +886,7 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) return; } - BEGIN_CS(9 + code->length); + BEGIN_CS(size); /* R300_VAP_PVS_CODE_CNTL_0 * R300_VAP_PVS_CONST_CNTL * R300_VAP_PVS_CODE_CNTL_1 @@ -953,11 +952,11 @@ void r300_emit_viewport_state(struct r300_context* r300, CS_LOCALS(r300); if (r300->tcl_bypass) { - BEGIN_CS(2); + BEGIN_CS(2); /* XXX tcl_bypass will be removed in gallium anyway */ OUT_CS_REG(R300_VAP_VTE_CNTL, 0); END_CS; } else { - BEGIN_CS(9); + BEGIN_CS(size); OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); OUT_CS_32F(viewport->xscale); OUT_CS_32F(viewport->xoffset); @@ -997,7 +996,7 @@ void r300_emit_ztop_state(struct r300_context* r300, struct r300_ztop_state* ztop = (struct r300_ztop_state*)state; CS_LOCALS(r300); - BEGIN_CS(2); + BEGIN_CS(size); OUT_CS_REG(R300_ZB_ZTOP, ztop->z_buffer_top); END_CS; } @@ -1006,7 +1005,7 @@ void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, voi { CS_LOCALS(r300); - BEGIN_CS(2); + BEGIN_CS(size); OUT_CS_REG(R300_TX_INVALTAGS, 0); END_CS; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 15e0a0ad358..97a0897a5e2 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1111,7 +1111,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) } r300->vs_state.state = vs; - r300->vs_state.size = vs->code.length + 11; + r300->vs_state.size = vs->code.length + 9; r300->vs_state.dirty = TRUE; r300->vertex_format_state.dirty = TRUE; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index b33d44990a9..86301e23d7e 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -420,7 +420,7 @@ static void r300_update_rs_block(struct r300_context* r300, /* Now, after all that, see if we actually need to update the state. */ if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); - r300->rs_block_state.size = 5 + count; + r300->rs_block_state.size = 5 + count*2; r300->rs_block_state.dirty = TRUE; } } -- cgit v1.2.3 From d36e3952c21240cde19dac7f16cc37aac7174673 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 27 Feb 2010 17:00:03 +0100 Subject: r300g: put validating buffers after flushing Also cleaning up the nasty validation process. --- src/gallium/drivers/r300/r300_emit.c | 32 +++++++++++++++++--- src/gallium/drivers/r300/r300_emit.h | 4 ++- src/gallium/drivers/r300/r300_render.c | 54 ++++------------------------------ 3 files changed, 37 insertions(+), 53 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 013611018b0..d66fa0dbdba 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1010,11 +1010,16 @@ void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, voi END_CS; } -void r300_emit_buffer_validate(struct r300_context *r300) +void r300_emit_buffer_validate(struct r300_context *r300, + boolean do_validate_vertex_buffers, + struct pipe_buffer *index_buffer) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; struct r300_texture* tex; + struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; + struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_buffer *pbuf; unsigned i; boolean invalid = FALSE; @@ -1061,16 +1066,35 @@ validate: goto validate; } } - /* ...and vertex buffer. */ + /* ...vertex buffer for SWTCL path... */ if (r300->vbo) { if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } - } else { - /* debug_printf("No VBO while emitting dirty state!\n"); */ } + /* ...vertex buffers for HWTCL path... */ + if (do_validate_vertex_buffers) { + for (i = 0; i < r300->vertex_element_count; i++) { + pbuf = vbuf[velem[i].vertex_buffer_index].buffer; + + if (!r300->winsys->add_buffer(r300->winsys, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { + r300->context.flush(&r300->context, 0, NULL); + goto validate; + } + } + } + /* ...and index buffer for HWTCL path. */ + if (index_buffer) { + if (!r300->winsys->add_buffer(r300->winsys, index_buffer, + RADEON_GEM_DOMAIN_GTT, 0)) { + r300->context.flush(&r300->context, 0, NULL); + goto validate; + } + } + if (!r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index c73b016b76c..4a3f94087bf 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -105,6 +105,8 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300); /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); -void r300_emit_buffer_validate(struct r300_context *r300); +void r300_emit_buffer_validate(struct r300_context *r300, + boolean do_validate_vertex_buffers, + struct pipe_buffer *index_buffer); #endif /* R300_EMIT_H */ diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index e4f7615368d..c5baf5508e5 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -186,6 +186,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, dwords = 10 + count * vertex_size; r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); + r300_emit_buffer_validate(r300, FALSE, 0); r300_emit_dirty_state(r300); BEGIN_CS(dwords); @@ -313,31 +314,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } -static boolean r300_setup_vertex_buffers(struct r300_context *r300) -{ - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; - struct pipe_buffer *pbuf; - -validate: - for (int i = 0; i < r300->vertex_element_count; i++) { - pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { - r300->context.flush(&r300->context, 0, NULL); - goto validate; - } - } - - if (!r300->winsys->validate(r300->winsys)) { - r300->context.flush(&r300->context, 0, NULL); - return r300->winsys->validate(r300->winsys); - } - - return TRUE; -} - static void r300_shorten_ubyte_elts(struct r300_context* r300, struct pipe_buffer** elts, unsigned count) @@ -393,30 +369,16 @@ void r300_draw_range_elements(struct pipe_context* pipe, return; } - r300_update_derived_state(r300); - - r300_emit_buffer_validate(r300); - - if (!r300_setup_vertex_buffers(r300)) { - return; - } - if (indexSize == 1) { r300_shorten_ubyte_elts(r300, &indexBuffer, count); indexSize = 2; } - if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, - RADEON_GEM_DOMAIN_GTT, 0)) { - goto cleanup; - } - - if (!r300->winsys->validate(r300->winsys)) { - goto cleanup; - } + r300_update_derived_state(r300); /* 128 dwords for emit_aos and emit_draw_elements */ r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); + r300_emit_buffer_validate(r300, TRUE, indexBuffer); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); @@ -434,13 +396,13 @@ void r300_draw_range_elements(struct pipe_context* pipe, /* 16 spare dwords are enough for emit_draw_elements. */ if (count && r300_reserve_cs_space(r300, 16)) { + r300_emit_buffer_validate(r300, TRUE, indexBuffer); r300_emit_dirty_state(r300); r300_emit_aos(r300, 0); } } while (count); } -cleanup: if (indexBuffer != orgIndexBuffer) { pipe->screen->buffer_destroy(indexBuffer); } @@ -477,18 +439,13 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, r300_update_derived_state(r300); - r300_emit_buffer_validate(r300); - if (immd_is_good_idea(r300, count)) { r300_emit_draw_arrays_immediate(r300, mode, start, count); } else { - if (!r300_setup_vertex_buffers(r300)) { - return; - } - /* Make sure there are at least 128 spare dwords in the command buffer. * (most of it being consumed by emit_aos) */ r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); + r300_emit_buffer_validate(r300, TRUE, 0); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { @@ -506,6 +463,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, /* Again, we emit both AOS and draw_arrays so there should be * at least 128 spare dwords. */ if (count && r300_reserve_cs_space(r300, 128)) { + r300_emit_buffer_validate(r300, TRUE, 0); r300_emit_dirty_state(r300); } } while (count); -- cgit v1.2.3 From 942762cd973af0df75040de21d3321cd19829e70 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 28 Feb 2010 07:45:56 +0100 Subject: r300g: decouple vertex stream setup (PSC) and VS output mapping (VAP_OUT) Formerly known as vertex_format_state. These two are completely unrelated when using HWTCL and decoupling them makes the design less SWTCL-centric. When bypass_vs_clip_and_viewport gets removed, the PSC setup will no longer be a derived state. This change shouldn't make unbreaking SWTCL harder. --- src/gallium/drivers/r300/r300_context.c | 9 +++-- src/gallium/drivers/r300/r300_context.h | 35 ++++++++++------- src/gallium/drivers/r300/r300_emit.c | 55 +++++++++++++++------------ src/gallium/drivers/r300/r300_emit.h | 5 ++- src/gallium/drivers/r300/r300_render.c | 2 +- src/gallium/drivers/r300/r300_state.c | 14 +++++-- src/gallium/drivers/r300/r300_state_derived.c | 47 +++++++++++++---------- 7 files changed, 101 insertions(+), 66 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 3a84fc564d9..1d7d598b24b 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -59,7 +59,8 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->fb_state.state); FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); - FREE(r300->vertex_format_state.state); + FREE(r300->vertex_stream_state.state); + FREE(r300->vap_output_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); FREE(r300); @@ -127,7 +128,8 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(scissor_state, 3); R300_INIT_ATOM(viewport_state, 9); R300_INIT_ATOM(rs_block_state, 0); - R300_INIT_ATOM(vertex_format_state, 26); + R300_INIT_ATOM(vertex_stream_state, 0); + R300_INIT_ATOM(vap_output_state, 6); R300_INIT_ATOM(pvs_flush, 2); R300_INIT_ATOM(vs_state, 0); R300_INIT_ATOM(texture_cache_inval, 2); @@ -138,7 +140,8 @@ static void r300_setup_atoms(struct r300_context* r300) r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); - r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info); + r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state); + r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 47f2aa5154a..3eb884a0cf0 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -134,6 +134,21 @@ struct r300_texture_fb_state { uint32_t zb_format; /* R300_ZB_FORMAT */ }; +struct r300_vertex_stream_state { + /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ + uint32_t vap_prog_stream_cntl[8]; + /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ + uint32_t vap_prog_stream_cntl_ext[8]; + + unsigned count; +}; + +struct r300_vap_output_state { + uint32_t vap_vtx_state_cntl; /* R300_VAP_VTX_STATE_CNTL: 0x2180 */ + uint32_t vap_vsm_vtx_assm; /* R300_VAP_VSM_VTX_ASSM: 0x2184 */ + uint32_t vap_out_vtx_fmt[2]; /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */ +}; + struct r300_viewport_state { float xscale; /* R300_VAP_VPORT_XSCALE: 0x2098 */ float xoffset; /* R300_VAP_VPORT_XOFFSET: 0x209c */ @@ -246,16 +261,6 @@ struct r300_texture { enum r300_buffer_tiling microtile, macrotile; }; -struct r300_vertex_info { - /* Parent class */ - struct vertex_info vinfo; - - /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ - uint32_t vap_prog_stream_cntl[8]; - /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */ - uint32_t vap_prog_stream_cntl_ext[8]; -}; - extern struct pipe_viewport_state r300_viewport_identity; struct r300_context { @@ -280,9 +285,6 @@ struct r300_context { struct r300_query *query_current; struct r300_query query_list; - /* Vertex formatting information. */ - struct r300_atom vertex_format_state; - /* Various CSO state objects. */ /* Beginning of atom list. */ struct r300_atom atom_list; @@ -312,6 +314,10 @@ struct r300_context { /* Texture states. */ struct r300_texture* textures[8]; int texture_count; + /* Vertex stream formatting state. */ + struct r300_atom vertex_stream_state; + /* VAP (vertex shader) output mapping state. */ + struct r300_atom vap_output_state; /* Vertex shader. */ struct r300_atom vs_state; /* Viewport state. */ @@ -334,6 +340,9 @@ struct r300_context { struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; + /* Vertex info for Draw. */ + struct vertex_info vertex_info; + struct pipe_stencil_ref stencil_ref; /* Bitmask of dirty state objects. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index d66fa0dbdba..6a6771399a8 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -814,44 +814,51 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) END_CS; } -void r300_emit_vertex_format_state(struct r300_context* r300, +void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state) { - struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state; + struct r300_vertex_stream_state *streams = + (struct r300_vertex_stream_state*)state; unsigned i; CS_LOCALS(r300); - DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n"); + DBG(r300, DBG_DRAW, "r300: PSC emit:\n"); BEGIN_CS(size); - OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size); - - OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); - OUT_CS(vertex_info->vinfo.hwfmt[0]); - OUT_CS(vertex_info->vinfo.hwfmt[1]); - OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); - OUT_CS(vertex_info->vinfo.hwfmt[2]); - OUT_CS(vertex_info->vinfo.hwfmt[3]); - for (i = 0; i < 4; i++) { - DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i, - vertex_info->vinfo.hwfmt[i]); - } - - OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8); - for (i = 0; i < 8; i++) { - OUT_CS(vertex_info->vap_prog_stream_cntl[i]); + OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count); + for (i = 0; i < streams->count; i++) { + OUT_CS(streams->vap_prog_stream_cntl[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i, - vertex_info->vap_prog_stream_cntl[i]); + streams->vap_prog_stream_cntl[i]); } - OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8); - for (i = 0; i < 8; i++) { - OUT_CS(vertex_info->vap_prog_stream_cntl_ext[i]); + OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count); + for (i = 0; i < streams->count; i++) { + OUT_CS(streams->vap_prog_stream_cntl_ext[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i, - vertex_info->vap_prog_stream_cntl_ext[i]); + streams->vap_prog_stream_cntl_ext[i]); } END_CS; } +void r300_emit_vap_output_state(struct r300_context* r300, + unsigned size, void* state) +{ + struct r300_vap_output_state *vap_out_state = + (struct r300_vap_output_state*)state; + CS_LOCALS(r300); + + DBG(r300, DBG_DRAW, "r300: VAP emit:\n"); + + BEGIN_CS(size); + OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); + OUT_CS(vap_out_state->vap_vtx_state_cntl); + OUT_CS(vap_out_state->vap_vsm_vtx_assm); + OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); + OUT_CS(vap_out_state->vap_out_vtx_fmt[0]); + OUT_CS(vap_out_state->vap_out_vtx_fmt[1]); + END_CS; +} + void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state) { CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 4a3f94087bf..a2c2a91b880 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -77,9 +77,12 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_buffer(struct r300_context* r300); -void r300_emit_vertex_format_state(struct r300_context* r300, +void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state); +void r300_emit_vap_output_state(struct r300_context* r300, + unsigned size, void* state); + void r300_emit_vertex_program_code(struct r300_context* r300, struct r300_vertex_program_code* code); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index c5baf5508e5..770a92be74f 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -597,7 +597,7 @@ r300_render_get_vertex_info(struct vbuf_render* render) r300_update_derived_state(r300); - return (struct vertex_info*)r300->vertex_format_state.state; + return &r300->vertex_info; } static boolean r300_render_allocate_vertices(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 97a0897a5e2..5a471584005 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -659,7 +659,11 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300->fs = fs; r300_pick_fragment_shader(r300); - r300->vertex_format_state.dirty = TRUE; + r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ + + if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) { + r300->vap_output_state.dirty = TRUE; + } r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -1033,9 +1037,9 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, if (r300->draw) { draw_flush(r300->draw); draw_set_vertex_buffers(r300->draw, count, buffers); + } else { + r300->vertex_stream_state.dirty = TRUE; } - - r300->vertex_format_state.dirty = TRUE; } static boolean r300_validate_aos(struct r300_context *r300) @@ -1114,7 +1118,9 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->vs_state.size = vs->code.length + 9; r300->vs_state.dirty = TRUE; - r300->vertex_format_state.dirty = TRUE; + r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ + r300->vap_output_state.dirty = TRUE; + r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */ r300->pvs_flush.dirty = TRUE; if (r300->fs) { diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 86301e23d7e..0574d98e071 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -49,9 +49,7 @@ static void r300_draw_emit_attrib(struct r300_context* r300, output = draw_find_shader_output(r300->draw, info->output_semantic_name[index], info->output_semantic_index[index]); - draw_emit_vertex_attr( - (struct vertex_info*)r300->vertex_format_state.state, - emit, interp, output); + draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output); } static void r300_draw_emit_all_attribs(struct r300_context* r300) @@ -106,17 +104,21 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) } /* Update the PSC tables. */ +/* XXX move this function into r300_state.c after TCL-bypass gets removed + * XXX because this one is dependent only on vertex elements. */ static void r300_vertex_psc(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_info *vformat = - (struct r300_vertex_info*)r300->vertex_format_state.state; + struct r300_vertex_stream_state *vformat = + (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; uint16_t type, swizzle; enum pipe_format format; unsigned i; int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; int* stream_tab; + memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); + /* If TCL is bypassed, map vertex streams to equivalent VS output * locations. */ if (r300->tcl_bypass) { @@ -157,20 +159,25 @@ static void r300_vertex_psc(struct r300_context* r300) } vformat->vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC << (i & 1 ? 16 : 0)); + + vformat->count = (i >> 1) + 1; + r300->vertex_stream_state.size = (1 + vformat->count) * 2; } /* Update the PSC tables for SW TCL, using Draw. */ static void r300_swtcl_vertex_psc(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_info *vformat = - (struct r300_vertex_info*)r300->vertex_format_state.state; - struct vertex_info* vinfo = &vformat->vinfo; + struct r300_vertex_stream_state *vformat = + (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; + struct vertex_info* vinfo = &r300->vertex_info; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; int* vs_output_tab = vs->stream_loc_notcl; + memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); + /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ attrib_count = vinfo->num_attribs; @@ -212,6 +219,9 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) } vformat->vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC << (i & 1 ? 16 : 0)); + + vformat->count = (i >> 1) + 1; + r300->vertex_stream_state.size = (1 + vformat->count) * 2; } static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, @@ -430,13 +440,12 @@ static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_screen* r300screen = r300_screen(r300->context.screen); - struct r300_vertex_info *vformat = - (struct r300_vertex_info*)r300->vertex_format_state.state; - struct vertex_info* vinfo = &vformat->vinfo; + struct r300_vap_output_state *vap_out = + (struct r300_vap_output_state*)r300->vap_output_state.state; - /* Mmm, delicious hax */ - memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info)); - memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4); + /* XXX Mmm, delicious hax */ + memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); + memcpy(vap_out, vs->hwfmt, sizeof(uint)*4); r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); @@ -444,8 +453,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300) r300_vertex_psc(r300); } else { r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size( - (struct vertex_info*)r300->vertex_format_state.state); + draw_compute_vertex_size(&r300->vertex_info); r300_swtcl_vertex_psc(r300); } } @@ -523,10 +531,9 @@ static void r300_update_ztop(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - /* XXX */ - if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER || - r300->vs_state.dirty || r300->vertex_format_state.dirty || - r300->rs_state.dirty) { + if (r300->rs_block_state.dirty || + r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */ + r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */ r300_update_derived_shader_state(r300); } -- cgit v1.2.3 From d2ac3d5e79bdf5a32a2dca135403d963ac6c83e4 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 28 Feb 2010 19:28:31 +0100 Subject: r300g: atomize texture and sampler states --- src/gallium/drivers/r300/r300_blit.c | 8 +- src/gallium/drivers/r300/r300_context.c | 3 + src/gallium/drivers/r300/r300_context.h | 35 +++++--- src/gallium/drivers/r300/r300_emit.c | 117 +++++++------------------- src/gallium/drivers/r300/r300_emit.h | 11 +-- src/gallium/drivers/r300/r300_fs.c | 7 +- src/gallium/drivers/r300/r300_state.c | 43 +++++----- src/gallium/drivers/r300/r300_state_derived.c | 62 +++++++++++++- src/gallium/drivers/r300/r300_texture.c | 2 +- 9 files changed, 153 insertions(+), 135 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 187b4bf384e..32d05749bdb 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -98,6 +98,8 @@ static void r300_hw_copy(struct pipe_context* pipe, unsigned width, unsigned height) { struct r300_context* r300 = r300_context(pipe); + struct r300_textures_state* state = + (struct r300_textures_state*)r300->textures_state.state; /* Yeah we have to save all those states to ensure this blitter operation * is really transparent. The states will be restored by the blitter once @@ -106,11 +108,11 @@ static void r300_hw_copy(struct pipe_context* pipe, util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_save_fragment_sampler_states( - r300->blitter, r300->sampler_count, (void**)r300->sampler_states); + r300->blitter, state->sampler_count, (void**)state->sampler_states); util_blitter_save_fragment_sampler_textures( - r300->blitter, r300->texture_count, - (struct pipe_texture**)r300->textures); + r300->blitter, state->texture_count, + (struct pipe_texture**)state->textures); /* Do a copy */ util_blitter_copy(r300->blitter, diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 1d7d598b24b..86b98a4ba52 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -59,6 +59,7 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->fb_state.state); FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); + FREE(r300->textures_state.state); FREE(r300->vertex_stream_state.state); FREE(r300->vap_output_state.state); FREE(r300->viewport_state.state); @@ -133,6 +134,7 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(pvs_flush, 2); R300_INIT_ATOM(vs_state, 0); R300_INIT_ATOM(texture_cache_inval, 2); + R300_INIT_ATOM(textures_state, 0); /* Some non-CSO atoms need explicit space to store the state locally. */ r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); @@ -140,6 +142,7 @@ static void r300_setup_atoms(struct r300_context* r300) r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); + r300->textures_state.state = CALLOC_STRUCT(r300_textures_state); r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state); r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 3eb884a0cf0..b98fe347b88 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -118,7 +118,7 @@ struct r300_sampler_state { unsigned min_lod, max_lod; }; -struct r300_texture_state { +struct r300_texture_format_state { uint32_t format0; /* R300_TX_FORMAT0: 0x4480 */ uint32_t format1; /* R300_TX_FORMAT1: 0x44c0 */ uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */ @@ -134,6 +134,25 @@ struct r300_texture_fb_state { uint32_t zb_format; /* R300_ZB_FORMAT */ }; +struct r300_textures_state { + /* Textures. */ + struct r300_texture *textures[8]; + int texture_count; + /* Sampler states. */ + struct r300_sampler_state *sampler_states[8]; + int sampler_count; + + /* These is the merge of the texture and sampler states. */ + unsigned count; + uint32_t tx_enable; /* R300_TX_ENABLE: 0x4101 */ + struct r300_texture_sampler_state { + uint32_t format[3]; /* R300_TX_FORMAT[0-2] */ + uint32_t filter[2]; /* R300_TX_FILTER[0-1] */ + uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ + uint32_t tile_config; /* R300_TX_OFFSET (subset thereof) */ + } regs[8]; +}; + struct r300_vertex_stream_state { /* R300_VAP_PROG_STREAK_CNTL_[0-7] */ uint32_t vap_prog_stream_cntl[8]; @@ -165,10 +184,6 @@ struct r300_ztop_state { #define R300_NEW_FRAGMENT_SHADER 0x00000020 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040 -#define R300_NEW_SAMPLER 0x00000200 -#define R300_ANY_NEW_SAMPLERS 0x0001fe00 -#define R300_NEW_TEXTURE 0x00040000 -#define R300_ANY_NEW_TEXTURES 0x03fc0000 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 #define R300_NEW_KITCHEN_SINK 0x7fffffff @@ -254,7 +269,7 @@ struct r300_texture { struct pipe_buffer* buffer; /* Registers carrying texture format data. */ - struct r300_texture_state state; + struct r300_texture_format_state state; struct r300_texture_fb_state fb_state; /* Buffer tiling */ @@ -306,14 +321,10 @@ struct r300_context { struct r300_atom rs_state; /* RS block state. */ struct r300_atom rs_block_state; - /* Sampler states. */ - struct r300_sampler_state* sampler_states[8]; - int sampler_count; /* Scissor state. */ struct r300_atom scissor_state; - /* Texture states. */ - struct r300_texture* textures[8]; - int texture_count; + /* Textures state. */ + struct r300_atom textures_state; /* Vertex stream formatting state. */ struct r300_atom vertex_stream_state; /* VAP (vertex shader) output mapping state. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 6a6771399a8..17d55ba3b43 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -146,6 +146,8 @@ static const float * get_shader_constant( { struct r300_viewport_state* viewport = (struct r300_viewport_state*)r300->viewport_state.state; + struct r300_textures_state* texstate = + (struct r300_textures_state*)r300->textures_state.state; static float vec[4] = { 0.0, 0.0, 0.0, 1.0 }; struct pipe_texture *tex; @@ -161,7 +163,7 @@ static const float * get_shader_constant( /* Factor for converting rectangle coords to * normalized coords. Should only show up on non-r500. */ case RC_STATE_R300_TEXRECT_FACTOR: - tex = &r300->textures[constant->u.State[1]]->tex; + tex = &texstate->textures[constant->u.State[1]]->tex; vec[0] = 1.0 / tex->width0; vec[1] = 1.0 / tex->height0; break; @@ -728,49 +730,35 @@ void r300_emit_scissor_state(struct r300_context* r300, END_CS; } -void r300_emit_texture(struct r300_context* r300, - struct r300_sampler_state* sampler, - struct r300_texture* tex, - unsigned offset) +void r300_emit_textures_state(struct r300_context *r300, + unsigned size, void *state) { - uint32_t filter0 = sampler->filter0; - uint32_t format0 = tex->state.format0; - unsigned min_level, max_level; + struct r300_textures_state *allstate = (struct r300_textures_state*)state; + struct r300_texture_sampler_state *texstate; + unsigned i; CS_LOCALS(r300); - /* to emulate 1D textures through 2D ones correctly */ - if (tex->tex.target == PIPE_TEXTURE_1D) { - filter0 &= ~R300_TX_WRAP_T_MASK; - filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); - } + BEGIN_CS(size); + OUT_CS_REG(R300_TX_ENABLE, allstate->tx_enable); - if (tex->is_npot) { - /* NPOT textures don't support mip filter, unfortunately. - * This prevents incorrect rendering. */ - filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK; - } else { - /* determine min/max levels */ - /* the MAX_MIP level is the largest (finest) one */ - max_level = MIN2(sampler->max_lod, tex->tex.last_level); - min_level = MIN2(sampler->min_lod, max_level); - format0 |= R300_TX_NUM_LEVELS(max_level); - filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); - } + for (i = 0; i < allstate->count; i++) { + if ((1 << i) & allstate->tx_enable) { + texstate = &allstate->regs[i]; + + OUT_CS_REG(R300_TX_FILTER0_0 + (i * 4), texstate->filter[0]); + OUT_CS_REG(R300_TX_FILTER1_0 + (i * 4), texstate->filter[1]); + OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (i * 4), + texstate->border_color); + + OUT_CS_REG(R300_TX_FORMAT0_0 + (i * 4), texstate->format[0]); + OUT_CS_REG(R300_TX_FORMAT1_0 + (i * 4), texstate->format[1]); + OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format[2]); - BEGIN_CS(16); - OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 | - (offset << 28)); - OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1); - OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color); - - OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), format0); - OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1); - OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2); - OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1); - OUT_CS_RELOC(tex->buffer, - R300_TXO_MACRO_TILE(tex->macrotile) | - R300_TXO_MICRO_TILE(tex->microtile), - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); + OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1); + OUT_CS_RELOC(allstate->textures[i]->buffer, texstate->tile_config, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); + } + } END_CS; } @@ -976,27 +964,6 @@ void r300_emit_viewport_state(struct r300_context* r300, } } -void r300_emit_texture_count(struct r300_context* r300) -{ - uint32_t tx_enable = 0; - int i; - CS_LOCALS(r300); - - /* Notice that texture_count and sampler_count are just sizes - * of the respective arrays. We still have to check for the individual - * elements. */ - for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) { - if (r300->textures[i]) { - tx_enable |= 1 << i; - } - } - - BEGIN_CS(2); - OUT_CS_REG(R300_TX_ENABLE, tx_enable); - END_CS; - -} - void r300_emit_ztop_state(struct r300_context* r300, unsigned size, void* state) { @@ -1023,6 +990,8 @@ void r300_emit_buffer_validate(struct r300_context *r300, { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_textures_state *texstate = + (struct r300_textures_state*)r300->textures_state.state; struct r300_texture* tex; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; @@ -1055,9 +1024,9 @@ validate: } } /* ...textures... */ - for (i = 0; i < r300->texture_count; i++) { - tex = r300->textures[i]; - if (!tex) + for (i = 0; i < texstate->count; i++) { + tex = texstate->textures[i]; + if (!tex || !texstate->sampler_states[i]) continue; if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { @@ -1136,7 +1105,6 @@ void r300_emit_dirty_state(struct r300_context* r300) { struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_atom* atom; - unsigned i; if (r300->dirty_state & R300_NEW_QUERY) { r300_emit_query_start(r300); @@ -1171,27 +1139,6 @@ void r300_emit_dirty_state(struct r300_context* r300) r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; } - /* Samplers and textures are tracked separately but emitted together. */ - if (r300->dirty_state & - (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) { - r300_emit_texture_count(r300); - - for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) { - if (r300->dirty_state & - ((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) { - if (r300->textures[i]) { - r300_emit_texture(r300, - r300->sampler_states[i], - r300->textures[i], - i); - } - r300->dirty_state &= - ~((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i)); - } - } - r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES); - } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { struct r300_vertex_shader* vs = r300->vs_state.state; r300_emit_vs_constant_buffer(r300, &vs->code.constants); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index a2c2a91b880..449e640a884 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -70,10 +70,8 @@ void r300_emit_rs_block_state(struct r300_context* r300, void r300_emit_scissor_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_texture(struct r300_context* r300, - struct r300_sampler_state* sampler, - struct r300_texture* tex, - unsigned offset); +void r300_emit_textures_state(struct r300_context *r300, + unsigned size, void *state); void r300_emit_vertex_buffer(struct r300_context* r300); @@ -83,9 +81,6 @@ void r300_emit_vertex_stream_state(struct r300_context* r300, void r300_emit_vap_output_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_vertex_program_code(struct r300_context* r300, - struct r300_vertex_program_code* code); - void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); @@ -94,8 +89,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state); void r300_emit_viewport_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_texture_count(struct r300_context* r300); - void r300_emit_ztop_state(struct r300_context* r300, unsigned size, void* state); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index ae4c62b2f1d..3c2625269b8 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -133,10 +133,13 @@ static void get_compare_state( struct r300_fragment_program_external_state* state, unsigned shadow_samplers) { + struct r300_textures_state *texstate = + (struct r300_textures_state*)r300->textures_state.state; + memset(state, 0, sizeof(*state)); - for (int i = 0; i < r300->sampler_count; i++) { - struct r300_sampler_state* s = r300->sampler_states[i]; + for (int i = 0; i < texstate->sampler_count; i++) { + struct r300_sampler_state* s = texstate->sampler_states[i]; if (s && s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { /* XXX Gallium doesn't provide us with any information regarding diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 5a471584005..12bf0838711 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -859,7 +859,7 @@ static void* state->max_anisotropy > 0); /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */ - /* We must pass these to the emit function to clamp them properly. */ + /* We must pass these to the merge function to clamp them properly. */ sampler->min_lod = MAX2((unsigned)state->min_lod, 0); sampler->max_lod = MAX2((unsigned)ceilf(state->max_lod), 0); @@ -885,23 +885,20 @@ static void r300_bind_sampler_states(struct pipe_context* pipe, void** states) { struct r300_context* r300 = r300_context(pipe); - int i; + struct r300_textures_state* state = + (struct r300_textures_state*)r300->textures_state.state; if (count > 8) { return; } - for (i = 0; i < count; i++) { - if (r300->sampler_states[i] != states[i]) { - r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; - r300->dirty_state |= (R300_NEW_SAMPLER << i); - } - } + memcpy(state->sampler_states, states, sizeof(void*) * count); + state->sampler_count = count; - r300->sampler_count = count; + r300->textures_state.dirty = TRUE; /* Pick a fragment shader based on the texture compare state. */ - if (r300->fs && (r300->dirty_state & R300_ANY_NEW_SAMPLERS)) { + if (r300->fs && count) { if (r300_pick_fragment_shader(r300)) { r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -925,24 +922,25 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, struct pipe_texture** texture) { struct r300_context* r300 = r300_context(pipe); + struct r300_textures_state* state = + (struct r300_textures_state*)r300->textures_state.state; + unsigned i; boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; boolean dirty_tex = FALSE; - int i; /* XXX magic num */ if (count > 8) { return; } - + for (i = 0; i < count; i++) { - if (r300->textures[i] != (struct r300_texture*)texture[i]) { - pipe_texture_reference((struct pipe_texture**)&r300->textures[i], - texture[i]); - r300->dirty_state |= (R300_NEW_TEXTURE << i); + if (state->textures[i] != (struct r300_texture*)texture[i]) { + pipe_texture_reference((struct pipe_texture**)&state->textures[i], + texture[i]); dirty_tex = TRUE; - /* R300-specific - set the texrect factor in a fragment shader */ - if (!is_r500 && r300->textures[i]->is_npot) { + /* R300-specific - set the texrect factor in the fragment shader */ + if (!is_r500 && state->textures[i]->is_npot) { /* XXX It would be nice to re-emit just 1 constant, * XXX not all of them */ r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -951,14 +949,15 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, } for (i = count; i < 8; i++) { - if (r300->textures[i]) { - pipe_texture_reference((struct pipe_texture**)&r300->textures[i], + if (state->textures[i]) { + pipe_texture_reference((struct pipe_texture**)&state->textures[i], NULL); - r300->dirty_state |= (R300_NEW_TEXTURE << i); } } - r300->texture_count = count; + state->texture_count = count; + + r300->textures_state.dirty = TRUE; if (dirty_tex) { r300->texture_cache_inval.dirty = TRUE; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 0574d98e071..6eb7f2bfd19 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -431,7 +431,6 @@ static void r300_update_rs_block(struct r300_context* r300, if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); r300->rs_block_state.size = 5 + count*2; - r300->rs_block_state.dirty = TRUE; } } @@ -529,6 +528,63 @@ static void r300_update_ztop(struct r300_context* r300) r300->ztop_state.dirty = TRUE; } +static void r300_merge_textures_and_samplers(struct r300_context* r300) +{ + struct r300_textures_state *state = + (struct r300_textures_state*)r300->textures_state.state; + struct r300_texture_sampler_state *texstate; + struct r300_sampler_state *sampler; + struct r300_texture *tex; + unsigned min_level, max_level, i, size; + unsigned count = MIN2(state->texture_count, state->sampler_count); + + state->tx_enable = 0; + size = 2; + + for (i = 0; i < count; i++) { + if (state->textures[i] && state->sampler_states[i]) { + state->tx_enable |= 1 << i; + + tex = state->textures[i]; + sampler = state->sampler_states[i]; + + texstate = &state->regs[i]; + memcpy(texstate->format, &tex->state, sizeof(uint32_t)*3); + texstate->filter[0] = sampler->filter0; + texstate->filter[1] = sampler->filter1; + texstate->border_color = sampler->border_color; + texstate->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) | + R300_TXO_MICRO_TILE(tex->microtile); + + /* to emulate 1D textures through 2D ones correctly */ + if (tex->tex.target == PIPE_TEXTURE_1D) { + texstate->filter[0] &= ~R300_TX_WRAP_T_MASK; + texstate->filter[0] |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); + } + + if (tex->is_npot) { + /* NPOT textures don't support mip filter, unfortunately. + * This prevents incorrect rendering. */ + texstate->filter[0] &= ~R300_TX_MIN_FILTER_MIP_MASK; + } else { + /* determine min/max levels */ + /* the MAX_MIP level is the largest (finest) one */ + max_level = MIN2(sampler->max_lod, tex->tex.last_level); + min_level = MIN2(sampler->min_lod, max_level); + texstate->format[0] |= R300_TX_NUM_LEVELS(max_level); + texstate->filter[0] |= R300_TX_MAX_MIP_LEVEL(min_level); + } + + texstate->filter[0] |= i << 28; + + size += 16; + state->count = i+1; + } + } + + r300->textures_state.size = size; +} + void r300_update_derived_state(struct r300_context* r300) { if (r300->rs_block_state.dirty || @@ -537,5 +593,9 @@ void r300_update_derived_state(struct r300_context* r300) r300_update_derived_shader_state(r300); } + if (r300->textures_state.dirty) { + r300_merge_textures_and_samplers(r300); + } + r300_update_ztop(r300); } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 7c3b781c0bf..2246c75056c 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -505,7 +505,7 @@ boolean r300_is_sampler_format_supported(enum pipe_format format) static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex) { - struct r300_texture_state* state = &tex->state; + struct r300_texture_format_state* state = &tex->state; struct pipe_texture *pt = &tex->tex; unsigned i; boolean is_r500 = screen->caps->is_r500; -- cgit v1.2.3 From 3a26193fd58e3cde277f63dcb9ea049a82860398 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 1 Mar 2010 15:14:00 +0000 Subject: r300: Don't implement PIPE_FORMAT_R8G8B8X8_SNORM. This format is not actually used by any state tracker. Probably the reverse notation was mean, which would make it identical to PIPE_FORMAT_X8B8G8R8_SNORM. --- src/gallium/drivers/r300/r300_texture.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 2246c75056c..181711b3d24 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -329,7 +329,6 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_R8G8B8X8_SRGB: - case PIPE_FORMAT_R8G8B8X8_SNORM: case PIPE_FORMAT_A8B8G8R8_SNORM: case PIPE_FORMAT_X8B8G8R8_SNORM: case PIPE_FORMAT_X8UB8UG8SR8S_NORM: @@ -463,7 +462,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_R8G8B8X8_SRGB: - case PIPE_FORMAT_R8G8B8X8_SNORM: return modifier | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; -- cgit v1.2.3 From 3f37f23d17734e8a49809859df58354ed9c00a2d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 17 Feb 2010 21:08:49 +0000 Subject: gallium: Reorg texture usage flags Introduce a new shared usage and rename primary to scanout. The display target usage is more of a windows concept and doesn't mean the same thing as shared. Display target means that the surface should be presentable, for softpipe this means that it should be backed by a hardware buffer. --- src/gallium/drivers/i915/i915_texture.c | 14 +++++++------- src/gallium/drivers/i965/brw_screen_texture.c | 4 ++-- src/gallium/drivers/llvmpipe/lp_texture.c | 3 ++- src/gallium/drivers/r300/r300_screen.c | 6 ++++-- src/gallium/drivers/softpipe/sp_texture.c | 3 ++- src/gallium/drivers/svga/svga_screen_texture.c | 6 +++++- src/gallium/include/pipe/p_defines.h | 5 +++-- src/gallium/state_trackers/egl/kms/native_kms.c | 2 +- src/gallium/state_trackers/xorg/xorg_crtc.c | 2 +- src/gallium/state_trackers/xorg/xorg_dri2.c | 2 +- src/gallium/state_trackers/xorg/xorg_exa.c | 10 +++++----- src/gallium/state_trackers/xorg/xvmc/surface.c | 2 +- src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c | 2 +- 13 files changed, 35 insertions(+), 26 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c index 7ba222c78b7..5ad65a2e9c8 100644 --- a/src/gallium/drivers/i915/i915_texture.c +++ b/src/gallium/drivers/i915/i915_texture.c @@ -219,12 +219,12 @@ i915_miptree_layout_2d(struct i915_texture *tex) unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0); /* used for scanouts that need special layouts */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) if (i915_scanout_layout(tex)) return; - /* for shared buffers we use something very like scanout */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + /* shared buffers needs to be compatible with X servers */ + if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED) if (i915_display_target_layout(tex)) return; @@ -369,12 +369,12 @@ i945_miptree_layout_2d(struct i915_texture *tex) unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0); /* used for scanouts that need special layouts */ - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) if (i915_scanout_layout(tex)) return; - /* for shared buffers we use some very like scanout */ - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + /* shared buffers needs to be compatible with X servers */ + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED) if (i915_display_target_layout(tex)) return; @@ -642,7 +642,7 @@ i915_texture_create(struct pipe_screen *screen, /* for scanouts and cursors, cursors arn't scanouts */ - if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64) + if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64) buf_usage = INTEL_NEW_SCANOUT; else buf_usage = INTEL_NEW_TEXTURE; diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c index 38e99613981..2d7b6ec2222 100644 --- a/src/gallium/drivers/i965/brw_screen_texture.c +++ b/src/gallium/drivers/i965/brw_screen_texture.c @@ -231,8 +231,8 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen, goto fail; - if (templ->tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY)) { + if (templ->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { buffer_type = BRW_BUFFER_TYPE_SCANOUT; } else { diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 7f456355428..7d15e856007 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -125,7 +125,8 @@ llvmpipe_texture_create(struct pipe_screen *_screen, lpt->base.screen = &screen->base; if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY)) { + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { if (!llvmpipe_displaytarget_layout(screen, lpt)) goto fail; } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 6a55570571a..2d8b313e5d1 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -231,14 +231,16 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* Check colorbuffer format support. */ if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY)) && + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) && /* 2101010 cannot be rendered to on non-r5xx. */ (is_r500 || !is_color2101010) && r300_is_colorbuffer_format_supported(format)) { retval |= usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY); + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED); } /* Check depth-stencil format support. */ diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 371c4e20251..d3997854b2f 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -123,7 +123,8 @@ softpipe_texture_create(struct pipe_screen *screen, util_is_power_of_two(template->depth0)); if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY)) { + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { if (!softpipe_displaytarget_layout(screen, spt)) goto fail; } diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c index 12f3531a1df..b34f906ceb0 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ b/src/gallium/drivers/svga/svga_screen_texture.c @@ -315,7 +315,11 @@ svga_texture_create(struct pipe_screen *screen, tex->key.cachable = 0; } - if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) { + if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) { + tex->key.cachable = 0; + } + + if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) { tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; tex->key.cachable = 0; } diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 5cebd43ace2..5c97dc87e82 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -176,11 +176,12 @@ enum pipe_texture_target { #define PIPE_TEX_COMPARE_R_TO_TEXTURE 1 #define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 -#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ -#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */ +#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* windows presentable buffer, ie a backbuffer */ +#define PIPE_TEXTURE_USAGE_SCANOUT 0x4 /* ie a frontbuffer */ #define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 #define PIPE_TEXTURE_USAGE_SAMPLER 0x10 #define PIPE_TEXTURE_USAGE_DYNAMIC 0x20 +#define PIPE_TEXTURE_USAGE_SHARED 0x40 /** Pipe driver custom usage flags should be greater or equal to this value */ #define PIPE_TEXTURE_USAGE_CUSTOM (1 << 16) diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c index ee6ab2e60b8..dbdb1e635a7 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.c +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, templ.format = ksurf->color_format; templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT) - templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; + templ.tex_usage |= PIPE_TEXTURE_SCANOUT; } /* create textures */ diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 4a77f540805..8f6426bcc87 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -201,7 +201,7 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; - templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; + templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth0 = 1; diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 5472285ec1b..e7f1b2d4112 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -129,7 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form template.depth0 = 1; template.last_level = 0; template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + PIPE_TEXTURE_USAGE_SHARED; tex = ms->screen->texture_create(ms->screen, &template); pipe_texture_reference(&exa_priv->depth_stencil_tex, tex); } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 665efdc0f03..5c3e92efdfd 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -789,7 +789,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap) return 0; } - priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; + priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT; return 0; } @@ -805,7 +805,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap) return 0; } - priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + priv->flags |= PIPE_TEXTURE_USAGE_SHARED; return 0; } @@ -943,7 +943,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex) { struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); - int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT; if (!priv) return FALSE; @@ -976,8 +976,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn, template.depth0 = 1; template.last_level = 0; template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; - template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; - template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; + template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED; return exa->scrn->texture_create(exa->scrn, &template); } diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 0e39a390c69..c113f49e556 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -106,7 +106,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u template.width0 = width; template.height0 = height; template.depth0 = 1; - template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + template.tex_usage = PIPE_TEXTURE_USAGE_SHARED; tex = vpipe->screen->texture_create(vpipe->screen, &template); if (!tex) diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index c814d986b1d..80b5a4c0914 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -23,7 +23,7 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen, struct pipe_texture tmpl; memset(&tmpl, 0, sizeof(tmpl)); - tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY; + tmpl.tex_usage = PIPE_TEXTURE_USAGE_SCANOUT; tmpl.target = PIPE_TEXTURE_2D; tmpl.last_level = 0; tmpl.depth0 = 1; -- cgit v1.2.3 From d160eed005e75d8933562f4880dfc84033011ac5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 1 Mar 2010 15:11:39 +0000 Subject: r300g: Conversion to to winsys handle --- src/gallium/drivers/r300/r300_texture.c | 66 +++++++++++ src/gallium/winsys/drm/radeon/core/radeon_buffer.c | 71 ++++++++++++ src/gallium/winsys/drm/radeon/core/radeon_drm.c | 121 --------------------- src/gallium/winsys/drm/radeon/core/radeon_drm.h | 22 ---- src/gallium/winsys/drm/radeon/core/radeon_winsys.h | 12 ++ 5 files changed, 149 insertions(+), 143 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 2246c75056c..3b39207a455 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -848,6 +848,70 @@ static struct pipe_texture* return (struct pipe_texture*)tex; } +static struct pipe_texture* + r300_texture_from_handle(struct pipe_screen* screen, + const struct pipe_texture* base, + struct winsys_handle *whandle) +{ + struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; + struct r300_screen* rscreen = r300_screen(screen); + struct pipe_buffer *buffer; + struct r300_texture* tex; + unsigned stride; + + /* Support only 2D textures without mipmaps */ + if (base->target != PIPE_TEXTURE_2D || + base->depth0 != 1 || + base->last_level != 0) { + return NULL; + } + + buffer = winsys->buffer_from_handle(winsys, screen, whandle, &stride); + if (!buffer) { + return NULL; + } + + tex = CALLOC_STRUCT(r300_texture); + if (!tex) { + return NULL; + } + + tex->tex = *base; + pipe_reference_init(&tex->tex.reference, 1); + tex->tex.screen = screen; + + tex->stride_override = stride; + tex->pitch[0] = stride / util_format_get_blocksize(base->format); + + r300_setup_flags(tex); + r300_setup_texture_state(rscreen, tex); + + /* one ref already taken */ + tex->buffer = buffer; + + return (struct pipe_texture*)tex; +} + +static boolean + r300_texture_get_handle(struct pipe_screen* screen, + struct pipe_texture *texture, + struct winsys_handle *whandle) +{ + struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; + struct r300_texture* tex = (struct r300_texture*)texture; + unsigned stride; + + if (!tex) { + return FALSE; + } + + stride = r300_texture_get_stride(r300_screen(screen), tex, 0); + + winsys->buffer_get_handle(winsys, tex->buffer, stride, whandle); + + return TRUE; +} + static struct pipe_video_surface * r300_video_surface_create(struct pipe_screen *screen, enum pipe_video_chroma_format chroma_format, @@ -899,6 +963,8 @@ static void r300_video_surface_destroy(struct pipe_video_surface *vsfc) void r300_init_screen_texture_functions(struct pipe_screen* screen) { screen->texture_create = r300_texture_create; + screen->texture_from_handle = r300_texture_from_handle; + screen->texture_get_handle = r300_texture_get_handle; screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; screen->tex_surface_destroy = r300_tex_surface_destroy; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index e5c69199330..daa032af6f2 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -264,6 +264,75 @@ static int radeon_fence_finish(struct pipe_winsys *ws, return 0; } +/* Create a buffer from a handle. */ +static struct pipe_buffer* radeon_buffer_from_handle(struct radeon_winsys *radeon_ws, + struct pipe_screen *screen, + struct winsys_handle *whandle, + unsigned *stride) +{ + struct radeon_bo_manager* bom = radeon_ws->priv->bom; + struct radeon_pipe_buffer* radeon_buffer; + struct radeon_bo* bo = NULL; + + bo = radeon_bo_open(bom, whandle->handle, 0, 0, 0, 0); + if (bo == NULL) { + return NULL; + } + + radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); + if (radeon_buffer == NULL) { + radeon_bo_unref(bo); + return NULL; + } + + pipe_reference_init(&radeon_buffer->base.reference, 1); + radeon_buffer->base.screen = screen; + radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; + radeon_buffer->bo = bo; + + *stride = whandle->stride; + + return &radeon_buffer->base; +} + +static boolean radeon_buffer_get_handle(struct radeon_winsys *radeon_ws, + struct pipe_buffer *buffer, + unsigned stride, + struct winsys_handle *whandle) +{ + int retval, fd; + struct drm_gem_flink flink; + struct radeon_pipe_buffer* radeon_buffer; + + radeon_buffer = (struct radeon_pipe_buffer*)buffer; + + + if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { + if (!radeon_buffer->flinked) { + fd = radeon_ws->priv->fd; + + flink.handle = radeon_buffer->bo->handle; + + retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (retval) { + debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", + retval); + return FALSE; + } + + radeon_buffer->flink = flink.name; + radeon_buffer->flinked = TRUE; + } + + whandle->handle = radeon_buffer->flink; + } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { + whandle->handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle; + } + whandle->stride = stride; + + return TRUE; +} + struct radeon_winsys* radeon_pipe_winsys(int fd) { struct radeon_winsys* radeon_ws; @@ -298,6 +367,8 @@ struct radeon_winsys* radeon_pipe_winsys(int fd) radeon_ws->base.get_name = radeon_get_name; radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling; + radeon_ws->buffer_from_handle = radeon_buffer_from_handle; + radeon_ws->buffer_get_handle = radeon_buffer_get_handle; return radeon_ws; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index e817a26da6d..97edb6a47e3 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -148,124 +148,6 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, } } - -boolean radeon_buffer_from_texture(struct drm_api* api, - struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride) -{ - /* XXX fix this */ - return r300_get_texture_buffer(screen, texture, buffer, stride); -} - -/* Create a buffer from a handle. */ -/* XXX what's up with name? */ -struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, - struct pipe_screen* screen, - const char* name, - unsigned handle) -{ - struct radeon_bo_manager* bom = - ((struct radeon_winsys*)screen->winsys)->priv->bom; - struct radeon_pipe_buffer* radeon_buffer; - struct radeon_bo* bo = NULL; - - bo = radeon_bo_open(bom, handle, 0, 0, 0, 0); - if (bo == NULL) { - return NULL; - } - - radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); - if (radeon_buffer == NULL) { - radeon_bo_unref(bo); - return NULL; - } - - pipe_reference_init(&radeon_buffer->base.reference, 1); - radeon_buffer->base.screen = screen; - radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; - radeon_buffer->bo = bo; - return &radeon_buffer->base; -} - -static struct pipe_texture* -radeon_texture_from_shared_handle(struct drm_api *api, - struct pipe_screen *screen, - struct pipe_texture *templ, - const char *name, - unsigned stride, - unsigned handle) -{ - struct pipe_buffer *buffer; - struct pipe_texture *blanket; - - buffer = radeon_buffer_from_handle(api, screen, name, handle); - if (!buffer) { - return NULL; - } - - blanket = screen->texture_blanket(screen, templ, &stride, buffer); - - pipe_buffer_reference(&buffer, NULL); - - return blanket; -} - -static boolean radeon_shared_handle_from_texture(struct drm_api *api, - struct pipe_screen *screen, - struct pipe_texture *texture, - unsigned *stride, - unsigned *handle) -{ - int retval, fd; - struct drm_gem_flink flink; - struct radeon_pipe_buffer* radeon_buffer; - struct pipe_buffer *buffer = NULL; - - if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { - return FALSE; - } - - radeon_buffer = (struct radeon_pipe_buffer*)buffer; - if (!radeon_buffer->flinked) { - fd = ((struct radeon_winsys*)screen->winsys)->priv->fd; - - flink.handle = radeon_buffer->bo->handle; - - retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - if (retval) { - debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n", - retval); - return FALSE; - } - - radeon_buffer->flink = flink.name; - radeon_buffer->flinked = TRUE; - } - - *handle = radeon_buffer->flink; - return TRUE; -} - -static boolean radeon_local_handle_from_texture(struct drm_api *api, - struct pipe_screen *screen, - struct pipe_texture *texture, - unsigned *stride, - unsigned *handle) -{ - struct pipe_buffer *buffer = NULL; - if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { - return FALSE; - } - - *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle; - - pipe_buffer_reference(&buffer, NULL); - - return TRUE; -} - static void radeon_drm_api_destroy(struct drm_api *api) { return; @@ -275,9 +157,6 @@ struct drm_api drm_api_hooks = { .name = "radeon", .driver_name = "radeon", .create_screen = radeon_create_screen, - .texture_from_shared_handle = radeon_texture_from_shared_handle, - .shared_handle_from_texture = radeon_shared_handle_from_texture, - .local_handle_from_texture = radeon_local_handle_from_texture, .destroy = radeon_drm_api_destroy, }; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index f62a9b80485..78451b6f011 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -37,28 +37,6 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg); - -boolean radeon_buffer_from_texture(struct drm_api* api, - struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride); - -struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api, - struct pipe_screen* screen, - const char* name, - unsigned handle); - -boolean radeon_handle_from_buffer(struct drm_api* api, - struct pipe_screen* screen, - struct pipe_buffer* buffer, - unsigned* handle); - -boolean radeon_global_handle_from_buffer(struct drm_api* api, - struct pipe_screen* screen, - struct pipe_buffer* buffer, - unsigned* handle); - void radeon_destroy_drm_api(struct drm_api* api); /* Guess at whether this chipset should use r300g. diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index 4901080ca7b..37eeb459791 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -56,6 +56,18 @@ struct radeon_winsys { /* VRAM size. */ uint32_t vram_size; + /* Create a buffer from a winsys handle. */ + struct pipe_buffer *(*buffer_from_handle)(struct radeon_winsys *winsys, + struct pipe_screen *screen, + struct winsys_handle *whandle, + unsigned *stride); + + /* Get the handle from a buffer. */ + boolean (*buffer_get_handle)(struct radeon_winsys *winsys, + struct pipe_buffer *buffer, + unsigned stride, + struct winsys_handle *whandle); + /* Add a pipe_buffer to the list of buffer objects to validate. */ boolean (*add_buffer)(struct radeon_winsys* winsys, struct pipe_buffer* pbuffer, -- cgit v1.2.3 From b42455c4f48076eec34e383d5b9cc4670f2d048f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 1 Mar 2010 17:07:03 +0100 Subject: r300: Save viewport and clip states before invoking blitter. --- src/gallium/drivers/r300/r300_blit.c | 2 ++ src/gallium/drivers/r300/r300_context.h | 4 ++++ src/gallium/drivers/r300/r300_state.c | 4 ++++ 3 files changed, 10 insertions(+) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index eb9b0beeb5a..ec7414dc369 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -34,6 +34,8 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); util_blitter_save_vertex_shader(r300->blitter, r300->vs); + util_blitter_save_viewport(r300->blitter, &r300->viewport); + util_blitter_save_clip(r300->blitter, &r300->clip); } /* Clear currently bound buffers. */ diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 2f056aafcbf..97100c08ccb 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -333,6 +333,10 @@ struct r300_context { struct pipe_stencil_ref stencil_ref; + struct pipe_clip_state clip; + + struct pipe_viewport_state viewport; + /* Bitmask of dirty state objects. */ uint32_t dirty_state; /* Flag indicating whether or not the HW is dirty. */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 3550c69c46d..ebb859138fa 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -376,6 +376,8 @@ static void r300_set_clip_state(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); + r300->clip = *state; + if (r300_screen(pipe->screen)->caps->has_tcl) { memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state)); r300->clip_state.size = 29; @@ -986,6 +988,8 @@ static void r300_set_viewport_state(struct pipe_context* pipe, struct r300_viewport_state* viewport = (struct r300_viewport_state*)r300->viewport_state.state; + r300->viewport = *state; + /* Do the transform in HW. */ viewport->vte_control = R300_VTX_W0_FMT; -- cgit v1.2.3 From a2bcdb7e509fde231846f3af09bef38ed1df4068 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 1 Mar 2010 16:26:36 +0000 Subject: r300: Use PIPE_FORMAT_R8G8B8A8_UNORM_REV where appropriate. --- src/gallium/drivers/r300/r300_texture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 181711b3d24..5b674f6e57d 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -324,7 +324,7 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_B8G8R8A8_SRGB: case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B8G8R8X8_SRGB: - case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM_REV: case PIPE_FORMAT_R8G8B8A8_SNORM: case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: @@ -457,7 +457,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) R300_C2_SEL_G | R300_C3_SEL_B; /* RGBA 32-bit outputs. */ - case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM_REV: case PIPE_FORMAT_R8G8B8A8_SNORM: case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: -- cgit v1.2.3 From e9441e1f88cc07365f4d7d9149ccefe128809645 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 1 Mar 2010 18:46:49 +0100 Subject: r300g: adapt to new vertex element cso --- src/gallium/drivers/r300/r300_blit.c | 1 + src/gallium/drivers/r300/r300_context.h | 8 +++-- src/gallium/drivers/r300/r300_emit.c | 4 +-- src/gallium/drivers/r300/r300_render.c | 12 ++++---- src/gallium/drivers/r300/r300_state.c | 44 +++++++++++++++++++-------- src/gallium/drivers/r300/r300_state_derived.c | 6 ++-- 6 files changed, 50 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index eb9b0beeb5a..2f9650df1b7 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -34,6 +34,7 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); util_blitter_save_vertex_shader(r300->blitter, r300->vs); + util_blitter_save_vertex_elements(r300->blitter, r300->vs); } /* Clear currently bound buffers. */ diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 1eba8a8ed12..0ee0ab47a6b 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -247,6 +247,11 @@ struct r300_vertex_info { uint32_t vap_prog_stream_cntl_ext[8]; }; +struct r300_velems_state { + unsigned count; + struct pipe_vertex_element velem[]; +}; + extern struct pipe_viewport_state r300_viewport_identity; struct r300_context { @@ -317,8 +322,7 @@ struct r300_context { struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; /* Vertex elements for Gallium. */ - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; - int vertex_element_count; + struct r300_velems_state *velems; struct pipe_stencil_ref stencil_ref; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 88fe166359b..fa3df9a23b6 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -776,9 +776,9 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_aos(struct r300_context* r300, unsigned offset) { struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; int i; - unsigned size1, size2, aos_count = r300->vertex_element_count; + unsigned size1, size2, aos_count = r300->velems->count; unsigned packet_size = (aos_count * 3 + 1) / 2; CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cd4971ae136..1850a6f247a 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -128,7 +128,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, { struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; - unsigned vertex_element_count = r300->vertex_element_count; + unsigned vertex_element_count = r300->velems->count; unsigned i, v, vbi, dw, elem_offset; /* Size of the vertex, in dwords. */ @@ -151,7 +151,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ for (i = 0; i < vertex_element_count; i++) { - velem = &r300->vertex_element[i]; + velem = &r300->velems->velem[i]; offset[i] = velem->src_offset / 4; size[i] = util_format_get_blocksize(velem->src_format) / 4; vertex_size += size[i]; @@ -183,7 +183,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Emit vertices. */ for (v = 0; v < count; v++) { for (i = 0; i < vertex_element_count; i++) { - velem = &r300->vertex_element[i]; + velem = &r300->velems->velem[i]; vbi = velem->vertex_buffer_index; elem_offset = offset[i] + stride[vbi] * (v + start); @@ -196,7 +196,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Unmap buffers. */ for (i = 0; i < vertex_element_count; i++) { - vbi = r300->vertex_element[i].vertex_buffer_index; + vbi = r300->velems->velem[i].vertex_buffer_index; if (map[vbi]) { vbuf = &r300->vertex_buffer[vbi]; @@ -278,11 +278,11 @@ static void r300_emit_draw_elements(struct r300_context *r300, static boolean r300_setup_vertex_buffers(struct r300_context *r300) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; struct pipe_buffer *pbuf; validate: - for (int i = 0; i < r300->vertex_element_count; i++) { + for (int i = 0; i < r300->velems->count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; if (!r300->winsys->add_buffer(r300->winsys, pbuf, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c1930..ceac690fc46 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1044,11 +1044,11 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, static boolean r300_validate_aos(struct r300_context *r300) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; int i; /* Check if formats and strides are aligned to the size of DWORD. */ - for (i = 0; i < r300->vertex_element_count; i++) { + for (i = 0; i < r300->velems->count; i++) { if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || util_format_get_blocksize(velem[i].src_format) % 4 != 0) { return FALSE; @@ -1057,20 +1057,32 @@ static boolean r300_validate_aos(struct r300_context *r300) return TRUE; } -static void r300_set_vertex_elements(struct pipe_context* pipe, - unsigned count, - const struct pipe_vertex_element* elements) +static void* r300_create_vertex_elements_state(struct pipe_context* pipe, + unsigned count, + const struct pipe_vertex_element* attribs) { - struct r300_context* r300 = r300_context(pipe); + /*XXX could precalculate state here instead of later */ + struct r300_velems_state *velems; + assert(count <= PIPE_MAX_ATTRIBS); + velems = (struct r300_velems_state *) MALLOC(sizeof(struct r300_velems_state) + count * sizeof(*attribs)); + if (velems) { + velems->count = count; + memcpy(velems->velem, attribs, sizeof(*attribs) * count); + } + return velems; +} + +static void r300_bind_vertex_elements_state(struct pipe_context *pipe, + void *velems) +{ + struct r300_context *r300 = r300_context(pipe); + struct r300_velems_state *r300_velems = (struct r300_velems_state *) velems; - memcpy(r300->vertex_element, - elements, - sizeof(struct pipe_vertex_element) * count); - r300->vertex_element_count = count; + r300->velems = r300_velems; if (r300->draw) { draw_flush(r300->draw); - draw_set_vertex_elements(r300->draw, count, elements); + draw_set_vertex_elements(r300->draw, r300_velems->count, r300_velems->velem); } if (!r300_validate_aos(r300)) { @@ -1080,6 +1092,11 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, } } +static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) +{ + FREE( velems ); +} + static void* r300_create_vs_state(struct pipe_context* pipe, const struct pipe_shader_state* shader) { @@ -1241,7 +1258,10 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.set_viewport_state = r300_set_viewport_state; r300->context.set_vertex_buffers = r300_set_vertex_buffers; - r300->context.set_vertex_elements = r300_set_vertex_elements; + + r300->context.create_vertex_elements_state = r300_create_vertex_elements_state; + r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state; + r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state; r300->context.create_vs_state = r300_create_vs_state; r300->context.bind_vs_state = r300_bind_vs_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2cbce9210a7..c43a93601cb 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -128,10 +128,10 @@ static void r300_vertex_psc(struct r300_context* r300) DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" " in psc\n", r300->vs->info.num_inputs, - r300->vertex_element_count); + r300->velems->count); - for (i = 0; i < r300->vertex_element_count; i++) { - format = r300->vertex_element[i].src_format; + for (i = 0; i < r300->velems->count; i++) { + format = r300->velems->velem[i].src_format; type = r300_translate_vertex_data_type(format) | (stream_tab[i] << R300_DST_VEC_LOC_SHIFT); -- cgit v1.2.3 From 568a3c73652f02e8b0fee7693578c8fd2013d97f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 1 Mar 2010 18:41:05 +0000 Subject: r300: Remove PIPE_FORMAT_A8B8G8R8_SNORM. PIPE_FORMAT_R8G8B8A8_SNORM already listed. --- src/gallium/drivers/r300/r300_texture.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 5b674f6e57d..ea474737b12 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -329,7 +329,6 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R8G8B8A8_SRGB: case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_R8G8B8X8_SRGB: - case PIPE_FORMAT_A8B8G8R8_SNORM: case PIPE_FORMAT_X8B8G8R8_SNORM: case PIPE_FORMAT_X8UB8UG8SR8S_NORM: return R300_COLOR_FORMAT_ARGB8888; @@ -467,7 +466,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) R300_C2_SEL_G | R300_C3_SEL_R; /* ABGR 32-bit outputs. */ - case PIPE_FORMAT_A8B8G8R8_SNORM: case PIPE_FORMAT_X8B8G8R8_SNORM: case PIPE_FORMAT_X8UB8UG8SR8S_NORM: case PIPE_FORMAT_A2B10G10R10_UNORM: -- cgit v1.2.3 From b5cfa6f1966557106a7033b2c80769d64c72ce4c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 1 Mar 2010 18:13:41 +0000 Subject: r300: Rename pipe formats. --- src/gallium/drivers/r300/r300_blit.c | 4 +- src/gallium/drivers/r300/r300_screen.c | 6 +-- src/gallium/drivers/r300/r300_state.c | 4 +- src/gallium/drivers/r300/r300_texture.c | 82 ++++++++++++++++----------------- 4 files changed, 48 insertions(+), 48 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 32d05749bdb..0e2d6c5b42a 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -141,10 +141,10 @@ void r300_surface_copy(struct pipe_context* pipe, new_format = PIPE_FORMAT_I8_UNORM; break; case 2: - new_format = PIPE_FORMAT_A4R4G4B4_UNORM; + new_format = PIPE_FORMAT_B4G4R4A4_UNORM; break; case 4: - new_format = PIPE_FORMAT_A8R8G8B8_UNORM; + new_format = PIPE_FORMAT_B8G8R8A8_UNORM; break; default: debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n" diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 6a55570571a..d397a8eb2b4 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -210,9 +210,9 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, { uint32_t retval = 0; boolean is_r500 = r300_screen(screen)->caps->is_r500; - boolean is_z24 = format == PIPE_FORMAT_Z24X8_UNORM || - format == PIPE_FORMAT_Z24S8_UNORM; - boolean is_color2101010 = format == PIPE_FORMAT_A2B10G10R10_UNORM; + boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM || + format == PIPE_FORMAT_S8Z24_UNORM; + boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM; if (target >= PIPE_MAX_TEXTURE_TYPES) { debug_printf("r300: Implementation error: Received bogus texture " diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 12bf0838711..6c230455615 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -356,7 +356,7 @@ static void r300_set_blend_color(struct pipe_context* pipe, (struct r300_blend_color_state*)r300->blend_color_state.state; union util_color uc; - util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); + util_pack_color(color->color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); state->blend_color = uc.ui; /* XXX if FP16 blending is enabled, we should use the FP16 format */ @@ -869,7 +869,7 @@ static void* sampler->filter1 |= r300_anisotropy(state->max_anisotropy); - util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc); + util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); sampler->border_color = uc.ui; /* R500-specific fixups and optimizations */ diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index ea474737b12..44cfe82a574 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -92,8 +92,8 @@ static uint32_t r300_translate_texformat(enum pipe_format format) switch (format) { case PIPE_FORMAT_Z16_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X16); - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); default: return ~0; /* Unsupported. */ @@ -104,9 +104,9 @@ static uint32_t r300_translate_texformat(enum pipe_format format) result |= R300_TX_FORMAT_YUV_TO_RGB; switch (format) { - case PIPE_FORMAT_YCBCR: + case PIPE_FORMAT_UYVY: return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; - case PIPE_FORMAT_YCBCR_REV: + case PIPE_FORMAT_YUYV: return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; default: return ~0; /* Unsupported/unknown. */ @@ -308,31 +308,31 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) return R300_COLOR_FORMAT_I8; /* 16-bit buffers. */ - case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_B5G6R5_UNORM: return R300_COLOR_FORMAT_RGB565; - case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: return R300_COLOR_FORMAT_ARGB1555; - case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_B4G4R4A4_UNORM: return R300_COLOR_FORMAT_ARGB4444; /* 32-bit buffers. */ - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_SRGB: case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8A8_SRGB: case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B8G8R8X8_SRGB: - case PIPE_FORMAT_R8G8B8A8_UNORM_REV: + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_SRGB: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_SRGB: + case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SRGB: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_R8G8B8X8_SRGB: - case PIPE_FORMAT_X8B8G8R8_SNORM: - case PIPE_FORMAT_X8UB8UG8SR8S_NORM: + case PIPE_FORMAT_A8B8G8R8_SRGB: + case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_X8B8G8R8_SRGB: + case PIPE_FORMAT_R8G8B8X8_SNORM: + case PIPE_FORMAT_R8SG8SB8UX8U_NORM: return R300_COLOR_FORMAT_ARGB8888; - case PIPE_FORMAT_A2B10G10R10_UNORM: + case PIPE_FORMAT_R10G10B10A2_UNORM: return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */ /* 64-bit buffers. */ @@ -349,9 +349,9 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) #endif /* YUV buffers. */ - case PIPE_FORMAT_YCBCR: + case PIPE_FORMAT_UYVY: return R300_COLOR_FORMAT_YVYU; - case PIPE_FORMAT_YCBCR_REV: + case PIPE_FORMAT_YUYV: return R300_COLOR_FORMAT_VYUY; default: return ~0; /* Unsupported. */ @@ -366,9 +366,9 @@ static uint32_t r300_translate_zsformat(enum pipe_format format) case PIPE_FORMAT_Z16_UNORM: return R300_DEPTHFORMAT_16BIT_INT_Z; /* 24-bit depth, ignored stencil */ - case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: /* 24-bit depth, 8-bit stencil */ - case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; default: return ~0; /* Unsupported. */ @@ -435,40 +435,40 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) return modifier | R300_C2_SEL_R; /* ARGB 32-bit outputs. */ - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_SRGB: + case PIPE_FORMAT_B5G6R5_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8X8_SRGB: return modifier | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; /* BGRA 32-bit outputs. */ - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_B8G8R8X8_SRGB: + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_SRGB: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_SRGB: return modifier | R300_C0_SEL_A | R300_C1_SEL_R | R300_C2_SEL_G | R300_C3_SEL_B; /* RGBA 32-bit outputs. */ - case PIPE_FORMAT_R8G8B8A8_UNORM_REV: + case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SRGB: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_R8G8B8X8_SRGB: + case PIPE_FORMAT_A8B8G8R8_SRGB: + case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_X8B8G8R8_SRGB: return modifier | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; /* ABGR 32-bit outputs. */ - case PIPE_FORMAT_X8B8G8R8_SNORM: - case PIPE_FORMAT_X8UB8UG8SR8S_NORM: - case PIPE_FORMAT_A2B10G10R10_UNORM: + case PIPE_FORMAT_R8G8B8X8_SNORM: + case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + case PIPE_FORMAT_R10G10B10A2_UNORM: /* RGBA high precision outputs (same swizzles as ABGR low precision) */ case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: @@ -867,7 +867,7 @@ r300_video_surface_create(struct pipe_screen *screen, memset(&template, 0, sizeof(struct pipe_texture)); template.target = PIPE_TEXTURE_2D; - template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.format = PIPE_FORMAT_B8G8R8X8_UNORM; template.last_level = 0; template.width0 = util_next_power_of_two(width); template.height0 = util_next_power_of_two(height); -- cgit v1.2.3 From 4240987cecdaaaeb2d6188f7c83ff4cb8e670c59 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Tue, 2 Mar 2010 18:40:03 -0800 Subject: r300g: Make velem CSO actually work. glxgears runs again. --- src/gallium/drivers/r300/r300_blit.c | 2 +- src/gallium/drivers/r300/r300_context.h | 2 +- src/gallium/drivers/r300/r300_state.c | 15 ++++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 2f9650df1b7..297768e5cf4 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -34,7 +34,7 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); util_blitter_save_vertex_shader(r300->blitter, r300->vs); - util_blitter_save_vertex_elements(r300->blitter, r300->vs); + util_blitter_save_vertex_elements(r300->blitter, r300->velems); } /* Clear currently bound buffers. */ diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 0ee0ab47a6b..f372743c5b8 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -249,7 +249,7 @@ struct r300_vertex_info { struct r300_velems_state { unsigned count; - struct pipe_vertex_element velem[]; + struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; }; extern struct pipe_viewport_state r300_viewport_identity; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index ceac690fc46..995664d9000 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1061,13 +1061,14 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, unsigned count, const struct pipe_vertex_element* attribs) { - /*XXX could precalculate state here instead of later */ struct r300_velems_state *velems; + + /*XXX should precalculate state here instead of later */ assert(count <= PIPE_MAX_ATTRIBS); - velems = (struct r300_velems_state *) MALLOC(sizeof(struct r300_velems_state) + count * sizeof(*attribs)); + velems = CALLOC_STRUCT(r300_velems_state); if (velems) { - velems->count = count; - memcpy(velems->velem, attribs, sizeof(*attribs) * count); + velems->count = count; + memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count); } return velems; } @@ -1078,6 +1079,10 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, struct r300_context *r300 = r300_context(pipe); struct r300_velems_state *r300_velems = (struct r300_velems_state *) velems; + if (velems == NULL) { + return; + } + r300->velems = r300_velems; if (r300->draw) { @@ -1094,7 +1099,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) { - FREE( velems ); + FREE(velems); } static void* r300_create_vs_state(struct pipe_context* pipe, -- cgit v1.2.3 From 4cb7642ff3ba390e2918d71220625a837bf8a7b9 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Tue, 2 Mar 2010 19:14:09 -0800 Subject: r300g: Use a macro to consolidate general state handling. My God, I've reinvented R300_STATECHANGE. Forgive me. :C --- src/gallium/drivers/r300/r300_state.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index a983ec7b5bd..1f6f99d3e52 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -43,6 +43,12 @@ /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ +#define UPDATE_STATE(cso, atom) \ + if (cso != atom.state) { \ + atom.state = cso; \ + atom.dirty = TRUE; \ + } + static boolean blend_discard_if_src_alpha_0(unsigned srcRGB, unsigned srcA, unsigned dstRGB, unsigned dstA) { @@ -328,8 +334,7 @@ static void r300_bind_blend_state(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); - r300->blend_state.state = state; - r300->blend_state.dirty = TRUE; + UPDATE_STATE(state, r300->blend_state); } /* Free blend state. */ @@ -478,11 +483,8 @@ static void r300_bind_dsa_state(struct pipe_context* pipe, void* state) { struct r300_context* r300 = r300_context(pipe); - struct r300_screen* r300screen = r300_screen(pipe->screen); - r300->dsa_state.state = state; - r300->dsa_state.size = r300screen->caps->is_r500 ? 8 : 6; - r300->dsa_state.dirty = TRUE; + UPDATE_STATE(state, r300->dsa_state); } /* Free DSA state. */ @@ -813,13 +815,13 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) if (rs) { r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; - r300->rs_state.dirty = TRUE; } else { r300->polygon_offset_enabled = FALSE; } - r300->rs_state.state = rs; + UPDATE_STATE(state, r300->rs_state); r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0); + /* XXX Why is this still needed, dammit!? */ r300->scissor_state.dirty = TRUE; r300->viewport_state.dirty = TRUE; @@ -1114,9 +1116,8 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300_translate_vertex_shader(r300, vs); } - r300->vs_state.state = vs; + UPDATE_STATE(shader, r300->vs_state); r300->vs_state.size = vs->code.length + 9; - r300->vs_state.dirty = TRUE; r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ r300->vap_output_state.dirty = TRUE; -- cgit v1.2.3 From c51f7a48cde970c06a42a9ca195a2d1cf808fd2c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 3 Mar 2010 13:07:56 +0000 Subject: r300: Remove PIPE_FORMAT_R8G8B8X8_SNORM support. --- src/gallium/drivers/r300/r300_texture.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 44cfe82a574..c0144f64b4a 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -329,7 +329,6 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_SRGB: case PIPE_FORMAT_X8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_SRGB: - case PIPE_FORMAT_R8G8B8X8_SNORM: case PIPE_FORMAT_R8SG8SB8UX8U_NORM: return R300_COLOR_FORMAT_ARGB8888; case PIPE_FORMAT_R10G10B10A2_UNORM: @@ -466,7 +465,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) R300_C2_SEL_G | R300_C3_SEL_R; /* ABGR 32-bit outputs. */ - case PIPE_FORMAT_R8G8B8X8_SNORM: case PIPE_FORMAT_R8SG8SB8UX8U_NORM: case PIPE_FORMAT_R10G10B10A2_UNORM: /* RGBA high precision outputs (same swizzles as ABGR low precision) */ -- cgit v1.2.3 From 4b61fd22a87342bafc3da2264b68537c6eb80375 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 4 Mar 2010 13:22:21 +0000 Subject: r300g: remove dead r300_get_texture_buffer function --- src/gallium/drivers/r300/r300_context.c | 16 ++++++++++------ src/gallium/drivers/r300/r300_texture.c | 18 ------------------ src/gallium/drivers/r300/r300_texture.h | 6 ++---- src/gallium/drivers/r300/r300_winsys.h | 5 ----- 4 files changed, 12 insertions(+), 33 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 86b98a4ba52..6308d3a087c 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -72,11 +72,8 @@ r300_is_texture_referenced(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level) { - struct pipe_buffer* buf = 0; - - r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); - - return pipe->is_buffer_referenced(pipe, buf); + return pipe->is_buffer_referenced(pipe, + ((struct r300_texture *)texture)->buffer); } static unsigned int @@ -86,7 +83,14 @@ r300_is_buffer_referenced(struct pipe_context *pipe, /* This only checks to see whether actual hardware buffers are * referenced. Since we use managed BOs and transfers, it's actually not * possible for pipe_buffers to ever reference the actual hardware, so - * buffers are never referenced. */ + * buffers are never referenced. + */ + + /* XXX: that doesn't make sense given that + * r300_is_texture_referenced is implemented on top of this + * function and hardware can certainly refer to textures + * directly... + */ return 0; } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 3b39207a455..93224e8d205 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -974,21 +974,3 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->video_surface_destroy= r300_video_surface_destroy; } -boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride) -{ - struct r300_texture* tex = (struct r300_texture*)texture; - if (!tex) { - return FALSE; - } - - pipe_buffer_reference(buffer, tex->buffer); - - if (stride) { - *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); - } - - return TRUE; -} diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 46a5fb6188b..138b62784e6 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -60,13 +60,11 @@ r300_video_surface(struct pipe_video_surface *pvs) return (struct r300_video_surface *)pvs; } -#ifndef R300_WINSYS_H - +/* Used internally for texture_is_referenced() + */ boolean r300_get_texture_buffer(struct pipe_screen* screen, struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); -#endif /* R300_WINSYS_H */ - #endif /* R300_TEXTURE_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 40fb8a95ca5..ddf2b790039 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -40,11 +40,6 @@ struct radeon_winsys; struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); -boolean r300_get_texture_buffer(struct pipe_screen* screen, - struct pipe_texture* texture, - struct pipe_buffer** buffer, - unsigned* stride); - #ifdef __cplusplus } #endif -- cgit v1.2.3 From 566390bedf4e5f24b5234e9dc08ecb1a6fd4d13b Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Thu, 4 Mar 2010 12:46:20 -0800 Subject: r300g: Fix indexbuf upper limits. Wine tends to pessimistically use ~0 for its max index, but r300s only can go up to 2^24-1, causing the kernel checker to freak out. Civ4 is marginally improved now. Still crashes, but not as bad. --- src/gallium/drivers/r300/r300_render.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 770a92be74f..6c891029a56 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -273,9 +273,14 @@ static void r300_emit_draw_elements(struct r300_context *r300, CS_LOCALS(r300); assert((start * indexSize) % 4 == 0); + assert(count < (1 << 24)); + + DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", + count, minIndex, maxIndex); + + maxIndex = MIN2(maxIndex, ((1 << 24) - 1)); if (alt_num_verts) { - assert(count < (1 << 24)); BEGIN_CS(16); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); } else { -- cgit v1.2.3 From c37a20416d681a3fea42a1a2ce907eb8e11ba795 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 6 Mar 2010 19:35:10 +0100 Subject: r300g: clamp vertex max index according to currently bound buffers --- src/gallium/drivers/r300/r300_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 6c891029a56..073664fa451 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -278,7 +278,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", count, minIndex, maxIndex); - maxIndex = MIN2(maxIndex, ((1 << 24) - 1)); + maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); if (alt_num_verts) { BEGIN_CS(16); -- cgit v1.2.3 From 09653d65e9650c3c04b3e8160b8f2ad7198fc122 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 6 Mar 2010 23:29:17 +0100 Subject: r300g: minor cleanups after the no-rhw merge --- src/gallium/drivers/r300/r300_state.c | 4 +--- src/gallium/drivers/r300/r300_state_derived.c | 10 ++++------ 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 1f6f99d3e52..4349bc1d507 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -716,8 +716,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->vap_control_status = R300_VC_32BIT_SWAP; #endif - /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL. - * Else, enable HW TCL and force Draw's TCL off. */ + /* If no TCL engine is present, turn off the HW TCL. */ if (!r300screen->caps->has_tcl) { rs->vap_control_status |= R300_VAP_TCL_BYPASS; } @@ -1121,7 +1120,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ r300->vap_output_state.dirty = TRUE; - r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */ r300->pvs_flush.dirty = TRUE; if (r300->fs) { diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 9c8e907fdf7..fc24cd58172 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -436,15 +436,14 @@ static void r300_update_derived_shader_state(struct r300_context* r300) struct r300_vap_output_state *vap_out = (struct r300_vap_output_state*)r300->vap_output_state.state; - /* XXX Mmm, delicious hax */ - memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); - memcpy(vap_out, vs->hwfmt, sizeof(uint)*4); - r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); if (r300screen->caps->has_tcl) { + memcpy(vap_out, vs->hwfmt, sizeof(uint)*4); r300_vertex_psc(r300); } else { + /* XXX set vap_out */ + memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); r300_draw_emit_all_attribs(r300); draw_compute_vertex_size(&r300->vertex_info); r300_swtcl_vertex_psc(r300); @@ -582,8 +581,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { if (r300->rs_block_state.dirty || - r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */ - r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */ + r300->vertex_stream_state.dirty) { /* XXX put updating PSC out of this file */ r300_update_derived_shader_state(r300); } -- cgit v1.2.3 From 6f4a19ca562ccd7e4bc2f7ea32263391abaa16bd Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 7 Mar 2010 01:12:57 +0100 Subject: r300g: abort if FS compilation fails on non-debug builds --- src/gallium/drivers/r300/r300_fs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 3c2625269b8..9e71e61c303 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -207,6 +207,7 @@ static void r300_translate_fragment_shader( DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n", compiler.Base.ErrorMsg); assert(0); + abort(); } /* And, finally... */ -- cgit v1.2.3 From 4f541db80c5ffff8932679a389a6043105f0b1be Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 7 Mar 2010 02:32:09 +0100 Subject: r300g: share the VS-output-mapping state with SWTCL And associated cleanups. --- src/gallium/drivers/r300/r300_state.c | 64 +++++----- src/gallium/drivers/r300/r300_state_derived.c | 4 - src/gallium/drivers/r300/r300_vs.c | 163 +++++++++----------------- src/gallium/drivers/r300/r300_vs.h | 13 +- 4 files changed, 96 insertions(+), 148 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 4349bc1d507..381676e09a6 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1087,67 +1087,71 @@ static void* r300_create_vs_state(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); - if (r300_screen(pipe->screen)->caps->has_tcl) { - struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); - /* Copy state directly into shader. */ - vs->state = *shader; - vs->state.tokens = tgsi_dup_tokens(shader->tokens); - - tgsi_scan_shader(shader->tokens, &vs->info); + struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); + r300_vertex_shader_common_init(vs, shader); - return (void*)vs; + if (r300_screen(pipe->screen)->caps->has_tcl) { + r300_translate_vertex_shader(r300, vs); } else { - return draw_create_vertex_shader(r300->draw, shader); + vs->draw_vs = draw_create_vertex_shader(r300->draw, shader); } + + return vs; } static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; - if (r300_screen(pipe->screen)->caps->has_tcl) { - struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; + if (vs == NULL) { + r300->vs_state.state = NULL; + return; + } + if (vs == r300->vs_state.state) { + return; + } + r300->vs_state.state = vs; - if (vs == NULL) { - r300->vs_state.state = NULL; - return; - } else if (!vs->translated) { - r300_translate_vertex_shader(r300, vs); - } + // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block + if (r300->fs) { + r300_vertex_shader_setup_wpos(r300); + } + memcpy(r300->vap_output_state.state, &vs->vap_out, + sizeof(struct r300_vap_output_state)); + r300->vap_output_state.dirty = TRUE; + + /* The majority of the RS block bits is dependent on the vertex shader. */ + r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ - UPDATE_STATE(shader, r300->vs_state); + if (r300_screen(pipe->screen)->caps->has_tcl) { + r300->vs_state.dirty = TRUE; r300->vs_state.size = vs->code.length + 9; - r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ - r300->vap_output_state.dirty = TRUE; r300->pvs_flush.dirty = TRUE; - if (r300->fs) { - r300_vertex_shader_setup_wpos(r300); - } - r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, - (struct draw_vertex_shader*)shader); + (struct draw_vertex_shader*)vs->draw_vs); } } static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; if (r300_screen(pipe->screen)->caps->has_tcl) { - struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; - rc_constants_destroy(&vs->code.constants); - FREE((void*)vs->state.tokens); - FREE(shader); } else { draw_delete_vertex_shader(r300->draw, - (struct draw_vertex_shader*)shader); + (struct draw_vertex_shader*)vs->draw_vs); } + + FREE((void*)vs->state.tokens); + FREE(shader); } static void r300_set_constant_buffer(struct pipe_context *pipe, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index fc24cd58172..e9e40747ef1 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -433,16 +433,12 @@ static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_screen* r300screen = r300_screen(r300->context.screen); - struct r300_vap_output_state *vap_out = - (struct r300_vap_output_state*)r300->vap_output_state.state; r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); if (r300screen->caps->has_tcl) { - memcpy(vap_out, vs->hwfmt, sizeof(uint)*4); r300_vertex_psc(r300); } else { - /* XXX set vap_out */ memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); r300_draw_emit_all_attribs(r300); draw_compute_vertex_size(&r300->vertex_info); diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index 60a04bbfeda..379939ac750 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -89,95 +89,41 @@ static void r300_shader_read_vs_outputs( assert(0); } } + + /* WPOS is a straight copy of POSITION and it's always emitted. */ + vs_outputs->wpos = i; } -static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs) +/* This function sets up: + * - VAP mapping, which maps VS registers to output semantics and + * at the same time it indicates which attributes are enabled and should + * be rasterized. + * - Stream mapping to VS outputs if TCL is not present. */ +static void r300_init_vs_output_mapping(struct r300_vertex_shader* vs) { struct r300_shader_semantics* vs_outputs = &vs->outputs; - uint32_t* hwfmt = vs->hwfmt; - int i, gen_count; + struct r300_vap_output_state *vap_out = &vs->vap_out; + int *stream_loc = vs->stream_loc_notcl; + int i, gen_count, tabi = 0; boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || vs_outputs->bcolor[1] != ATTR_UNUSED; - /* Do the actual vertex_info setup. - * - * vertex_info has four uints of hardware-specific data in it. - * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL - * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM - * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0 - * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */ - - hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */ + vap_out->vap_vtx_state_cntl = 0x5555; /* XXX this is classic Mesa bonghits */ /* Position. */ if (vs_outputs->pos != ATTR_UNUSED) { - hwfmt[1] |= R300_INPUT_CNTL_POS; - hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; + vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS; + vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; + + stream_loc[tabi++] = 0; } else { assert(0); } /* Point size. */ if (vs_outputs->psize != ATTR_UNUSED) { - hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; - } - - /* Colors. */ - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || - vs_outputs->color[1] != ATTR_UNUSED) { - hwfmt[1] |= R300_INPUT_CNTL_COLOR; - hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; - } - } - - /* Back-face colors. */ - if (any_bcolor_used) { - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - hwfmt[1] |= R300_INPUT_CNTL_COLOR; - hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); - } - } + vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; - /* Texture coordinates. */ - gen_count = 0; - for (i = 0; i < ATTR_GENERIC_COUNT; i++) { - if (vs_outputs->generic[i] != ATTR_UNUSED) { - hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count); - hwfmt[3] |= (4 << (3 * gen_count)); - gen_count++; - } - } - - /* Fog coordinates. */ - if (vs_outputs->fog != ATTR_UNUSED) { - hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count); - hwfmt[3] |= (4 << (3 * gen_count)); - gen_count++; - } - - /* XXX magic */ - assert(gen_count <= 8); - - /* WPOS. */ - vs->wpos_tex_output = gen_count; -} - -/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed - * or isn't present. */ -static void r300_stream_locations_notcl( - struct r300_shader_semantics* vs_outputs, - int* stream_loc) -{ - int i, tabi = 0, gen_count; - boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || - vs_outputs->bcolor[1] != ATTR_UNUSED; - - /* Position. */ - stream_loc[tabi++] = 0; - - /* Point size. */ - if (vs_outputs->psize != ATTR_UNUSED) { stream_loc[tabi++] = 1; } @@ -185,6 +131,9 @@ static void r300_stream_locations_notcl( for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || vs_outputs->color[1] != ATTR_UNUSED) { + vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; + vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; + stream_loc[tabi++] = 2 + i; } } @@ -192,6 +141,9 @@ static void r300_stream_locations_notcl( /* Back-face colors. */ if (any_bcolor_used) { for (i = 0; i < ATTR_COLOR_COUNT; i++) { + vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; + vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); + stream_loc[tabi++] = 4 + i; } } @@ -200,6 +152,9 @@ static void r300_stream_locations_notcl( gen_count = 0; for (i = 0; i < ATTR_GENERIC_COUNT; i++) { if (vs_outputs->generic[i] != ATTR_UNUSED) { + vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count); + vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count)); + assert(tabi < 16); stream_loc[tabi++] = 6 + gen_count; gen_count++; @@ -208,17 +163,22 @@ static void r300_stream_locations_notcl( /* Fog coordinates. */ if (vs_outputs->fog != ATTR_UNUSED) { + vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count); + vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count)); + assert(tabi < 16); stream_loc[tabi++] = 6 + gen_count; gen_count++; } + /* XXX magic */ + assert(gen_count <= 8); + /* WPOS. */ - if (vs_outputs->wpos != ATTR_UNUSED) { - assert(tabi < 16); - stream_loc[tabi++] = 6 + gen_count; - gen_count++; - } + vs->wpos_tex_output = gen_count; + + assert(tabi < 16); + stream_loc[tabi++] = 6 + gen_count; for (; tabi < 16;) { stream_loc[tabi++] = -1; @@ -294,26 +254,16 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) } } -static void r300_insert_wpos(struct r300_vertex_program_compiler* c, - struct r300_shader_semantics* outputs) +void r300_vertex_shader_common_init(struct r300_vertex_shader *vs, + const struct pipe_shader_state *shader) { - int i, lastOutput = 0; - - /* Find the max output index. */ - lastOutput = MAX2(lastOutput, outputs->psize); - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - lastOutput = MAX2(lastOutput, outputs->color[i]); - lastOutput = MAX2(lastOutput, outputs->bcolor[i]); - } - for (i = 0; i < ATTR_GENERIC_COUNT; i++) { - lastOutput = MAX2(lastOutput, outputs->generic[i]); - } - lastOutput = MAX2(lastOutput, outputs->fog); + /* Copy state directly into shader. */ + vs->state = *shader; + vs->state.tokens = tgsi_dup_tokens(shader->tokens); + tgsi_scan_shader(shader->tokens, &vs->info); - /* Set WPOS after the last output. */ - lastOutput++; - rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */ - outputs->wpos = lastOutput; + r300_shader_read_vs_outputs(&vs->info, &vs->outputs); + r300_init_vs_output_mapping(vs); } void r300_translate_vertex_shader(struct r300_context* r300, @@ -322,9 +272,6 @@ void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_program_compiler compiler; struct tgsi_to_rc ttr; - /* Initialize. */ - r300_shader_read_vs_outputs(&vs->info, &vs->outputs); - /* Setup the compiler */ rc_init(&compiler.Base); @@ -348,10 +295,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, compiler.SetHwInputOutput = &set_vertex_inputs_outputs; /* Insert the WPOS output. */ - r300_insert_wpos(&compiler, &vs->outputs); - - r300_shader_vap_output_fmt(vs); - r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl); + rc_copy_output(&compiler.Base, 0, vs->outputs.wpos); /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); @@ -363,30 +307,29 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* And, finally... */ rc_destroy(&compiler.Base); - vs->translated = TRUE; } boolean r300_vertex_shader_setup_wpos(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; + struct r300_vap_output_state *vap_out = &vs->vap_out; int tex_output = vs->wpos_tex_output; uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output; - uint32_t* hwfmt = vs->hwfmt; if (r300->fs->inputs.wpos != ATTR_UNUSED) { /* Enable WPOS in VAP. */ - if (!(hwfmt[1] & tex_fmt)) { - hwfmt[1] |= tex_fmt; - hwfmt[3] |= (4 << (3 * tex_output)); + if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) { + vap_out->vap_vsm_vtx_assm |= tex_fmt; + vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * tex_output)); assert(tex_output < 8); return TRUE; } } else { /* Disable WPOS in VAP. */ - if (hwfmt[1] & tex_fmt) { - hwfmt[1] &= ~tex_fmt; - hwfmt[3] &= ~(4 << (3 * tex_output)); + if (vap_out->vap_vsm_vtx_assm & tex_fmt) { + vap_out->vap_vsm_vtx_assm &= ~tex_fmt; + vap_out->vap_out_vtx_fmt[1] &= ~(4 << (3 * tex_output)); return TRUE; } } diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 18cfeee3cd4..f6f0b86b683 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -28,6 +28,7 @@ #include "tgsi/tgsi_scan.h" #include "radeon_code.h" +#include "r300_context.h" #include "r300_shader_semantics.h" struct r300_context; @@ -38,7 +39,7 @@ struct r300_vertex_shader { struct tgsi_shader_info info; struct r300_shader_semantics outputs; - uint hwfmt[4]; + struct r300_vap_output_state vap_out; /* Stream locations for SWTCL or if TCL is bypassed. */ int stream_loc_notcl[16]; @@ -46,13 +47,17 @@ struct r300_vertex_shader { /* Output stream location for WPOS. */ int wpos_tex_output; - /* Has this shader been translated yet? */ - boolean translated; - + /* HWTCL-specific. */ /* Machine code (if translated) */ struct r300_vertex_program_code code; + + /* SWTCL-specific. */ + void *draw_vs; }; +void r300_vertex_shader_common_init(struct r300_vertex_shader *vs, + const struct pipe_shader_state *shader); + void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs); -- cgit v1.2.3 From b03b70f6586baf3ff419be28817f61e6c4bacfb5 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 7 Mar 2010 02:40:57 +0100 Subject: r300g: validate buffers when using SWTCL --- src/gallium/drivers/r300/r300_render.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 073664fa451..c8420bcdd5b 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -186,7 +186,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, dwords = 10 + count * vertex_size; r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); - r300_emit_buffer_validate(r300, FALSE, 0); + r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_dirty_state(r300); BEGIN_CS(dwords); @@ -450,7 +450,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, /* Make sure there are at least 128 spare dwords in the command buffer. * (most of it being consumed by emit_aos) */ r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128); - r300_emit_buffer_validate(r300, TRUE, 0); + r300_emit_buffer_validate(r300, TRUE, NULL); r300_emit_dirty_state(r300); if (alt_num_verts || count <= 65535) { @@ -468,7 +468,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, /* Again, we emit both AOS and draw_arrays so there should be * at least 128 spare dwords. */ if (count && r300_reserve_cs_space(r300, 128)) { - r300_emit_buffer_validate(r300, TRUE, 0); + r300_emit_buffer_validate(r300, TRUE, NULL); r300_emit_dirty_state(r300); } } while (count); @@ -688,6 +688,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render, CS_LOCALS(r300); r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2); + r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_dirty_state(r300); DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); @@ -711,6 +712,7 @@ static void r300_render_draw(struct vbuf_render* render, CS_LOCALS(r300); r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); + r300_emit_buffer_validate(r300, FALSE, NULL); r300_emit_dirty_state(r300); BEGIN_CS(dwords); -- cgit v1.2.3 From 81992f37da64c2c89ce108e6b17159eee6085e5d Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 7 Mar 2010 03:00:07 +0100 Subject: r300g: resurrect r300_emit_vertex_buffer for SWTCL Taken over from c9928ac3ee5dc0d10127388f9312779a6c59da7c. --- src/gallium/drivers/r300/r300_emit.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index addb28bded3..03da4754b72 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -794,6 +794,30 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) END_CS; } +void r300_emit_vertex_buffer(struct r300_context* r300) +{ + CS_LOCALS(r300); + + DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, " + "vertex size %d\n", r300->vbo, + r300->vertex_info.size); + /* Set the pointer to our vertex buffer. The emitted values are this: + * PACKET3 [3D_LOAD_VBPNTR] + * COUNT [1] + * FORMAT [size | stride << 8] + * OFFSET [offset into BO] + * VBPNTR [relocated BO] + */ + BEGIN_CS(7); + OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); + OUT_CS(1); + OUT_CS(r300->vertex_info.size | + (r300->vertex_info.size << 8)); + OUT_CS(r300->vbo_offset); + OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); + END_CS; +} + void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state) { @@ -1135,8 +1159,10 @@ void r300_emit_dirty_state(struct r300_context* r300) assert(r300->dirty_state == 0); */ - /* Finally, emit the VBO. */ - /* r300_emit_vertex_buffer(r300); */ + /* Emit the VBO for SWTCL. */ + if (!r300screen->caps->has_tcl) { + r300_emit_vertex_buffer(r300); + } r300->dirty_hw++; } -- cgit v1.2.3 From 690ded32cdda4363c30aca32ef94383ba356a3c5 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 7 Mar 2010 03:17:58 +0100 Subject: r300g: disable emitting the HWTCL-related state when SWTCL is in use Now SWTCL renders at least "something", we're close... --- src/gallium/drivers/r300/r300_context.c | 1 - src/gallium/drivers/r300/r300_emit.c | 4 ++-- src/gallium/drivers/r300/r300_flush.c | 6 ++++++ src/gallium/drivers/r300/r300_state.c | 6 ++++-- 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 86b98a4ba52..ec1c5865220 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -212,7 +212,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->invariant_state.dirty = TRUE; r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); - r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw++; r300->blitter = util_blitter_create(&r300->context); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 03da4754b72..a1d31d57b83 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -892,7 +892,7 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) CS_LOCALS(r300); if (!r300screen->caps->has_tcl) { - debug_printf("r300: Implementation error: emit_vertex_shader called," + debug_printf("r300: Implementation error: emit_vs_state called," " but has_tcl is FALSE!\n"); return; } @@ -931,7 +931,7 @@ void r300_emit_vs_constant_buffer(struct r300_context* r300, CS_LOCALS(r300); if (!r300screen->caps->has_tcl) { - debug_printf("r300: Implementation error: emit_vertex_shader called," + debug_printf("r300: Implementation error: emit_vs_constant_buffer called," " but has_tcl is FALSE!\n"); return; } diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index e37d3092703..70de152713d 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -61,6 +61,12 @@ static void r300_flush(struct pipe_context* pipe, atom->dirty = TRUE; } } + + /* Unmark HWTCL state for SWTCL. */ + if (!r300_screen(pipe->screen)->caps->has_tcl) { + r300->vs_state.dirty = FALSE; + r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS; + } } /* reset flushed query */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 381676e09a6..de3ee0eefb9 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1203,8 +1203,10 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, pipe_buffer_unmap(pipe->screen, buf); if (shader == PIPE_SHADER_VERTEX) { - r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; - r300->pvs_flush.dirty = TRUE; + if (r300screen->caps->has_tcl) { + r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; + r300->pvs_flush.dirty = TRUE; + } } else if (shader == PIPE_SHADER_FRAGMENT) r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; -- cgit v1.2.3 From 4012219f1f215cec9406be644b6b9d421bb5d8e4 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 6 Feb 2010 03:11:50 +0100 Subject: r300g: move r300_transfer to separate files --- src/gallium/drivers/r300/Makefile | 3 +- src/gallium/drivers/r300/SConscript | 1 + src/gallium/drivers/r300/r300_screen.c | 74 ++-------------------- src/gallium/drivers/r300/r300_screen.h | 16 +---- src/gallium/drivers/r300/r300_transfer.c | 101 +++++++++++++++++++++++++++++++ src/gallium/drivers/r300/r300_transfer.h | 60 ++++++++++++++++++ 6 files changed, 171 insertions(+), 84 deletions(-) create mode 100644 src/gallium/drivers/r300/r300_transfer.c create mode 100644 src/gallium/drivers/r300/r300_transfer.h (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 1f69daec819..61b54af4ddf 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -19,7 +19,8 @@ C_SOURCES = \ r300_state_invariant.c \ r300_vs.c \ r300_texture.c \ - r300_tgsi_to_rc.c + r300_tgsi_to_rc.c \ + r300_transfer.c LIBRARY_INCLUDES = \ -I$(TOP)/src/mesa/drivers/dri/r300/compiler \ diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 183aa17f9b3..27b2e309932 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -30,6 +30,7 @@ r300 = env.ConvenienceLibrary( 'r300_vs.c', 'r300_texture.c', 'r300_tgsi_to_rc.c', + 'r300_transfer.c', ] + r300compiler) + r300compiler Export('r300') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index d397a8eb2b4..a35be05940d 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson + * Copyright 2010 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"), @@ -20,14 +21,13 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_simple_screen.h" #include "r300_context.h" -#include "r300_screen.h" #include "r300_texture.h" +#include "r300_transfer.h" #include "radeon_winsys.h" #include "r300_winsys.h" @@ -250,70 +250,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, return retval == usage; } -static struct pipe_transfer* -r300_get_tex_transfer(struct pipe_screen *screen, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, unsigned x, unsigned y, - unsigned w, unsigned h) -{ - struct r300_texture *tex = (struct r300_texture *)texture; - struct r300_transfer *trans; - struct r300_screen *rscreen = r300_screen(screen); - unsigned offset; - - offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */ - - trans = CALLOC_STRUCT(r300_transfer); - if (trans) { - pipe_texture_reference(&trans->transfer.texture, texture); - trans->transfer.x = x; - trans->transfer.y = y; - trans->transfer.width = w; - trans->transfer.height = h; - trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level); - trans->transfer.usage = usage; - trans->transfer.zslice = zslice; - trans->transfer.face = face; - - trans->offset = offset; - } - return &trans->transfer; -} - -static void -r300_tex_transfer_destroy(struct pipe_transfer *trans) -{ - pipe_texture_reference(&trans->texture, NULL); - FREE(trans); -} - -static void* r300_transfer_map(struct pipe_screen* screen, - struct pipe_transfer* transfer) -{ - struct r300_texture* tex = (struct r300_texture*)transfer->texture; - char* map; - enum pipe_format format = tex->tex.format; - - map = pipe_buffer_map(screen, tex->buffer, - pipe_transfer_buffer_flags(transfer)); - - if (!map) { - return NULL; - } - - return map + r300_transfer(transfer)->offset + - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); -} - -static void r300_transfer_unmap(struct pipe_screen* screen, - struct pipe_transfer* transfer) -{ - struct r300_texture* tex = (struct r300_texture*)transfer->texture; - pipe_buffer_unmap(screen, tex->buffer); -} - static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); @@ -350,13 +286,11 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) r300screen->screen.get_paramf = r300_get_paramf; r300screen->screen.is_format_supported = r300_is_format_supported; r300screen->screen.context_create = r300_create_context; - r300screen->screen.get_tex_transfer = r300_get_tex_transfer; - r300screen->screen.tex_transfer_destroy = r300_tex_transfer_destroy; - r300screen->screen.transfer_map = r300_transfer_map; - r300screen->screen.transfer_unmap = r300_transfer_unmap; r300_init_screen_texture_functions(&r300screen->screen); + r300_init_screen_transfer_functions(&r300screen->screen); u_simple_screen_init(&r300screen->screen); return &r300screen->screen; } + diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 502fbfa5a24..6d72fec7788 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson + * Copyright 2010 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"), @@ -42,25 +43,14 @@ struct r300_screen { unsigned debug; }; -struct r300_transfer { - /* Parent class */ - struct pipe_transfer transfer; - - /* Offset from start of buffer. */ - unsigned offset; -}; /* Convenience cast wrapper. */ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) { return (struct r300_screen*)screen; } -/* Convenience cast wrapper. */ -static INLINE struct r300_transfer* -r300_transfer(struct pipe_transfer* transfer) -{ - return (struct r300_transfer*)transfer; -} +/* Creates a new r300 screen. */ +struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); /* Debug functionality. */ diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c new file mode 100644 index 00000000000..fa48688db28 --- /dev/null +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -0,0 +1,101 @@ +/* + * Copyright 2008 Corbin Simpson + * Copyright 2010 Marek Olšák + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_context.h" +#include "r300_transfer.h" +#include "r300_texture.h" +#include "r300_screen.h" + +#include "util/u_memory.h" +#include "util/u_format.h" + +static struct pipe_transfer* +r300_get_tex_transfer(struct pipe_screen *screen, + struct pipe_texture *texture, + unsigned face, unsigned level, unsigned zslice, + enum pipe_transfer_usage usage, unsigned x, unsigned y, + unsigned w, unsigned h) +{ + struct r300_texture *tex = (struct r300_texture *)texture; + struct r300_transfer *trans; + struct r300_screen *rscreen = r300_screen(screen); + unsigned offset; + + offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */ + + trans = CALLOC_STRUCT(r300_transfer); + if (trans) { + pipe_texture_reference(&trans->transfer.texture, texture); + trans->transfer.x = x; + trans->transfer.y = y; + trans->transfer.width = w; + trans->transfer.height = h; + trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level); + trans->transfer.usage = usage; + trans->transfer.zslice = zslice; + trans->transfer.face = face; + + trans->offset = offset; + } + return &trans->transfer; +} + +static void r300_tex_transfer_destroy(struct pipe_transfer *trans) +{ + pipe_texture_reference(&trans->texture, NULL); + FREE(trans); +} + +static void* r300_transfer_map(struct pipe_screen *screen, + struct pipe_transfer *transfer) +{ + struct r300_texture *tex = (struct r300_texture*)transfer->texture; + char *map; + enum pipe_format format = tex->tex.format; + + map = pipe_buffer_map(screen, tex->buffer, + pipe_transfer_buffer_flags(transfer)); + + if (!map) { + return NULL; + } + + return map + r300_transfer(transfer)->offset + + transfer->y / util_format_get_blockheight(format) * transfer->stride + + transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); +} + +static void r300_transfer_unmap(struct pipe_screen *screen, + struct pipe_transfer *transfer) +{ + struct r300_texture *tex = (struct r300_texture*)transfer->texture; + pipe_buffer_unmap(screen, tex->buffer); +} + +void r300_init_screen_transfer_functions(struct pipe_screen *screen) +{ + screen->get_tex_transfer = r300_get_tex_transfer; + screen->tex_transfer_destroy = r300_tex_transfer_destroy; + screen->transfer_map = r300_transfer_map; + screen->transfer_unmap = r300_transfer_unmap; +} diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h new file mode 100644 index 00000000000..faf62338efb --- /dev/null +++ b/src/gallium/drivers/r300/r300_transfer.h @@ -0,0 +1,60 @@ +/* + * Copyright 2008 Corbin Simpson + * Copyright 2010 Marek Olšák + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_TRANSFER +#define R300_TRANSFER + +#include "pipe/p_screen.h" +#include "pipe/p_state.h" + +struct r300_texture; +struct r300_screen; + +struct r300_transfer { + /* Parent class */ + struct pipe_transfer transfer; + + /* Parameters of get_tex_transfer. */ + unsigned x, y, level, zslice, face; + + /* Offset from start of buffer. */ + unsigned offset; + + /* Untiled texture. */ + struct r300_texture *untiled_texture; + + /* Transfer and format flags. */ + unsigned buffer_usage, render_target_usage; +}; + +/* Convenience cast wrapper. */ +static INLINE struct r300_transfer* +r300_transfer(struct pipe_transfer* transfer) +{ + return (struct r300_transfer*)transfer; +} + +void r300_init_screen_transfer_functions(struct pipe_screen *screen); + +#endif + -- cgit v1.2.3 From 6c7fac846ef99cde5305cf1011b4570bd1901625 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 14 Feb 2010 03:19:01 +0100 Subject: r300g: add ability to tile/detile textures using blit during transfers --- src/gallium/drivers/r300/r300_context.c | 2 + src/gallium/drivers/r300/r300_screen.h | 6 + src/gallium/drivers/r300/r300_texture.c | 5 +- src/gallium/drivers/r300/r300_transfer.c | 210 +++++++++++++++++++++++++++---- src/gallium/drivers/r300/r300_transfer.h | 29 ----- 5 files changed, 197 insertions(+), 55 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index ec1c5865220..e43e088b368 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -159,6 +159,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, if (!r300) return NULL; + r300screen->ctx = (struct pipe_context*)r300; + r300->winsys = radeon_winsys; r300->context.winsys = (struct pipe_winsys*)radeon_winsys; diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 6d72fec7788..484bde6a6be 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -28,6 +28,8 @@ #include "r300_chipset.h" +#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM + struct radeon_winsys; struct r300_screen { @@ -36,6 +38,10 @@ struct r300_screen { struct radeon_winsys* radeon_winsys; + /* XXX This hack will be removed once texture transfers become part of + * pipe_context. */ + struct pipe_context* ctx; + /* Chipset capabilities */ struct r300_capabilities* caps; diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index c0144f64b4a..04e326eb787 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -725,9 +725,8 @@ static void r300_setup_flags(struct r300_texture* tex) } /* Create a new texture. */ -static struct pipe_texture* - r300_texture_create(struct pipe_screen* screen, - const struct pipe_texture* template) +static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, + const struct pipe_texture* template) { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); struct r300_screen* rscreen = r300_screen(screen); diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index fa48688db28..56a6976e8b6 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -29,6 +29,89 @@ #include "util/u_memory.h" #include "util/u_format.h" +struct r300_transfer { + /* Parent class */ + struct pipe_transfer transfer; + + /* Pipe context. */ + struct pipe_context *ctx; + + /* Parameters of get_tex_transfer. */ + unsigned x, y, level, zslice, face; + + /* Offset from start of buffer. */ + unsigned offset; + + /* Detiled texture. */ + struct r300_texture *detiled_texture; + + /* Transfer and format flags. */ + unsigned buffer_usage, render_target_usage; +}; + +/* Convenience cast wrapper. */ +static INLINE struct r300_transfer* +r300_transfer(struct pipe_transfer* transfer) +{ + return (struct r300_transfer*)transfer; +} + +/* Copy from a tiled texture to a detiled one. */ +static void r300_copy_from_tiled_texture(struct pipe_context *ctx, + struct r300_transfer *r300transfer) +{ + struct pipe_screen *screen = ctx->screen; + struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; + struct pipe_texture *tex = transfer->texture; + struct pipe_surface *src, *dst; + + src = screen->get_tex_surface(screen, tex, r300transfer->face, + r300transfer->level, r300transfer->zslice, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_PIXEL); + + dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex, + 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_PIXEL | + r300transfer->buffer_usage); + + ctx->surface_copy(ctx, dst, 0, 0, src, r300transfer->x, r300transfer->y, + transfer->width, transfer->height); + + pipe_surface_reference(&src, NULL); + pipe_surface_reference(&dst, NULL); +} + +/* Copy a detiled texture to a tiled one. */ +static void r300_copy_into_tiled_texture(struct pipe_context *ctx, + struct r300_transfer *r300transfer) +{ + struct pipe_screen *screen = ctx->screen; + struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; + struct pipe_texture *tex = transfer->texture; + struct pipe_surface *src, *dst; + + src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex, + 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_PIXEL); + + dst = screen->get_tex_surface(screen, tex, r300transfer->face, + r300transfer->level, r300transfer->zslice, + PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_PIXEL); + + ctx->surface_copy(ctx, dst, r300transfer->x, r300transfer->y, src, 0, 0, + transfer->width, transfer->height); + + /* XXX this flush fixes lots of regressions, not sure why */ + ctx->flush(ctx, 0, NULL); + + pipe_surface_reference(&src, NULL); + pipe_surface_reference(&dst, NULL); +} + static struct pipe_transfer* r300_get_tex_transfer(struct pipe_screen *screen, struct pipe_texture *texture, @@ -38,58 +121,139 @@ r300_get_tex_transfer(struct pipe_screen *screen, { struct r300_texture *tex = (struct r300_texture *)texture; struct r300_transfer *trans; - struct r300_screen *rscreen = r300_screen(screen); - unsigned offset; - - offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */ + struct r300_screen *r300screen = r300_screen(screen); + struct pipe_texture template; trans = CALLOC_STRUCT(r300_transfer); if (trans) { + /* Initialize the transfer object. */ pipe_texture_reference(&trans->transfer.texture, texture); - trans->transfer.x = x; - trans->transfer.y = y; + trans->transfer.usage = usage; trans->transfer.width = w; trans->transfer.height = h; - trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level); - trans->transfer.usage = usage; - trans->transfer.zslice = zslice; - trans->transfer.face = face; + trans->ctx = r300screen->ctx; + trans->x = x; + trans->y = y; + trans->level = level; + trans->zslice = zslice; + trans->face = face; + + /* If the texture is tiled, we must create a temporary detiled texture + * for this transfer. */ + if (tex->microtile || tex->macrotile) { + trans->buffer_usage = pipe_transfer_buffer_flags(&trans->transfer); + trans->render_target_usage = + util_format_is_depth_or_stencil(texture->format) ? + PIPE_TEXTURE_USAGE_DEPTH_STENCIL : + PIPE_TEXTURE_USAGE_RENDER_TARGET; + + template.target = PIPE_TEXTURE_2D; + template.format = texture->format; + template.width0 = w; + template.height0 = h; + template.depth0 = 0; + template.last_level = 0; + template.nr_samples = 0; + template.tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | + R300_TEXTURE_USAGE_TRANSFER; - trans->offset = offset; + /* For texture reading, the temporary (detiled) texture is used as + * a render target when blitting from a tiled texture. */ + if (usage & PIPE_TRANSFER_READ) { + template.tex_usage |= trans->render_target_usage; + } + /* For texture writing, the temporary texture is used as a sampler + * when blitting into a tiled texture. */ + if (usage & PIPE_TRANSFER_WRITE) { + template.tex_usage |= PIPE_TEXTURE_USAGE_SAMPLER; + } + + /* Create the temporary texture. */ + trans->detiled_texture = + (struct r300_texture*)screen->texture_create(screen, &template); + assert(!trans->detiled_texture->microtile && + !trans->detiled_texture->macrotile); + + /* Set the stride. + * Parameters x, y, level, zslice, and face remain zero. */ + trans->transfer.stride = + r300_texture_get_stride(r300screen, trans->detiled_texture, 0); + + if (usage & PIPE_TRANSFER_READ) { + /* We cannot map a tiled texture directly because the data is + * in a different order, therefore we do detiling using a blit. */ + r300_copy_from_tiled_texture(r300screen->ctx, trans); + } + } else { + trans->transfer.x = x; + trans->transfer.y = y; + trans->transfer.stride = + r300_texture_get_stride(r300screen, tex, level); + trans->transfer.level = level; + trans->transfer.zslice = zslice; + trans->transfer.face = face; + trans->offset = r300_texture_get_offset(tex, level, zslice, face); + } } return &trans->transfer; } static void r300_tex_transfer_destroy(struct pipe_transfer *trans) { - pipe_texture_reference(&trans->texture, NULL); - FREE(trans); + struct r300_transfer *r300transfer = r300_transfer(trans); + + if (r300transfer->detiled_texture) { + if (trans->usage & PIPE_TRANSFER_WRITE) { + r300_copy_into_tiled_texture(r300transfer->ctx, r300transfer); + } + + pipe_texture_reference( + (struct pipe_texture**)&r300transfer->detiled_texture, NULL); + } + pipe_texture_reference(&trans->texture, NULL); + FREE(trans); } static void* r300_transfer_map(struct pipe_screen *screen, - struct pipe_transfer *transfer) + struct pipe_transfer *transfer) { + struct r300_transfer *r300transfer = r300_transfer(transfer); struct r300_texture *tex = (struct r300_texture*)transfer->texture; char *map; enum pipe_format format = tex->tex.format; - map = pipe_buffer_map(screen, tex->buffer, - pipe_transfer_buffer_flags(transfer)); + if (r300transfer->detiled_texture) { + /* The detiled texture is of the same size as the region being mapped + * (no offset needed). */ + return pipe_buffer_map(screen, + r300transfer->detiled_texture->buffer, + pipe_transfer_buffer_flags(transfer)); + } else { + /* Tiling is disabled. */ + map = pipe_buffer_map(screen, tex->buffer, + pipe_transfer_buffer_flags(transfer)); - if (!map) { - return NULL; - } + if (!map) { + return NULL; + } - return map + r300_transfer(transfer)->offset + - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + return map + r300_transfer(transfer)->offset + + transfer->y / util_format_get_blockheight(format) * transfer->stride + + transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + } } static void r300_transfer_unmap(struct pipe_screen *screen, struct pipe_transfer *transfer) { + struct r300_transfer *r300transfer = r300_transfer(transfer); struct r300_texture *tex = (struct r300_texture*)transfer->texture; - pipe_buffer_unmap(screen, tex->buffer); + + if (r300transfer->detiled_texture) { + pipe_buffer_unmap(screen, r300transfer->detiled_texture->buffer); + } else { + pipe_buffer_unmap(screen, tex->buffer); + } } void r300_init_screen_transfer_functions(struct pipe_screen *screen) diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h index faf62338efb..60d1d3dc85c 100644 --- a/src/gallium/drivers/r300/r300_transfer.h +++ b/src/gallium/drivers/r300/r300_transfer.h @@ -25,36 +25,7 @@ #define R300_TRANSFER #include "pipe/p_screen.h" -#include "pipe/p_state.h" - -struct r300_texture; -struct r300_screen; - -struct r300_transfer { - /* Parent class */ - struct pipe_transfer transfer; - - /* Parameters of get_tex_transfer. */ - unsigned x, y, level, zslice, face; - - /* Offset from start of buffer. */ - unsigned offset; - - /* Untiled texture. */ - struct r300_texture *untiled_texture; - - /* Transfer and format flags. */ - unsigned buffer_usage, render_target_usage; -}; - -/* Convenience cast wrapper. */ -static INLINE struct r300_transfer* -r300_transfer(struct pipe_transfer* transfer) -{ - return (struct r300_transfer*)transfer; -} void r300_init_screen_transfer_functions(struct pipe_screen *screen); #endif - -- cgit v1.2.3 From b37d63337596aabc543ea7ecfa82f0f9fdbade69 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 14 Feb 2010 04:57:09 +0100 Subject: r300g: enable micro- and macrotiling for all textures and renderbuffers --- src/gallium/drivers/r300/r300_texture.c | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 04e326eb787..0736155d528 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -724,6 +724,42 @@ static void r300_setup_flags(struct r300_texture* tex) !util_is_power_of_two(tex->tex.height0); } +static void r300_setup_tiling(struct pipe_screen *screen, + struct r300_texture *tex) +{ + enum pipe_format format = tex->tex.format; + boolean rv350_mode = r300_screen(screen)->caps->family >= CHIP_FAMILY_RV350; + + if (util_format_is_compressed(format)) { + return; + } + + if (tex->tex.width0 == 1 || + tex->tex.height0 == 1) { + return; + } + + /* Set microtiling. */ + switch (util_format_get_blocksize(format)) { + case 1: + case 4: + tex->microtile = R300_BUFFER_TILED; + break; + + /* XXX Square-tiling doesn't work with kernel older than 2.6.34, + * XXX need to check the DRM version */ + /*case 2: + case 8: + tex->microtile = R300_BUFFER_SQUARETILED; + break;*/ + } + + /* Set macrotiling. */ + if (r300_texture_macro_switch(tex, 0, rv350_mode)) { + tex->macrotile = R300_BUFFER_TILED; + } +} + /* Create a new texture. */ static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, const struct pipe_texture* template) @@ -741,6 +777,9 @@ static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, tex->tex.screen = screen; r300_setup_flags(tex); + if (!(template->tex_usage & R300_TEXTURE_USAGE_TRANSFER)) { + r300_setup_tiling(screen, tex); + } r300_setup_miptree(rscreen, tex); r300_setup_texture_state(rscreen, tex); -- cgit v1.2.3 From 57a1395ec3f8eb01af6cfea3fd6b5903dcc61720 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 19 Feb 2010 03:02:34 +0100 Subject: r300g: disable macrotiling when the texture height is smaller than a macrotile Otherwise incorrect rendering occurs (no idea why). --- src/gallium/drivers/r300/r300_texture.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 0736155d528..c0da339916e 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -617,18 +617,23 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex, /* Return true if macrotiling should be enabled on the miplevel. */ static boolean r300_texture_macro_switch(struct r300_texture *tex, unsigned level, - boolean rv350_mode) + boolean rv350_mode, + int dim) { - unsigned tile_width, width; + unsigned tile, texdim; - tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE); - width = u_minify(tex->tex.width0, level); + tile = r300_texture_get_tile_size(tex, dim, TRUE); + if (dim == TILE_WIDTH) { + texdim = u_minify(tex->tex.width0, level); + } else { + texdim = u_minify(tex->tex.height0, level); + } /* See TX_FILTER1_n.MACRO_SWITCH. */ if (rv350_mode) { - return width >= tile_width; + return texdim >= tile; } else { - return width > tile_width; + return texdim > tile; } } @@ -692,9 +697,10 @@ static void r300_setup_miptree(struct r300_screen* screen, for (i = 0; i <= base->last_level; i++) { /* Let's see if this miplevel can be macrotiled. */ - tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED && - r300_texture_macro_switch(tex, i, rv350_mode)) ? - R300_BUFFER_TILED : R300_BUFFER_LINEAR; + tex->mip_macrotile[i] = + (tex->macrotile == R300_BUFFER_TILED && + r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH)) ? + R300_BUFFER_TILED : R300_BUFFER_LINEAR; stride = r300_texture_get_stride(screen, tex, i); nblocksy = r300_texture_get_nblocksy(tex, i); @@ -755,7 +761,8 @@ static void r300_setup_tiling(struct pipe_screen *screen, } /* Set macrotiling. */ - if (r300_texture_macro_switch(tex, 0, rv350_mode)) { + if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) && + r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) { tex->macrotile = R300_BUFFER_TILED; } } -- cgit v1.2.3 From 6b39abb63acba34f0f4f017f06b0c90da79e6e70 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 23 Feb 2010 01:14:44 +0100 Subject: r300g: fix DRM errors --- src/gallium/drivers/r300/r300_transfer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 56a6976e8b6..ec89681a3c0 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -102,10 +102,15 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, PIPE_BUFFER_USAGE_GPU_WRITE | PIPE_BUFFER_USAGE_PIXEL); + /* XXX this flush prevents the following DRM error from occuring: + * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation ! + * Reproducible with perf/copytex. */ + ctx->flush(ctx, 0, NULL); + ctx->surface_copy(ctx, dst, r300transfer->x, r300transfer->y, src, 0, 0, transfer->width, transfer->height); - /* XXX this flush fixes lots of regressions, not sure why */ + /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */ ctx->flush(ctx, 0, NULL); pipe_surface_reference(&src, NULL); -- cgit v1.2.3 From 6abe6145fb3b642fc2ae1d6ad2cc9de045efe0cb Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 8 Mar 2010 04:31:03 +0100 Subject: r300g: remove unnecessary state emissions and clean up --- src/gallium/drivers/r300/r300_context.h | 2 ++ src/gallium/drivers/r300/r300_emit.c | 2 +- src/gallium/drivers/r300/r300_state.c | 37 ++++++++++++++++++++------------- 3 files changed, 26 insertions(+), 15 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 0d1518a05bc..8c52d880a36 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -368,6 +368,8 @@ struct r300_context { boolean polygon_offset_enabled; /* Z buffer bit depth. */ uint32_t zbuffer_bpp; + /* Whether scissor is enabled. */ + boolean scissor_enabled; }; /* Convenience cast wrapper. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index a1d31d57b83..51fc590e5d9 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -675,7 +675,7 @@ void r300_emit_scissor_state(struct r300_context* r300, maxx = fb->width; maxy = fb->height; - if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) { + if (r300->scissor_enabled) { minx = MAX2(minx, scissor->minx); miny = MAX2(miny, scissor->miny); maxx = MIN2(maxx, scissor->maxx); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index de3ee0eefb9..31259b557fc 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -571,6 +571,7 @@ static void { struct r300_context* r300 = r300_context(pipe); struct r300_screen* r300screen = r300_screen(pipe->screen); + struct pipe_framebuffer_state *old_state = r300->fb_state.state; unsigned max_width, max_height; uint32_t zbuffer_bpp = 0; @@ -595,11 +596,24 @@ static void return; } - if (r300->draw) { draw_flush(r300->draw); } + r300->fb_state.dirty = TRUE; + + /* If nr_cbufs is changed from zero to non-zero or vice versa... */ + if (!!old_state->nr_cbufs != !!state->nr_cbufs) { + r300->blend_state.dirty = TRUE; + } + /* If zsbuf is set from NULL to non-NULL or vice versa.. */ + if (!!old_state->zsbuf != !!state->zsbuf) { + r300->dsa_state.dirty = TRUE; + } + if (!r300->scissor_enabled) { + r300->scissor_state.dirty = TRUE; + } + memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) + @@ -607,11 +621,6 @@ static void r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); - /* XXX wait what */ - r300->blend_state.dirty = TRUE; - r300->dsa_state.dirty = TRUE; - r300->fb_state.dirty = TRUE; - r300->scissor_state.dirty = TRUE; /* Polygon offset depends on the zbuffer bit depth. */ if (state->zsbuf && r300->polygon_offset_enabled) { @@ -806,6 +815,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) { struct r300_context* r300 = r300_context(pipe); struct r300_rs_state* rs = (struct r300_rs_state*)state; + boolean scissor_was_enabled = r300->scissor_enabled; if (r300->draw) { draw_flush(r300->draw); @@ -814,20 +824,17 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) if (rs) { r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; + r300->scissor_enabled = rs->rs.scissor; } else { r300->polygon_offset_enabled = FALSE; + r300->scissor_enabled = FALSE; } UPDATE_STATE(state, r300->rs_state); r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0); - /* XXX Why is this still needed, dammit!? */ - r300->scissor_state.dirty = TRUE; - r300->viewport_state.dirty = TRUE; - - /* XXX Clean these up when we move to atom emits */ - if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) { - r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; + if (scissor_was_enabled != r300->scissor_enabled) { + r300->scissor_state.dirty = TRUE; } } @@ -972,7 +979,9 @@ static void r300_set_scissor_state(struct pipe_context* pipe, memcpy(r300->scissor_state.state, state, sizeof(struct pipe_scissor_state)); - r300->scissor_state.dirty = TRUE; + if (r300->scissor_enabled) { + r300->scissor_state.dirty = TRUE; + } } static void r300_set_viewport_state(struct pipe_context* pipe, -- cgit v1.2.3 From 9860f652e271d03672ec3e5f0e379170953a1e56 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 8 Mar 2010 04:38:16 +0100 Subject: r300g: fix updating the tiling flags for the framebuffer state --- src/gallium/drivers/r300/r300_state.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 31259b557fc..8c9f6046228 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -614,14 +614,13 @@ static void r300->scissor_state.dirty = TRUE; } + r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); + memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) + (state->zsbuf ? 10 : 0) + 8; - r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); - - /* Polygon offset depends on the zbuffer bit depth. */ if (state->zsbuf && r300->polygon_offset_enabled) { switch (util_format_get_blocksize(state->zsbuf->texture->format)) { -- cgit v1.2.3 From ac2e8491117dcf4a608eff4f52a9e34c1bea2a03 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 8 Mar 2010 14:01:30 -0700 Subject: r300g: define R300_MAX_TEXTURE_LEVELS --- src/gallium/drivers/r300/r300_context.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8c52d880a36..c2825d5f267 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -124,13 +124,15 @@ struct r300_texture_format_state { uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */ }; +#define R300_MAX_TEXTURE_LEVELS 13 + struct r300_texture_fb_state { /* Colorbuffer. */ - uint32_t colorpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/ + uint32_t colorpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/ uint32_t us_out_fmt; /* R300_US_OUT_FMT[0-3] */ /* Zbuffer. */ - uint32_t depthpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */ + uint32_t depthpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */ uint32_t zb_format; /* R300_ZB_FORMAT */ }; @@ -236,16 +238,16 @@ struct r300_texture { struct pipe_texture tex; /* Offsets into the buffer. */ - unsigned offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned offset[R300_MAX_TEXTURE_LEVELS]; /* A pitch for each mip-level */ - unsigned pitch[PIPE_MAX_TEXTURE_LEVELS]; + unsigned pitch[R300_MAX_TEXTURE_LEVELS]; /* Size of one zslice or face based on the texture target */ - unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS]; + unsigned layer_size[R300_MAX_TEXTURE_LEVELS]; /* Whether the mipmap level is macrotiled. */ - enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS]; + enum r300_buffer_tiling mip_macrotile[R300_MAX_TEXTURE_LEVELS]; /** * If non-zero, override the natural texture layout with -- cgit v1.2.3 From 821c830f11fc1c3529a186ace1d1ba3ddeab4957 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 9 Mar 2010 02:10:36 +0100 Subject: r300g: remove hacks from translate_vertex_data_swizzle The first part of the fix of BGRA vertex colors. --- src/gallium/drivers/r300/r300_state_inlines.h | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 2f3a56e1fbc..af7827820cc 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -453,7 +453,6 @@ r300_translate_vertex_data_type(enum pipe_format format) { static INLINE uint16_t r300_translate_vertex_data_swizzle(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); - unsigned swizzle[4], i; assert(format); @@ -463,25 +462,10 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) { return 0; } - /* Swizzles for 8bits formats are in the reversed order, not sure why. */ - if (desc->channel[0].size == 8) { - for (i = 0; i < 4; i++) { - if (desc->swizzle[i] <= 3) { - swizzle[i] = 3 - desc->swizzle[i]; - } else { - swizzle[i] = desc->swizzle[i]; - } - } - } else { - for (i = 0; i < 4; i++) { - swizzle[i] = desc->swizzle[i]; - } - } - - return ((swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | - (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | - (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | - (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) | + return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | + (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | + (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | + (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) | (0xf << R300_WRITE_ENA_SHIFT)); } -- cgit v1.2.3 From 6f4ce4a4fed9f0f0f0ee89a63e406ab86dae7150 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 9 Mar 2010 10:54:13 +0000 Subject: Squashed commit of gallium-no-texture-blanket commit f90b3f01af82b9522067b1824e21709a6fb2d3af Author: Keith Whitwell Date: Mon Mar 8 14:39:44 2010 +0000 gallium: remove p_screen::surface_buffer_create This isn't very useful without texture_blanket(), which has also been removed. Note that this function hasn't been removed from the old pipe_winsys (u_simple_screen) still used internally by some drivers (eg softpipe). commit 6c462de39a4b9980a5f034a95e580efdfcb8173b Author: Keith Whitwell Date: Mon Mar 8 14:27:40 2010 +0000 egl/x11: disable texture_blanket usage commit b42da9160df9f47224e5b3291b972f41767aa6e5 Merge: 4be2436 3ca9336 Author: Keith Whitwell Date: Mon Mar 8 14:27:24 2010 +0000 Merge commit 'origin/master' into gallium-no-texture-blanket Conflicts: src/gallium/drivers/svga/svga_screen_texture.c commit 4be2436316929e3dfc55bc34d810920c06556b66 Author: Keith Whitwell Date: Thu Mar 4 14:59:26 2010 +0000 gallium: remove texture blanket call No longer needed, except for nouveau and egl/xll/native_ximage.c. Fix for nouveau is to keep the call, but move it to an internal function within nouveau. Fix for that egl/x11 relies on gallium-sw-api branch or its successor. commit 69b6764330367d63c237d0bde9fb96435d0e0257 Author: Keith Whitwell Date: Thu Mar 4 13:35:16 2010 +0000 drm_api: wrap comment --- src/gallium/auxiliary/util/u_simple_screen.c | 16 ----- src/gallium/drivers/i915/i915_texture.c | 38 ------------ src/gallium/drivers/i965/brw_screen_texture.c | 9 +-- src/gallium/drivers/i965/brw_winsys.h | 22 ------- src/gallium/drivers/identity/id_screen.c | 47 --------------- src/gallium/drivers/llvmpipe/lp_screen.c | 13 ---- src/gallium/drivers/llvmpipe/lp_texture.c | 38 ------------ src/gallium/drivers/nouveau/nouveau_screen.c | 3 +- src/gallium/drivers/nouveau/nouveau_screen.h | 12 ++++ src/gallium/drivers/nv30/nv30_miptree.c | 3 +- src/gallium/drivers/nv40/nv40_miptree.c | 3 +- src/gallium/drivers/nv50/nv50_miptree.c | 3 +- src/gallium/drivers/r300/r300_texture.c | 36 ----------- src/gallium/drivers/softpipe/sp_texture.c | 48 +++------------ src/gallium/drivers/svga/svga_screen_texture.c | 65 -------------------- src/gallium/drivers/trace/tr_screen.c | 70 ---------------------- src/gallium/include/pipe/p_screen.h | 28 --------- src/gallium/include/state_tracker/drm_api.h | 5 +- src/gallium/state_trackers/egl/x11/native_ximage.c | 9 ++- 19 files changed, 40 insertions(+), 428 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c index 53f3c16dbcc..9203cb6580c 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.c +++ b/src/gallium/auxiliary/util/u_simple_screen.c @@ -59,22 +59,7 @@ pass_user_buffer_create(struct pipe_screen *screen, return buffer; } -static struct pipe_buffer * -pass_surface_buffer_create(struct pipe_screen *screen, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride) -{ - struct pipe_buffer *buffer = - screen->winsys->surface_buffer_create(screen->winsys, width, height, - format, usage, tex_usage, stride); - buffer->screen = screen; - - return buffer; -} static void * pass_buffer_map(struct pipe_screen *screen, @@ -135,7 +120,6 @@ u_simple_screen_init(struct pipe_screen *screen) { screen->buffer_create = pass_buffer_create; screen->user_buffer_create = pass_user_buffer_create; - screen->surface_buffer_create = pass_surface_buffer_create; screen->buffer_map = pass_buffer_map; screen->buffer_unmap = pass_buffer_unmap; diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c index 5b1f42313ef..3ce52cdcdbd 100644 --- a/src/gallium/drivers/i915/i915_texture.c +++ b/src/gallium/drivers/i915/i915_texture.c @@ -724,43 +724,6 @@ i915_texture_get_handle(struct pipe_screen * screen, return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride); } -static struct pipe_texture * -i915_texture_blanket(struct pipe_screen * screen, - const struct pipe_texture *base, - const unsigned *stride, - struct pipe_buffer *buffer) -{ -#if 0 - struct i915_texture *tex; - assert(screen); - - /* Only supports one type */ - if (base->target != PIPE_TEXTURE_2D || - base->last_level != 0 || - base->depth0 != 1) { - return NULL; - } - - tex = CALLOC_STRUCT(i915_texture); - if (!tex) - return NULL; - - tex->base = *base; - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; - - tex->stride = stride[0]; - - i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1); - i915_miptree_set_image_offset(tex, 0, 0, 0, 0); - - pipe_buffer_reference(&tex->buffer, buffer); - - return &tex->base; -#else - return NULL; -#endif -} static void i915_texture_destroy(struct pipe_texture *pt) @@ -923,7 +886,6 @@ i915_init_screen_texture_functions(struct i915_screen *is) is->base.texture_create = i915_texture_create; is->base.texture_from_handle = i915_texture_from_handle; is->base.texture_get_handle = i915_texture_get_handle; - is->base.texture_blanket = i915_texture_blanket; is->base.texture_destroy = i915_texture_destroy; is->base.get_tex_surface = i915_get_tex_surface; is->base.tex_surface_destroy = i915_tex_surface_destroy; diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c index caa16ee1502..cc79bfc7715 100644 --- a/src/gallium/drivers/i965/brw_screen_texture.c +++ b/src/gallium/drivers/i965/brw_screen_texture.c @@ -416,13 +416,7 @@ brw_texture_get_handle(struct pipe_screen *screen, return bscreen->sws->bo_get_handle(tex->bo, whandle, stride); } -static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen, - const struct pipe_texture *templ, - const unsigned *stride, - struct pipe_buffer *buffer) -{ - return NULL; -} + static void brw_texture_destroy(struct pipe_texture *pt) { @@ -571,7 +565,6 @@ void brw_screen_tex_init( struct brw_screen *brw_screen ) brw_screen->base.texture_from_handle = brw_texture_from_handle; brw_screen->base.texture_get_handle = brw_texture_get_handle; brw_screen->base.texture_destroy = brw_texture_destroy; - brw_screen->base.texture_blanket = brw_texture_blanket; brw_screen->base.get_tex_transfer = brw_get_tex_transfer; brw_screen->base.transfer_map = brw_transfer_map; brw_screen->base.transfer_unmap = brw_transfer_unmap; diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index 139e26e31fe..f30c7f18132 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -267,28 +267,6 @@ bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf) struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id); -/** - * Get the brw_winsys buffer backing the texture. - * - * TODO UGLY - */ -struct pipe_texture; -boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture, - struct brw_winsys_buffer **buffer, - unsigned *stride); - -/** - * Wrap a brw_winsys buffer with a texture blanket. - * - * TODO UGLY - */ -struct pipe_texture * -brw_texture_blanket_winsys_buffer(struct pipe_screen *screen, - const struct pipe_texture *template, - unsigned pitch, - unsigned tiling, - struct brw_winsys_buffer *buffer); - /************************************************************************* * Cooperative dumping between winsys and driver. TODO: make this diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 77e15b92f77..b9d0f003d74 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -167,27 +167,7 @@ identity_screen_texture_get_handle(struct pipe_screen *_screen, return screen->texture_get_handle(screen, texture, handle); } -static struct pipe_texture * -identity_screen_texture_blanket(struct pipe_screen *_screen, - const struct pipe_texture *templat, - const unsigned *stride, - struct pipe_buffer *_buffer) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct identity_buffer *id_buffer = identity_buffer(_buffer); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *buffer = id_buffer->buffer; - struct pipe_texture *result; - - result = screen->texture_blanket(screen, - templat, - stride, - buffer); - if (result) - return identity_texture_create(id_screen, result); - return NULL; -} static void identity_screen_texture_destroy(struct pipe_texture *_texture) @@ -331,31 +311,6 @@ identity_screen_user_buffer_create(struct pipe_screen *_screen, return NULL; } -static struct pipe_buffer * -identity_screen_surface_buffer_create(struct pipe_screen *_screen, - unsigned width, - unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct pipe_screen *screen = id_screen->screen; - struct pipe_buffer *result; - - result = screen->surface_buffer_create(screen, - width, - height, - format, - usage, - tex_usage, - stride); - - if (result) - return identity_buffer_create(id_screen, result); - return NULL; -} static void * identity_screen_buffer_map(struct pipe_screen *_screen, @@ -530,7 +485,6 @@ identity_screen_create(struct pipe_screen *screen) id_screen->base.texture_create = identity_screen_texture_create; id_screen->base.texture_from_handle = identity_screen_texture_from_handle; id_screen->base.texture_get_handle = identity_screen_texture_get_handle; - id_screen->base.texture_blanket = identity_screen_texture_blanket; id_screen->base.texture_destroy = identity_screen_texture_destroy; id_screen->base.get_tex_surface = identity_screen_get_tex_surface; id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy; @@ -540,7 +494,6 @@ identity_screen_create(struct pipe_screen *screen) id_screen->base.transfer_unmap = identity_screen_transfer_unmap; id_screen->base.buffer_create = identity_screen_buffer_create; id_screen->base.user_buffer_create = identity_screen_user_buffer_create; - id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create; if (screen->buffer_map) id_screen->base.buffer_map = identity_screen_buffer_map; if (screen->buffer_map_range) diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 2c6fd67eae8..934b0d8439e 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -238,18 +238,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, } -static struct pipe_buffer * -llvmpipe_surface_buffer_create(struct pipe_screen *screen, - unsigned width, unsigned height, - enum pipe_format format, - unsigned tex_usage, - unsigned usage, - unsigned *stride) -{ - /* This function should never be used */ - assert(0); - return NULL; -} static void @@ -309,7 +297,6 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys) screen->base.get_paramf = llvmpipe_get_paramf; screen->base.is_format_supported = llvmpipe_is_format_supported; - screen->base.surface_buffer_create = llvmpipe_surface_buffer_create; screen->base.context_create = llvmpipe_create_context; screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 7d15e856007..e41d6238ed2 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -143,43 +143,6 @@ llvmpipe_texture_create(struct pipe_screen *_screen, } -static struct pipe_texture * -llvmpipe_texture_blanket(struct pipe_screen * screen, - const struct pipe_texture *base, - const unsigned *stride, - struct pipe_buffer *buffer) -{ - /* FIXME */ -#if 0 - struct llvmpipe_texture *lpt; - assert(screen); - - /* Only supports one type */ - if (base->target != PIPE_TEXTURE_2D || - base->last_level != 0 || - base->depth0 != 1) { - return NULL; - } - - lpt = CALLOC_STRUCT(llvmpipe_texture); - if (!lpt) - return NULL; - - lpt->base = *base; - pipe_reference_init(&lpt->base.reference, 1); - lpt->base.screen = screen; - lpt->stride[0] = stride[0]; - - pipe_buffer_reference(&lpt->buffer, buffer); - - return &lpt->base; -#else - debug_printf("llvmpipe_texture_blanket() not implemented!"); - return NULL; -#endif -} - - static void llvmpipe_texture_destroy(struct pipe_texture *pt) { @@ -409,7 +372,6 @@ void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = llvmpipe_texture_create; - screen->texture_blanket = llvmpipe_texture_blanket; screen->texture_destroy = llvmpipe_texture_destroy; screen->get_tex_surface = llvmpipe_get_tex_surface; diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 2013eef0c5a..f7d10a591f6 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -273,7 +273,8 @@ nouveau_screen_texture_from_handle(struct pipe_screen *pscreen, pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE | PIPE_BUFFER_USAGE_CPU_READ_WRITE; pb->size = nouveau_bo(pb)->size; - pt = pscreen->texture_blanket(pscreen, templ, &whandle->stride, pb); + pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ, + &whandle->stride, pb); pipe_buffer_reference(&pb, NULL); return pt; } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index a7927d88dfc..f4a7a2bc234 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -6,6 +6,18 @@ struct nouveau_screen { struct nouveau_device *device; struct nouveau_channel *channel; + /** + * Create a new texture object, using the given template info, but on top of + * existing memory. + * + * It is assumed that the buffer data is layed out according to the expected + * by the hardware. NULL will be returned if any inconsistency is found. + */ + struct pipe_texture * (*texture_blanket)(struct pipe_screen *, + const struct pipe_texture *templat, + const unsigned *stride, + struct pipe_buffer *buffer); + int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen, struct pipe_buffer *pb, unsigned usage); }; diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index cb756cf6e64..5ef74a832dc 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -232,8 +232,9 @@ void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv30_miptree_create; - pscreen->texture_blanket = nv30_miptree_blanket; pscreen->texture_destroy = nv30_miptree_destroy; pscreen->get_tex_surface = nv30_miptree_surface_new; pscreen->tex_surface_destroy = nv30_miptree_surface_del; + + nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket; } diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index b17255dc6bd..62e97bcea48 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -227,9 +227,10 @@ void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv40_miptree_create; - pscreen->texture_blanket = nv40_miptree_blanket; pscreen->texture_destroy = nv40_miptree_destroy; pscreen->get_tex_surface = nv40_miptree_surface_new; pscreen->tex_surface_destroy = nv40_miptree_surface_del; + + nouveau_screen(pscreen)->texture_blanket = nv40_miptree_blanket; } diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index a7788249aba..e091cae6024 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -255,9 +255,10 @@ void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv50_miptree_create; - pscreen->texture_blanket = nv50_miptree_blanket; pscreen->texture_destroy = nv50_miptree_destroy; pscreen->get_tex_surface = nv50_miptree_surface_new; pscreen->tex_surface_destroy = nv50_miptree_surface_del; + + nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket; } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 21e5910450f..04124afd4dc 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -851,41 +851,6 @@ static void r300_tex_surface_destroy(struct pipe_surface* s) FREE(s); } -static struct pipe_texture* - r300_texture_blanket(struct pipe_screen* screen, - const struct pipe_texture* base, - const unsigned* stride, - struct pipe_buffer* buffer) -{ - struct r300_texture* tex; - struct r300_screen* rscreen = r300_screen(screen); - - /* Support only 2D textures without mipmaps */ - if (base->target != PIPE_TEXTURE_2D || - base->depth0 != 1 || - base->last_level != 0) { - return NULL; - } - - tex = CALLOC_STRUCT(r300_texture); - if (!tex) { - return NULL; - } - - tex->tex = *base; - pipe_reference_init(&tex->tex.reference, 1); - tex->tex.screen = screen; - - tex->stride_override = *stride; - tex->pitch[0] = *stride / util_format_get_blocksize(base->format); - - r300_setup_flags(tex); - r300_setup_texture_state(rscreen, tex); - - pipe_buffer_reference(&tex->buffer, buffer); - - return (struct pipe_texture*)tex; -} static struct pipe_texture* r300_texture_from_handle(struct pipe_screen* screen, @@ -1007,7 +972,6 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; screen->tex_surface_destroy = r300_tex_surface_destroy; - screen->texture_blanket = r300_texture_blanket; screen->video_surface_create = r300_video_surface_create; screen->video_surface_destroy= r300_video_surface_destroy; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 6ea060023da..c0052359fdc 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -36,6 +36,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_simple_screen.h" #include "sp_context.h" #include "sp_texture.h" @@ -91,13 +92,13 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, PIPE_BUFFER_USAGE_GPU_READ_WRITE); unsigned tex_usage = spt->base.tex_usage; - spt->buffer = screen->surface_buffer_create( screen, - spt->base.width0, - spt->base.height0, - spt->base.format, - usage, - tex_usage, - &spt->stride[0]); + spt->buffer = screen->winsys->surface_buffer_create( screen->winsys, + spt->base.width0, + spt->base.height0, + spt->base.format, + usage, + tex_usage, + &spt->stride[0]); return spt->buffer != NULL; } @@ -141,38 +142,6 @@ softpipe_texture_create(struct pipe_screen *screen, } -/** - * Create a new pipe_texture which wraps an existing buffer. - */ -static struct pipe_texture * -softpipe_texture_blanket(struct pipe_screen * screen, - const struct pipe_texture *base, - const unsigned *stride, - struct pipe_buffer *buffer) -{ - struct softpipe_texture *spt; - assert(screen); - - /* Only supports one type */ - if (base->target != PIPE_TEXTURE_2D || - base->last_level != 0 || - base->depth0 != 1) { - return NULL; - } - - spt = CALLOC_STRUCT(softpipe_texture); - if (!spt) - return NULL; - - spt->base = *base; - pipe_reference_init(&spt->base.reference, 1); - spt->base.screen = screen; - spt->stride[0] = stride[0]; - - pipe_buffer_reference(&spt->buffer, buffer); - - return &spt->base; -} static void @@ -459,7 +428,6 @@ void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; - screen->texture_blanket = softpipe_texture_blanket; screen->texture_destroy = softpipe_texture_destroy; screen->get_tex_surface = softpipe_get_tex_surface; diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c index 4b045c44d89..5b581debfc7 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ b/src/gallium/drivers/svga/svga_screen_texture.c @@ -359,71 +359,7 @@ error1: } -static struct pipe_texture * -svga_texture_blanket(struct pipe_screen * screen, - const struct pipe_texture *base, - const unsigned *stride, - struct pipe_buffer *buffer) -{ - struct svga_texture *tex; - struct svga_buffer *sbuf = svga_buffer(buffer); - struct svga_winsys_screen *sws = svga_winsys_screen(screen); - assert(screen); - - /* Only supports one type */ - if (base->target != PIPE_TEXTURE_2D || - base->last_level != 0 || - base->depth0 != 1) { - return NULL; - } - - /** - * We currently can't do texture blanket on - * SVGA3D_BUFFER. Need to blit to a temporary surface? - */ - - assert(sbuf->handle); - if (!sbuf->handle) - return NULL; - - if (svga_translate_format(base->format) != sbuf->key.format) { - unsigned f1 = svga_translate_format(base->format); - unsigned f2 = sbuf->key.format; - - /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */ - if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) || - (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) || - (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) { - debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2); - return NULL; - } - } - - tex = CALLOC_STRUCT(svga_texture); - if (!tex) - return NULL; - - tex->base = *base; - - if (sbuf->key.format == 1) - tex->base.format = PIPE_FORMAT_B8G8R8X8_UNORM; - else if (sbuf->key.format == 2) - tex->base.format = PIPE_FORMAT_B8G8R8A8_UNORM; - - pipe_reference_init(&tex->base.reference, 1); - tex->base.screen = screen; - - SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle); - - /* We don't own this storage, so don't try to cache it. - */ - assert(sbuf->key.cachable == 0); - tex->key.cachable = 0; - sws->surface_reference(sws, &tex->handle, sbuf->handle); - - return &tex->base; -} static struct pipe_texture * @@ -984,7 +920,6 @@ svga_screen_init_texture_functions(struct pipe_screen *screen) screen->texture_destroy = svga_texture_destroy; screen->get_tex_surface = svga_get_tex_surface; screen->tex_surface_destroy = svga_tex_surface_destroy; - screen->texture_blanket = svga_texture_blanket; screen->get_tex_transfer = svga_get_tex_transfer; screen->transfer_map = svga_transfer_map; screen->transfer_unmap = svga_transfer_unmap; diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index ac0876c3a80..a15addeb8cf 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -269,36 +269,6 @@ trace_screen_texture_get_handle(struct pipe_screen *_screen, return screen->texture_get_handle(screen, texture, handle); } -static struct pipe_texture * -trace_screen_texture_blanket(struct pipe_screen *_screen, - const struct pipe_texture *templat, - const unsigned *ppitch, - struct pipe_buffer *_buffer) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_buffer *tr_buf = trace_buffer(_buffer); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_buffer *buffer = tr_buf->buffer; - unsigned pitch = *ppitch; - struct pipe_texture *result; - - trace_dump_call_begin("pipe_screen", "texture_blanket"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(template, templat); - trace_dump_arg(uint, pitch); - trace_dump_arg(ptr, buffer); - - result = screen->texture_blanket(screen, templat, ppitch, buffer); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - result = trace_texture_create(tr_scr, result); - - return result; -} static void @@ -516,45 +486,7 @@ trace_screen_transfer_unmap(struct pipe_screen *_screen, */ -static struct pipe_buffer * -trace_screen_surface_buffer_create(struct pipe_screen *_screen, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *pstride) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - unsigned stride; - struct pipe_buffer *result; - trace_dump_call_begin("pipe_screen", "surface_buffer_create"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(uint, width); - trace_dump_arg(uint, height); - trace_dump_arg(format, format); - trace_dump_arg(uint, usage); - trace_dump_arg(uint, tex_usage); - - result = screen->surface_buffer_create(screen, - width, height, - format, - usage, - tex_usage, - pstride); - - stride = *pstride; - - trace_dump_arg(uint, stride); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return trace_buffer_create(tr_scr, result); -} static struct pipe_buffer * @@ -965,7 +897,6 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.texture_create = trace_screen_texture_create; tr_scr->base.texture_from_handle = trace_screen_texture_from_handle; tr_scr->base.texture_get_handle = trace_screen_texture_get_handle; - tr_scr->base.texture_blanket = trace_screen_texture_blanket; tr_scr->base.texture_destroy = trace_screen_texture_destroy; tr_scr->base.get_tex_surface = trace_screen_get_tex_surface; tr_scr->base.tex_surface_destroy = trace_screen_tex_surface_destroy; @@ -975,7 +906,6 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.transfer_unmap = trace_screen_transfer_unmap; tr_scr->base.buffer_create = trace_screen_buffer_create; tr_scr->base.user_buffer_create = trace_screen_user_buffer_create; - tr_scr->base.surface_buffer_create = trace_screen_surface_buffer_create; if (screen->buffer_map) tr_scr->base.buffer_map = trace_screen_buffer_map; if (screen->buffer_map_range) diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 617c47e4dc2..690455f7222 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -127,17 +127,6 @@ struct pipe_screen { struct pipe_texture *tex, struct winsys_handle *handle); - /** - * Create a new texture object, using the given template info, but on top of - * existing memory. - * - * It is assumed that the buffer data is layed out according to the expected - * by the hardware. NULL will be returned if any inconsistency is found. - */ - struct pipe_texture * (*texture_blanket)(struct pipe_screen *, - const struct pipe_texture *templat, - const unsigned *stride, - struct pipe_buffer *buffer); void (*texture_destroy)(struct pipe_texture *pt); @@ -207,23 +196,6 @@ struct pipe_screen { void *ptr, unsigned bytes); - /** - * Allocate storage for a display target surface. - * - * Often surfaces which are meant to be blitted to the front screen (i.e., - * display targets) must be allocated with special characteristics, memory - * pools, or obtained directly from the windowing system. - * - * This callback is invoked by the pipe_screenwhen creating a texture marked - * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying - * buffer storage. - */ - struct pipe_buffer *(*surface_buffer_create)(struct pipe_screen *screen, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride); /** diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h index d3edddd5d4e..fe7ef253ef0 100644 --- a/src/gallium/include/state_tracker/drm_api.h +++ b/src/gallium/include/state_tracker/drm_api.h @@ -26,8 +26,9 @@ enum drm_create_screen_mode { struct winsys_handle { /** - * Unused for texture_from_handle, always DRM_API_HANDLE_TYPE_SHARED. - * Input to texture_get_handle, use TEXTURE_USAGE to select handle for kms or ipc. + * Unused for texture_from_handle, always + * DRM_API_HANDLE_TYPE_SHARED. Input to texture_get_handle, + * use TEXTURE_USAGE to select handle for kms or ipc. */ unsigned type; /** diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 3421c1951aa..a94b1ca6c66 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -156,6 +156,11 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf, templ.depth0 = 1; templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; +#if 0 + /* Interesting and suprising use of texture_blanket + + * user_buffer_create... To be superceded by the sw_winsys branch, + * but currently disabled. + */ if (xbuf->shm_info) { struct pipe_buffer *pbuf; unsigned stride, size; @@ -188,7 +193,9 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf, } } } - else { + else +#endif + { xbuf->texture = screen->texture_create(screen, &templ); } -- cgit v1.2.3 From 22812421b5f394af741022f2f65ba19bc7b0aa73 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 9 Mar 2010 16:24:47 +0100 Subject: r300g: fix gallium-vertexlementcso merge damage --- src/gallium/drivers/r300/r300_emit.c | 4 ++-- src/gallium/drivers/r300/r300_render.c | 25 ------------------------- src/gallium/drivers/r300/r300_state_derived.c | 1 - 3 files changed, 2 insertions(+), 28 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 65377b3865a..55e9217fd32 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1004,7 +1004,7 @@ void r300_emit_buffer_validate(struct r300_context *r300, (struct r300_textures_state*)r300->textures_state.state; struct r300_texture* tex; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; struct pipe_buffer *pbuf; unsigned i; boolean invalid = FALSE; @@ -1062,7 +1062,7 @@ validate: } /* ...vertex buffers for HWTCL path... */ if (do_validate_vertex_buffers) { - for (i = 0; i < r300->vertex_element_count; i++) { + for (i = 0; i < r300->velems->count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; if (!r300->winsys->add_buffer(r300->winsys, pbuf, diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index d0e06ade40f..2605628c025 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -319,31 +319,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } -static boolean r300_setup_vertex_buffers(struct r300_context *r300) -{ - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->velems->velem; - struct pipe_buffer *pbuf; - -validate: - for (int i = 0; i < r300->velems->count; i++) { - pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { - r300->context.flush(&r300->context, 0, NULL); - goto validate; - } - } - - if (!r300->winsys->validate(r300->winsys)) { - r300->context.flush(&r300->context, 0, NULL); - return r300->winsys->validate(r300->winsys); - } - - return TRUE; -} - static void r300_shorten_ubyte_elts(struct r300_context* r300, struct pipe_buffer** elts, unsigned count) diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 4422581b514..81a373abad2 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -128,7 +128,6 @@ static void r300_vertex_psc(struct r300_context* r300) " in psc\n", vs->info.num_inputs, r300->velems->count); - r300->vertex_element_count); for (i = 0; i < r300->velems->count; i++) { format = r300->velems->velem[i].src_format; -- cgit v1.2.3 From 9c8cb12388be6818ac11a28d40034d01047584b2 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 8 Mar 2010 21:35:43 -0800 Subject: r300g: Cleanup old PSC code a bit. --- src/gallium/drivers/r300/r300_state_derived.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 81a373abad2..cb2b9bd99f6 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -114,13 +114,9 @@ static void r300_vertex_psc(struct r300_context* r300) uint16_t type, swizzle; enum pipe_format format; unsigned i; - int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - int* stream_tab; memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); - stream_tab = identity; - /* Vertex shaders have no semantics on their inputs, * so PSC should just route stuff based on the vertex elements, * and not on attrib information. */ @@ -133,7 +129,7 @@ static void r300_vertex_psc(struct r300_context* r300) format = r300->velems->velem[i].src_format; type = r300_translate_vertex_data_type(format) | - (stream_tab[i] << R300_DST_VEC_LOC_SHIFT); + (i << R300_DST_VEC_LOC_SHIFT); swizzle = r300_translate_vertex_data_swizzle(format); if (i & 1) { -- cgit v1.2.3 From 141c7cb0d6078b3a2832c4be03ddcf25e35e596b Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 8 Mar 2010 23:36:04 -0800 Subject: r300g: Precalculate and CSO-bind PSC state. --- src/gallium/drivers/r300/r300_context.c | 2 - src/gallium/drivers/r300/r300_context.h | 6 +- src/gallium/drivers/r300/r300_state.c | 197 ++++++++++++++++++++++++-- src/gallium/drivers/r300/r300_state_derived.c | 190 +------------------------ 4 files changed, 190 insertions(+), 205 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index e0a55323273..923e1e541ff 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -60,7 +60,6 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); FREE(r300->textures_state.state); - FREE(r300->vertex_stream_state.state); FREE(r300->vap_output_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); @@ -147,7 +146,6 @@ static void r300_setup_atoms(struct r300_context* r300) r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); r300->textures_state.state = CALLOC_STRUCT(r300_textures_state); - r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state); r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 80e69924f08..985e3391126 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -288,9 +288,11 @@ struct r300_vertex_info { uint32_t vap_prog_stream_cntl_ext[8]; }; -struct r300_velems_state { +struct r300_vertex_element_state { unsigned count; struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; + + struct r300_vertex_stream_state vertex_stream; }; extern struct pipe_viewport_state r300_viewport_identity; @@ -365,7 +367,7 @@ struct r300_context { int vertex_buffer_count; int vertex_buffer_max_index; /* Vertex elements for Gallium. */ - struct r300_velems_state *velems; + struct r300_vertex_element_state *velems; /* Vertex info for Draw. */ struct vertex_info vertex_info; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 7683a423f2f..bd4c2766cb1 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1046,8 +1046,6 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, if (r300->draw) { draw_flush(r300->draw); draw_set_vertex_buffers(r300->draw, count, buffers); - } else { - r300->vertex_stream_state.dirty = TRUE; } } @@ -1067,37 +1065,209 @@ static boolean r300_validate_aos(struct r300_context *r300) return TRUE; } +static void r300_draw_emit_attrib(struct r300_context* r300, + enum attrib_emit emit, + enum interp_mode interp, + int index) +{ + struct r300_vertex_shader* vs = r300->vs_state.state; + struct tgsi_shader_info* info = &vs->info; + int output; + + output = draw_find_shader_output(r300->draw, + info->output_semantic_name[index], + info->output_semantic_index[index]); + draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output); +} + +static void r300_draw_emit_all_attribs(struct r300_context* r300) +{ + struct r300_vertex_shader* vs = r300->vs_state.state; + struct r300_shader_semantics* vs_outputs = &vs->outputs; + int i, gen_count; + + /* Position. */ + if (vs_outputs->pos != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, + vs_outputs->pos); + } else { + assert(0); + } + + /* Point size. */ + if (vs_outputs->psize != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS, + vs_outputs->psize); + } + + /* Colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (vs_outputs->color[i] != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR, + vs_outputs->color[i]); + } + } + + /* XXX Back-face colors. */ + + /* Texture coordinates. */ + gen_count = 0; + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (vs_outputs->generic[i] != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, + vs_outputs->generic[i]); + gen_count++; + } + } + + /* Fog coordinates. */ + if (vs_outputs->fog != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, + vs_outputs->fog); + gen_count++; + } + + /* XXX magic */ + assert(gen_count <= 8); +} + +/* Update the PSC tables. */ +static void r300_vertex_psc(struct r300_vertex_element_state *velems) +{ + struct r300_vertex_stream_state *vstream = &velems->vertex_stream; + uint16_t type, swizzle; + enum pipe_format format; + unsigned i; + + assert(velems->count <= 16); + + /* Vertex shaders have no semantics on their inputs, + * so PSC should just route stuff based on the vertex elements, + * and not on attrib information. */ + for (i = 0; i < velems->count; i++) { + format = velems->velem[i].src_format; + + type = r300_translate_vertex_data_type(format) | + (i << R300_DST_VEC_LOC_SHIFT); + swizzle = r300_translate_vertex_data_swizzle(format); + + if (i & 1) { + vstream->vap_prog_stream_cntl[i >> 1] |= type << 16; + vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; + } else { + vstream->vap_prog_stream_cntl[i >> 1] |= type; + vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; + } + } + + /* Set the last vector in the PSC. */ + if (i) { + i -= 1; + } + vstream->vap_prog_stream_cntl[i >> 1] |= + (R300_LAST_VEC << (i & 1 ? 16 : 0)); + + vstream->count = (i >> 1) + 1; +} + +/* Update the PSC tables for SW TCL, using Draw. */ +static void r300_swtcl_vertex_psc(struct r300_context *r300, + struct r300_vertex_element_state *velems) +{ + struct r300_vertex_stream_state *vstream = &velems->vertex_stream; + struct r300_vertex_shader* vs = r300->vs_state.state; + struct vertex_info* vinfo = &r300->vertex_info; + uint16_t type, swizzle; + enum pipe_format format; + unsigned i, attrib_count; + int* vs_output_tab = vs->stream_loc_notcl; + + /* For each Draw attribute, route it to the fragment shader according + * to the vs_output_tab. */ + attrib_count = vinfo->num_attribs; + DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count); + for (i = 0; i < attrib_count; i++) { + DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d," + " vs_output_tab %d\n", vinfo->attrib[i].src_index, + vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, + vs_output_tab[i]); + } + + for (i = 0; i < attrib_count; i++) { + /* Make sure we have a proper destination for our attribute. */ + assert(vs_output_tab[i] != -1); + + format = draw_translate_vinfo_format(vinfo->attrib[i].emit); + + /* Obtain the type of data in this attribute. */ + type = r300_translate_vertex_data_type(format) | + vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT; + + /* Obtain the swizzle for this attribute. Note that the default + * swizzle in the hardware is not XYZW! */ + swizzle = r300_translate_vertex_data_swizzle(format); + + /* Add the attribute to the PSC table. */ + if (i & 1) { + vstream->vap_prog_stream_cntl[i >> 1] |= type << 16; + vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; + } else { + vstream->vap_prog_stream_cntl[i >> 1] |= type; + vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; + } + } + + /* Set the last vector in the PSC. */ + if (i) { + i -= 1; + } + vstream->vap_prog_stream_cntl[i >> 1] |= + (R300_LAST_VEC << (i & 1 ? 16 : 0)); + + vstream->count = (i >> 1) + 1; +} + static void* r300_create_vertex_elements_state(struct pipe_context* pipe, unsigned count, const struct pipe_vertex_element* attribs) { - struct r300_velems_state *velems; + struct r300_context *r300 = r300_context(pipe); + struct r300_screen* r300screen = r300_screen(pipe->screen); + struct r300_vertex_element_state *velems; - /*XXX should precalculate state here instead of later */ assert(count <= PIPE_MAX_ATTRIBS); - velems = CALLOC_STRUCT(r300_velems_state); - if (velems) { + velems = CALLOC_STRUCT(r300_vertex_element_state); + if (velems != NULL) { velems->count = count; memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count); + + if (r300screen->caps->has_tcl) { + r300_vertex_psc(velems); + } else { + memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); + r300_draw_emit_all_attribs(r300); + draw_compute_vertex_size(&r300->vertex_info); + r300_swtcl_vertex_psc(r300, velems); + } } return velems; } static void r300_bind_vertex_elements_state(struct pipe_context *pipe, - void *velems) + void *state) { struct r300_context *r300 = r300_context(pipe); - struct r300_velems_state *r300_velems = (struct r300_velems_state *) velems; + struct r300_vertex_element_state *velems = state; if (velems == NULL) { return; } - r300->velems = r300_velems; + r300->velems = velems; if (r300->draw) { draw_flush(r300->draw); - draw_set_vertex_elements(r300->draw, r300_velems->count, r300_velems->velem); + draw_set_vertex_elements(r300->draw, velems->count, velems->velem); } if (!r300_validate_aos(r300)) { @@ -1105,11 +1275,14 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, assert(0); abort(); } + + UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state); + r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2; } -static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) +static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state) { - FREE(velems); + FREE(state); } static void* r300_create_vs_state(struct pipe_context* pipe, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index cb2b9bd99f6..6b9f61acd7b 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -37,183 +37,6 @@ /* r300_state_derived: Various bits of state which are dependent upon * currently bound CSO data. */ -static void r300_draw_emit_attrib(struct r300_context* r300, - enum attrib_emit emit, - enum interp_mode interp, - int index) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - struct tgsi_shader_info* info = &vs->info; - int output; - - output = draw_find_shader_output(r300->draw, - info->output_semantic_name[index], - info->output_semantic_index[index]); - draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output); -} - -static void r300_draw_emit_all_attribs(struct r300_context* r300) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_shader_semantics* vs_outputs = &vs->outputs; - int i, gen_count; - - /* Position. */ - if (vs_outputs->pos != ATTR_UNUSED) { - r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, - vs_outputs->pos); - } else { - assert(0); - } - - /* Point size. */ - if (vs_outputs->psize != ATTR_UNUSED) { - r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS, - vs_outputs->psize); - } - - /* Colors. */ - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED) { - r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR, - vs_outputs->color[i]); - } - } - - /* XXX Back-face colors. */ - - /* Texture coordinates. */ - gen_count = 0; - for (i = 0; i < ATTR_GENERIC_COUNT; i++) { - if (vs_outputs->generic[i] != ATTR_UNUSED) { - r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, - vs_outputs->generic[i]); - gen_count++; - } - } - - /* Fog coordinates. */ - if (vs_outputs->fog != ATTR_UNUSED) { - r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, - vs_outputs->fog); - gen_count++; - } - - /* XXX magic */ - assert(gen_count <= 8); -} - -/* Update the PSC tables. */ -/* XXX move this function into r300_state.c after TCL-bypass gets removed - * XXX because this one is dependent only on vertex elements. */ -static void r300_vertex_psc(struct r300_context* r300) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_stream_state *vformat = - (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; - uint16_t type, swizzle; - enum pipe_format format; - unsigned i; - - memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); - - /* Vertex shaders have no semantics on their inputs, - * so PSC should just route stuff based on the vertex elements, - * and not on attrib information. */ - DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" - " in psc\n", - vs->info.num_inputs, - r300->velems->count); - - for (i = 0; i < r300->velems->count; i++) { - format = r300->velems->velem[i].src_format; - - type = r300_translate_vertex_data_type(format) | - (i << R300_DST_VEC_LOC_SHIFT); - swizzle = r300_translate_vertex_data_swizzle(format); - - if (i & 1) { - vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; - } else { - vformat->vap_prog_stream_cntl[i >> 1] |= type; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; - } - } - - assert(i <= 15); - - /* Set the last vector in the PSC. */ - if (i) { - i -= 1; - } - vformat->vap_prog_stream_cntl[i >> 1] |= - (R300_LAST_VEC << (i & 1 ? 16 : 0)); - - vformat->count = (i >> 1) + 1; - r300->vertex_stream_state.size = (1 + vformat->count) * 2; -} - -/* Update the PSC tables for SW TCL, using Draw. */ -static void r300_swtcl_vertex_psc(struct r300_context* r300) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_stream_state *vformat = - (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; - struct vertex_info* vinfo = &r300->vertex_info; - uint16_t type, swizzle; - enum pipe_format format; - unsigned i, attrib_count; - int* vs_output_tab = vs->stream_loc_notcl; - - memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); - - /* For each Draw attribute, route it to the fragment shader according - * to the vs_output_tab. */ - attrib_count = vinfo->num_attribs; - DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count); - for (i = 0; i < attrib_count; i++) { - DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d," - " vs_output_tab %d\n", vinfo->attrib[i].src_index, - vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, - vs_output_tab[i]); - } - - for (i = 0; i < attrib_count; i++) { - /* Make sure we have a proper destination for our attribute. */ - assert(vs_output_tab[i] != -1); - - format = draw_translate_vinfo_format(vinfo->attrib[i].emit); - - /* Obtain the type of data in this attribute. */ - type = r300_translate_vertex_data_type(format) | - vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT; - - /* Obtain the swizzle for this attribute. Note that the default - * swizzle in the hardware is not XYZW! */ - swizzle = r300_translate_vertex_data_swizzle(format); - - /* Add the attribute to the PSC table. */ - if (i & 1) { - vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; - } else { - vformat->vap_prog_stream_cntl[i >> 1] |= type; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; - } - } - - /* Set the last vector in the PSC. */ - if (i) { - i -= 1; - } - vformat->vap_prog_stream_cntl[i >> 1] |= - (R300_LAST_VEC << (i & 1 ? 16 : 0)); - - vformat->count = (i >> 1) + 1; - r300->vertex_stream_state.size = (1 + vformat->count) * 2; -} - static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, boolean swizzle_0001) { @@ -428,18 +251,8 @@ static void r300_update_rs_block(struct r300_context* r300, static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_screen* r300screen = r300_screen(r300->context.screen); r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); - - if (r300screen->caps->has_tcl) { - r300_vertex_psc(r300); - } else { - memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); - r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size(&r300->vertex_info); - r300_swtcl_vertex_psc(r300); - } } static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) @@ -572,8 +385,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - if (r300->rs_block_state.dirty || - r300->vertex_stream_state.dirty) { /* XXX put updating PSC out of this file */ + if (r300->rs_block_state.dirty) { r300_update_derived_shader_state(r300); } -- cgit v1.2.3 From bf50d40f1ba68a0f19ca06196af99c01efce1e76 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 9 Mar 2010 20:12:52 +0100 Subject: r300g: kill pf_component_count --- src/gallium/drivers/r300/r300_state_inlines.h | 29 +-------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index af7827820cc..a32924ed0a3 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -348,39 +348,12 @@ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count) return 0; } -/* Utility function to count the number of components in RGBAZS formats. - * XXX should go to util or p_format.h */ -static INLINE unsigned pf_component_count(enum pipe_format format) { - unsigned count = 0; - - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) { - count++; - } - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) { - count++; - } - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) { - count++; - } - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) { - count++; - } - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) { - count++; - } - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) { - count++; - } - - return count; -} - /* Translate pipe_formats into PSC vertex types. */ static INLINE uint16_t r300_translate_vertex_data_type(enum pipe_format format) { uint32_t result = 0; const struct util_format_description *desc; - unsigned components = pf_component_count(format); + unsigned components = util_format_get_nr_components(format); desc = util_format_description(format); -- cgit v1.2.3 From 007f25b3bde88de550d6ddba6a96769e4f3d5ce7 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Tue, 9 Mar 2010 20:03:35 -0800 Subject: r300g: Reorder regs, save one dword. Or, put another way, save 10% on rendering calls. --- src/gallium/drivers/r300/r300_render.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 2605628c025..9c001ae186d 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -183,7 +183,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, } } - dwords = 10 + count * vertex_size; + dwords = 9 + count * vertex_size; r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords); r300_emit_buffer_validate(r300, FALSE, NULL); @@ -193,8 +193,9 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); + OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); + OUT_CS(count - 1); + OUT_CS(0); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | r300_translate_primitive(mode)); @@ -238,15 +239,16 @@ static void r300_emit_draw_arrays(struct r300_context *r300, if (alt_num_verts) { assert(count < (1 << 24)); - BEGIN_CS(10); + BEGIN_CS(9); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); } else { - BEGIN_CS(8); + BEGIN_CS(7); } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); + OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); + OUT_CS(count - 1); + OUT_CS(0); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300_translate_primitive(mode) | @@ -281,15 +283,16 @@ static void r300_emit_draw_elements(struct r300_context *r300, maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); if (alt_num_verts) { - BEGIN_CS(16); + BEGIN_CS(15); OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); } else { - BEGIN_CS(14); + BEGIN_CS(13); } OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, mode)); - OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex); - OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex); + OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); + OUT_CS(maxIndex); + OUT_CS(minIndex); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); if (indexSize == 4) { count_dwords = count; -- cgit v1.2.3