summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r--src/gallium/drivers/r300/r300_texture.c195
1 files changed, 114 insertions, 81 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 5a013e2a25..6206570fca 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -21,30 +21,28 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#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"
+/* Always include headers in the reverse order!! ~ M. */
+#include "r300_texture.h"
#include "r300_context.h"
#include "r300_reg.h"
-#include "r300_texture.h"
#include "r300_transfer.h"
#include "r300_screen.h"
#include "r300_winsys.h"
-#define TILE_WIDTH 0
-#define TILE_HEIGHT 1
+#include "util/u_format.h"
+#include "util/u_format_s3tc.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "pipe/p_screen.h"
-static const unsigned microblock_table[5][3][2] = {
- /*linear tiled square-tiled */
- {{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */
- {{16, 1}, {8, 2}, {4, 4}}, /* 16 bits per pixel */
- {{ 8, 1}, {4, 2}, {0, 0}}, /* 32 bits per pixel */
- {{ 4, 1}, {0, 0}, {2, 2}}, /* 64 bits per pixel */
- {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
+/* XXX NO! just no! */
+#include "state_tracker/drm_driver.h"
+
+enum r300_dim {
+ DIM_WIDTH = 0,
+ DIM_HEIGHT = 1
};
unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
@@ -596,21 +594,21 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen,
/* Set framebuffer state. */
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->fb_state.pitch[i] =
tex->hwpitch[i] |
R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
R300_DEPTHMICROTILE(tex->microtile);
}
- tex->fb_state.zb_format = r300_translate_zsformat(tex->b.b.format);
+ tex->fb_state.format = r300_translate_zsformat(tex->b.b.format);
} else {
for (i = 0; i <= tex->b.b.last_level; i++) {
- tex->fb_state.colorpitch[i] =
+ tex->fb_state.pitch[i] =
tex->hwpitch[i] |
r300_translate_colorformat(tex->b.b.format) |
R300_COLOR_TILE(tex->mip_macrotile[i]) |
R300_COLOR_MICROTILE(tex->microtile);
}
- tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->b.b.format);
+ tex->fb_state.format = r300_translate_out_fmt(tex->b.b.format);
}
}
@@ -620,8 +618,10 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
{
struct r300_screen *r300screen = r300_screen(screen);
- SCREEN_DBG(r300screen, DBG_TEX, "r300: texture_reinterpret_format: %s -> %s\n",
- util_format_short_name(tex->format), util_format_short_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;
@@ -648,36 +648,65 @@ unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
}
}
-/**
- * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
- * of the given texture.
- */
-static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
- int dim, boolean macrotile)
+/* Returns the number of pixels that the texture should be aligned to
+ * in the given dimension. */
+static unsigned r300_get_pixel_alignment(struct r300_texture *tex,
+ enum r300_buffer_tiling macrotile,
+ enum r300_dim dim)
{
- unsigned pixsize, tile_size;
-
- pixsize = util_format_get_blocksize(tex->b.b.format);
- tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];
-
- if (macrotile) {
- tile_size *= 8;
+ static const unsigned table[2][5][3][2] =
+ {
+ {
+ /* Macro: linear linear linear
+ Micro: linear tiled square-tiled */
+ {{ 32, 1}, { 8, 4}, { 0, 0}}, /* 8 bits per pixel */
+ {{ 16, 1}, { 8, 2}, { 4, 4}}, /* 16 bits per pixel */
+ {{ 8, 1}, { 4, 2}, { 0, 0}}, /* 32 bits per pixel */
+ {{ 4, 1}, { 0, 0}, { 2, 2}}, /* 64 bits per pixel */
+ {{ 2, 1}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */
+ },
+ {
+ /* Macro: tiled tiled tiled
+ Micro: linear tiled square-tiled */
+ {{256, 8}, {64, 32}, { 0, 0}}, /* 8 bits per pixel */
+ {{128, 8}, {64, 16}, {32, 32}}, /* 16 bits per pixel */
+ {{ 64, 8}, {32, 16}, { 0, 0}}, /* 32 bits per pixel */
+ {{ 32, 8}, { 0, 0}, {16, 16}}, /* 64 bits per pixel */
+ {{ 16, 8}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */
+ }
+ };
+ static const unsigned aa_block[2] = {4, 8};
+ unsigned res = 0;
+ unsigned pixsize = util_format_get_blocksize(tex->b.b.format);
+
+ assert(macrotile <= R300_BUFFER_TILED);
+ assert(tex->microtile <= R300_BUFFER_SQUARETILED);
+ assert(pixsize <= 16);
+ assert(dim <= DIM_HEIGHT);
+
+ if (tex->b.b.nr_samples > 1) {
+ /* Multisampled textures have their own alignment scheme. */
+ if (pixsize == 4)
+ res = aa_block[dim];
+ } else {
+ /* Standard alignment. */
+ res = table[macrotile][util_logbase2(pixsize)][tex->microtile][dim];
}
- assert(tile_size);
- return tile_size;
+ assert(res);
+ return res;
}
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_texture *tex,
unsigned level,
boolean rv350_mode,
- int dim)
+ enum r300_dim dim)
{
unsigned tile, texdim;
- tile = r300_texture_get_tile_size(tex, dim, TRUE);
- if (dim == TILE_WIDTH) {
+ tile = r300_get_pixel_alignment(tex, R300_BUFFER_TILED, dim);
+ if (dim == DIM_WIDTH) {
texdim = u_minify(tex->b.b.width0, level);
} else {
texdim = u_minify(tex->b.b.height0, level);
@@ -713,8 +742,8 @@ unsigned r300_texture_get_stride(struct r300_screen* screen,
width = u_minify(tex->b.b.width0, level);
if (util_format_is_plain(tex->b.b.format)) {
- tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
- tex->mip_macrotile[level]);
+ tile_width = r300_get_pixel_alignment(tex, tex->mip_macrotile[level],
+ DIM_WIDTH);
width = align(width, tile_width);
stride = util_format_get_stride(tex->b.b.format, width);
@@ -743,8 +772,8 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
height = u_minify(tex->b.b.height0, level);
if (util_format_is_plain(tex->b.b.format)) {
- tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
- tex->mip_macrotile[level]);
+ tile_height = r300_get_pixel_alignment(tex, tex->mip_macrotile[level],
+ DIM_HEIGHT);
height = align(height, tile_height);
/* This is needed for the kernel checker, unfortunately. */
@@ -784,21 +813,26 @@ static void r300_setup_miptree(struct r300_screen* screen,
unsigned stride, size, layer_size, nblocksy, i;
boolean rv350_mode = screen->caps.is_rv350;
- SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Making miptree for texture, format %s\n",
- util_format_short_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. */
tex->mip_macrotile[i] =
(tex->macrotile == R300_BUFFER_TILED &&
- r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH) &&
- r300_texture_macro_switch(tex, i, rv350_mode, TILE_HEIGHT)) ?
+ r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) &&
+ r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ?
R300_BUFFER_TILED : R300_BUFFER_LINEAR;
stride = r300_texture_get_stride(screen, tex, i);
nblocksy = r300_texture_get_nblocksy(tex, i);
layer_size = stride * nblocksy;
+ if (base->nr_samples) {
+ layer_size *= base->nr_samples;
+ }
+
if (base->target == PIPE_TEXTURE_CUBE)
size = layer_size * 6;
else
@@ -864,8 +898,8 @@ static void r300_setup_tiling(struct pipe_screen *screen,
}
/* Set macrotiling. */
- if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) &&
- r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) {
+ if (r300_texture_macro_switch(tex, 0, rv350_mode, DIM_WIDTH) &&
+ r300_texture_macro_switch(tex, 0, rv350_mode, DIM_HEIGHT)) {
tex->macrotile = R300_BUFFER_TILED;
}
}
@@ -899,17 +933,14 @@ static boolean r300_texture_get_handle(struct pipe_screen* screen,
{
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
struct r300_texture* tex = (struct r300_texture*)texture;
- unsigned stride;
if (!tex) {
return FALSE;
}
- stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
-
- rws->buffer_get_handle(rws, tex->buffer, stride, whandle);
+ whandle->stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
- return TRUE;
+ return rws->buffer_get_handle(rws, tex->buffer, whandle);
}
struct u_resource_vtbl r300_texture_vtbl =
@@ -966,11 +997,12 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
SCREEN_DBG(rscreen, DBG_TEX,
"r300: texture_create: Macro: %s, Micro: %s, Pitch: %i, "
- "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
+ "Dim: %ix%ix%i, LastLevel: %i, Size: %i, Format: %s\n",
tex->macrotile ? "YES" : " NO",
tex->microtile ? "YES" : " NO",
tex->hwpitch[0],
base->width0, base->height0, base->depth0, base->last_level,
+ tex->size,
util_format_short_name(base->format));
tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ? R300_DOMAIN_GTT :
@@ -979,16 +1011,16 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
tex->buffer = rws->buffer_create(rws, 2048, base->bind, tex->domain,
tex->size);
+ if (!tex->buffer) {
+ FREE(tex);
+ return NULL;
+ }
+
rws->buffer_set_tiling(rws, tex->buffer,
tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
tex->microtile,
tex->macrotile);
- if (!tex->buffer) {
- FREE(tex);
- return NULL;
- }
-
return (struct pipe_resource*)tex;
}
@@ -1002,26 +1034,27 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
unsigned flags)
{
struct r300_texture* tex = r300_texture(texture);
- struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
- unsigned offset;
-
- offset = r300_texture_get_offset(tex, level, zslice, face);
+ struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
if (surface) {
- pipe_reference_init(&surface->reference, 1);
- pipe_resource_reference(&surface->texture, texture);
- surface->format = texture->format;
- surface->width = u_minify(texture->width0, level);
- surface->height = u_minify(texture->height0, level);
- surface->offset = offset;
- surface->usage = flags;
- surface->zslice = zslice;
- surface->texture = texture;
- surface->face = face;
- surface->level = level;
+ pipe_reference_init(&surface->base.reference, 1);
+ pipe_resource_reference(&surface->base.texture, texture);
+ surface->base.format = texture->format;
+ surface->base.width = u_minify(texture->width0, level);
+ surface->base.height = u_minify(texture->height0, level);
+ surface->base.usage = flags;
+ surface->base.zslice = zslice;
+ surface->base.face = face;
+ surface->base.level = level;
+
+ surface->buffer = tex->buffer;
+ surface->domain = tex->domain;
+ surface->offset = r300_texture_get_offset(tex, level, zslice, face);
+ surface->pitch = tex->fb_state.pitch[level];
+ surface->format = tex->fb_state.format;
}
- return surface;
+ return &surface->base;
}
/* Not required to implement u_resource_vtbl, consider moving to another file:
@@ -1041,7 +1074,6 @@ r300_texture_from_handle(struct pipe_screen* screen,
struct r300_screen* rscreen = r300_screen(screen);
struct r300_winsys_buffer *buffer;
struct r300_texture* tex;
- unsigned stride;
boolean override_zb_flags;
/* Support only 2D textures without mipmaps */
@@ -1051,7 +1083,8 @@ r300_texture_from_handle(struct pipe_screen* screen,
return NULL;
}
- buffer = rws->buffer_from_handle(rws, screen, whandle, &stride);
+ /* XXX make the winsys return the stride_override, see i915_resource_texture.c:830 */
+ buffer = rws->buffer_from_handle(rws, whandle->handle);
if (!buffer) {
return NULL;
}
@@ -1067,7 +1100,7 @@ r300_texture_from_handle(struct pipe_screen* screen,
tex->b.b.screen = screen;
tex->domain = R300_DOMAIN_VRAM;
- tex->stride_override = stride;
+ tex->stride_override = whandle->stride;
/* one ref already taken */
tex->buffer = buffer;
@@ -1079,7 +1112,7 @@ r300_texture_from_handle(struct pipe_screen* screen,
"Pitch: % 4i, Dim: %ix%i, Format: %s\n",
tex->macrotile ? "YES" : " NO",
tex->microtile ? "YES" : " NO",
- stride / util_format_get_blocksize(base->format),
+ whandle->stride / util_format_get_blocksize(base->format),
base->width0, base->height0,
util_format_short_name(base->format));