docs: Update status of GL 3.x related extensions
[mesa.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->data = ptr;
68 buffer->size = bytes;
69 buffer->bytes_to_draw_until_static = bytes * screen->static_reuse_threshold;
70 buffer->dirty_end = bytes;
71
72 return &buffer->base.base;
73 }
74
75 void nvfx_buffer_upload(struct nvfx_buffer* buffer)
76 {
77 unsigned dirty = buffer->dirty_end - buffer->dirty_begin;
78 if(!buffer->base.bo)
79 {
80 buffer->base.bo = nouveau_screen_bo_new(buffer->base.base.screen,
81 16,
82 buffer->base.base.usage,
83 buffer->base.base.bind,
84 buffer->base.base.width0);
85 }
86
87 if(dirty)
88 {
89 // TODO: may want to use a temporary in some cases
90 nouveau_bo_map(buffer->base.bo, NOUVEAU_BO_WR
91 | (buffer->dirty_unsynchronized ? NOUVEAU_BO_NOSYNC : 0));
92 memcpy((uint8_t*)buffer->base.bo->map + buffer->dirty_begin, buffer->data + buffer->dirty_begin, dirty);
93 nouveau_bo_unmap(buffer->base.bo);
94 buffer->dirty_begin = buffer->dirty_end = 0;
95 }
96 }