1 /**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "main/arrayobj.h"
30 #include "main/image.h"
31 #include "main/macros.h"
32 #include "main/varray.h"
33
34 #include "vbo/vbo.h"
35
36 #include "st_context.h"
37 #include "st_atom.h"
38 #include "st_cb_bitmap.h"
39 #include "st_draw.h"
40 #include "st_program.h"
41 #include "st_util.h"
42
43 #include "pipe/p_context.h"
44 #include "pipe/p_defines.h"
45 #include "util/u_inlines.h"
46 #include "util/u_draw.h"
47 #include "util/format/u_format.h"
48
49 #include "draw/draw_private.h"
50 #include "draw/draw_context.h"
51
52
53 /**
54 * Set the (private) draw module's post-transformed vertex format when in
55 * GL_SELECT or GL_FEEDBACK mode or for glRasterPos.
56 */
57 static void
set_feedback_vertex_format(struct gl_context * ctx)58 set_feedback_vertex_format(struct gl_context *ctx)
59 {
60 #if 0
61 struct st_context *st = st_context(ctx);
62 struct vertex_info vinfo;
63 GLuint i;
64
65 memset(&vinfo, 0, sizeof(vinfo));
66
67 if (ctx->RenderMode == GL_SELECT) {
68 assert(ctx->RenderMode == GL_SELECT);
69 vinfo.num_attribs = 1;
70 vinfo.format[0] = FORMAT_4F;
71 vinfo.interp_mode[0] = INTERP_LINEAR;
72 }
73 else {
74 /* GL_FEEDBACK, or glRasterPos */
75 /* emit all attribs (pos, color, texcoord) as GLfloat[4] */
76 vinfo.num_attribs = st->state.vs->cso->state.num_outputs;
77 for (i = 0; i < vinfo.num_attribs; i++) {
78 vinfo.format[i] = FORMAT_4F;
79 vinfo.interp_mode[i] = INTERP_LINEAR;
80 }
81 }
82
83 draw_set_vertex_info(st->draw, &vinfo);
84 #endif
85 }
86
87
88 /**
89 * Called by VBO to draw arrays when in selection or feedback mode and
90 * to implement glRasterPos.
91 * This function mirrors the normal st_draw_vbo().
92 * Look at code refactoring some day.
93 */
94 void
st_feedback_draw_vbo(struct gl_context * ctx,const struct pipe_draw_info * info,unsigned drawid_offset,const struct pipe_draw_indirect_info * indirect,const struct pipe_draw_start_count_bias * draws,unsigned num_draws)95 st_feedback_draw_vbo(struct gl_context *ctx,
96 const struct pipe_draw_info *info,
97 unsigned drawid_offset,
98 const struct pipe_draw_indirect_info *indirect,
99 const struct pipe_draw_start_count_bias *draws,
100 unsigned num_draws)
101 {
102 struct st_context *st = st_context(ctx);
103 struct pipe_context *pipe = st->pipe;
104 struct draw_context *draw = st_get_draw_context(st);
105 struct gl_vertex_program *vp;
106 struct st_common_variant *vp_variant;
107 struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
108 unsigned num_vbuffers = 0;
109 struct cso_velems_state velements;
110 struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL};
111 struct pipe_transfer *ib_transfer = NULL;
112 GLuint i;
113 const void *mapped_indices = NULL;
114
115 if (!draw)
116 return;
117
118 /* must get these after state validation! */
119 struct st_common_variant_key key = {
120 .st = st,
121 .passthrough_edgeflags = st->ctx->Array._PerVertexEdgeFlagsEnabled,
122 .is_draw_shader = true
123 };
124 vp = (struct gl_vertex_program *)ctx->VertexProgram._Current;
125 vp_variant = st_get_common_variant(st, &vp->Base, &key);
126
127 /*
128 * Set up the draw module's state.
129 *
130 * We'd like to do this less frequently, but the normal state-update
131 * code sends state updates to the pipe, not to our private draw module.
132 */
133 assert(draw);
134 draw_set_viewport_states(draw, 0, 1, &st->state.viewport[0]);
135 draw_set_clip_state(draw, &st->state.clip);
136 draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
137 draw_bind_vertex_shader(draw, vp_variant->base.driver_shader);
138 set_feedback_vertex_format(ctx);
139
140 /* Must setup these after state validation! */
141 /* Setup arrays */
142 st_setup_arrays(st, vp, vp_variant, &velements, vbuffers, &num_vbuffers);
143 /* Setup current values as userspace arrays */
144 st_setup_current_user(st, vp, vp_variant, &velements, vbuffers, &num_vbuffers);
145
146 /* Map all buffers and tell draw about their mapping */
147 for (unsigned buf = 0; buf < num_vbuffers; ++buf) {
148 struct pipe_vertex_buffer *vbuffer = &vbuffers[buf];
149
150 if (vbuffer->is_user_buffer) {
151 draw_set_mapped_vertex_buffer(draw, buf, vbuffer->buffer.user, ~0);
152 } else {
153 void *map = pipe_buffer_map(pipe, vbuffer->buffer.resource,
154 PIPE_MAP_READ, &vb_transfer[buf]);
155 draw_set_mapped_vertex_buffer(draw, buf, map,
156 vbuffer->buffer.resource->width0);
157 }
158 }
159
160 draw_set_vertex_elements(draw, vp->num_inputs, velements.velems);
161 draw_set_vertex_buffers(draw, num_vbuffers, vbuffers);
162
163 if (info->index_size) {
164 if (info->has_user_indices) {
165 mapped_indices = info->index.user;
166 } else {
167 mapped_indices = pipe_buffer_map(pipe, info->index.resource,
168 PIPE_MAP_READ, &ib_transfer);
169 }
170
171 draw_set_indexes(draw, (uint8_t *)mapped_indices, info->index_size, ~0);
172 }
173
174 /* set constant buffer 0 */
175 struct gl_program_parameter_list *params = vp->Base.Parameters;
176
177 /* Update the constants which come from fixed-function state, such as
178 * transformation matrices, fog factors, etc.
179 *
180 * It must be done here if the state tracker doesn't update state vars
181 * in gl_program_parameter_list because allow_constbuf0_as_real_buffer
182 * is set.
183 */
184 if ((st->prefer_real_buffer_in_constbuf0 || st->allow_st_finalize_nir_twice) && params->StateFlags)
185 _mesa_load_state_parameters(st->ctx, params);
186
187 draw_set_constant_buffer_stride(draw, sizeof(float));
188 draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
189 params->ParameterValues,
190 params->NumParameterValues * 4);
191
192 /* set uniform buffers */
193 const struct gl_program *prog = &vp->Base;
194 struct pipe_transfer *ubo_transfer[PIPE_MAX_CONSTANT_BUFFERS] = {0};
195 assert(prog->info.num_ubos <= ARRAY_SIZE(ubo_transfer));
196
197 for (unsigned i = 0; i < prog->sh.NumUniformBlocks; i++) {
198 struct gl_buffer_binding *binding =
199 &st->ctx->UniformBufferBindings[prog->sh.UniformBlocks[i]->Binding];
200 struct gl_buffer_object *st_obj = binding->BufferObject;
201 struct pipe_resource *buf = st_obj->buffer;
202
203 if (!buf)
204 continue;
205
206 unsigned offset = binding->Offset;
207 unsigned size = buf->width0 - offset;
208
209 /* AutomaticSize is FALSE if the buffer was set with BindBufferRange.
210 * Take the minimum just to be sure.
211 */
212 if (!binding->AutomaticSize)
213 size = MIN2(size, (unsigned) binding->Size);
214
215 void *ptr = pipe_buffer_map_range(pipe, buf, offset, size,
216 PIPE_MAP_READ, &ubo_transfer[i]);
217
218 draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 1 + i, ptr,
219 size);
220 }
221
222 /* shader buffers */
223 /* TODO: atomic counter buffers */
224 struct pipe_transfer *ssbo_transfer[PIPE_MAX_SHADER_BUFFERS] = {0};
225
226 for (unsigned i = 0; i < prog->info.num_ssbos; i++) {
227 struct gl_buffer_binding *binding =
228 &st->ctx->ShaderStorageBufferBindings[
229 prog->sh.ShaderStorageBlocks[i]->Binding];
230 struct gl_buffer_object *st_obj = binding->BufferObject;
231 struct pipe_resource *buf = st_obj->buffer;
232
233 if (!buf)
234 continue;
235
236 unsigned offset = binding->Offset;
237 unsigned size = buf->width0 - binding->Offset;
238
239 /* AutomaticSize is FALSE if the buffer was set with BindBufferRange.
240 * Take the minimum just to be sure.
241 */
242 if (!binding->AutomaticSize)
243 size = MIN2(size, (unsigned) binding->Size);
244
245 void *ptr = pipe_buffer_map_range(pipe, buf, offset, size,
246 PIPE_MAP_READ, &ssbo_transfer[i]);
247
248 draw_set_mapped_shader_buffer(draw, PIPE_SHADER_VERTEX,
249 i, ptr, size);
250 }
251
252 /* samplers */
253 struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
254 for (unsigned i = 0; i < st->state.num_vert_samplers; i++)
255 samplers[i] = &st->state.vert_samplers[i];
256
257 draw_set_samplers(draw, PIPE_SHADER_VERTEX, samplers,
258 st->state.num_vert_samplers);
259
260 /* sampler views */
261 struct pipe_sampler_view *views[PIPE_MAX_SAMPLERS];
262 unsigned num_views =
263 st_get_sampler_views(st, PIPE_SHADER_VERTEX, prog, views);
264
265 draw_set_sampler_views(draw, PIPE_SHADER_VERTEX, views, num_views);
266
267 struct pipe_transfer *sv_transfer[PIPE_MAX_SAMPLERS][PIPE_MAX_TEXTURE_LEVELS];
268
269 for (unsigned i = 0; i < num_views; i++) {
270 struct pipe_sampler_view *view = views[i];
271 if (!view)
272 continue;
273
274 struct pipe_resource *res = view->texture;
275 unsigned width0 = res->width0;
276 unsigned num_layers = res->depth0;
277 unsigned first_level = 0;
278 unsigned last_level = 0;
279 uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
280 uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
281 uint32_t mip_offset[PIPE_MAX_TEXTURE_LEVELS];
282 uintptr_t mip_addr[PIPE_MAX_TEXTURE_LEVELS];
283 uintptr_t base_addr;
284
285 if (res->target != PIPE_BUFFER) {
286 first_level = view->u.tex.first_level;
287 last_level = view->u.tex.last_level;
288 num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
289 base_addr = UINTPTR_MAX;
290
291 for (unsigned j = first_level; j <= last_level; j++) {
292 unsigned map_layers = res->target == PIPE_TEXTURE_3D ?
293 util_num_layers(res, j) : num_layers;
294
295 sv_transfer[i][j] = NULL;
296 mip_addr[j] = (uintptr_t)
297 pipe_texture_map_3d(pipe, res, j,
298 PIPE_MAP_READ, 0, 0,
299 view->u.tex.first_layer,
300 u_minify(res->width0, j),
301 u_minify(res->height0, j),
302 map_layers, &sv_transfer[i][j]);
303 row_stride[j] = sv_transfer[i][j]->stride;
304 img_stride[j] = sv_transfer[i][j]->layer_stride;
305
306 /* Get the minimum address, because the draw module takes only
307 * 1 address for the whole texture + uint32 offsets for mip levels,
308 * so we need to convert mapped resource pointers into that scheme.
309 */
310 base_addr = MIN2(base_addr, mip_addr[j]);
311 }
312 for (unsigned j = first_level; j <= last_level; j++) {
313 /* TODO: The draw module should accept pointers for mipmap levels
314 * instead of offsets. This is unlikely to work on 64-bit archs.
315 */
316 assert(mip_addr[j] - base_addr <= UINT32_MAX);
317 mip_offset[j] = mip_addr[j] - base_addr;
318 }
319 } else {
320 width0 = view->u.buf.size / util_format_get_blocksize(view->format);
321
322 /* probably don't really need to fill that out */
323 mip_offset[0] = 0;
324 row_stride[0] = 0;
325 img_stride[0] = 0;
326
327 sv_transfer[i][0] = NULL;
328 base_addr = (uintptr_t)
329 pipe_buffer_map_range(pipe, res, view->u.buf.offset,
330 view->u.buf.size,
331 PIPE_MAP_READ,
332 &sv_transfer[i][0]);
333 }
334
335 draw_set_mapped_texture(draw, PIPE_SHADER_VERTEX, i, width0,
336 res->height0, num_layers, first_level,
337 last_level, 0, 0, (void*)base_addr, row_stride,
338 img_stride, mip_offset);
339 }
340
341 /* shader images */
342 struct pipe_image_view images[PIPE_MAX_SHADER_IMAGES];
343 struct pipe_transfer *img_transfer[PIPE_MAX_SHADER_IMAGES] = {0};
344
345 for (unsigned i = 0; i < prog->info.num_images; i++) {
346 struct pipe_image_view *img = &images[i];
347
348 st_convert_image_from_unit(st, img, prog->sh.ImageUnits[i],
349 prog->sh.image_access[i]);
350
351 struct pipe_resource *res = img->resource;
352 if (!res)
353 continue;
354
355 unsigned width, height, num_layers, row_stride, img_stride;
356 void *addr;
357
358 if (res->target != PIPE_BUFFER) {
359 width = u_minify(res->width0, img->u.tex.level);
360 height = u_minify(res->height0, img->u.tex.level);
361 num_layers = img->u.tex.last_layer - img->u.tex.first_layer + 1;
362
363 addr = pipe_texture_map_3d(pipe, res, img->u.tex.level,
364 PIPE_MAP_READ, 0, 0,
365 img->u.tex.first_layer,
366 width, height, num_layers,
367 &img_transfer[i]);
368 row_stride = img_transfer[i]->stride;
369 img_stride = img_transfer[i]->layer_stride;
370 } else {
371 width = img->u.buf.size / util_format_get_blocksize(img->format);
372
373 /* probably don't really need to fill that out */
374 row_stride = 0;
375 img_stride = 0;
376 height = num_layers = 1;
377
378 addr = pipe_buffer_map_range(pipe, res, img->u.buf.offset,
379 img->u.buf.size, PIPE_MAP_READ,
380 &img_transfer[i]);
381 }
382
383 draw_set_mapped_image(draw, PIPE_SHADER_VERTEX, i, width, height,
384 num_layers, addr, row_stride, img_stride, 0, 0);
385 }
386 draw_set_images(draw, PIPE_SHADER_VERTEX, images, prog->info.num_images);
387
388 /* draw here */
389 for (i = 0; i < num_draws; i++) {
390 draw_vbo(draw, info, info->increment_draw_id ? i : 0, indirect,
391 &draws[i], 1, ctx->TessCtrlProgram.patch_vertices);
392 }
393
394 /* unmap images */
395 for (unsigned i = 0; i < prog->info.num_images; i++) {
396 if (img_transfer[i]) {
397 draw_set_mapped_image(draw, PIPE_SHADER_VERTEX, i, 0, 0, 0, NULL, 0, 0, 0, 0);
398 if (img_transfer[i]->resource->target == PIPE_BUFFER)
399 pipe_buffer_unmap(pipe, img_transfer[i]);
400 else
401 pipe_texture_unmap(pipe, img_transfer[i]);
402 }
403 }
404
405 /* unmap sampler views */
406 for (unsigned i = 0; i < num_views; i++) {
407 struct pipe_sampler_view *view = views[i];
408
409 if (view) {
410 if (view->texture->target != PIPE_BUFFER) {
411 for (unsigned j = view->u.tex.first_level;
412 j <= view->u.tex.last_level; j++) {
413 pipe_texture_unmap(pipe, sv_transfer[i][j]);
414 }
415 } else {
416 pipe_buffer_unmap(pipe, sv_transfer[i][0]);
417 }
418
419 pipe_sampler_view_reference(&views[i], NULL);
420 }
421 }
422
423 draw_set_samplers(draw, PIPE_SHADER_VERTEX, NULL, 0);
424 draw_set_sampler_views(draw, PIPE_SHADER_VERTEX, NULL, 0);
425
426 for (unsigned i = 0; i < prog->info.num_ssbos; i++) {
427 if (ssbo_transfer[i]) {
428 draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 1 + i,
429 NULL, 0);
430 pipe_buffer_unmap(pipe, ssbo_transfer[i]);
431 }
432 }
433
434 for (unsigned i = 0; i < prog->info.num_ubos; i++) {
435 if (ubo_transfer[i]) {
436 draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 1 + i,
437 NULL, 0);
438 pipe_buffer_unmap(pipe, ubo_transfer[i]);
439 }
440 }
441
442 /*
443 * unmap vertex/index buffers
444 */
445 if (info->index_size) {
446 draw_set_indexes(draw, NULL, 0, 0);
447 if (ib_transfer)
448 pipe_buffer_unmap(pipe, ib_transfer);
449 }
450
451 for (unsigned buf = 0; buf < num_vbuffers; ++buf) {
452 if (vb_transfer[buf])
453 pipe_buffer_unmap(pipe, vb_transfer[buf]);
454 draw_set_mapped_vertex_buffer(draw, buf, NULL, 0);
455 if (!vbuffers[buf].is_user_buffer)
456 pipe_resource_reference(&vbuffers[buf].buffer.resource, NULL);
457 }
458 draw_set_vertex_buffers(draw, 0, NULL);
459
460 draw_bind_vertex_shader(draw, NULL);
461 }
462
463 void
st_feedback_draw_vbo_multi_mode(struct gl_context * ctx,struct pipe_draw_info * info,const struct pipe_draw_start_count_bias * draws,const unsigned char * mode,unsigned num_draws)464 st_feedback_draw_vbo_multi_mode(struct gl_context *ctx,
465 struct pipe_draw_info *info,
466 const struct pipe_draw_start_count_bias *draws,
467 const unsigned char *mode,
468 unsigned num_draws)
469 {
470 for (unsigned i = 0; i < num_draws; i++) {
471 info->mode = mode[i];
472 st_feedback_draw_vbo(ctx, info, 0, NULL, &draws[i], 1);
473 }
474 }
475