summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c6
-rw-r--r--src/gallium/drivers/nvfx/nv40_fragtex.c12
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c332
-rw-r--r--src/gallium/drivers/nvfx/nvfx_resource.h48
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_fb.c6
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.c27
6 files changed, 207 insertions, 224 deletions
diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c
index 0cd70ca104..85489eab28 100644
--- a/src/gallium/drivers/nvfx/nv30_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv30_fragtex.c
@@ -92,9 +92,9 @@ void
nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
- struct nvfx_miptree *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
- struct pipe_resource *pt = &nv30mt->base.base;
- struct nouveau_bo *bo = nv30mt->base.bo;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
+ struct pipe_resource *pt = &mt->base.base;
+ struct nouveau_bo *bo = mt->base.bo;
struct nv30_texture_format *tf;
struct nouveau_channel* chan = nvfx->screen->base.channel;
uint32_t txf, txs;
diff --git a/src/gallium/drivers/nvfx/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c
index 0d3e90dcb0..45c34c7ffd 100644
--- a/src/gallium/drivers/nvfx/nv40_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv40_fragtex.c
@@ -111,9 +111,9 @@ nv40_fragtex_set(struct nvfx_context *nvfx, int unit)
{
struct nouveau_channel* chan = nvfx->screen->base.channel;
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
- struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
- struct nouveau_bo *bo = nv40mt->base.bo;
- struct pipe_resource *pt = &nv40mt->base.base;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
+ struct nouveau_bo *bo = mt->base.bo;
+ struct pipe_resource *pt = &mt->base.base;
struct nv40_texture_format *tf;
uint32_t txf, txs, txp;
@@ -149,10 +149,10 @@ nv40_fragtex_set(struct nvfx_context *nvfx, int unit)
return;
}
- if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
+ if (!mt->linear_pitch)
txp = 0;
- } else {
- txp = nv40mt->level[0].pitch;
+ else {
+ txp = mt->linear_pitch;
txf |= NV40TCL_TEX_FORMAT_LINEAR;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 1fec1ffa42..0b08f88884 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -2,69 +2,111 @@
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "util/u_memory.h"
#include "util/u_math.h"
-
+#include "state_tracker/drm_driver.h"
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_screen.h"
+#include "nv04_surface_2d.h"
#include "nvfx_context.h"
#include "nvfx_resource.h"
#include "nvfx_transfer.h"
-#include "nv04_surface_2d.h"
-
-/* Currently using separate implementations for buffers and textures,
- * even though gallium has a unified abstraction of these objects.
- * Eventually these should be combined, and mechanisms like transfers
- * be adapted to work for both buffer and texture uploads.
- */
static void
-nvfx_miptree_layout(struct nvfx_miptree *mt)
+nvfx_miptree_choose_format(struct nvfx_miptree *mt)
{
struct pipe_resource *pt = &mt->base.base;
- uint width = pt->width0;
- uint offset = 0;
- int nr_faces, l, f;
- uint wide_pitch = pt->bind & (PIPE_BIND_SAMPLER_VIEW |
- PIPE_BIND_DEPTH_STENCIL |
- PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT);
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- nr_faces = 6;
- } else
- if (pt->target == PIPE_TEXTURE_3D) {
- nr_faces = pt->depth0;
- } else {
- nr_faces = 1;
+ unsigned uniform_pitch = 0;
+ static int no_swizzle = -1;
+ if(no_swizzle < 0)
+ no_swizzle = debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE);
+
+ /* Non-uniform pitch textures must be POT */
+ if (pt->width0 & (pt->width0 - 1) ||
+ pt->height0 & (pt->height0 - 1) ||
+ pt->depth0 & (pt->depth0 - 1)
+ )
+ uniform_pitch = 1;
+
+ /* All texture formats except compressed ones can be swizzled
+ * Unsure about depth, let's prevent swizzling for now
+ */
+ if (
+ (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET))
+ || (pt->usage & PIPE_USAGE_DYNAMIC) || (pt->usage & PIPE_USAGE_STAGING)
+ || util_format_is_depth_or_stencil(pt->format)
+ || util_format_is_compressed(pt->format)
+ // disable swizzled textures on NV04-NV20 as our current drivers don't fully support that
+ // TODO: hardware should support them, fix the drivers and reenable
+ || nouveau_screen(pt->screen)->device->chipset < 0x30
+ || no_swizzle
+
+ // disable swizzling for non-RGBA 2D because our current 2D code can't handle anything
+ // else correctly, and even that is semi-broken
+ || pt->target != PIPE_TEXTURE_2D
+ || (pt->format != PIPE_FORMAT_B8G8R8A8_UNORM && pt->format != PIPE_FORMAT_B8G8R8X8_UNORM)
+ )
+ mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
+
+ /* non compressed formats with uniform pitch must be linear, and vice versa */
+ if(!util_format_is_s3tc(pt->format)
+ && (uniform_pitch || mt->base.base.flags & NVFX_RESOURCE_FLAG_LINEAR))
+ {
+ mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
+ uniform_pitch = 1;
}
- for (l = 0; l <= pt->last_level; l++) {
- if (wide_pitch && (pt->flags & NVFX_RESOURCE_FLAG_LINEAR))
- mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64);
- else
- mt->level[l].pitch = util_format_get_stride(pt->format, width);
+ if(uniform_pitch)
+ {
+ mt->linear_pitch = util_format_get_stride(pt->format, pt->width0);
+
+ // TODO: this is only a constraint for rendering and not sampling, apparently
+ // we may also want this unconditionally
+ if(pt->bind & (PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DEPTH_STENCIL |
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT))
+ mt->linear_pitch = align(mt->linear_pitch, 64);
+ }
+ else
+ mt->linear_pitch = 0;
+}
- mt->level[l].image_offset =
- CALLOC(nr_faces, sizeof(unsigned));
+static unsigned
+nvfx_miptree_layout(struct nvfx_miptree *mt)
+{
+ struct pipe_resource* pt = &mt->base.base;
+ uint offset = 0;
- width = u_minify(width, 1);
+ if(!nvfx_screen(pt->screen)->is_nv4x)
+ {
+ assert(pt->target == PIPE_TEXTURE_RECT
+ || (util_is_pot(pt->width0) && util_is_pot(pt->height0)));
}
- for (f = 0; f < nr_faces; f++) {
- for (l = 0; l < pt->last_level; l++) {
- mt->level[l].image_offset[f] = offset;
+ for (unsigned l = 0; l <= pt->last_level; l++)
+ {
+ unsigned size;
+ mt->level_offset[l] = offset;
+
+ if(mt->linear_pitch)
+ size = mt->linear_pitch;
+ else
+ size = util_format_get_stride(pt->format, u_minify(pt->width0, l));
+ size = util_format_get_2d_size(pt->format, size, u_minify(pt->height0, l));
- if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR) &&
- u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1)
- offset += align(mt->level[l].pitch * u_minify(pt->height0, l), 64);
- else
- offset += mt->level[l].pitch * u_minify(pt->height0, l);
- }
+ if(pt->target == PIPE_TEXTURE_3D)
+ size *= u_minify(pt->depth0, l);
- mt->level[l].image_offset[f] = offset;
- offset += mt->level[l].pitch * u_minify(pt->height0, l);
+ offset += size;
}
- mt->total_size = offset;
+ offset = align(offset, 128);
+ mt->face_size = offset;
+ if(mt->base.base.target == PIPE_TEXTURE_CUBE)
+ offset += 5 * mt->face_size;
+ return offset;
}
static boolean
@@ -79,7 +121,7 @@ nvfx_miptree_get_handle(struct pipe_screen *pscreen,
return nouveau_screen_bo_get_handle(pscreen,
mt->base.bo,
- mt->level[0].pitch,
+ mt->linear_pitch,
whandle);
}
@@ -88,15 +130,7 @@ static void
nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
- int l;
-
nouveau_screen_bo_release(screen, mt->base.bo);
-
- for (l = 0; l <= pt->last_level; l++) {
- if (mt->level[l].image_offset)
- FREE(mt->level[l].image_offset);
- }
-
FREE(mt);
}
@@ -116,76 +150,50 @@ struct u_resource_vtbl nvfx_miptree_vtbl =
u_default_transfer_inline_write /* transfer_inline_write */
};
+static struct nvfx_miptree*
+nvfx_miptree_create_skeleton(struct pipe_screen *pscreen, const struct pipe_resource *pt)
+{
+ struct nvfx_miptree *mt;
+
+ if(pt->width0 > 4096 || pt->height0 > 4096)
+ return NULL;
+
+ mt = CALLOC_STRUCT(nvfx_miptree);
+ if (!mt)
+ return NULL;
+
+ mt->base.base = *pt;
+ mt->base.vtbl = &nvfx_miptree_vtbl;
+ pipe_reference_init(&mt->base.base.reference, 1);
+ mt->base.base.screen = pscreen;
+
+ // set this to the actual capabilities, we use it to decide whether to use the 3D engine for copies
+ // TODO: is this the correct way to use Gallium?
+ mt->base.base.bind = pt->bind | PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
+
+ // on our current driver (and the driver too), format support does not depend on geometry, so don't bother computing it
+ // TODO: may want to revisit this
+ if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_RENDER_TARGET, 0))
+ mt->base.base.bind &=~ PIPE_BIND_RENDER_TARGET;
+ if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ mt->base.base.bind &=~ PIPE_BIND_SAMPLER_VIEW;
+ if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_DEPTH_STENCIL, 0))
+ mt->base.base.bind &=~ PIPE_BIND_DEPTH_STENCIL;
+
+ return mt;
+}
struct pipe_resource *
nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt)
{
- struct nvfx_miptree *mt;
- static int no_swizzle = -1;
- if(no_swizzle < 0)
- no_swizzle = debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE);
-
- mt = CALLOC_STRUCT(nvfx_miptree);
- if (!mt)
- return NULL;
-
- mt->base.base = *pt;
- mt->base.vtbl = &nvfx_miptree_vtbl;
- pipe_reference_init(&mt->base.base.reference, 1);
- mt->base.base.screen = pscreen;
-
- /* Swizzled textures must be POT */
- if (pt->width0 & (pt->width0 - 1) ||
- pt->height0 & (pt->height0 - 1))
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
- else
- if (pt->bind & (PIPE_BIND_SCANOUT |
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_DEPTH_STENCIL))
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
- else
- if (pt->usage == PIPE_USAGE_DYNAMIC)
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
- else {
- switch (pt->format) {
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_I8_UNORM:
- /* TODO: we can actually swizzle these formats on nv40, we
- are just preserving the pre-unification behavior.
- The whole 2D code is going to be rewritten anyway. */
- if(nvfx_screen(pscreen)->is_nv4x) {
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
- break;
- }
- /* TODO: Figure out which formats can be swizzled */
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_R16_SNORM:
- {
- if (no_swizzle)
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
- break;
- }
- default:
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
- }
- }
+ struct nvfx_miptree* mt = nvfx_miptree_create_skeleton(pscreen, pt);
+ nvfx_miptree_choose_format(mt);
- /* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear.
- * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
- * This also happens for small mipmaps of large textures. */
- if (pt->bind & PIPE_BIND_RENDER_TARGET &&
- util_format_get_stride(pt->format, pt->width0) < 64)
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
+ unsigned size = nvfx_miptree_layout(mt);
- nvfx_miptree_layout(mt);
+ mt->base.bo = nouveau_screen_bo_new(pscreen, 256, pt->usage, pt->bind, size);
- mt->base.bo = nouveau_screen_bo_new(pscreen, 256,
- pt->usage, pt->bind, mt->total_size);
if (!mt->base.bo) {
FREE(mt);
return NULL;
@@ -193,54 +201,28 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt)
return &mt->base.base;
}
-
-
-
+// TODO: redo this, just calling miptree_layout
struct pipe_resource *
-nvfx_miptree_from_handle(struct pipe_screen *pscreen,
- const struct pipe_resource *template,
- struct winsys_handle *whandle)
+nvfx_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *whandle)
{
- struct nvfx_miptree *mt;
- unsigned stride;
-
- /* Only supports 2D, non-mipmapped textures for the moment */
- if ((template->target != PIPE_TEXTURE_2D &&
- template->target != PIPE_TEXTURE_RECT) ||
- template->last_level != 0 ||
- template->depth0 != 1)
- return NULL;
-
- mt = CALLOC_STRUCT(nvfx_miptree);
- if (!mt)
- return NULL;
-
- mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
- if (mt->base.bo == NULL) {
- FREE(mt);
- return NULL;
- }
-
- mt->base.base = *template;
- mt->base.vtbl = &nvfx_miptree_vtbl;
- pipe_reference_init(&mt->base.base.reference, 1);
- mt->base.base.screen = pscreen;
- mt->level[0].pitch = stride;
- mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
-
- /* Assume whoever created this buffer expects it to be linear for now */
- mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
-
- /* XXX: Need to adjust bo refcount??
- */
- /* nouveau_bo_ref(bo, &mt->base.bo); */
- return &mt->base.base;
+ struct nvfx_miptree* mt = nvfx_miptree_create_skeleton(pscreen, template);
+ if(whandle->stride) {
+ mt->linear_pitch = whandle->stride;
+ mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
+ } else
+ nvfx_miptree_choose_format(mt);
+
+ nvfx_miptree_layout(mt);
+
+ unsigned stride;
+ mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
+ if (mt->base.bo == NULL) {
+ FREE(mt);
+ return NULL;
+ }
+ return &mt->base.base;
}
-
-
-
-
/* Surface helpers, not strictly required to implement the resource vtbl:
*/
struct pipe_surface *
@@ -248,7 +230,6 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
- struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nv04_surface *ns;
ns = CALLOC_STRUCT(nv04_surface);
@@ -263,33 +244,8 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
ns->base.face = face;
ns->base.level = level;
ns->base.zslice = zslice;
- ns->pitch = mt->level[level].pitch;
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- ns->base.offset = mt->level[level].image_offset[face];
- } else
- if (pt->target == PIPE_TEXTURE_3D) {
- ns->base.offset = mt->level[level].image_offset[zslice];
- } else {
- ns->base.offset = mt->level[level].image_offset[0];
- }
-
- /* create a linear temporary that we can render into if
- * necessary.
- *
- * Note that ns->pitch is always a multiple of 64 for linear
- * surfaces and swizzled surfaces are POT, so ns->pitch & 63
- * is equivalent to (ns->pitch < 64 && swizzled)
- */
-
- if ((ns->pitch & 63) &&
- (ns->base.usage & PIPE_BIND_RENDER_TARGET))
- {
- struct nv04_surface_2d* eng2d =
- ((struct nvfx_screen*)pscreen)->eng2d;
-
- ns = nv04_surface_wrap_for_render(pscreen, eng2d, ns);
- }
+ ns->pitch = nvfx_subresource_pitch(pt, level);
+ ns->base.offset = nvfx_subresource_offset(pt, face, level, zslice);
return &ns->base;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_resource.h b/src/gallium/drivers/nvfx/nvfx_resource.h
index bdbf3dd3d8..0e24ec2f1f 100644
--- a/src/gallium/drivers/nvfx/nvfx_resource.h
+++ b/src/gallium/drivers/nvfx/nvfx_resource.h
@@ -39,15 +39,11 @@ nvfx_resource_on_gpu(struct pipe_resource* pr)
#define NVFX_MAX_TEXTURE_LEVELS 16
struct nvfx_miptree {
- struct nvfx_resource base;
- uint total_size;
+ struct nvfx_resource base;
- struct {
- uint pitch;
- uint *image_offset;
- } level[NVFX_MAX_TEXTURE_LEVELS];
-
- unsigned image_nr;
+ unsigned linear_pitch; /* for linear textures, 0 for swizzled and compressed textures with level-dependent minimal pitch */
+ unsigned face_size; /* 128-byte aligned face/total size */
+ unsigned level_offset[NVFX_MAX_TEXTURE_LEVELS];
};
static INLINE
@@ -103,5 +99,41 @@ nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags);
+/* only for miptrees, don't use for buffers */
+
+/* NOTE: for swizzled 3D textures, this just returns the offset of the mipmap level */
+static inline unsigned
+nvfx_subresource_offset(struct pipe_resource* pt, unsigned face, unsigned level, unsigned zslice)
+{
+ if(pt->target == PIPE_BUFFER)
+ return 0;
+ else
+ {
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+
+ unsigned offset = mt->level_offset[level];
+ if (pt->target == PIPE_TEXTURE_CUBE)
+ offset += mt->face_size * face;
+ else if (pt->target == PIPE_TEXTURE_3D && mt->linear_pitch)
+ offset += zslice * util_format_get_2d_size(pt->format, (mt->linear_pitch ? mt->linear_pitch : util_format_get_stride(pt->format, u_minify(pt->width0, level))), u_minify(pt->height0, level));
+ return offset;
+ }
+}
+
+static inline unsigned
+nvfx_subresource_pitch(struct pipe_resource* pt, unsigned level)
+{
+ if(pt->target == PIPE_BUFFER)
+ return ((struct nvfx_resource*)pt)->bo->size;
+ else
+ {
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+
+ if(mt->linear_pitch)
+ return mt->linear_pitch;
+ else
+ return util_format_get_stride(pt->format, u_minify(pt->width0, level));
+ }
+}
#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_state_fb.c b/src/gallium/drivers/nvfx/nvfx_state_fb.c
index 360e569f77..657e315f06 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_fb.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_fb.c
@@ -29,7 +29,7 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
colour_format = fb->cbufs[i]->format;
rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
- nvfx->hw_rt[i].bo = nvfx_surface_buffer(fb->cbufs[i]);
+ nvfx->hw_rt[i].bo = ((struct nvfx_miptree*)fb->cbufs[i]->texture)->base.bo;
nvfx->hw_rt[i].offset = fb->cbufs[i]->offset;
nvfx->hw_rt[i].pitch = ((struct nv04_surface *)fb->cbufs[i])->pitch;
}
@@ -42,7 +42,7 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
if (fb->zsbuf) {
zeta_format = fb->zsbuf->format;
- nvfx->hw_zeta.bo = nvfx_surface_buffer(fb->zsbuf);
+ nvfx->hw_zeta.bo = ((struct nvfx_miptree*)fb->zsbuf->texture)->base.bo;
nvfx->hw_zeta.offset = fb->zsbuf->offset;
nvfx->hw_zeta.pitch = ((struct nv04_surface *)fb->zsbuf)->pitch;
}
@@ -67,7 +67,7 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
depth_only = 1;
/* Render to depth buffer only */
- if (!(fb->zsbuf->texture->usage & NVFX_RESOURCE_FLAG_LINEAR)) {
+ if (!(fb->zsbuf->texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c
index 9ff0a93d30..957e586f81 100644
--- a/src/gallium/drivers/nvfx/nvfx_transfer.c
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.c
@@ -59,14 +59,9 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
const struct pipe_box *box)
{
struct pipe_screen *pscreen = pipe->screen;
- struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nvfx_transfer *tx;
struct pipe_resource tx_tex_template, *tx_tex;
- static int no_transfer = -1;
unsigned bind = nvfx_transfer_bind_flags(usage);
- if(no_transfer < 0)
- no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", FALSE);
-
tx = CALLOC_STRUCT(nvfx_transfer);
if (!tx)
@@ -78,13 +73,13 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
pipe_resource_reference(&tx->base.resource, pt);
tx->base.sr = sr;
+ tx->base.stride = nvfx_subresource_pitch(pt, sr.level);
+ tx->base.slice_stride = tx->base.stride * u_minify(pt->height0, sr.level);
tx->base.usage = usage;
tx->base.box = *box;
- tx->base.stride = mt->level[sr.level].pitch;
/* Direct access to texture */
- if ((pt->usage == PIPE_USAGE_DYNAMIC ||
- no_transfer) &&
+ if ((util_format_is_s3tc(pt->format) || pt->usage & PIPE_USAGE_DYNAMIC) &&
pt->flags & NVFX_RESOURCE_FLAG_LINEAR)
{
tx->direct = true;
@@ -109,7 +104,8 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe,
return NULL;
}
- tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch;
+ tx->base.stride = ((struct nvfx_miptree*)tx_tex)->linear_pitch;
+ tx->base.slice_stride = tx->base.stride * box->height;
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
0, 0, 0,
@@ -181,27 +177,26 @@ nvfx_miptree_transfer_del(struct pipe_context *pipe,
void *
nvfx_miptree_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct pipe_screen *pscreen = pipe->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
- uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo,
+
+ uint8_t *map = nouveau_screen_bo_map(pipe->screen, mt->base.bo,
nouveau_screen_transfer_flags(ptx->usage));
if(!tx->direct)
return map + ns->base.offset;
else
- return (map + ns->base.offset +
- ptx->box.y * ns->pitch +
- ptx->box.x * util_format_get_blocksize(ptx->resource->format));
+ return map + ns->base.offset
+ + util_format_get_2d_size(ns->base.format, ns->pitch, ptx->box.y)
+ + util_format_get_stride(ptx->resource->format, ptx->box.x);
}
void
nvfx_miptree_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct pipe_screen *pscreen = pipe->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
- nouveau_screen_bo_unmap(pscreen, mt->base.bo);
+ nouveau_screen_bo_unmap(pipe->screen, mt->base.bo);
}