summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/nv50_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_resource.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c
index 1ae4d70a845..a66a6a02675 100644
--- a/src/gallium/drivers/nv50/nv50_resource.c
+++ b/src/gallium/drivers/nv50/nv50_resource.c
@@ -1,8 +1,11 @@
#include "pipe/p_context.h"
-#include "nv50_resource.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+
#include "nouveau/nouveau_screen.h"
+#include "nv50_resource.h"
static struct pipe_resource *
nv50_resource_create(struct pipe_screen *screen,
@@ -27,6 +30,59 @@ nv50_resource_from_handle(struct pipe_screen * screen,
return nv50_miptree_from_handle(screen, templ, whandle);
}
+struct pipe_surface *
+nv50_surface_from_buffer(struct pipe_context *pipe,
+ struct pipe_resource *pbuf,
+ const struct pipe_surface *templ)
+{
+ struct nv50_surface *sf = CALLOC_STRUCT(nv50_surface);
+ if (!sf)
+ return NULL;
+
+ pipe_reference_init(&sf->base.reference, 1);
+ pipe_resource_reference(&sf->base.texture, pbuf);
+
+ sf->base.format = templ->format;
+ sf->base.usage = templ->usage;
+ sf->base.u.buf.first_element = templ->u.buf.first_element;
+ sf->base.u.buf.last_element = templ->u.buf.last_element;
+
+ sf->offset =
+ templ->u.buf.first_element * util_format_get_blocksize(sf->base.format);
+
+ sf->offset &= ~0x7f; /* FIXME: RT_ADDRESS requires 128 byte alignment */
+
+ sf->width = templ->u.buf.last_element - templ->u.buf.first_element + 1;
+ sf->height = 1;
+ sf->depth = 1;
+
+ sf->base.width = sf->width;
+ sf->base.height = sf->height;
+
+ sf->base.context = pipe;
+ return &sf->base;
+}
+
+static struct pipe_surface *
+nv50_surface_create(struct pipe_context *pipe,
+ struct pipe_resource *pres,
+ const struct pipe_surface *templ)
+{
+ if (unlikely(pres->target == PIPE_BUFFER))
+ return nv50_surface_from_buffer(pipe, pres, templ);
+ return nv50_miptree_surface_new(pipe, pres, templ);
+}
+
+void
+nv50_surface_destroy(struct pipe_context *pipe, struct pipe_surface *ps)
+{
+ struct nv50_surface *s = nv50_surface(ps);
+
+ pipe_resource_reference(&ps->texture, NULL);
+
+ FREE(s);
+}
+
void
nv50_init_resource_functions(struct pipe_context *pcontext)
{
@@ -36,8 +92,8 @@ nv50_init_resource_functions(struct pipe_context *pcontext)
pcontext->transfer_unmap = u_transfer_unmap_vtbl;
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
- pcontext->create_surface = nv50_miptree_surface_new;
- pcontext->surface_destroy = nv50_miptree_surface_del;
+ pcontext->create_surface = nv50_surface_create;
+ pcontext->surface_destroy = nv50_surface_destroy;
}
void