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