s/Tungsten Graphics/VMware/
[mesa.git] / src / mesa / drivers / dri / i965 / intel_upload.c
1 /*
2 * Copyright 2003 VMware, Inc.
3 * Copyright © 2007 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 /**
26 * @file intel_upload.c
27 *
28 * Batched upload via BOs.
29 */
30
31 #include "main/imports.h"
32 #include "main/mtypes.h"
33 #include "main/macros.h"
34 #include "main/bufferobj.h"
35
36 #include "brw_context.h"
37 #include "intel_blit.h"
38 #include "intel_buffer_objects.h"
39 #include "intel_batchbuffer.h"
40 #include "intel_fbo.h"
41 #include "intel_mipmap_tree.h"
42 #include "intel_regions.h"
43
44 #include "brw_context.h"
45
46 #define INTEL_UPLOAD_SIZE (64*1024)
47
48 void
49 intel_upload_finish(struct brw_context *brw)
50 {
51 if (!brw->upload.bo)
52 return;
53
54 if (brw->upload.buffer_len) {
55 drm_intel_bo_subdata(brw->upload.bo,
56 brw->upload.buffer_offset,
57 brw->upload.buffer_len,
58 brw->upload.buffer);
59 brw->upload.buffer_len = 0;
60 }
61
62 drm_intel_bo_unreference(brw->upload.bo);
63 brw->upload.bo = NULL;
64 }
65
66 static void
67 wrap_buffers(struct brw_context *brw, GLuint size)
68 {
69 intel_upload_finish(brw);
70
71 if (size < INTEL_UPLOAD_SIZE)
72 size = INTEL_UPLOAD_SIZE;
73
74 brw->upload.bo = drm_intel_bo_alloc(brw->bufmgr, "upload", size, 0);
75 brw->upload.offset = 0;
76 }
77
78 void
79 intel_upload_data(struct brw_context *brw,
80 const void *ptr, GLuint size, GLuint align,
81 drm_intel_bo **return_bo,
82 GLuint *return_offset)
83 {
84 GLuint base, delta;
85
86 base = (brw->upload.offset + align - 1) / align * align;
87 if (brw->upload.bo == NULL || base + size > brw->upload.bo->size) {
88 wrap_buffers(brw, size);
89 base = 0;
90 }
91
92 drm_intel_bo_reference(brw->upload.bo);
93 *return_bo = brw->upload.bo;
94 *return_offset = base;
95
96 delta = base - brw->upload.offset;
97 if (brw->upload.buffer_len &&
98 brw->upload.buffer_len + delta + size > sizeof(brw->upload.buffer)) {
99 drm_intel_bo_subdata(brw->upload.bo,
100 brw->upload.buffer_offset,
101 brw->upload.buffer_len,
102 brw->upload.buffer);
103 brw->upload.buffer_len = 0;
104 }
105
106 if (size < sizeof(brw->upload.buffer)) {
107 if (brw->upload.buffer_len == 0)
108 brw->upload.buffer_offset = base;
109 else
110 brw->upload.buffer_len += delta;
111
112 memcpy(brw->upload.buffer + brw->upload.buffer_len, ptr, size);
113 brw->upload.buffer_len += size;
114 } else {
115 drm_intel_bo_subdata(brw->upload.bo, base, size, ptr);
116 }
117
118 brw->upload.offset = base + size;
119 }
120
121 void *
122 intel_upload_map(struct brw_context *brw, GLuint size, GLuint align)
123 {
124 GLuint base, delta;
125 char *ptr;
126
127 base = (brw->upload.offset + align - 1) / align * align;
128 if (brw->upload.bo == NULL || base + size > brw->upload.bo->size) {
129 wrap_buffers(brw, size);
130 base = 0;
131 }
132
133 delta = base - brw->upload.offset;
134 if (brw->upload.buffer_len &&
135 brw->upload.buffer_len + delta + size > sizeof(brw->upload.buffer)) {
136 drm_intel_bo_subdata(brw->upload.bo,
137 brw->upload.buffer_offset,
138 brw->upload.buffer_len,
139 brw->upload.buffer);
140 brw->upload.buffer_len = 0;
141 }
142
143 if (size <= sizeof(brw->upload.buffer)) {
144 if (brw->upload.buffer_len == 0)
145 brw->upload.buffer_offset = base;
146 else
147 brw->upload.buffer_len += delta;
148
149 ptr = brw->upload.buffer + brw->upload.buffer_len;
150 brw->upload.buffer_len += size;
151 } else {
152 ptr = malloc(size);
153 }
154
155 return ptr;
156 }
157
158 void
159 intel_upload_unmap(struct brw_context *brw,
160 const void *ptr, GLuint size, GLuint align,
161 drm_intel_bo **return_bo,
162 GLuint *return_offset)
163 {
164 GLuint base;
165
166 base = (brw->upload.offset + align - 1) / align * align;
167 if (size > sizeof(brw->upload.buffer)) {
168 drm_intel_bo_subdata(brw->upload.bo, base, size, ptr);
169 free((void*)ptr);
170 }
171
172 drm_intel_bo_reference(brw->upload.bo);
173 *return_bo = brw->upload.bo;
174 *return_offset = base;
175
176 brw->upload.offset = base + size;
177 }