Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / nvfx / nvfx_buffer.c
1
2 #include "util/u_inlines.h"
3 #include "util/u_memory.h"
4 #include "util/u_math.h"
5
6 #include "nouveau/nouveau_screen.h"
7 #include "nouveau/nouveau_winsys.h"
8 #include "nvfx_resource.h"
9 #include "nvfx_screen.h"
10
11 void nvfx_buffer_destroy(struct pipe_screen *pscreen,
12                                 struct pipe_resource *presource)
13 {
14         struct nvfx_buffer *buffer = nvfx_buffer(presource);
15
16         if(!(buffer->base.base.flags & NVFX_RESOURCE_FLAG_USER))
17                 align_free(buffer->data);
18         nouveau_screen_bo_release(pscreen, buffer->base.bo);
19         FREE(buffer);
20 }
21
22 struct pipe_resource *
23 nvfx_buffer_create(struct pipe_screen *pscreen,
24                    const struct pipe_resource *template)
25 {
26         struct nvfx_screen* screen = nvfx_screen(pscreen);
27         struct nvfx_buffer* buffer;
28
29         buffer = CALLOC_STRUCT(nvfx_buffer);
30         if (!buffer)
31                 return NULL;
32
33         buffer->base.base = *template;
34         buffer->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
35         pipe_reference_init(&buffer->base.base.reference, 1);
36         buffer->base.base.screen = pscreen;
37         buffer->size = util_format_get_stride(template->format, template->width0);
38         buffer->bytes_to_draw_until_static = buffer->size * screen->static_reuse_threshold;
39         buffer->data = align_malloc(buffer->size, 16);
40
41         return &buffer->base.base;
42 }
43
44
45 struct pipe_resource *
46 nvfx_user_buffer_create(struct pipe_screen *pscreen,
47                         void *ptr,
48                         unsigned bytes,
49                         unsigned usage)
50 {
51         struct nvfx_screen* screen = nvfx_screen(pscreen);
52         struct nvfx_buffer* buffer;
53
54         buffer = CALLOC_STRUCT(nvfx_buffer);
55         if (!buffer)
56                 return NULL;
57
58         pipe_reference_init(&buffer->base.base.reference, 1);
59         buffer->base.base.flags = NVFX_RESOURCE_FLAG_LINEAR | NVFX_RESOURCE_FLAG_USER;
60         buffer->base.base.screen = pscreen;
61         buffer->base.base.format = PIPE_FORMAT_R8_UNORM;
62         buffer->base.base.usage = PIPE_USAGE_IMMUTABLE;
63         buffer->base.base.bind = usage;
64         buffer->base.base.width0 = bytes;
65         buffer->base.base.height0 = 1;
66         buffer->base.base.depth0 = 1;
67         buffer->base.base.array_size = 1;
68         buffer->data = ptr;
69         buffer->size = bytes;
70         buffer->bytes_to_draw_until_static = bytes * screen->static_reuse_threshold;
71         buffer->dirty_end = bytes;
72
73         return &buffer->base.base;
74 }
75
76 void nvfx_buffer_upload(struct nvfx_buffer* buffer)
77 {
78         unsigned dirty = buffer->dirty_end - buffer->dirty_begin;
79         if(!buffer->base.bo)
80         {
81                 buffer->base.bo = nouveau_screen_bo_new(buffer->base.base.screen,
82                                            16,
83                                            buffer->base.base.usage,
84                                            buffer->base.base.bind,
85                                            buffer->base.base.width0);
86         }
87
88         if(dirty)
89         {
90                 // TODO: may want to use a temporary in some cases
91                 nouveau_bo_map(buffer->base.bo, NOUVEAU_BO_WR
92                                 | (buffer->dirty_unsynchronized ? NOUVEAU_BO_NOSYNC : 0));
93                 memcpy((uint8_t*)buffer->base.bo->map + buffer->dirty_begin, buffer->data + buffer->dirty_begin, dirty);
94                 nouveau_bo_unmap(buffer->base.bo);
95                 buffer->dirty_begin = buffer->dirty_end = 0;
96         }
97 }