summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600/r600_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/r600_texture.c')
-rw-r--r--src/gallium/drivers/r600/r600_texture.c140
1 files changed, 87 insertions, 53 deletions
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 708f9effa3..b41d7a3b00 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -29,14 +29,17 @@
#include <util/u_math.h>
#include <util/u_inlines.h>
#include <util/u_memory.h>
+#include "state_tracker/drm_api.h"
#include "r600_screen.h"
#include "r600_texture.h"
+extern struct u_resource_vtbl r600_texture_vtbl;
+
unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face)
{
unsigned long offset = rtex->offset[level];
- switch (rtex->tex.target) {
+ switch (rtex->b.b.target) {
case PIPE_TEXTURE_3D:
assert(face == 0);
return offset + zslice * rtex->layer_size[level];
@@ -51,7 +54,7 @@ unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level,
static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture *rtex)
{
- struct pipe_texture *ptex = &rtex->tex;
+ struct pipe_resource *ptex = &rtex->b.b;
unsigned long w, h, stride, size, layer_size, i, offset;
for (i = 0, offset = 0; i <= ptex->last_level; i++) {
@@ -72,36 +75,50 @@ static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture
rtex->size = offset;
}
-static struct pipe_texture *r600_texture_create(struct pipe_screen *screen, const struct pipe_texture *template)
+struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
{
struct r600_texture *rtex = CALLOC_STRUCT(r600_texture);
struct r600_screen *rscreen = r600_screen(screen);
+ struct pipe_resource templ_buf;
if (!rtex) {
return NULL;
}
- rtex->tex = *template;
- pipe_reference_init(&rtex->tex.reference, 1);
- rtex->tex.screen = screen;
+ rtex->b.b = *templ;
+ rtex->b.vtbl = &r600_texture_vtbl;
+ pipe_reference_init(&rtex->b.b.reference, 1);
+ rtex->b.b.screen = screen;
r600_setup_miptree(rscreen, rtex);
- rtex->buffer = screen->buffer_create(screen, 4096, PIPE_BUFFER_USAGE_PIXEL, rtex->size);
+
+ memset(&templ_buf, 0, sizeof(struct pipe_resource));
+ templ_buf.target = PIPE_BUFFER;
+ templ_buf.format = PIPE_FORMAT_R8_UNORM;
+ templ_buf.usage = templ->usage;
+ templ_buf.bind = templ->bind;
+ templ_buf.width0 = rtex->size;
+ templ_buf.height0 = 1;
+ templ_buf.depth0 = 1;
+
+ rtex->buffer = screen->resource_create(screen, &templ_buf);
if (!rtex->buffer) {
FREE(rtex);
return NULL;
}
- return (struct pipe_texture*)&rtex->tex;
+ return &rtex->b.b;
}
-static void r600_texture_destroy(struct pipe_texture *ptex)
+static void r600_texture_destroy(struct pipe_screen *screen,
+ struct pipe_resource *ptex)
{
struct r600_texture *rtex = (struct r600_texture*)ptex;
- pipe_buffer_reference(&rtex->buffer, NULL);
+ pipe_resource_reference((struct pipe_resource**)&rtex, NULL);
FREE(rtex);
}
static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
- struct pipe_texture *texture,
+ struct pipe_resource *texture,
unsigned face, unsigned level,
unsigned zslice, unsigned flags)
{
@@ -113,7 +130,7 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
return NULL;
offset = r600_texture_get_offset(rtex, level, zslice, face);
pipe_reference_init(&surface->reference, 1);
- pipe_texture_reference(&surface->texture, texture);
+ pipe_resource_reference(&surface->texture, texture);
surface->format = texture->format;
surface->width = u_minify(texture->width0, level);
surface->height = u_minify(texture->height0, level);
@@ -128,71 +145,88 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
static void r600_tex_surface_destroy(struct pipe_surface *surface)
{
- pipe_texture_reference(&surface->texture, NULL);
+ pipe_resource_reference(&surface->texture, NULL);
FREE(surface);
}
-static struct pipe_texture *r600_texture_blanket(struct pipe_screen *screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *base,
+ struct winsys_handle *whandle)
{
+ struct pipe_resource *buffer;
struct r600_texture *rtex;
+ buffer = r600_buffer_from_handle(screen, whandle);
+ if (buffer == NULL) {
+ return NULL;
+ }
+
/* Support only 2D textures without mipmaps */
if (base->target != PIPE_TEXTURE_2D || base->depth0 != 1 || base->last_level != 0)
return NULL;
+
rtex = CALLOC_STRUCT(r600_texture);
if (rtex == NULL)
return NULL;
- rtex->tex = *base;
- pipe_reference_init(&rtex->tex.reference, 1);
- rtex->tex.screen = screen;
- rtex->stride_override = *stride;
- rtex->pitch[0] = *stride / util_format_get_blocksize(base->format);
- rtex->stride[0] = *stride;
+
+ /* one ref already taken */
+ rtex->buffer = buffer;
+
+ rtex->b.b = *base;
+ rtex->b.vtbl = &r600_texture_vtbl;
+ pipe_reference_init(&rtex->b.b.reference, 1);
+ rtex->b.b.screen = screen;
+ rtex->stride_override = whandle->stride;
+ rtex->pitch[0] = whandle->stride / util_format_get_blocksize(base->format);
+ rtex->stride[0] = whandle->stride;
rtex->offset[0] = 0;
rtex->size = align(rtex->stride[0] * base->height0, 32);
- pipe_buffer_reference(&rtex->buffer, buffer);
- return &rtex->tex;
+
+ return &rtex->b.b;
}
-static struct pipe_video_surface *r600_video_surface_create(struct pipe_screen *screen,
- enum pipe_video_chroma_format chroma_format,
- unsigned width, unsigned height)
+static boolean r600_texture_get_handle(struct pipe_screen* screen,
+ struct pipe_resource *texture,
+ struct winsys_handle *whandle)
{
- return NULL;
+ struct r600_screen *rscreen = r600_screen(screen);
+ struct r600_texture* rtex = (struct r600_texture*)texture;
+
+ if (!rtex) {
+ return FALSE;
+ }
+
+ whandle->stride = rtex->stride[0];
+
+ r600_buffer_get_handle(rscreen->rw, rtex->buffer, whandle);
+
+ return TRUE;
}
-static void r600_video_surface_destroy(struct pipe_video_surface *vsfc)
+static unsigned int r600_texture_is_referenced(struct pipe_context *context,
+ struct pipe_resource *texture,
+ unsigned face, unsigned level)
{
- FREE(vsfc);
+ struct r600_texture *rtex = (struct r600_texture*)texture;
+
+ return r600_buffer_is_referenced_by_cs(context, rtex->buffer, face, level);
}
+struct u_resource_vtbl r600_texture_vtbl =
+{
+ r600_texture_get_handle, /* get_handle */
+ r600_texture_destroy, /* resource_destroy */
+ r600_texture_is_referenced, /* is_resource_referenced */
+ r600_texture_get_transfer, /* get_transfer */
+ r600_texture_transfer_destroy, /* transfer_destroy */
+ r600_texture_transfer_map, /* transfer_map */
+ u_default_transfer_flush_region,/* transfer_flush_region */
+ r600_texture_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
void r600_init_screen_texture_functions(struct pipe_screen *screen)
{
- screen->texture_create = r600_texture_create;
- screen->texture_destroy = r600_texture_destroy;
screen->get_tex_surface = r600_get_tex_surface;
screen->tex_surface_destroy = r600_tex_surface_destroy;
- screen->texture_blanket = r600_texture_blanket;
- screen->video_surface_create = r600_video_surface_create;
- screen->video_surface_destroy= r600_video_surface_destroy;
-}
-
-boolean r600_get_texture_buffer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride)
-{
- struct r600_texture *rtex = (struct r600_texture*)texture;
-
- if (rtex == NULL) {
- return FALSE;
- }
- pipe_buffer_reference(buffer, rtex->buffer);
- if (stride) {
- *stride = rtex->stride[0];
- }
- return TRUE;
}