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/r300_screen.c') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 5fa1ea0850..036736ccc4 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 036736ccc4..5fa1ea0850 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 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 5fa1ea0850..0b3b96def7 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 34a49bec34..5b7afc6eb9 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 e2c10325fa..01209efe3c 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 0b3b96def7..4bb4e5a785 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 c990be40b9..63f5ff6045 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 1eba8a8ed1..443af4ec2e 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 88fe166359..5a2865887f 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 4bb4e5a785..6a55570571 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 63f5ff6045..0e1cb328d1 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 5b7afc6eb9..ed2be06254 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 01209efe3c..46a5fb6188 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 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index afddcb161f..5707309bdf 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 f631b4ed27..a8a6a07a84 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 443af4ec2e..749bac0498 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 151f72b0fe..ad07efbffd 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 f7dcd8dc52..6fb1d7bd92 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 754eb4dc76..47f5d6f7f1 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 6a55570571..3b70312c82 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 502fbfa5a2..87fc6190ce 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 0000000000..358582ea21 --- /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 0000000000..7c026508b5 --- /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 34bf81c193..d8a87dec15 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 ed2be06254..9016e86ccd 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 46a5fb6188..97724f790c 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 40fb8a95ca..c6f9174496 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 c6a7d4a8c5..b36680eb66 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 860cbb6dbf..13bbbf730d 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 f1c8fc2a3b..8e0274e33d 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 0c0e118ba3..f886fda2f2 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 8d74cbafc2..2f55061330 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 0000000000..5f2fd2d7fc --- /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 d759beaba1..997abb8f5c 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 cfbdb30266..82a8aad715 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 4901080ca7..c8e725cff0 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 5707309bdf..afddcb161f 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 a8a6a07a84..f631b4ed27 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 749bac0498..443af4ec2e 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 ad07efbffd..151f72b0fe 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 6fb1d7bd92..f7dcd8dc52 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 47f5d6f7f1..754eb4dc76 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 3b70312c82..6a55570571 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 87fc6190ce..502fbfa5a2 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 358582ea21..0000000000 --- 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 7c026508b5..0000000000 --- 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 d8a87dec15..34bf81c193 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 9016e86ccd..ed2be06254 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 97724f790c..46a5fb6188 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 c6f9174496..40fb8a95ca 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 b36680eb66..c6a7d4a8c5 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 13bbbf730d..860cbb6dbf 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 8e0274e33d..f1c8fc2a3b 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 f886fda2f2..0c0e118ba3 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 2f55061330..8d74cbafc2 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 5f2fd2d7fc..0000000000 --- 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 997abb8f5c..d759beaba1 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 82a8aad715..cfbdb30266 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 c8e725cff0..4901080ca7 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 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/r300_screen.c') diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c index 7ba222c78b..5ad65a2e9c 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 38e9961398..2d7b6ec222 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 7f45635542..7d15e85600 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 6a55570571..2d8b313e5d 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 371c4e2025..d3997854b2 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 12f3531a1d..b34f906ceb 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 5cebd43ace..5c97dc87e8 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 ee6ab2e60b..dbdb1e635a 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 4a77f54080..8f6426bcc8 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 5472285ec1..e7f1b2d411 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 665efdc0f0..5c3e92efdf 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 0e39a390c6..c113f49e55 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 c814d986b1..80b5a4c091 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 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 32d05749bd..0e2d6c5b42 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 6a55570571..d397a8eb2b 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 12bf083871..6c23045561 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 ea474737b1..44cfe82a57 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 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/r300_screen.c') diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 1f69daec81..61b54af4dd 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 183aa17f9b..27b2e30993 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 d397a8eb2b..a35be05940 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 502fbfa5a2..6d72fec778 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 0000000000..fa48688db2 --- /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 0000000000..faf62338ef --- /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