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