Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
/*
2
 * Copyright (C) 2009 Francisco Jerez.
3
 * All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining
6
 * a copy of this software and associated documentation files (the
7
 * "Software"), to deal in the Software without restriction, including
8
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * distribute, sublicense, and/or sell copies of the Software, and to
10
 * permit persons to whom the Software is furnished to do so, subject to
11
 * the following conditions:
12
 *
13
 * The above copyright notice and this permission notice (including the
14
 * next paragraph) shall be included in all copies or substantial
15
 * portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 *
25
 */
26
 
27
#include "nouveau_driver.h"
28
#include "nouveau_bufferobj.h"
29
#include "nouveau_context.h"
30
 
31
#include "main/bufferobj.h"
32
 
33
static inline char *
34
get_bufferobj_map(struct gl_context *ctx, struct gl_buffer_object *obj,
35
		  unsigned flags)
36
{
37
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
38
	void *map = NULL;
39
 
40
	if (nbo->sys) {
41
		map = nbo->sys;
42
	} else if (nbo->bo) {
43
		nouveau_bo_map(nbo->bo, flags, context_client(ctx));
44
		map = nbo->bo->map;
45
	}
46
 
47
	return map;
48
}
49
 
50
static struct gl_buffer_object *
51
nouveau_bufferobj_new(struct gl_context *ctx, GLuint buffer, GLenum target)
52
{
53
	struct nouveau_bufferobj *nbo;
54
 
55
	nbo = CALLOC_STRUCT(nouveau_bufferobj);
56
	if (!nbo)
57
		return NULL;
58
 
59
	_mesa_initialize_buffer_object(ctx, &nbo->base, buffer, target);
60
 
61
	return &nbo->base;
62
}
63
 
64
static void
65
nouveau_bufferobj_del(struct gl_context *ctx, struct gl_buffer_object *obj)
66
{
67
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
68
 
69
	nouveau_bo_ref(NULL, &nbo->bo);
70
	free(nbo->sys);
71
	free(nbo);
72
}
73
 
74
static GLboolean
75
nouveau_bufferobj_data(struct gl_context *ctx, GLenum target, GLsizeiptrARB size,
76
		       const GLvoid *data, GLenum usage,
77
		       struct gl_buffer_object *obj)
78
{
79
	struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
80
	int ret;
81
 
82
	obj->Size = size;
83
	obj->Usage = usage;
84
 
85
	/* Free previous storage */
86
	nouveau_bo_ref(NULL, &nbo->bo);
87
	free(nbo->sys);
88
 
89
	if (target == GL_ELEMENT_ARRAY_BUFFER_ARB ||
90
	    (size < 512 && usage == GL_DYNAMIC_DRAW_ARB) ||
91
	    context_chipset(ctx) < 0x10) {
92
		/* Heuristic: keep it in system ram */
93
		nbo->sys = malloc(size);
94
 
95
	} else {
96
		/* Get a hardware BO */
97
		ret = nouveau_bo_new(context_dev(ctx),
98
				     NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
99
				     size, NULL, &nbo->bo);
100
		assert(!ret);
101
	}
102
 
103
	if (data)
104
		memcpy(get_bufferobj_map(ctx, obj, NOUVEAU_BO_WR), data, size);
105
 
106
	return GL_TRUE;
107
}
108
 
109
static void
110
nouveau_bufferobj_subdata(struct gl_context *ctx, GLintptrARB offset,
111
			  GLsizeiptrARB size, const GLvoid *data,
112
			  struct gl_buffer_object *obj)
113
{
114
	memcpy(get_bufferobj_map(ctx, obj, NOUVEAU_BO_WR) + offset, data, size);
115
}
116
 
117
static void
118
nouveau_bufferobj_get_subdata(struct gl_context *ctx, GLintptrARB offset,
119
			   GLsizeiptrARB size, GLvoid *data,
120
			   struct gl_buffer_object *obj)
121
{
122
	memcpy(data, get_bufferobj_map(ctx, obj, NOUVEAU_BO_RD) + offset, size);
123
}
124
 
125
static void *
126
nouveau_bufferobj_map_range(struct gl_context *ctx, GLintptr offset,
127
			    GLsizeiptr length, GLbitfield access,
128
			    struct gl_buffer_object *obj)
129
{
130
	unsigned flags = 0;
131
	char *map;
132
 
133
	assert(!obj->Pointer);
134
 
135
	if (!(access & GL_MAP_UNSYNCHRONIZED_BIT)) {
136
		if (access & GL_MAP_READ_BIT)
137
			flags |= NOUVEAU_BO_RD;
138
		if (access & GL_MAP_WRITE_BIT)
139
			flags |= NOUVEAU_BO_WR;
140
	}
141
 
142
	map = get_bufferobj_map(ctx, obj, flags);
143
	if (!map)
144
		return NULL;
145
 
146
	obj->Pointer = map + offset;
147
	obj->Offset = offset;
148
	obj->Length = length;
149
	obj->AccessFlags = access;
150
 
151
	return obj->Pointer;
152
}
153
 
154
static GLboolean
155
nouveau_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj)
156
{
157
	assert(obj->Pointer);
158
 
159
	obj->Pointer = NULL;
160
	obj->Offset = 0;
161
	obj->Length = 0;
162
	obj->AccessFlags = 0;
163
 
164
	return GL_TRUE;
165
}
166
 
167
void
168
nouveau_bufferobj_functions_init(struct dd_function_table *functions)
169
{
170
	functions->NewBufferObject = nouveau_bufferobj_new;
171
	functions->DeleteBuffer	= nouveau_bufferobj_del;
172
	functions->BufferData = nouveau_bufferobj_data;
173
	functions->BufferSubData = nouveau_bufferobj_subdata;
174
	functions->GetBufferSubData = nouveau_bufferobj_get_subdata;
175
	functions->MapBufferRange = nouveau_bufferobj_map_range;
176
	functions->UnmapBuffer = nouveau_bufferobj_unmap;
177
}