2 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * Copyright © 2007 Intel Corporation
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:
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
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
26 * @file intel_upload.c
28 * Batched upload via BOs.
31 #include "main/imports.h"
32 #include "main/mtypes.h"
33 #include "main/macros.h"
34 #include "main/bufferobj.h"
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"
44 #include "brw_context.h"
46 #define INTEL_UPLOAD_SIZE (64*1024)
49 intel_upload_finish(struct brw_context
*brw
)
54 if (brw
->upload
.buffer_len
) {
55 drm_intel_bo_subdata(brw
->upload
.bo
,
56 brw
->upload
.buffer_offset
,
57 brw
->upload
.buffer_len
,
59 brw
->upload
.buffer_len
= 0;
62 drm_intel_bo_unreference(brw
->upload
.bo
);
63 brw
->upload
.bo
= NULL
;
67 wrap_buffers(struct brw_context
*brw
, GLuint size
)
69 intel_upload_finish(brw
);
71 if (size
< INTEL_UPLOAD_SIZE
)
72 size
= INTEL_UPLOAD_SIZE
;
74 brw
->upload
.bo
= drm_intel_bo_alloc(brw
->bufmgr
, "upload", size
, 0);
75 brw
->upload
.offset
= 0;
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
)
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
);
92 drm_intel_bo_reference(brw
->upload
.bo
);
93 *return_bo
= brw
->upload
.bo
;
94 *return_offset
= base
;
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
,
103 brw
->upload
.buffer_len
= 0;
106 if (size
< sizeof(brw
->upload
.buffer
)) {
107 if (brw
->upload
.buffer_len
== 0)
108 brw
->upload
.buffer_offset
= base
;
110 brw
->upload
.buffer_len
+= delta
;
112 memcpy(brw
->upload
.buffer
+ brw
->upload
.buffer_len
, ptr
, size
);
113 brw
->upload
.buffer_len
+= size
;
115 drm_intel_bo_subdata(brw
->upload
.bo
, base
, size
, ptr
);
118 brw
->upload
.offset
= base
+ size
;
122 intel_upload_map(struct brw_context
*brw
, GLuint size
, GLuint align
)
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
);
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
,
140 brw
->upload
.buffer_len
= 0;
143 if (size
<= sizeof(brw
->upload
.buffer
)) {
144 if (brw
->upload
.buffer_len
== 0)
145 brw
->upload
.buffer_offset
= base
;
147 brw
->upload
.buffer_len
+= delta
;
149 ptr
= brw
->upload
.buffer
+ brw
->upload
.buffer_len
;
150 brw
->upload
.buffer_len
+= size
;
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
)
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
);
172 drm_intel_bo_reference(brw
->upload
.bo
);
173 *return_bo
= brw
->upload
.bo
;
174 *return_offset
= base
;
176 brw
->upload
.offset
= base
+ size
;