X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr300%2Fr300_texture.c;h=a6f65fce2161519d0ee84d717ae10e7f803d3ea1;hb=88512e837e45b72c33a7d28ccf02f00580a4cf10;hp=4439e35d670bc00ff34553810177c2d25b7788a9;hpb=0203136e69bfa711edd69a4f69c4539cd877b5cb;p=mesa.git diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 4439e35d670..a6f65fce216 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -24,6 +24,7 @@ #include "pipe/p_screen.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -34,9 +35,6 @@ #include "r300_screen.h" #include "r300_winsys.h" -/* XXX Enable float textures here. */ -/*#define ENABLE_FLOAT_TEXTURES*/ - #define TILE_WIDTH 0 #define TILE_HEIGHT 1 @@ -49,18 +47,6 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; -/* Return true for non-compressed and non-YUV formats. */ -static boolean r300_format_is_plain(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - if (!format) { - return FALSE; - } - - return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN; -} - /* Translate a pipe_format into a useful texture format for sampling. * * Some special formats are translated directly using R300_EASY_TX_FORMAT, @@ -74,7 +60,7 @@ static boolean r300_format_is_plain(enum pipe_format format) * The FORMAT specifies how the texture sampler will treat the texture, and * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ uint32_t r300_translate_texformat(enum pipe_format format, - const unsigned char *swizzle) + const unsigned char *swizzle_view) { uint32_t result = 0; const struct util_format_description *desc; @@ -98,6 +84,7 @@ uint32_t r300_translate_texformat(enum pipe_format format, R300_TX_FORMAT_SIGNED_Z, R300_TX_FORMAT_SIGNED_W, }; + unsigned char swizzle[4]; desc = util_format_description(format); @@ -144,25 +131,18 @@ uint32_t r300_translate_texformat(enum pipe_format format, } } - /* Add swizzle. */ - if (!swizzle) { - swizzle = desc->swizzle; - } /*else { - if (swizzle[0] != desc->swizzle[0] || - swizzle[1] != desc->swizzle[1] || - swizzle[2] != desc->swizzle[2] || - swizzle[3] != desc->swizzle[3]) - { - const char n[6] = "RGBA01"; - fprintf(stderr, "Got different swizzling! Format: %c%c%c%c, " - "View: %c%c%c%c\n", - n[desc->swizzle[0]], n[desc->swizzle[1]], - n[desc->swizzle[2]], n[desc->swizzle[3]], - n[swizzle[0]], n[swizzle[1]], n[swizzle[2]], - n[swizzle[3]]); + /* Get swizzle. */ + if (swizzle_view) { + /* Compose two sets of swizzles. */ + for (i = 0; i < 4; i++) { + swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? + desc->swizzle[swizzle_view[i]] : swizzle_view[i]; } - }*/ + } else { + memcpy(swizzle, desc->swizzle, sizeof(swizzle)); + } + /* Add swizzle. */ for (i = 0; i < 4; i++) { switch (swizzle[i]) { case UTIL_FORMAT_SWIZZLE_X: @@ -191,6 +171,10 @@ uint32_t r300_translate_texformat(enum pipe_format format, /* S3TC formats. */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { + if (!util_format_s3tc_enabled) { + return ~0; /* Unsupported. */ + } + switch (format) { case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: @@ -316,7 +300,6 @@ uint32_t r300_translate_texformat(enum pipe_format format, } return ~0; -#if defined(ENABLE_FLOAT_TEXTURES) case UTIL_FORMAT_TYPE_FLOAT: switch (desc->channel[0].size) { case 16: @@ -340,7 +323,6 @@ uint32_t r300_translate_texformat(enum pipe_format format, return R300_TX_FORMAT_32F_32F_32F_32F | result; } } -#endif } return ~0; /* Unsupported/unknown. */ @@ -405,16 +387,12 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: -#if defined(ENABLE_FLOAT_TEXTURES) case PIPE_FORMAT_R16G16B16A16_FLOAT: -#endif return R300_COLOR_FORMAT_ARGB16161616; /* 128-bit buffers. */ -#if defined(ENABLE_FLOAT_TEXTURES) case PIPE_FORMAT_R32G32B32A32_FLOAT: return R300_COLOR_FORMAT_ARGB32323232; -#endif /* YUV buffers. */ case PIPE_FORMAT_UYVY: @@ -532,7 +510,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) case PIPE_FORMAT_R10SG10SB10SA2U_NORM: case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: - //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ + case PIPE_FORMAT_R16G16B16A16_FLOAT: case PIPE_FORMAT_R32G32B32A32_FLOAT: return modifier | R300_C0_SEL_R | R300_C1_SEL_G | @@ -573,7 +551,7 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen, if (tex->uses_pitch) { /* rectangles love this */ f->format0 |= R300_TX_PITCH_EN; - f->format2 = (tex->pitch[0] - 1) & 0x1fff; + f->format2 = (tex->hwpitch[0] - 1) & 0x1fff; } else { /* power of two textures (3D, mipmaps, and no pitch) */ f->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf); @@ -600,9 +578,6 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen, f->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) | R300_TXO_MICRO_TILE(tex->microtile); - - SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n", - pt->width0, pt->height0, pt->last_level); } static void r300_texture_setup_fb_state(struct r300_screen* screen, @@ -614,7 +589,7 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen, if (util_format_is_depth_or_stencil(tex->b.b.format)) { for (i = 0; i <= tex->b.b.last_level; i++) { tex->fb_state.depthpitch[i] = - tex->pitch[i] | + tex->hwpitch[i] | R300_DEPTHMACROTILE(tex->mip_macrotile[i]) | R300_DEPTHMICROTILE(tex->microtile); } @@ -622,7 +597,7 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen, } else { for (i = 0; i <= tex->b.b.last_level; i++) { tex->fb_state.colorpitch[i] = - tex->pitch[i] | + tex->hwpitch[i] | r300_translate_colorformat(tex->b.b.format) | R300_COLOR_TILE(tex->mip_macrotile[i]) | R300_COLOR_MICROTILE(tex->microtile); @@ -637,8 +612,8 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen, { struct r300_screen *r300screen = r300_screen(screen); - SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n", - util_format_name(tex->format), util_format_name(new_format)); + SCREEN_DBG(r300screen, DBG_TEX, "r300: texture_reinterpret_format: %s -> %s\n", + util_format_short_name(tex->format), util_format_short_name(new_format)); tex->format = new_format; @@ -729,7 +704,7 @@ unsigned r300_texture_get_stride(struct r300_screen* screen, width = u_minify(tex->b.b.width0, level); - if (r300_format_is_plain(tex->b.b.format)) { + if (util_format_is_plain(tex->b.b.format)) { tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, tex->mip_macrotile[level]); width = align(width, tile_width); @@ -747,7 +722,7 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, height = u_minify(tex->b.b.height0, level); - if (r300_format_is_plain(tex->b.b.format)) { + if (util_format_is_plain(tex->b.b.format)) { tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT, tex->mip_macrotile[level]); height = align(height, tile_height); @@ -762,12 +737,12 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen, struct r300_texture *tex) { - /* The kernels <= 2.6.34-rc3 compute the size of mipmapped 3D textures + /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures * incorrectly. This is a workaround to prevent CS from being rejected. */ unsigned i, size; - if (screen->rws->get_value(screen->rws, R300_VID_TEX3D_MIP_BUG) && + if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) && tex->b.b.target == PIPE_TEXTURE_3D && tex->b.b.last_level > 0) { size = 0; @@ -787,10 +762,10 @@ static void r300_setup_miptree(struct r300_screen* screen, { struct pipe_resource* base = &tex->b.b; unsigned stride, size, layer_size, nblocksy, i; - boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_RV350; + boolean rv350_mode = screen->caps.is_rv350; - SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n", - util_format_name(base->format)); + SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Making miptree for texture, format %s\n", + util_format_short_name(base->format)); for (i = 0; i <= base->last_level; i++) { /* Let's see if this miplevel can be macrotiled. */ @@ -813,8 +788,10 @@ static void r300_setup_miptree(struct r300_screen* screen, tex->size = tex->offset[i] + size; tex->layer_size[i] = layer_size; tex->pitch[i] = stride / util_format_get_blocksize(base->format); + tex->hwpitch[i] = + tex->pitch[i] * util_format_get_blockwidth(base->format); - SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d " + SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", i, u_minify(base->width0, i), u_minify(base->height0, i), u_minify(base->depth0, i), stride, tex->size, @@ -834,14 +811,16 @@ static void r300_setup_tiling(struct pipe_screen *screen, { struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; enum pipe_format format = tex->b.b.format; - boolean rv350_mode = r300_screen(screen)->caps.family >= CHIP_FAMILY_RV350; + boolean rv350_mode = r300_screen(screen)->caps.is_rv350; + boolean is_zb = util_format_is_depth_or_stencil(format); + boolean dbg_no_tiling = SCREEN_DBG_ON(r300_screen(screen), DBG_NO_TILING); - if (!r300_format_is_plain(format)) { + if (!util_format_is_plain(format)) { return; } - if (tex->b.b.width0 == 1 || - tex->b.b.height0 == 1) { + /* If height == 1, disable microtiling except for zbuffer. */ + if (!is_zb && (tex->b.b.height0 == 1 || dbg_no_tiling)) { return; } @@ -860,6 +839,10 @@ static void r300_setup_tiling(struct pipe_screen *screen, break; } + if (dbg_no_tiling) { + return; + } + /* Set macrotiling. */ if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) && r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) { @@ -874,7 +857,7 @@ static unsigned r300_texture_is_referenced(struct pipe_context *context, struct r300_context *r300 = r300_context(context); struct r300_texture *rtex = (struct r300_texture *)texture; - if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer)) + if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer, R300_REF_CS)) return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; return PIPE_UNREFERENCED; @@ -890,13 +873,9 @@ static void r300_texture_destroy(struct pipe_screen *screen, FREE(tex); } - - - -static boolean - r300_texture_get_handle(struct pipe_screen* screen, - struct pipe_resource *texture, - struct winsys_handle *whandle) +static boolean r300_texture_get_handle(struct pipe_screen* screen, + struct pipe_resource *texture, + struct winsys_handle *whandle) { struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; struct r300_texture* tex = (struct r300_texture*)texture; @@ -913,8 +892,6 @@ static boolean return TRUE; } - - struct u_resource_vtbl r300_texture_vtbl = { r300_texture_get_handle, /* get_handle */ @@ -928,8 +905,6 @@ struct u_resource_vtbl r300_texture_vtbl = u_default_transfer_inline_write /* transfer_inline_write */ }; - - /* Create a new texture. */ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, const struct pipe_resource* base) @@ -942,6 +917,17 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, return NULL; } + /* Refuse to create a texture with size 0. */ + if (!base->width0 || + (!base->height0 && (base->target == PIPE_TEXTURE_2D || + base->target == PIPE_TEXTURE_CUBE)) || + (!base->depth0 && base->target == PIPE_TEXTURE_3D)) { + fprintf(stderr, "r300: texture_create: " + "Got invalid texture dimensions: %ix%ix%i\n", + base->width0, base->height0, base->depth0); + return NULL; + } + tex->b.b = *base; tex->b.vtbl = &r300_texture_vtbl; pipe_reference_init(&tex->b.b.reference, 1); @@ -957,6 +943,15 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, r300_texture_setup_immutable_state(rscreen, tex); r300_texture_setup_fb_state(rscreen, tex); + SCREEN_DBG(rscreen, DBG_TEX, + "r300: texture_create: Macro: %s, Micro: %s, Pitch: %i, " + "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n", + tex->macrotile ? "YES" : " NO", + tex->microtile ? "YES" : " NO", + tex->hwpitch[0], + base->width0, base->height0, base->depth0, base->last_level, + util_format_short_name(base->format)); + tex->buffer = rws->buffer_create(rws, 2048, PIPE_BIND_SAMPLER_VIEW, /* XXX */ tex->size); @@ -973,8 +968,6 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, return (struct pipe_resource*)tex; } - - /* Not required to implement u_resource_vtbl, consider moving to another file: */ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, @@ -1056,6 +1049,14 @@ r300_texture_from_handle(struct pipe_screen* screen, rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile); r300_setup_flags(tex); + SCREEN_DBG(rscreen, DBG_TEX, + "r300: texture_from_handle: Macro: %s, Micro: %s, " + "Pitch: % 4i, Dim: %ix%i, Format: %s\n", + tex->macrotile ? "YES" : " NO", + tex->microtile ? "YES" : " NO", + stride / util_format_get_blocksize(base->format), + base->width0, base->height0, + util_format_short_name(base->format)); /* Enforce microtiled zbuffer. */ override_zb_flags = util_format_is_depth_or_stencil(base->format) && @@ -1091,4 +1092,3 @@ r300_texture_from_handle(struct pipe_screen* screen, } return (struct pipe_resource*)tex; } -