summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nvfx/nvfx_miptree.c
diff options
context:
space:
mode:
authorLuca Barbieri <luca@luca-barbieri.com>2010-08-03 05:47:41 +0200
committerLuca Barbieri <luca@luca-barbieri.com>2010-08-21 20:42:14 +0200
commit28eb392a853bb43bdc6cfe7ba814f046c39ca7ae (patch)
tree6e7cc6d42f4a439aa8e543976e3893829a23be85 /src/gallium/drivers/nvfx/nvfx_miptree.c
parentff74143fcc80b0157875bb0ce4b34a80f92e09c2 (diff)
nvfx: new 2D: new render temporaries with resources
This patch adds support for creating temporary surfaces to allow rendering to surfaces that cannot be rendered to. It uses the _second_ version of the render temporary infrastructure. This is necessary for swizzled 3D textures and small mipmaps of swizzled 2D textures. This version of the patch creates a resource to use as a temporary instead of a raw BO, making the code simpler.
Diffstat (limited to 'src/gallium/drivers/nvfx/nvfx_miptree.c')
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 7deb9d7b9a..530d705e13 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -11,6 +11,7 @@
#include "nvfx_screen.h"
#include "nvfx_resource.h"
#include "nvfx_transfer.h"
+#include "nv04_2d.h"
static void
nvfx_miptree_choose_format(struct nvfx_miptree *mt)
@@ -115,16 +116,23 @@ nvfx_miptree_get_handle(struct pipe_screen *pscreen,
static void
+nvfx_miptree_surface_final_destroy(struct pipe_surface* ps)
+{
+ struct nvfx_surface* ns = (struct nvfx_surface*)ps;
+ pipe_resource_reference(&ps->texture, 0);
+ pipe_resource_reference((struct pipe_resource**)&ns->temp, 0);
+ FREE(ps);
+}
+
+static void
nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+ util_surfaces_destroy(&mt->surfaces, pt, nvfx_miptree_surface_final_destroy);
nouveau_screen_bo_release(screen, mt->base.bo);
FREE(mt);
}
-
-
-
struct u_resource_vtbl nvfx_miptree_vtbl =
{
nvfx_miptree_get_handle, /* get_handle */
@@ -152,6 +160,8 @@ nvfx_miptree_create_skeleton(struct pipe_screen *pscreen, const struct pipe_reso
mt->base.base = *pt;
mt->base.vtbl = &nvfx_miptree_vtbl;
+ util_dirty_surfaces_init(&mt->dirty_surfaces);
+
pipe_reference_init(&mt->base.base.reference, 1);
mt->base.base.screen = pscreen;
@@ -218,29 +228,28 @@ 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 nvfx_surface *ns;
- ns = CALLOC_STRUCT(nvfx_surface);
- if (!ns)
- return NULL;
- pipe_resource_reference(&ns->base.texture, pt);
- ns->base.format = pt->format;
- ns->base.width = u_minify(pt->width0, level);
- ns->base.height = u_minify(pt->height0, level);
- ns->base.usage = flags;
- pipe_reference_init(&ns->base.reference, 1);
- ns->base.face = face;
- ns->base.level = level;
- ns->base.zslice = zslice;
- ns->pitch = nvfx_subresource_pitch(pt, level);
- ns->base.offset = nvfx_subresource_offset(pt, face, level, zslice);
-
- return &ns->base;
+ ns = (struct nvfx_surface*)util_surfaces_get(&mt->surfaces, sizeof(struct nvfx_surface), pscreen, pt, face, level, zslice, flags);
+ if(ns->base.base.offset == ~0) {
+ util_dirty_surface_init(&ns->base);
+ ns->pitch = nvfx_subresource_pitch(pt, level);
+ ns->base.base.offset = nvfx_subresource_offset(pt, face, level, zslice);
+ }
+
+ return &ns->base.base;
}
void
nvfx_miptree_surface_del(struct pipe_surface *ps)
{
- pipe_resource_reference(&ps->texture, NULL);
- FREE(ps);
+ struct nvfx_surface* ns = (struct nvfx_surface*)ps;
+
+ if(!ns->temp)
+ {
+ util_surfaces_detach(&((struct nvfx_miptree*)ps->texture)->surfaces, ps);
+ pipe_resource_reference(&ps->texture, 0);
+ FREE(ps);
+ }
}