summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-05-10 03:27:58 +0200
committerJerome Glisse <jglisse@redhat.com>2010-05-27 23:24:02 +0200
commitb8fb1d75ce95fe5d404b301ab31ca0c323967d14 (patch)
tree78b648b638f7ed1560c569877c2c0c3b8b1dd81e /src/gallium/drivers/r600
parent72128962d640846472c1b0dc22cf4ac6ce875dc9 (diff)
r600g: adapt to latest interfaces changes
- Wrapped the buffer and texture create/destroy/transfer/... functions using u_resource, which is then used to implement the resource functions. - Implemented texture transfers. I left the buffer and texture transfers separate because one day we'll need a special codepath for textures. - Added index_bias to the draw_*elements functions. - Removed nonexistent *REP and *FOR instructions. - Some pipe formats have changed channel ordering, so I've removed/fixed nonexistent ones. - Added stubs for create/set/destroy sampler views. - Added a naive implementation of vertex elements state (new CSO). - Reworked {texture,buffer}_{from,to}_handle. - Reorganized winsys files, removed dri,egl,python directories. - Added a new build target dri-r600.
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/Makefile1
-rw-r--r--src/gallium/drivers/r600/SConscript9
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c173
-rw-r--r--src/gallium/drivers/r600/r600_compiler_tgsi.c14
-rw-r--r--src/gallium/drivers/r600/r600_context.c19
-rw-r--r--src/gallium/drivers/r600/r600_context.h6
-rw-r--r--src/gallium/drivers/r600/r600_draw.c12
-rw-r--r--src/gallium/drivers/r600/r600_helper.c18
-rw-r--r--src/gallium/drivers/r600/r600_resource.c68
-rw-r--r--src/gallium/drivers/r600/r600_resource.h33
-rw-r--r--src/gallium/drivers/r600/r600_screen.c86
-rw-r--r--src/gallium/drivers/r600/r600_screen.h37
-rw-r--r--src/gallium/drivers/r600/r600_state.c87
-rw-r--r--src/gallium/drivers/r600/r600_texture.c140
-rw-r--r--src/gallium/drivers/r600/r600_texture.h19
15 files changed, 490 insertions, 232 deletions
diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile
index bc58575c78..aae31a6a6e 100644
--- a/src/gallium/drivers/r600/Makefile
+++ b/src/gallium/drivers/r600/Makefile
@@ -13,6 +13,7 @@ C_SOURCES = \
r600_blit.c \
r600_helper.c \
r600_query.c \
+ r600_resource.c \
r600_screen.c \
r600_state.c \
r600_texture.c \
diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript
index a88c545252..26d95bb766 100644
--- a/src/gallium/drivers/r600/SConscript
+++ b/src/gallium/drivers/r600/SConscript
@@ -12,10 +12,19 @@ r600 = env.ConvenienceLibrary(
'r600_buffer.c',
'r600_context.c',
'r600_draw.c',
+ 'r600_blit.c',
+ 'r600_helper.c',
'r600_query.c',
+ 'r600_resource.c',
'r600_screen.c',
'r600_state.c',
'r600_texture.c',
+ 'r600_shader.c',
+ 'r600_compiler.c',
+ 'r600_compiler_tgsi.c',
+ 'r600_compiler_dump.c',
+ 'r600_compiler_r600.c',
+ 'r600_compiler_r700.c'
])
Export('r600')
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index f3a0208b00..634a02b686 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -29,89 +29,108 @@
#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"
#include "r600_context.h"
+extern struct u_resource_vtbl r600_buffer_vtbl;
+
static u32 r600_domain_from_usage(unsigned usage)
{
u32 domain = RADEON_GEM_DOMAIN_GTT;
- if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
+ if (usage & PIPE_BIND_RENDER_TARGET) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
+ }
+ if (usage & PIPE_BIND_DEPTH_STENCIL) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
}
- if (usage & PIPE_BUFFER_USAGE_PIXEL) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
+ if (usage & PIPE_BIND_SAMPLER_VIEW) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
}
- if (usage & PIPE_BUFFER_USAGE_VERTEX) {
- domain |= RADEON_GEM_DOMAIN_GTT;
+ /* also need BIND_BLIT_SOURCE/DESTINATION ? */
+ if (usage & PIPE_BIND_VERTEX_BUFFER) {
+ domain |= RADEON_GEM_DOMAIN_GTT;
}
- if (usage & PIPE_BUFFER_USAGE_INDEX) {
- domain |= RADEON_GEM_DOMAIN_GTT;
+ if (usage & PIPE_BIND_INDEX_BUFFER) {
+ domain |= RADEON_GEM_DOMAIN_GTT;
}
+
return domain;
}
-static struct pipe_buffer *r600_buffer_create(struct pipe_screen *screen,
- unsigned alignment,
- unsigned usage,
- unsigned size)
+struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
{
struct r600_screen *rscreen = r600_screen(screen);
- struct r600_pipe_buffer *rbuffer;
+ struct r600_buffer *rbuffer;
struct radeon_bo *bo;
struct pb_desc desc;
+ /* XXX We probably want a different alignment for buffers and textures. */
+ unsigned alignment = 4096;
- rbuffer = CALLOC_STRUCT(r600_pipe_buffer);
+ rbuffer = CALLOC_STRUCT(r600_buffer);
if (rbuffer == NULL)
return NULL;
- pipe_reference_init(&rbuffer->base.reference, 1);
- rbuffer->base.screen = screen;
- rbuffer->base.alignment = alignment;
- rbuffer->base.usage = usage;
- rbuffer->base.size = size;
+ pipe_reference_init(&rbuffer->b.b.reference, 1);
+ rbuffer->b.b = *templ;
+ rbuffer->b.b.screen = screen;
+ rbuffer->b.vtbl = &r600_buffer_vtbl;
- if (usage & PIPE_BUFFER_USAGE_CONSTANT) {
+ if (rbuffer->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
desc.alignment = alignment;
- desc.usage = usage;
- rbuffer->pb = pb_malloc_buffer_create(size, &desc);
+ desc.usage = rbuffer->b.b.bind;
+ rbuffer->pb = pb_malloc_buffer_create(rbuffer->b.b.width0,
+ &desc);
if (rbuffer->pb == NULL) {
free(rbuffer);
return NULL;
}
- return &rbuffer->base;
+ return &rbuffer->b.b;
}
- rbuffer->domain = r600_domain_from_usage(usage);
- bo = radeon_bo(rscreen->rw, 0, size, alignment, NULL);
+ rbuffer->domain = r600_domain_from_usage(rbuffer->b.b.bind);
+ bo = radeon_bo(rscreen->rw, 0, rbuffer->b.b.width0, alignment, NULL);
if (bo == NULL) {
FREE(rbuffer);
return NULL;
}
rbuffer->bo = bo;
- return &rbuffer->base;
+ return &rbuffer->b.b;
}
-static struct pipe_buffer *r600_user_buffer_create(struct pipe_screen *screen,
- void *ptr, unsigned bytes)
+struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
+ void *ptr, unsigned bytes,
+ unsigned bind)
{
- struct r600_pipe_buffer *rbuffer;
+ struct r600_buffer *rbuffer;
struct r600_screen *rscreen = r600_screen(screen);
-
- rbuffer = (struct r600_pipe_buffer*)r600_buffer_create(screen, 0, 0, bytes);
+ struct pipe_resource templ;
+
+ memset(&templ, 0, sizeof(struct pipe_resource));
+ templ.target = PIPE_BUFFER;
+ templ.format = PIPE_FORMAT_R8_UNORM;
+ templ.usage = PIPE_USAGE_IMMUTABLE;
+ templ.bind = bind;
+ templ.width0 = bytes;
+ templ.height0 = 1;
+ templ.depth0 = 1;
+
+ rbuffer = (struct r600_buffer*)r600_buffer_create(screen, &templ);
if (rbuffer == NULL) {
return NULL;
}
radeon_bo_map(rscreen->rw, rbuffer->bo);
memcpy(rbuffer->bo->data, ptr, bytes);
radeon_bo_unmap(rscreen->rw, rbuffer->bo);
- return &rbuffer->base;
+ return &rbuffer->b.b;
}
-static void r600_buffer_destroy(struct pipe_buffer *buffer)
+static void r600_buffer_destroy(struct pipe_screen *screen,
+ struct pipe_resource *buf)
{
- struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer;
- struct r600_screen *rscreen = r600_screen(buffer->screen);
+ struct r600_buffer *rbuffer = (struct r600_buffer*)buf;
+ struct r600_screen *rscreen = r600_screen(screen);
if (rbuffer->pb) {
pipe_reference_init(&rbuffer->pb->base.reference, 0);
@@ -124,34 +143,33 @@ static void r600_buffer_destroy(struct pipe_buffer *buffer)
FREE(rbuffer);
}
-static void *r600_buffer_map_range(struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned offset, unsigned length,
- unsigned usage)
+static void *r600_buffer_transfer_map(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
- struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer;
- struct r600_screen *rscreen = r600_screen(buffer->screen);
+ struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource;
+ struct r600_screen *rscreen = r600_screen(pipe->screen);
int write = 0;
if (rbuffer->pb) {
- return pb_map(rbuffer->pb, usage);
+ return pb_map(rbuffer->pb, transfer->usage) + transfer->box.x;
}
- if (usage & PIPE_BUFFER_USAGE_DONTBLOCK) {
+ if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
/* FIXME */
}
- if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
write = 1;
}
if (radeon_bo_map(rscreen->rw, rbuffer->bo)) {
return NULL;
}
- return rbuffer->bo->data;
+ return rbuffer->bo->data + transfer->box.x;
}
-static void r600_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *buffer)
+static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
- struct r600_pipe_buffer *rbuffer = (struct r600_pipe_buffer*)buffer;
- struct r600_screen *rscreen = r600_screen(buffer->screen);
+ struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource;
+ struct r600_screen *rscreen = r600_screen(pipe->screen);
if (rbuffer->pb) {
pb_unmap(rbuffer->pb);
@@ -160,18 +178,55 @@ static void r600_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *b
}
}
-static void r600_buffer_flush_mapped_range(struct pipe_screen *screen,
- struct pipe_buffer *buf,
- unsigned offset, unsigned length)
+static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
{
}
-void r600_screen_init_buffer_functions(struct pipe_screen *screen)
+unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
+ struct pipe_resource *buf,
+ unsigned face, unsigned level)
{
- screen->buffer_create = r600_buffer_create;
- screen->user_buffer_create = r600_user_buffer_create;
- screen->buffer_map_range = r600_buffer_map_range;
- screen->buffer_flush_mapped_range = r600_buffer_flush_mapped_range;
- screen->buffer_unmap = r600_buffer_unmap;
- screen->buffer_destroy = r600_buffer_destroy;
+ /* XXX */
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
+ struct winsys_handle *whandle)
+{
+ struct radeon *rw = (struct radeon*)screen->winsys;
+ struct r600_buffer *rbuffer;
+ struct radeon_bo *bo = NULL;
+
+ bo = radeon_bo(rw, whandle->handle, 0, 0, NULL);
+ if (bo == NULL) {
+ return NULL;
+ }
+
+ rbuffer = CALLOC_STRUCT(r600_buffer);
+ if (rbuffer == NULL) {
+ radeon_bo_decref(rw, bo);
+ return NULL;
+ }
+
+ pipe_reference_init(&rbuffer->b.b.reference, 1);
+ rbuffer->b.b.target = PIPE_BUFFER;
+ rbuffer->b.b.screen = screen;
+ rbuffer->b.vtbl = &r600_buffer_vtbl;
+ rbuffer->bo = bo;
+ return &rbuffer->b.b;
}
+
+struct u_resource_vtbl r600_buffer_vtbl =
+{
+ u_default_resource_get_handle, /* get_handle */
+ r600_buffer_destroy, /* resource_destroy */
+ r600_buffer_is_referenced_by_cs, /* is_buffer_referenced */
+ u_default_get_transfer, /* get_transfer */
+ u_default_transfer_destroy, /* transfer_destroy */
+ r600_buffer_transfer_map, /* transfer_map */
+ r600_buffer_transfer_flush_region, /* transfer_flush_region */
+ r600_buffer_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c
index 745f92272f..563ca063af 100644
--- a/src/gallium/drivers/r600/r600_compiler_tgsi.c
+++ b/src/gallium/drivers/r600/r600_compiler_tgsi.c
@@ -270,8 +270,6 @@ static unsigned tgsi_file_to_c_file(unsigned file)
return C_FILE_ADDRESS;
case TGSI_FILE_IMMEDIATE:
return C_FILE_IMMEDIATE;
- case TGSI_FILE_LOOP:
- return C_FILE_LOOP;
case TGSI_FILE_PREDICATE:
return C_FILE_PREDICATE;
case TGSI_FILE_SYSTEM_VALUE:
@@ -533,24 +531,12 @@ static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode)
case TGSI_OPCODE_IF:
*copcode = C_OPCODE_IF;
return 0;
- case TGSI_OPCODE_BGNFOR:
- *copcode = C_OPCODE_BGNFOR;
- return 0;
- case TGSI_OPCODE_REP:
- *copcode = C_OPCODE_REP;
- return 0;
case TGSI_OPCODE_ELSE:
*copcode = C_OPCODE_ELSE;
return 0;
case TGSI_OPCODE_ENDIF:
*copcode = C_OPCODE_ENDIF;
return 0;
- case TGSI_OPCODE_ENDFOR:
- *copcode = C_OPCODE_ENDFOR;
- return 0;
- case TGSI_OPCODE_ENDREP:
- *copcode = C_OPCODE_ENDREP;
- return 0;
case TGSI_OPCODE_PUSHA:
*copcode = C_OPCODE_PUSHA;
return 0;
diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c
index faefdb4378..e2760f9ecd 100644
--- a/src/gallium/drivers/r600/r600_context.c
+++ b/src/gallium/drivers/r600/r600_context.c
@@ -29,6 +29,7 @@
#include <util/u_format.h>
#include <util/u_memory.h>
#include <util/u_blitter.h>
+#include "r600_resource.h"
#include "r600_screen.h"
#include "r600_texture.h"
#include "r600_context.h"
@@ -40,21 +41,6 @@ static void r600_destroy_context(struct pipe_context *context)
FREE(rctx);
}
-static unsigned int r600_is_texture_referenced(struct pipe_context *context,
- struct pipe_texture *texture,
- unsigned face, unsigned level)
-{
- struct pipe_buffer *buffer = NULL;
-
- r600_get_texture_buffer(context->screen, texture, &buffer, NULL);
- return context->is_buffer_referenced(context, buffer);
-}
-
-static unsigned int r600_is_buffer_referenced(struct pipe_context *context, struct pipe_buffer *buffer)
-{
- return 0;
-}
-
static void r600_flush(struct pipe_context *ctx, unsigned flags,
struct pipe_fence_handle **fence)
{
@@ -90,11 +76,10 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
rctx->context.draw_arrays = r600_draw_arrays;
rctx->context.draw_elements = r600_draw_elements;
rctx->context.draw_range_elements = r600_draw_range_elements;
- rctx->context.is_texture_referenced = r600_is_texture_referenced;
- rctx->context.is_buffer_referenced = r600_is_buffer_referenced;
rctx->context.flush = r600_flush;
r600_init_query_functions(rctx);
r600_init_state_functions(rctx);
+ r600_init_context_resource_functions(rctx);
#if 0
rctx->blitter = util_blitter_create(&rctx->context);
if (rctx->blitter == NULL) {
diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h
index 4646df3b56..afe544819c 100644
--- a/src/gallium/drivers/r600/r600_context.h
+++ b/src/gallium/drivers/r600/r600_context.h
@@ -76,12 +76,12 @@ void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
unsigned start, unsigned count);
void r600_draw_elements(struct pipe_context *ctx,
struct pipe_buffer *index_buffer,
- unsigned index_size, unsigned mode,
+ unsigned index_size, unsigned index_bias, unsigned mode,
unsigned start, unsigned count);
void r600_draw_range_elements(struct pipe_context *ctx,
struct pipe_buffer *index_buffer,
- unsigned indexSize, unsigned minIndex,
- unsigned maxIndex, unsigned mode,
+ unsigned index_size, unsigned index_bias, unsigned min_index,
+ unsigned max_index, unsigned mode,
unsigned start, unsigned count);
void r600_state_destroy_common(struct r600_state *state);
diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c
index b903796311..aa254faf15 100644
--- a/src/gallium/drivers/r600/r600_draw.c
+++ b/src/gallium/drivers/r600/r600_draw.c
@@ -51,7 +51,7 @@ static int r600_draw_common(struct r600_draw *draw)
struct r600_context *rctx = (struct r600_context*)draw->ctx;
struct r600_screen *rscreen = (struct r600_screen*)draw->ctx->screen;
struct radeon_state *vs_resource;
- struct r600_pipe_buffer *rbuffer;
+ struct r600_buffer *rbuffer;
unsigned i, j, offset, format, prim;
u32 vgt_dma_index_type, vgt_draw_initiator;
int r;
@@ -101,7 +101,7 @@ static int r600_draw_common(struct r600_draw *draw)
for (i = 0 ; i < rctx->nvertex_element; i++) {
j = rctx->vertex_element[i].vertex_buffer_index;
- rbuffer = (struct r600_pipe_buffer*)rctx->vertex_buffer[j].buffer;
+ rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer;
offset = rctx->vertex_element[i].src_offset + rctx->vertex_buffer[j].buffer_offset;
r = r600_conv_pipe_format(rctx->vertex_element[i].src_format, &format);
if (r)
@@ -132,7 +132,7 @@ static int r600_draw_common(struct r600_draw *draw)
draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count;
draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator;
if (draw->index_buffer) {
- rbuffer = (struct r600_pipe_buffer*)draw->index_buffer;
+ rbuffer = (struct r600_buffer*)draw->index_buffer;
draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT;
draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT;
@@ -168,11 +168,12 @@ static int r600_draw_common(struct r600_draw *draw)
void r600_draw_range_elements(struct pipe_context *ctx,
struct pipe_buffer *index_buffer,
- unsigned index_size, unsigned min_index,
+ unsigned index_size, unsigned index_bias, unsigned min_index,
unsigned max_index, unsigned mode,
unsigned start, unsigned count)
{
struct r600_draw draw;
+ assert(index_bias == 0);
draw.ctx = ctx;
draw.mode = mode;
@@ -186,10 +187,11 @@ printf("index_size %d min %d max %d start %d count %d\n", index_size, min_inde
void r600_draw_elements(struct pipe_context *ctx,
struct pipe_buffer *index_buffer,
- unsigned index_size, unsigned mode,
+ unsigned index_size, unsigned index_bias, unsigned mode,
unsigned start, unsigned count)
{
struct r600_draw draw;
+ assert(index_bias == 0);
draw.ctx = ctx;
draw.mode = mode;
diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c
index 7757452104..c1b69cae30 100644
--- a/src/gallium/drivers/r600/r600_helper.c
+++ b/src/gallium/drivers/r600/r600_helper.c
@@ -47,34 +47,17 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_R8G8B8A8_USCALED:
- case PIPE_FORMAT_R8G8B8X8_USCALED:
case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_R8G8B8X8_SNORM:
- case PIPE_FORMAT_A8B8G8R8_SNORM:
- case PIPE_FORMAT_X8B8G8R8_SNORM:
case PIPE_FORMAT_R8G8B8A8_SSCALED:
- case PIPE_FORMAT_R8G8B8X8_SSCALED:
*format = V_0280A0_COLOR_8_8_8_8;
return 0;
- case PIPE_FORMAT_A1R5G5B5_UNORM:
- case PIPE_FORMAT_A4R4G4B4_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_A2B10G10R10_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_A8L8_UNORM:
case PIPE_FORMAT_L16_UNORM:
- case PIPE_FORMAT_YCBCR:
- case PIPE_FORMAT_YCBCR_REV:
case PIPE_FORMAT_Z16_UNORM:
case PIPE_FORMAT_Z32_UNORM:
case PIPE_FORMAT_Z32_FLOAT:
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_S8_UNORM:
case PIPE_FORMAT_R64_FLOAT:
case PIPE_FORMAT_R64G64_FLOAT:
case PIPE_FORMAT_R64G64B64_FLOAT:
@@ -122,7 +105,6 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
case PIPE_FORMAT_R8_SNORM:
case PIPE_FORMAT_R8G8_SNORM:
case PIPE_FORMAT_R8G8B8_SNORM:
- case PIPE_FORMAT_B6G5R5_SNORM:
case PIPE_FORMAT_R8_SSCALED:
case PIPE_FORMAT_R8G8_SSCALED:
case PIPE_FORMAT_R8G8B8_SSCALED:
diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c
new file mode 100644
index 0000000000..d9aa1df04f
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_resource.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "r600_context.h"
+#include "r600_resource.h"
+#include "r600_screen.h"
+#include "r600_texture.h"
+
+static struct pipe_resource *
+r600_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
+{
+ if (templ->target == PIPE_BUFFER)
+ return r600_buffer_create(screen, templ);
+ else
+ return r600_texture_create(screen, templ);
+}
+
+static struct pipe_resource *
+r600_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle)
+{
+ if (templ->target == PIPE_BUFFER)
+ return NULL;
+ else
+ return r600_texture_from_handle(screen, templ, whandle);
+}
+
+void r600_init_context_resource_functions(struct r600_context *r600)
+{
+ r600->context.get_transfer = u_get_transfer_vtbl;
+ r600->context.transfer_map = u_transfer_map_vtbl;
+ r600->context.transfer_flush_region = u_transfer_flush_region_vtbl;
+ r600->context.transfer_unmap = u_transfer_unmap_vtbl;
+ r600->context.transfer_destroy = u_transfer_destroy_vtbl;
+ r600->context.transfer_inline_write = u_transfer_inline_write_vtbl;
+ r600->context.is_resource_referenced = u_is_resource_referenced_vtbl;
+}
+
+void r600_init_screen_resource_functions(struct r600_screen *r600screen)
+{
+ r600screen->screen.resource_create = r600_resource_create;
+ r600screen->screen.resource_from_handle = r600_resource_from_handle;
+ r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl;
+ r600screen->screen.resource_destroy = u_resource_destroy_vtbl;
+ r600screen->screen.user_buffer_create = r600_user_buffer_create;
+}
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
new file mode 100644
index 0000000000..95084a371b
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef R600_RESOURCE_H
+#define R600_RESOURCE_H
+
+struct r600_context;
+struct r600_screen;
+
+void r600_init_context_resource_functions(struct r600_context *r600);
+void r600_init_screen_resource_functions(struct r600_screen *r600screen);
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c
index db17b88e9a..9cc4576151 100644
--- a/src/gallium/drivers/r600/r600_screen.c
+++ b/src/gallium/drivers/r600/r600_screen.c
@@ -27,6 +27,7 @@
#include <util/u_inlines.h>
#include <util/u_format.h>
#include <util/u_memory.h>
+#include "r600_resource.h"
#include "r600_screen.h"
#include "r600_texture.h"
#include "r600_context.h"
@@ -130,9 +131,9 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
return FALSE;
}
switch (format) {
- case PIPE_FORMAT_A4R4G4B4_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_A1R5G5B5_UNORM:
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_A8R8G8B8_SRGB:
@@ -141,21 +142,21 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
case PIPE_FORMAT_DXT1_RGBA:
case PIPE_FORMAT_DXT3_RGBA:
case PIPE_FORMAT_DXT5_RGBA:
- case PIPE_FORMAT_YCBCR:
+ case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_L8_SRGB:
- case PIPE_FORMAT_A8L8_SRGB:
- case PIPE_FORMAT_A8L8_UNORM:
+ case PIPE_FORMAT_L8A8_SRGB:
+ case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z32_UNORM:
- case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ case PIPE_FORMAT_Z24X8_UNORM:
return TRUE;
default:
/* Unknown format... */
@@ -164,13 +165,11 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
return FALSE;
}
-static struct pipe_transfer* r600_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y,
- unsigned w, unsigned h)
+struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box)
{
struct r600_texture *rtex = (struct r600_texture*)texture;
struct r600_transfer *trans;
@@ -178,31 +177,50 @@ static struct pipe_transfer* r600_get_tex_transfer(struct pipe_screen *screen,
trans = CALLOC_STRUCT(r600_transfer);
if (trans == NULL)
return NULL;
- pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.x = x;
- trans->transfer.y = y;
- trans->transfer.width = w;
- trans->transfer.height = h;
- trans->transfer.stride = rtex->stride[level];
+ pipe_resource_reference(&trans->transfer.resource, texture);
+ trans->transfer.sr = sr;
trans->transfer.usage = usage;
- trans->transfer.zslice = zslice;
- trans->transfer.face = face;
- trans->offset = r600_texture_get_offset(rtex, level, zslice, face);
+ trans->transfer.box = *box;
+ trans->transfer.stride = rtex->stride[sr.level];
+ trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
return &trans->transfer;
}
-static void r600_tex_transfer_destroy(struct pipe_transfer *trans)
+void r600_texture_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans)
{
+ pipe_resource_reference(&trans->resource, NULL);
+ FREE(trans);
}
-static void* r600_transfer_map(struct pipe_screen* screen, struct pipe_transfer* transfer)
+void* r600_texture_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer* transfer)
{
- /* FIXME implement */
- return NULL;
+ struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+ struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
+ char *map;
+ enum pipe_format format = rtex->b.b.format;
+
+ map = pipe_buffer_map(ctx, rtex->buffer,
+ transfer->usage,
+ &rtransfer->buffer_transfer);
+
+ if (!map) {
+ return NULL;
+ }
+
+ return map + rtransfer->offset +
+ transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
}
-static void r600_transfer_unmap(struct pipe_screen* screen, struct pipe_transfer* transfer)
+void r600_texture_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer* transfer)
{
+ struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+ struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
+
+ pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer);
}
static void r600_destroy_screen(struct pipe_screen* pscreen)
@@ -231,11 +249,7 @@ struct pipe_screen *radeon_create_screen(struct radeon *rw)
rscreen->screen.get_paramf = r600_get_paramf;
rscreen->screen.is_format_supported = r600_is_format_supported;
rscreen->screen.context_create = r600_create_context;
- rscreen->screen.get_tex_transfer = r600_get_tex_transfer;
- rscreen->screen.tex_transfer_destroy = r600_tex_transfer_destroy;
- rscreen->screen.transfer_map = r600_transfer_map;
- rscreen->screen.transfer_unmap = r600_transfer_unmap;
- r600_screen_init_buffer_functions(&rscreen->screen);
r600_init_screen_texture_functions(&rscreen->screen);
+ r600_init_screen_resource_functions(rscreen);
return &rscreen->screen;
}
diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h
index 97d57c027e..4748021d07 100644
--- a/src/gallium/drivers/r600/r600_screen.h
+++ b/src/gallium/drivers/r600/r600_screen.h
@@ -29,16 +29,21 @@
#include <xf86drm.h>
#include <radeon_drm.h>
#include "radeon.h"
+#include "util/u_transfer.h"
#define r600_screen(s) ((struct r600_screen*)s)
+/* Texture transfer. */
struct r600_transfer {
+ /* Base class. */
struct pipe_transfer transfer;
+ /* Buffer transfer. */
+ struct pipe_transfer *buffer_transfer;
unsigned offset;
};
-struct r600_pipe_buffer {
- struct pipe_buffer base;
+struct r600_buffer {
+ struct u_resource b;
struct radeon_bo *bo;
u32 domain;
u32 flink;
@@ -50,7 +55,33 @@ struct r600_screen {
struct radeon *rw;
};
-void r600_screen_init_buffer_functions(struct pipe_screen *screen);
+/* Buffer functions. */
+struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ);
+struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
+ void *ptr, unsigned bytes,
+ unsigned bind);
+unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
+ struct pipe_resource *buf,
+ unsigned face, unsigned level);
+struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
+ struct winsys_handle *whandle);
+
+/* Texture transfer functions. */
+struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box);
+void r600_texture_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans);
+void* r600_texture_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer* transfer);
+void r600_texture_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer* transfer);
+
+
+/* Blit functions. */
void r600_clear(struct pipe_context *ctx,
unsigned buffers,
const float *rgba,
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 96d45807e0..ac986af9f5 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -91,7 +91,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
struct r600_context *rctx = (struct r600_context*)ctx;
struct r600_texture *rtex;
- struct r600_pipe_buffer *rbuffer;
+ struct r600_buffer *rbuffer;
struct radeon_state *rstate;
unsigned level = state->cbufs[0]->level;
unsigned pitch, slice;
@@ -100,7 +100,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
if (rstate == NULL)
return;
rtex = (struct r600_texture*)state->cbufs[0]->texture;
- rbuffer = (struct r600_pipe_buffer*)rtex->buffer;
+ rbuffer = (struct r600_buffer*)rtex->buffer;
rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
@@ -217,9 +217,31 @@ static void r600_bind_sampler_states(struct pipe_context *ctx,
{
}
-static void r600_set_sampler_textures(struct pipe_context *ctx,
- unsigned count,
- struct pipe_texture **texture)
+static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ *view = *templ;
+ return view;
+}
+
+static void r600_sampler_view_destroy(struct pipe_context *ctx,
+ struct pipe_sampler_view *view)
+{
+ FREE(view);
+}
+
+static void r600_set_fragment_sampler_views(struct pipe_context *ctx,
+ unsigned count,
+ struct pipe_sampler_view **views)
+{
+}
+
+static void r600_set_vertex_sampler_views(struct pipe_context *ctx,
+ unsigned count,
+ struct pipe_sampler_view **views)
{
}
@@ -298,14 +320,37 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx,
rctx->nvertex_buffer = count;
}
-static void r600_set_vertex_elements(struct pipe_context *ctx,
- unsigned count,
- const struct pipe_vertex_element *elements)
+/* XXX move this to a more appropriate place */
+struct r600_vertex_elements_state
+{
+ unsigned count;
+ struct pipe_vertex_element elements[32];
+};
+
+static void *r600_create_vertex_elements_state(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
+{
+ struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state);
+
+ assert(count < 32);
+ v->count = count;
+ memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
+ return v;
+}
+
+static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state)
{
struct r600_context *rctx = (struct r600_context*)ctx;
+ struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state;
- memcpy(rctx->vertex_element, elements, sizeof(struct pipe_vertex_element) * count);
- rctx->nvertex_element = count;
+ memcpy(rctx->vertex_element, v->elements, v->count * sizeof(struct pipe_vertex_element));
+ rctx->nvertex_element = v->count;
+}
+
+static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state)
+{
+ FREE(state);
}
static void *r600_create_dsa_state(struct pipe_context *ctx,
@@ -347,13 +392,14 @@ static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
}
static void r600_set_constant_buffer(struct pipe_context *ctx,
- uint shader, uint index,
- struct pipe_buffer *buffer)
+ uint shader, uint index,
+ struct pipe_resource *buffer)
{
struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
struct r600_context *rctx = (struct r600_context*)ctx;
unsigned nconstant = 0, i, type, id;
struct radeon_state *rstate;
+ struct pipe_transfer *transfer;
u32 *ptr;
switch (shader) {
@@ -369,9 +415,9 @@ static void r600_set_constant_buffer(struct pipe_context *ctx,
fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
return;
}
- if (buffer && buffer->size > 0) {
- nconstant = buffer->size / 16;
- ptr = pipe_buffer_map(ctx->screen, buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ if (buffer && buffer->width0 > 0) {
+ nconstant = buffer->width0 / 16;
+ ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
if (ptr == NULL)
return;
for (i = 0; i < nconstant; i++) {
@@ -387,7 +433,7 @@ static void r600_set_constant_buffer(struct pipe_context *ctx,
if (radeon_draw_set_new(rctx->draw, rstate))
return;
}
- pipe_buffer_unmap(ctx->screen, buffer);
+ pipe_buffer_unmap(ctx, buffer, transfer);
}
}
@@ -421,11 +467,16 @@ void r600_init_state_functions(struct r600_context *rctx)
rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states;
rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states;
rctx->context.delete_sampler_state = r600_delete_state;
- rctx->context.set_fragment_sampler_textures = r600_set_sampler_textures;
+ rctx->context.create_sampler_view = r600_create_sampler_view;
+ rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
+ rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views;
+ rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views;
rctx->context.set_scissor_state = r600_set_scissor_state;
rctx->context.set_viewport_state = r600_set_viewport_state;
rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
- rctx->context.set_vertex_elements = r600_set_vertex_elements;
+ rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state;
+ rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state;
+ rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state;
rctx->context.create_vs_state = r600_create_vs_state;
rctx->context.bind_vs_state = r600_bind_vs_state;
rctx->context.delete_vs_state = r600_delete_state;
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;
}
diff --git a/src/gallium/drivers/r600/r600_texture.h b/src/gallium/drivers/r600/r600_texture.h
index a4424161eb..9bc08d6b04 100644
--- a/src/gallium/drivers/r600/r600_texture.h
+++ b/src/gallium/drivers/r600/r600_texture.h
@@ -26,21 +26,28 @@
#include <pipe/p_state.h>
struct r600_texture {
- struct pipe_texture tex;
+ struct u_resource b;
unsigned long offset[PIPE_MAX_TEXTURE_LEVELS];
unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
unsigned long stride[PIPE_MAX_TEXTURE_LEVELS];
unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS];
unsigned long stride_override;
unsigned long size;
- struct pipe_buffer *buffer;
+ struct pipe_resource *buffer;
};
+struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ);
unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face);
+struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *base,
+ struct winsys_handle *whandle);
void r600_init_screen_texture_functions(struct pipe_screen *screen);
-boolean r600_get_texture_buffer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
+
+/* This should be implemented by winsys. */
+boolean r600_buffer_get_handle(struct radeon *rw,
+ struct pipe_resource *buf,
+ struct winsys_handle *whandle);
+
#endif