1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2022 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "util/format/u_format.h" 27bf215546Sopenharmony_ci#include "util/u_bitmask.h" 28bf215546Sopenharmony_ci#include "util/u_inlines.h" 29bf215546Sopenharmony_ci#include "util/u_memory.h" 30bf215546Sopenharmony_ci#include "pipe/p_defines.h" 31bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "svga_screen.h" 34bf215546Sopenharmony_ci#include "svga_context.h" 35bf215546Sopenharmony_ci#include "svga_state.h" 36bf215546Sopenharmony_ci#include "svga_cmd.h" 37bf215546Sopenharmony_ci#include "svga_tgsi.h" 38bf215546Sopenharmony_ci#include "svga_debug.h" 39bf215546Sopenharmony_ci#include "svga_resource_buffer.h" 40bf215546Sopenharmony_ci#include "svga_shader.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include "svga_hw_reg.h" 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_cistatic unsigned 46bf215546Sopenharmony_cisvga_get_image_size_constant(const struct svga_context *svga, float **dest, 47bf215546Sopenharmony_ci enum pipe_shader_type shader, 48bf215546Sopenharmony_ci unsigned num_image_views, 49bf215546Sopenharmony_ci const struct svga_image_view images[PIPE_SHADER_TYPES][SVGA3D_MAX_UAVIEWS]) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci uint32_t *dest_u = (uint32_t *) *dest; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci for (int i = 0; i < num_image_views; i++) { 54bf215546Sopenharmony_ci if (images[shader][i].desc.resource) { 55bf215546Sopenharmony_ci if (images[shader][i].desc.resource->target == PIPE_BUFFER) { 56bf215546Sopenharmony_ci unsigned bytes_per_element = util_format_get_blocksize(images[shader][i].desc.format); 57bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->width0 / bytes_per_element; 58bf215546Sopenharmony_ci } 59bf215546Sopenharmony_ci else 60bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->width0; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci if (images[shader][i].desc.resource->target == PIPE_TEXTURE_1D_ARRAY) 63bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->array_size; 64bf215546Sopenharmony_ci else 65bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->height0; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci if (images[shader][i].desc.resource->target == PIPE_TEXTURE_2D_ARRAY) 68bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->array_size; 69bf215546Sopenharmony_ci else if (images[shader][i].desc.resource->target == PIPE_TEXTURE_CUBE_ARRAY) 70bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->array_size / 6; 71bf215546Sopenharmony_ci else 72bf215546Sopenharmony_ci *dest_u++ = images[shader][i].desc.resource->depth0; 73bf215546Sopenharmony_ci *dest_u++ = 1; // Later this can be used for sample counts 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci else { 76bf215546Sopenharmony_ci *dest_u += 4; 77bf215546Sopenharmony_ci } 78bf215546Sopenharmony_ci } 79bf215546Sopenharmony_ci return num_image_views; 80bf215546Sopenharmony_ci} 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci/* 84bf215546Sopenharmony_ci * Don't try to send more than 4kb of successive constants. 85bf215546Sopenharmony_ci */ 86bf215546Sopenharmony_ci#define MAX_CONST_REG_COUNT 256 /**< number of float[4] constants */ 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci/** 89bf215546Sopenharmony_ci * Extra space for svga-specific VS/PS constants (such as texcoord 90bf215546Sopenharmony_ci * scale factors, vertex transformation scale/translation). 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_ci#define MAX_EXTRA_CONSTS 32 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci/** Guest-backed surface constant buffers must be this size */ 95bf215546Sopenharmony_ci#define GB_CONSTBUF_SIZE (SVGA3D_CONSTREG_MAX) 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci/** 99bf215546Sopenharmony_ci * Emit any extra shader-type-independent shader constants into the buffer 100bf215546Sopenharmony_ci * pointed to by 'dest'. 101bf215546Sopenharmony_ci * \return number of float[4] constants put into the 'dest' buffer 102bf215546Sopenharmony_ci */ 103bf215546Sopenharmony_cistatic unsigned 104bf215546Sopenharmony_cisvga_get_extra_constants_common(const struct svga_context *svga, 105bf215546Sopenharmony_ci const struct svga_shader_variant *variant, 106bf215546Sopenharmony_ci enum pipe_shader_type shader, float *dest) 107bf215546Sopenharmony_ci{ 108bf215546Sopenharmony_ci uint32_t *dest_u = (uint32_t *) dest; // uint version of dest 109bf215546Sopenharmony_ci unsigned i; 110bf215546Sopenharmony_ci unsigned count = 0; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci for (i = 0; i < variant->key.num_textures; i++) { 113bf215546Sopenharmony_ci const struct pipe_sampler_view *sv = svga->curr.sampler_views[shader][i]; 114bf215546Sopenharmony_ci if (sv) { 115bf215546Sopenharmony_ci const struct pipe_resource *tex = sv->texture; 116bf215546Sopenharmony_ci /* Scaling factors needed for handling unnormalized texture coordinates 117bf215546Sopenharmony_ci * for texture rectangles. 118bf215546Sopenharmony_ci */ 119bf215546Sopenharmony_ci if (variant->key.tex[i].unnormalized) { 120bf215546Sopenharmony_ci /* debug/sanity check */ 121bf215546Sopenharmony_ci assert(variant->key.tex[i].width_height_idx == count); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci *dest++ = 1.0f / (float) tex->width0; 124bf215546Sopenharmony_ci *dest++ = 1.0f / (float) tex->height0; 125bf215546Sopenharmony_ci *dest++ = 1.0f; 126bf215546Sopenharmony_ci *dest++ = 1.0f; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci count++; 129bf215546Sopenharmony_ci } 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci /* Store the sizes for texture buffers. 132bf215546Sopenharmony_ci */ 133bf215546Sopenharmony_ci if (tex->target == PIPE_BUFFER) { 134bf215546Sopenharmony_ci unsigned bytes_per_element = util_format_get_blocksize(sv->format); 135bf215546Sopenharmony_ci *dest_u++ = tex->width0 / bytes_per_element; 136bf215546Sopenharmony_ci *dest_u++ = 1; 137bf215546Sopenharmony_ci *dest_u++ = 1; 138bf215546Sopenharmony_ci *dest_u++ = 1; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci count++; 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci } 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci /* image_size */ 146bf215546Sopenharmony_ci if (variant->key.image_size_used) { 147bf215546Sopenharmony_ci count += svga_get_image_size_constant(svga, &dest, shader, 148bf215546Sopenharmony_ci svga->state.hw_draw.num_image_views[shader], 149bf215546Sopenharmony_ci svga->state.hw_draw.image_views); 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci return count; 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci/** 158bf215546Sopenharmony_ci * Emit any extra fragment shader constants into the buffer pointed 159bf215546Sopenharmony_ci * to by 'dest'. 160bf215546Sopenharmony_ci * \return number of float[4] constants put into the dest buffer 161bf215546Sopenharmony_ci */ 162bf215546Sopenharmony_cistatic unsigned 163bf215546Sopenharmony_cisvga_get_extra_fs_constants(const struct svga_context *svga, float *dest) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.fs; 166bf215546Sopenharmony_ci unsigned count = 0; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci count += svga_get_extra_constants_common(svga, variant, 169bf215546Sopenharmony_ci PIPE_SHADER_FRAGMENT, dest); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci assert(count <= MAX_EXTRA_CONSTS); 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci return count; 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci/** 177bf215546Sopenharmony_ci * Emit extra constants needed for prescale computation into the 178bf215546Sopenharmony_ci * the buffer pointed to by '*dest'. The updated buffer pointer 179bf215546Sopenharmony_ci * will be returned in 'dest'. 180bf215546Sopenharmony_ci */ 181bf215546Sopenharmony_cistatic unsigned 182bf215546Sopenharmony_cisvga_get_prescale_constants(const struct svga_context *svga, float **dest, 183bf215546Sopenharmony_ci const struct svga_prescale *prescale) 184bf215546Sopenharmony_ci{ 185bf215546Sopenharmony_ci memcpy(*dest, prescale->scale, 4 * sizeof(float)); 186bf215546Sopenharmony_ci *dest += 4; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci memcpy(*dest, prescale->translate, 4 * sizeof(float)); 189bf215546Sopenharmony_ci *dest += 4; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci return 2; 192bf215546Sopenharmony_ci} 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci/** 195bf215546Sopenharmony_ci * Emit extra constants needed for point sprite emulation. 196bf215546Sopenharmony_ci */ 197bf215546Sopenharmony_cistatic unsigned 198bf215546Sopenharmony_cisvga_get_pt_sprite_constants(const struct svga_context *svga, float **dest) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci const struct svga_screen *screen = svga_screen(svga->pipe.screen); 201bf215546Sopenharmony_ci float *dst = *dest; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci dst[0] = 1.0 / (svga->curr.viewport[0].scale[0] * 2); 204bf215546Sopenharmony_ci dst[1] = 1.0 / (svga->curr.viewport[0].scale[1] * 2); 205bf215546Sopenharmony_ci dst[2] = svga->curr.rast->pointsize; 206bf215546Sopenharmony_ci dst[3] = screen->maxPointSize; 207bf215546Sopenharmony_ci *dest = *dest + 4; 208bf215546Sopenharmony_ci return 1; 209bf215546Sopenharmony_ci} 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci/** 212bf215546Sopenharmony_ci * Emit user-defined clip plane coefficients into the buffer pointed to 213bf215546Sopenharmony_ci * by '*dest'. The updated buffer pointer will be returned in 'dest'. 214bf215546Sopenharmony_ci */ 215bf215546Sopenharmony_cistatic unsigned 216bf215546Sopenharmony_cisvga_get_clip_plane_constants(const struct svga_context *svga, 217bf215546Sopenharmony_ci const struct svga_shader_variant *variant, 218bf215546Sopenharmony_ci float **dest) 219bf215546Sopenharmony_ci{ 220bf215546Sopenharmony_ci unsigned count = 0; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci /* SVGA_NEW_CLIP */ 223bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 224bf215546Sopenharmony_ci /* append user-defined clip plane coefficients onto constant buffer */ 225bf215546Sopenharmony_ci unsigned clip_planes = variant->key.clip_plane_enable; 226bf215546Sopenharmony_ci while (clip_planes) { 227bf215546Sopenharmony_ci int i = u_bit_scan(&clip_planes); 228bf215546Sopenharmony_ci COPY_4V(*dest, svga->curr.clip.ucp[i]); 229bf215546Sopenharmony_ci *dest += 4; 230bf215546Sopenharmony_ci count += 1; 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci } 233bf215546Sopenharmony_ci return count; 234bf215546Sopenharmony_ci} 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci/** 238bf215546Sopenharmony_ci * Emit any extra vertex shader constants into the buffer pointed 239bf215546Sopenharmony_ci * to by 'dest'. 240bf215546Sopenharmony_ci * In particular, these would be the scale and bias factors computed 241bf215546Sopenharmony_ci * from the framebuffer size which are used to copy with differences in 242bf215546Sopenharmony_ci * GL vs D3D coordinate spaces. See svga_tgsi_insn.c for more info. 243bf215546Sopenharmony_ci * \return number of float[4] constants put into the dest buffer 244bf215546Sopenharmony_ci */ 245bf215546Sopenharmony_cistatic unsigned 246bf215546Sopenharmony_cisvga_get_extra_vs_constants(const struct svga_context *svga, float *dest) 247bf215546Sopenharmony_ci{ 248bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.vs; 249bf215546Sopenharmony_ci unsigned count = 0; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci /* SVGA_NEW_VS_VARIANT 252bf215546Sopenharmony_ci */ 253bf215546Sopenharmony_ci if (variant->key.vs.need_prescale) { 254bf215546Sopenharmony_ci count += svga_get_prescale_constants(svga, &dest, 255bf215546Sopenharmony_ci &svga->state.hw_clear.prescale[0]); 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci if (variant->key.vs.undo_viewport) { 259bf215546Sopenharmony_ci /* Used to convert window coords back to NDC coords */ 260bf215546Sopenharmony_ci dest[0] = 1.0f / svga->curr.viewport[0].scale[0]; 261bf215546Sopenharmony_ci dest[1] = 1.0f / svga->curr.viewport[0].scale[1]; 262bf215546Sopenharmony_ci dest[2] = -svga->curr.viewport[0].translate[0]; 263bf215546Sopenharmony_ci dest[3] = -svga->curr.viewport[0].translate[1]; 264bf215546Sopenharmony_ci dest += 4; 265bf215546Sopenharmony_ci count += 1; 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci /* Bias to be added to VertexID */ 269bf215546Sopenharmony_ci if (variant->key.vs.need_vertex_id_bias) { 270bf215546Sopenharmony_ci uint32_t *dest_u = (uint32_t *) dest; // uint version of dest 271bf215546Sopenharmony_ci dest_u[0] = svga->curr.vertex_id_bias; 272bf215546Sopenharmony_ci dest_u[1] = 1; 273bf215546Sopenharmony_ci dest_u[2] = 1; 274bf215546Sopenharmony_ci dest_u[3] = 1; 275bf215546Sopenharmony_ci dest+=4; 276bf215546Sopenharmony_ci count++; 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci /* SVGA_NEW_CLIP */ 280bf215546Sopenharmony_ci count += svga_get_clip_plane_constants(svga, variant, &dest); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci /* common constants */ 283bf215546Sopenharmony_ci count += svga_get_extra_constants_common(svga, variant, 284bf215546Sopenharmony_ci PIPE_SHADER_VERTEX, dest); 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci assert(count <= MAX_EXTRA_CONSTS); 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci return count; 289bf215546Sopenharmony_ci} 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci/** 292bf215546Sopenharmony_ci * Emit any extra geometry shader constants into the buffer pointed 293bf215546Sopenharmony_ci * to by 'dest'. 294bf215546Sopenharmony_ci */ 295bf215546Sopenharmony_cistatic unsigned 296bf215546Sopenharmony_cisvga_get_extra_gs_constants(const struct svga_context *svga, float *dest) 297bf215546Sopenharmony_ci{ 298bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.gs; 299bf215546Sopenharmony_ci unsigned count = 0; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci /* SVGA_NEW_GS_VARIANT 302bf215546Sopenharmony_ci */ 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci /* Constants for point sprite 305bf215546Sopenharmony_ci * These are used in the transformed gs that supports point sprite. 306bf215546Sopenharmony_ci * They need to be added before the prescale constants. 307bf215546Sopenharmony_ci */ 308bf215546Sopenharmony_ci if (variant->key.gs.wide_point) { 309bf215546Sopenharmony_ci count += svga_get_pt_sprite_constants(svga, &dest); 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci if (variant->key.gs.need_prescale) { 313bf215546Sopenharmony_ci unsigned i, num_prescale = 1; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci /* If prescale is needed and the geometry shader writes to viewport 316bf215546Sopenharmony_ci * index, then prescale for all viewports will be added to the 317bf215546Sopenharmony_ci * constant buffer. 318bf215546Sopenharmony_ci */ 319bf215546Sopenharmony_ci if (variant->key.gs.writes_viewport_index) 320bf215546Sopenharmony_ci num_prescale = svga->state.hw_clear.num_prescale; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci for (i = 0; i < num_prescale; i++) { 323bf215546Sopenharmony_ci count += 324bf215546Sopenharmony_ci svga_get_prescale_constants(svga, &dest, 325bf215546Sopenharmony_ci &svga->state.hw_clear.prescale[i]); 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci /* SVGA_NEW_CLIP */ 330bf215546Sopenharmony_ci count += svga_get_clip_plane_constants(svga, variant, &dest); 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci /* common constants */ 333bf215546Sopenharmony_ci count += svga_get_extra_constants_common(svga, variant, 334bf215546Sopenharmony_ci PIPE_SHADER_GEOMETRY, dest); 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci assert(count <= MAX_EXTRA_CONSTS); 337bf215546Sopenharmony_ci return count; 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci/** 342bf215546Sopenharmony_ci * Emit any extra tessellation control shader constants into the 343bf215546Sopenharmony_ci * buffer pointed to by 'dest'. 344bf215546Sopenharmony_ci */ 345bf215546Sopenharmony_cistatic unsigned 346bf215546Sopenharmony_cisvga_get_extra_tcs_constants(struct svga_context *svga, float *dest) 347bf215546Sopenharmony_ci{ 348bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.tcs; 349bf215546Sopenharmony_ci unsigned count = 0; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci /* SVGA_NEW_CLIP */ 352bf215546Sopenharmony_ci count += svga_get_clip_plane_constants(svga, variant, &dest); 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci /* common constants */ 355bf215546Sopenharmony_ci count += svga_get_extra_constants_common(svga, variant, 356bf215546Sopenharmony_ci PIPE_SHADER_TESS_CTRL, 357bf215546Sopenharmony_ci dest); 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci assert(count <= MAX_EXTRA_CONSTS); 360bf215546Sopenharmony_ci return count; 361bf215546Sopenharmony_ci} 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci/** 365bf215546Sopenharmony_ci * Emit any extra tessellation evaluation shader constants into 366bf215546Sopenharmony_ci * the buffer pointed to by 'dest'. 367bf215546Sopenharmony_ci */ 368bf215546Sopenharmony_cistatic unsigned 369bf215546Sopenharmony_cisvga_get_extra_tes_constants(struct svga_context *svga, float *dest) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.tes; 372bf215546Sopenharmony_ci unsigned count = 0; 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci if (variant->key.tes.need_prescale) { 375bf215546Sopenharmony_ci count += svga_get_prescale_constants(svga, &dest, 376bf215546Sopenharmony_ci &svga->state.hw_clear.prescale[0]); 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci /* SVGA_NEW_CLIP */ 380bf215546Sopenharmony_ci count += svga_get_clip_plane_constants(svga, variant, &dest); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci /* common constants */ 383bf215546Sopenharmony_ci count += svga_get_extra_constants_common(svga, variant, 384bf215546Sopenharmony_ci PIPE_SHADER_TESS_EVAL, 385bf215546Sopenharmony_ci dest); 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci assert(count <= MAX_EXTRA_CONSTS); 388bf215546Sopenharmony_ci return count; 389bf215546Sopenharmony_ci} 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci/** 393bf215546Sopenharmony_ci * Emit any extra compute shader constants into 394bf215546Sopenharmony_ci * the buffer pointed to by 'dest'. 395bf215546Sopenharmony_ci */ 396bf215546Sopenharmony_cistatic unsigned 397bf215546Sopenharmony_cisvga_get_extra_cs_constants(struct svga_context *svga, float *dest) 398bf215546Sopenharmony_ci{ 399bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.cs; 400bf215546Sopenharmony_ci unsigned count = 0; 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci /* common constants */ 403bf215546Sopenharmony_ci count += svga_get_extra_constants_common(svga, variant, 404bf215546Sopenharmony_ci PIPE_SHADER_COMPUTE, 405bf215546Sopenharmony_ci dest); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci assert(count <= MAX_EXTRA_CONSTS); 408bf215546Sopenharmony_ci return count; 409bf215546Sopenharmony_ci} 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci/* 413bf215546Sopenharmony_ci * Check and emit a range of shader constant registers, trying to coalesce 414bf215546Sopenharmony_ci * successive shader constant updates in a single command in order to save 415bf215546Sopenharmony_ci * space on the command buffer. This is a HWv8 feature. 416bf215546Sopenharmony_ci */ 417bf215546Sopenharmony_cistatic enum pipe_error 418bf215546Sopenharmony_ciemit_const_range(struct svga_context *svga, 419bf215546Sopenharmony_ci enum pipe_shader_type shader, 420bf215546Sopenharmony_ci unsigned offset, 421bf215546Sopenharmony_ci unsigned count, 422bf215546Sopenharmony_ci const float (*values)[4]) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci unsigned i, j; 425bf215546Sopenharmony_ci enum pipe_error ret; 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci assert(shader == PIPE_SHADER_VERTEX || 428bf215546Sopenharmony_ci shader == PIPE_SHADER_FRAGMENT); 429bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci#ifdef DEBUG 432bf215546Sopenharmony_ci if (offset + count > SVGA3D_CONSTREG_MAX) { 433bf215546Sopenharmony_ci debug_printf("svga: too many constants (offset %u + count %u = %u (max = %u))\n", 434bf215546Sopenharmony_ci offset, count, offset + count, SVGA3D_CONSTREG_MAX); 435bf215546Sopenharmony_ci } 436bf215546Sopenharmony_ci#endif 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci if (offset > SVGA3D_CONSTREG_MAX) { 439bf215546Sopenharmony_ci /* This isn't OK, but if we propagate an error all the way up we'll 440bf215546Sopenharmony_ci * just get into more trouble. 441bf215546Sopenharmony_ci * XXX note that offset is always zero at this time so this is moot. 442bf215546Sopenharmony_ci */ 443bf215546Sopenharmony_ci return PIPE_OK; 444bf215546Sopenharmony_ci } 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci if (offset + count > SVGA3D_CONSTREG_MAX) { 447bf215546Sopenharmony_ci /* Just drop the extra constants for now. 448bf215546Sopenharmony_ci * Ideally we should not have allowed the app to create a shader 449bf215546Sopenharmony_ci * that exceeds our constant buffer size but there's no way to 450bf215546Sopenharmony_ci * express that in gallium at this time. 451bf215546Sopenharmony_ci */ 452bf215546Sopenharmony_ci count = SVGA3D_CONSTREG_MAX - offset; 453bf215546Sopenharmony_ci } 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci i = 0; 456bf215546Sopenharmony_ci while (i < count) { 457bf215546Sopenharmony_ci if (memcmp(svga->state.hw_draw.cb[shader][offset + i], 458bf215546Sopenharmony_ci values[i], 459bf215546Sopenharmony_ci 4 * sizeof(float)) != 0) { 460bf215546Sopenharmony_ci /* Found one dirty constant 461bf215546Sopenharmony_ci */ 462bf215546Sopenharmony_ci if (SVGA_DEBUG & DEBUG_CONSTS) 463bf215546Sopenharmony_ci debug_printf("%s %s %d: %f %f %f %f\n", 464bf215546Sopenharmony_ci __FUNCTION__, 465bf215546Sopenharmony_ci shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG", 466bf215546Sopenharmony_ci offset + i, 467bf215546Sopenharmony_ci values[i][0], 468bf215546Sopenharmony_ci values[i][1], 469bf215546Sopenharmony_ci values[i][2], 470bf215546Sopenharmony_ci values[i][3]); 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci /* Look for more consecutive dirty constants. 473bf215546Sopenharmony_ci */ 474bf215546Sopenharmony_ci j = i + 1; 475bf215546Sopenharmony_ci while (j < count && 476bf215546Sopenharmony_ci j < i + MAX_CONST_REG_COUNT && 477bf215546Sopenharmony_ci memcmp(svga->state.hw_draw.cb[shader][offset + j], 478bf215546Sopenharmony_ci values[j], 479bf215546Sopenharmony_ci 4 * sizeof(float)) != 0) { 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci if (SVGA_DEBUG & DEBUG_CONSTS) 482bf215546Sopenharmony_ci debug_printf("%s %s %d: %f %f %f %f\n", 483bf215546Sopenharmony_ci __FUNCTION__, 484bf215546Sopenharmony_ci shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG", 485bf215546Sopenharmony_ci offset + j, 486bf215546Sopenharmony_ci values[j][0], 487bf215546Sopenharmony_ci values[j][1], 488bf215546Sopenharmony_ci values[j][2], 489bf215546Sopenharmony_ci values[j][3]); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci ++j; 492bf215546Sopenharmony_ci } 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci assert(j >= i + 1); 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci /* Send them all together. 497bf215546Sopenharmony_ci */ 498bf215546Sopenharmony_ci if (svga_have_gb_objects(svga)) { 499bf215546Sopenharmony_ci ret = SVGA3D_SetGBShaderConstsInline(svga->swc, 500bf215546Sopenharmony_ci offset + i, /* start */ 501bf215546Sopenharmony_ci j - i, /* count */ 502bf215546Sopenharmony_ci svga_shader_type(shader), 503bf215546Sopenharmony_ci SVGA3D_CONST_TYPE_FLOAT, 504bf215546Sopenharmony_ci values + i); 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci else { 507bf215546Sopenharmony_ci ret = SVGA3D_SetShaderConsts(svga->swc, 508bf215546Sopenharmony_ci offset + i, j - i, 509bf215546Sopenharmony_ci svga_shader_type(shader), 510bf215546Sopenharmony_ci SVGA3D_CONST_TYPE_FLOAT, 511bf215546Sopenharmony_ci values + i); 512bf215546Sopenharmony_ci } 513bf215546Sopenharmony_ci if (ret != PIPE_OK) { 514bf215546Sopenharmony_ci return ret; 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci /* 518bf215546Sopenharmony_ci * Local copy of the hardware state. 519bf215546Sopenharmony_ci */ 520bf215546Sopenharmony_ci memcpy(svga->state.hw_draw.cb[shader][offset + i], 521bf215546Sopenharmony_ci values[i], 522bf215546Sopenharmony_ci (j - i) * 4 * sizeof(float)); 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci i = j + 1; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci svga->hud.num_const_updates++; 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci } else { 529bf215546Sopenharmony_ci ++i; 530bf215546Sopenharmony_ci } 531bf215546Sopenharmony_ci } 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci return PIPE_OK; 534bf215546Sopenharmony_ci} 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci/** 538bf215546Sopenharmony_ci * Emit all the constants in a constant buffer for a shader stage. 539bf215546Sopenharmony_ci * On VGPU10, emit_consts_vgpu10 is used instead. 540bf215546Sopenharmony_ci */ 541bf215546Sopenharmony_cistatic enum pipe_error 542bf215546Sopenharmony_ciemit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader) 543bf215546Sopenharmony_ci{ 544bf215546Sopenharmony_ci const struct pipe_constant_buffer *cbuf; 545bf215546Sopenharmony_ci struct pipe_transfer *transfer = NULL; 546bf215546Sopenharmony_ci unsigned count; 547bf215546Sopenharmony_ci const float (*data)[4] = NULL; 548bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 549bf215546Sopenharmony_ci const unsigned offset = 0; 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci assert(shader < PIPE_SHADER_TYPES); 552bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 553bf215546Sopenharmony_ci /* Only one constant buffer per shader is supported before VGPU10. 554bf215546Sopenharmony_ci * This is only an approximate check against that. 555bf215546Sopenharmony_ci */ 556bf215546Sopenharmony_ci assert(svga->curr.constbufs[shader][1].buffer == NULL); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci cbuf = &svga->curr.constbufs[shader][0]; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci if (svga->curr.constbufs[shader][0].buffer) { 561bf215546Sopenharmony_ci /* emit user-provided constants */ 562bf215546Sopenharmony_ci data = (const float (*)[4]) 563bf215546Sopenharmony_ci pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer, 564bf215546Sopenharmony_ci PIPE_MAP_READ, &transfer); 565bf215546Sopenharmony_ci if (!data) { 566bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 567bf215546Sopenharmony_ci } 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci /* sanity check */ 570bf215546Sopenharmony_ci assert(cbuf->buffer->width0 >= cbuf->buffer_size); 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci /* Use/apply the constant buffer size and offsets here */ 573bf215546Sopenharmony_ci count = cbuf->buffer_size / (4 * sizeof(float)); 574bf215546Sopenharmony_ci data += cbuf->buffer_offset / (4 * sizeof(float)); 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci ret = emit_const_range( svga, shader, offset, count, data ); 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, transfer); 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci if (ret != PIPE_OK) { 581bf215546Sopenharmony_ci return ret; 582bf215546Sopenharmony_ci } 583bf215546Sopenharmony_ci } 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci /* emit extra shader constants */ 586bf215546Sopenharmony_ci { 587bf215546Sopenharmony_ci const struct svga_shader_variant *variant = NULL; 588bf215546Sopenharmony_ci unsigned offset; 589bf215546Sopenharmony_ci float extras[MAX_EXTRA_CONSTS][4]; 590bf215546Sopenharmony_ci unsigned count; 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci switch (shader) { 593bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 594bf215546Sopenharmony_ci variant = svga->state.hw_draw.vs; 595bf215546Sopenharmony_ci count = svga_get_extra_vs_constants(svga, (float *) extras); 596bf215546Sopenharmony_ci break; 597bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 598bf215546Sopenharmony_ci variant = svga->state.hw_draw.fs; 599bf215546Sopenharmony_ci count = svga_get_extra_fs_constants(svga, (float *) extras); 600bf215546Sopenharmony_ci break; 601bf215546Sopenharmony_ci default: 602bf215546Sopenharmony_ci assert(!"Unexpected shader type"); 603bf215546Sopenharmony_ci count = 0; 604bf215546Sopenharmony_ci } 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci assert(variant); 607bf215546Sopenharmony_ci offset = variant->shader->info.constbuf0_num_uniforms; 608bf215546Sopenharmony_ci assert(count <= ARRAY_SIZE(extras)); 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci if (count > 0) { 611bf215546Sopenharmony_ci ret = emit_const_range(svga, shader, offset, count, 612bf215546Sopenharmony_ci (const float (*) [4])extras); 613bf215546Sopenharmony_ci } 614bf215546Sopenharmony_ci } 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci return ret; 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci 620bf215546Sopenharmony_ci/** 621bf215546Sopenharmony_ci * A helper function to destroy any pending unused srv. 622bf215546Sopenharmony_ci */ 623bf215546Sopenharmony_civoid 624bf215546Sopenharmony_cisvga_destroy_rawbuf_srv(struct svga_context *svga) 625bf215546Sopenharmony_ci{ 626bf215546Sopenharmony_ci unsigned index = 0; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci while ((index = util_bitmask_get_next_index( 629bf215546Sopenharmony_ci svga->sampler_view_to_free_id_bm, index)) 630bf215546Sopenharmony_ci != UTIL_BITMASK_INVALID_INDEX) { 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc, 633bf215546Sopenharmony_ci index)); 634bf215546Sopenharmony_ci util_bitmask_clear(svga->sampler_view_id_bm, index); 635bf215546Sopenharmony_ci util_bitmask_clear(svga->sampler_view_to_free_id_bm, index); 636bf215546Sopenharmony_ci } 637bf215546Sopenharmony_ci} 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_ci/** 640bf215546Sopenharmony_ci * A helper function to emit constant buffer as srv raw buffer. 641bf215546Sopenharmony_ci */ 642bf215546Sopenharmony_cistatic enum pipe_error 643bf215546Sopenharmony_ciemit_rawbuf(struct svga_context *svga, 644bf215546Sopenharmony_ci unsigned slot, 645bf215546Sopenharmony_ci enum pipe_shader_type shader, 646bf215546Sopenharmony_ci unsigned buffer_offset, 647bf215546Sopenharmony_ci unsigned buffer_size, 648bf215546Sopenharmony_ci void *buffer) 649bf215546Sopenharmony_ci{ 650bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 651bf215546Sopenharmony_ci struct svga_raw_buffer *rawbuf = &svga->state.hw_draw.rawbufs[shader][slot]; 652bf215546Sopenharmony_ci struct svga_winsys_surface *buf_handle = NULL; 653bf215546Sopenharmony_ci unsigned srvid = SVGA3D_INVALID_ID; 654bf215546Sopenharmony_ci unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader]; 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITRAWBUFFER); 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci if (buffer == NULL) { 659bf215546Sopenharmony_ci if ((svga->state.hw_draw.enabled_rawbufs[shader] & (1 << slot)) == 0) { 660bf215546Sopenharmony_ci goto done; 661bf215546Sopenharmony_ci } 662bf215546Sopenharmony_ci enabled_rawbufs &= ~(1 << slot); 663bf215546Sopenharmony_ci } 664bf215546Sopenharmony_ci else { 665bf215546Sopenharmony_ci if ((rawbuf->buffer_offset != buffer_offset) || 666bf215546Sopenharmony_ci (rawbuf->buffer_size != buffer_size) || 667bf215546Sopenharmony_ci (rawbuf->buffer != buffer)) { 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci /* Add the current srvid to the delete list */ 670bf215546Sopenharmony_ci if (rawbuf->srvid != SVGA3D_INVALID_ID) { 671bf215546Sopenharmony_ci util_bitmask_set(svga->sampler_view_to_free_id_bm, rawbuf->srvid); 672bf215546Sopenharmony_ci rawbuf->srvid = SVGA3D_INVALID_ID; 673bf215546Sopenharmony_ci } 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci buf_handle = svga_buffer_handle(svga, buffer, 676bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW); 677bf215546Sopenharmony_ci if (!buf_handle) { 678bf215546Sopenharmony_ci ret = PIPE_ERROR_OUT_OF_MEMORY; 679bf215546Sopenharmony_ci goto done; 680bf215546Sopenharmony_ci } 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci /* Create a srv for the constant buffer */ 683bf215546Sopenharmony_ci srvid = util_bitmask_add(svga->sampler_view_id_bm); 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci SVGA3dShaderResourceViewDesc viewDesc; 686bf215546Sopenharmony_ci viewDesc.bufferex.firstElement = buffer_offset / 4; 687bf215546Sopenharmony_ci viewDesc.bufferex.numElements = buffer_size / 4; 688bf215546Sopenharmony_ci viewDesc.bufferex.flags = SVGA3D_BUFFEREX_SRV_RAW; 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_DefineShaderResourceView(svga->swc, 691bf215546Sopenharmony_ci srvid, buf_handle, SVGA3D_R32_TYPELESS, 692bf215546Sopenharmony_ci SVGA3D_RESOURCE_BUFFEREX, &viewDesc); 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci if (ret != PIPE_OK) { 695bf215546Sopenharmony_ci util_bitmask_clear(svga->sampler_view_id_bm, srvid); 696bf215546Sopenharmony_ci goto done; 697bf215546Sopenharmony_ci } 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci /* Save the current raw buffer attributes in the slot */ 700bf215546Sopenharmony_ci rawbuf->srvid = srvid; 701bf215546Sopenharmony_ci rawbuf->buffer_size = buffer_size; 702bf215546Sopenharmony_ci rawbuf->buffer = buffer; 703bf215546Sopenharmony_ci rawbuf->handle = buf_handle; 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci SVGA_STATS_COUNT_INC(svga_sws(svga), SVGA_STATS_COUNT_RAWBUFFERSRVIEW); 706bf215546Sopenharmony_ci } 707bf215546Sopenharmony_ci else { 708bf215546Sopenharmony_ci /* Same buffer attributes in the slot. Can use the same SRV. */ 709bf215546Sopenharmony_ci assert(rawbuf->srvid != SVGA3D_INVALID_ID); 710bf215546Sopenharmony_ci srvid = rawbuf->srvid; 711bf215546Sopenharmony_ci buf_handle = rawbuf->handle; 712bf215546Sopenharmony_ci } 713bf215546Sopenharmony_ci enabled_rawbufs |= (1 << slot); 714bf215546Sopenharmony_ci } 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_SetShaderResources(svga->swc, 717bf215546Sopenharmony_ci svga_shader_type(shader), 718bf215546Sopenharmony_ci slot + PIPE_MAX_SAMPLERS, 719bf215546Sopenharmony_ci 1, 720bf215546Sopenharmony_ci &srvid, 721bf215546Sopenharmony_ci &buf_handle); 722bf215546Sopenharmony_ci if (ret != PIPE_OK) { 723bf215546Sopenharmony_ci goto done; 724bf215546Sopenharmony_ci } 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci /* Save the enabled rawbuf state */ 727bf215546Sopenharmony_ci svga->state.hw_draw.enabled_rawbufs[shader] = enabled_rawbufs; 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_cidone: 730bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 731bf215546Sopenharmony_ci return ret; 732bf215546Sopenharmony_ci} 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci/** 736bf215546Sopenharmony_ci * A helper function to emit a constant buffer binding at the 737bf215546Sopenharmony_ci * specified slot for the specified shader type 738bf215546Sopenharmony_ci */ 739bf215546Sopenharmony_cistatic enum pipe_error 740bf215546Sopenharmony_ciemit_constbuf(struct svga_context *svga, 741bf215546Sopenharmony_ci unsigned slot, 742bf215546Sopenharmony_ci enum pipe_shader_type shader, 743bf215546Sopenharmony_ci unsigned buffer_offset, 744bf215546Sopenharmony_ci unsigned buffer_size, 745bf215546Sopenharmony_ci const void *buffer, 746bf215546Sopenharmony_ci unsigned extra_buffer_offset, 747bf215546Sopenharmony_ci unsigned extra_buffer_size, 748bf215546Sopenharmony_ci const void *extra_buffer) 749bf215546Sopenharmony_ci{ 750bf215546Sopenharmony_ci struct svga_buffer *sbuf = svga_buffer((struct pipe_resource *)buffer); 751bf215546Sopenharmony_ci struct pipe_resource *dst_buffer = NULL; 752bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 753bf215546Sopenharmony_ci struct pipe_transfer *src_transfer; 754bf215546Sopenharmony_ci struct svga_winsys_surface *dst_handle = NULL; 755bf215546Sopenharmony_ci unsigned new_buf_size = 0; 756bf215546Sopenharmony_ci unsigned alloc_buf_size; 757bf215546Sopenharmony_ci unsigned offset = 0;; 758bf215546Sopenharmony_ci void *src_map = NULL, *dst_map; 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci if ((sbuf && sbuf->swbuf) || extra_buffer) { 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_ci /* buffer here is a user-space buffer so mapping it is really cheap. */ 763bf215546Sopenharmony_ci if (buffer_size > 0) { 764bf215546Sopenharmony_ci src_map = pipe_buffer_map_range(&svga->pipe, 765bf215546Sopenharmony_ci (struct pipe_resource *)buffer, 766bf215546Sopenharmony_ci buffer_offset, buffer_size, 767bf215546Sopenharmony_ci PIPE_MAP_READ, &src_transfer); 768bf215546Sopenharmony_ci assert(src_map); 769bf215546Sopenharmony_ci if (!src_map) { 770bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 771bf215546Sopenharmony_ci } 772bf215546Sopenharmony_ci } 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_ci new_buf_size = MAX2(buffer_size, extra_buffer_offset) + extra_buffer_size; 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci /* According to the DX10 spec, the constant buffer size must be 777bf215546Sopenharmony_ci * in multiples of 16. 778bf215546Sopenharmony_ci */ 779bf215546Sopenharmony_ci new_buf_size = align(new_buf_size, 16); 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci /* Constant buffer size in the upload buffer must be in multiples of 256. 782bf215546Sopenharmony_ci * In order to maximize the chance of merging the upload buffer chunks 783bf215546Sopenharmony_ci * when svga_buffer_add_range() is called, 784bf215546Sopenharmony_ci * the allocate buffer size needs to be in multiples of 256 as well. 785bf215546Sopenharmony_ci * Otherwise, since there is gap between each dirty range of the upload buffer, 786bf215546Sopenharmony_ci * each dirty range will end up in its own UPDATE_GB_IMAGE command. 787bf215546Sopenharmony_ci */ 788bf215546Sopenharmony_ci alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT); 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci u_upload_alloc(svga->const0_upload, 0, alloc_buf_size, 791bf215546Sopenharmony_ci CONST0_UPLOAD_ALIGNMENT, &offset, 792bf215546Sopenharmony_ci &dst_buffer, &dst_map); 793bf215546Sopenharmony_ci 794bf215546Sopenharmony_ci if (!dst_map) { 795bf215546Sopenharmony_ci if (src_map) 796bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, src_transfer); 797bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 798bf215546Sopenharmony_ci } 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci /* Initialize the allocated buffer slot to 0 to ensure the padding is 801bf215546Sopenharmony_ci * filled with 0. 802bf215546Sopenharmony_ci */ 803bf215546Sopenharmony_ci memset(dst_map, 0, alloc_buf_size); 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci if (src_map) { 806bf215546Sopenharmony_ci memcpy(dst_map, src_map, buffer_size); 807bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, src_transfer); 808bf215546Sopenharmony_ci } 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci if (extra_buffer_size) { 811bf215546Sopenharmony_ci assert(extra_buffer_offset + extra_buffer_size <= new_buf_size); 812bf215546Sopenharmony_ci memcpy((char *) dst_map + extra_buffer_offset, extra_buffer, 813bf215546Sopenharmony_ci extra_buffer_size); 814bf215546Sopenharmony_ci } 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci /* Get winsys handle for the constant buffer */ 817bf215546Sopenharmony_ci if (svga->state.hw_draw.const0_buffer == dst_buffer && 818bf215546Sopenharmony_ci svga->state.hw_draw.const0_handle) { 819bf215546Sopenharmony_ci /* re-reference already mapped buffer */ 820bf215546Sopenharmony_ci dst_handle = svga->state.hw_draw.const0_handle; 821bf215546Sopenharmony_ci } 822bf215546Sopenharmony_ci else { 823bf215546Sopenharmony_ci /* we must unmap the buffer before getting the winsys handle */ 824bf215546Sopenharmony_ci u_upload_unmap(svga->const0_upload); 825bf215546Sopenharmony_ci 826bf215546Sopenharmony_ci dst_handle = svga_buffer_handle(svga, dst_buffer, 827bf215546Sopenharmony_ci PIPE_BIND_CONSTANT_BUFFER); 828bf215546Sopenharmony_ci if (!dst_handle) { 829bf215546Sopenharmony_ci pipe_resource_reference(&dst_buffer, NULL); 830bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 831bf215546Sopenharmony_ci } 832bf215546Sopenharmony_ci } 833bf215546Sopenharmony_ci } 834bf215546Sopenharmony_ci else if (sbuf) { 835bf215546Sopenharmony_ci dst_handle = svga_buffer_handle(svga, &sbuf->b, PIPE_BIND_CONSTANT_BUFFER); 836bf215546Sopenharmony_ci new_buf_size = align(buffer_size, 16); 837bf215546Sopenharmony_ci offset = buffer_offset; 838bf215546Sopenharmony_ci } 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci assert(new_buf_size % 16 == 0); 841bf215546Sopenharmony_ci 842bf215546Sopenharmony_ci /* clamp the buf size before sending the command */ 843bf215546Sopenharmony_ci new_buf_size = MIN2(new_buf_size, SVGA3D_DX_MAX_CONSTBUF_BINDING_SIZE); 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci const struct svga_screen *screen = svga_screen(svga->pipe.screen); 846bf215546Sopenharmony_ci const struct svga_winsys_screen *sws = screen->sws; 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci /* Issue the SetSingleConstantBuffer command */ 849bf215546Sopenharmony_ci if (!sws->have_constant_buffer_offset_cmd || 850bf215546Sopenharmony_ci svga->state.hw_draw.constbufoffsets[shader][slot].handle != dst_handle || 851bf215546Sopenharmony_ci svga->state.hw_draw.constbufoffsets[shader][slot].size != new_buf_size) { 852bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc, 853bf215546Sopenharmony_ci slot, /* index */ 854bf215546Sopenharmony_ci svga_shader_type(shader), 855bf215546Sopenharmony_ci dst_handle, 856bf215546Sopenharmony_ci offset, 857bf215546Sopenharmony_ci new_buf_size); 858bf215546Sopenharmony_ci } 859bf215546Sopenharmony_ci else if (dst_handle){ 860bf215546Sopenharmony_ci unsigned command = SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET + shader; 861bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_SetConstantBufferOffset(svga->swc, 862bf215546Sopenharmony_ci command, 863bf215546Sopenharmony_ci slot, /* index */ 864bf215546Sopenharmony_ci offset); 865bf215546Sopenharmony_ci } 866bf215546Sopenharmony_ci 867bf215546Sopenharmony_ci if (ret != PIPE_OK) { 868bf215546Sopenharmony_ci pipe_resource_reference(&dst_buffer, NULL); 869bf215546Sopenharmony_ci return ret; 870bf215546Sopenharmony_ci } 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci /* save the upload buffer / handle for next time */ 873bf215546Sopenharmony_ci if (dst_buffer != buffer && dst_buffer) { 874bf215546Sopenharmony_ci pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer); 875bf215546Sopenharmony_ci svga->state.hw_draw.const0_handle = dst_handle; 876bf215546Sopenharmony_ci } 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci /* Save this const buffer until it's replaced in the future. 879bf215546Sopenharmony_ci * Otherwise, all references to the buffer will go away after the 880bf215546Sopenharmony_ci * command buffer is submitted, it'll get recycled and we will have 881bf215546Sopenharmony_ci * incorrect constant buffer bindings. 882bf215546Sopenharmony_ci */ 883bf215546Sopenharmony_ci pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][slot], dst_buffer); 884bf215546Sopenharmony_ci svga->state.hw_draw.constbufoffsets[shader][slot].handle = dst_handle; 885bf215546Sopenharmony_ci svga->state.hw_draw.constbufoffsets[shader][slot].size = new_buf_size; 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci pipe_resource_reference(&dst_buffer, NULL); 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_ci return PIPE_OK; 890bf215546Sopenharmony_ci} 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci 893bf215546Sopenharmony_ci/* For constbuf 0 */ 894bf215546Sopenharmony_cistatic enum pipe_error 895bf215546Sopenharmony_ciemit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader) 896bf215546Sopenharmony_ci{ 897bf215546Sopenharmony_ci const struct pipe_constant_buffer *cbuf; 898bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 899bf215546Sopenharmony_ci float extras[MAX_EXTRA_CONSTS][4]; 900bf215546Sopenharmony_ci unsigned extra_count, extra_size, extra_offset; 901bf215546Sopenharmony_ci const struct svga_shader_variant *variant; 902bf215546Sopenharmony_ci 903bf215546Sopenharmony_ci assert(shader == PIPE_SHADER_VERTEX || 904bf215546Sopenharmony_ci shader == PIPE_SHADER_GEOMETRY || 905bf215546Sopenharmony_ci shader == PIPE_SHADER_FRAGMENT || 906bf215546Sopenharmony_ci shader == PIPE_SHADER_TESS_CTRL || 907bf215546Sopenharmony_ci shader == PIPE_SHADER_TESS_EVAL || 908bf215546Sopenharmony_ci shader == PIPE_SHADER_COMPUTE); 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci cbuf = &svga->curr.constbufs[shader][0]; 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci switch (shader) { 913bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 914bf215546Sopenharmony_ci variant = svga->state.hw_draw.vs; 915bf215546Sopenharmony_ci extra_count = svga_get_extra_vs_constants(svga, (float *) extras); 916bf215546Sopenharmony_ci break; 917bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 918bf215546Sopenharmony_ci variant = svga->state.hw_draw.fs; 919bf215546Sopenharmony_ci extra_count = svga_get_extra_fs_constants(svga, (float *) extras); 920bf215546Sopenharmony_ci break; 921bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 922bf215546Sopenharmony_ci variant = svga->state.hw_draw.gs; 923bf215546Sopenharmony_ci extra_count = svga_get_extra_gs_constants(svga, (float *) extras); 924bf215546Sopenharmony_ci break; 925bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 926bf215546Sopenharmony_ci variant = svga->state.hw_draw.tcs; 927bf215546Sopenharmony_ci extra_count = svga_get_extra_tcs_constants(svga, (float *) extras); 928bf215546Sopenharmony_ci break; 929bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 930bf215546Sopenharmony_ci variant = svga->state.hw_draw.tes; 931bf215546Sopenharmony_ci extra_count = svga_get_extra_tes_constants(svga, (float *) extras); 932bf215546Sopenharmony_ci break; 933bf215546Sopenharmony_ci case PIPE_SHADER_COMPUTE: 934bf215546Sopenharmony_ci variant = svga->state.hw_draw.cs; 935bf215546Sopenharmony_ci extra_count = svga_get_extra_cs_constants(svga, (float *) extras); 936bf215546Sopenharmony_ci break; 937bf215546Sopenharmony_ci default: 938bf215546Sopenharmony_ci assert(!"Unexpected shader type"); 939bf215546Sopenharmony_ci /* Don't return an error code since we don't want to keep re-trying 940bf215546Sopenharmony_ci * this function and getting stuck in an infinite loop. 941bf215546Sopenharmony_ci */ 942bf215546Sopenharmony_ci return PIPE_OK; 943bf215546Sopenharmony_ci } 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci assert(variant); 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci cbuf = &svga->curr.constbufs[shader][0]; 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci /* Compute extra constants size and offset in bytes */ 950bf215546Sopenharmony_ci extra_size = extra_count * 4 * sizeof(float); 951bf215546Sopenharmony_ci extra_offset = 4 * sizeof(float) * variant->extra_const_start; 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci if (cbuf->buffer_size + extra_size == 0) 954bf215546Sopenharmony_ci return PIPE_OK; /* nothing to do */ 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci ret = emit_constbuf(svga, 0, shader, 957bf215546Sopenharmony_ci cbuf->buffer_offset, cbuf->buffer_size, cbuf->buffer, 958bf215546Sopenharmony_ci extra_offset, extra_size, extras); 959bf215546Sopenharmony_ci if (ret != PIPE_OK) 960bf215546Sopenharmony_ci return ret; 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci svga->state.hw_draw.default_constbuf_size[shader] = 963bf215546Sopenharmony_ci svga->state.hw_draw.constbufoffsets[shader][0].size; 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci svga->hud.num_const_updates++; 966bf215546Sopenharmony_ci 967bf215546Sopenharmony_ci return ret; 968bf215546Sopenharmony_ci} 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_cistatic enum pipe_error 972bf215546Sopenharmony_ciemit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader) 973bf215546Sopenharmony_ci{ 974bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 975bf215546Sopenharmony_ci unsigned dirty_constbufs; 976bf215546Sopenharmony_ci unsigned enabled_constbufs; 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u; 979bf215546Sopenharmony_ci dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u; 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_ci while (dirty_constbufs) { 982bf215546Sopenharmony_ci unsigned index = u_bit_scan(&dirty_constbufs); 983bf215546Sopenharmony_ci unsigned offset = svga->curr.constbufs[shader][index].buffer_offset; 984bf215546Sopenharmony_ci unsigned size = svga->curr.constbufs[shader][index].buffer_size; 985bf215546Sopenharmony_ci struct svga_buffer *buffer = 986bf215546Sopenharmony_ci svga_buffer(svga->curr.constbufs[shader][index].buffer); 987bf215546Sopenharmony_ci 988bf215546Sopenharmony_ci if (buffer) { 989bf215546Sopenharmony_ci enabled_constbufs |= 1 << index; 990bf215546Sopenharmony_ci } 991bf215546Sopenharmony_ci else { 992bf215546Sopenharmony_ci enabled_constbufs &= ~(1 << index); 993bf215546Sopenharmony_ci assert(offset == 0); 994bf215546Sopenharmony_ci assert(size == 0); 995bf215546Sopenharmony_ci } 996bf215546Sopenharmony_ci 997bf215546Sopenharmony_ci if (size % 16 != 0) { 998bf215546Sopenharmony_ci /* GL's buffer range sizes can be any number of bytes but the 999bf215546Sopenharmony_ci * SVGA3D device requires a multiple of 16 bytes. 1000bf215546Sopenharmony_ci */ 1001bf215546Sopenharmony_ci const unsigned total_size = buffer->b.width0; 1002bf215546Sopenharmony_ci 1003bf215546Sopenharmony_ci if (offset + align(size, 16) <= total_size) { 1004bf215546Sopenharmony_ci /* round up size to multiple of 16 */ 1005bf215546Sopenharmony_ci size = align(size, 16); 1006bf215546Sopenharmony_ci } 1007bf215546Sopenharmony_ci else { 1008bf215546Sopenharmony_ci /* round down to multiple of 16 (this may cause rendering problems 1009bf215546Sopenharmony_ci * but should avoid a device error). 1010bf215546Sopenharmony_ci */ 1011bf215546Sopenharmony_ci size &= ~15; 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci } 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci assert(size % 16 == 0); 1016bf215546Sopenharmony_ci 1017bf215546Sopenharmony_ci /** 1018bf215546Sopenharmony_ci * If the buffer has been bound as an uav buffer, it will 1019bf215546Sopenharmony_ci * need to be bound as a shader resource raw buffer. 1020bf215546Sopenharmony_ci */ 1021bf215546Sopenharmony_ci if (svga->state.raw_constbufs[shader] & (1 << index)) { 1022bf215546Sopenharmony_ci ret = emit_rawbuf(svga, index, shader, offset, size, buffer); 1023bf215546Sopenharmony_ci if (ret != PIPE_OK) { 1024bf215546Sopenharmony_ci return ret; 1025bf215546Sopenharmony_ci } 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci ret = emit_constbuf(svga, index, shader, 0, 0, NULL, 1028bf215546Sopenharmony_ci 0, 0, NULL); 1029bf215546Sopenharmony_ci if (ret != PIPE_OK) { 1030bf215546Sopenharmony_ci return ret; 1031bf215546Sopenharmony_ci } 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci /* Remove the rawbuf from the to-be-enabled constbuf list 1034bf215546Sopenharmony_ci * so the buffer will not be referenced again as constant buffer 1035bf215546Sopenharmony_ci * at resource validation time. 1036bf215546Sopenharmony_ci */ 1037bf215546Sopenharmony_ci enabled_constbufs &= ~(1 << index); 1038bf215546Sopenharmony_ci } 1039bf215546Sopenharmony_ci else { 1040bf215546Sopenharmony_ci if (svga->state.hw_draw.enabled_rawbufs[shader] & (1 << index)) { 1041bf215546Sopenharmony_ci ret = emit_rawbuf(svga, index, shader, offset, size, NULL); 1042bf215546Sopenharmony_ci if (ret != PIPE_OK) { 1043bf215546Sopenharmony_ci return ret; 1044bf215546Sopenharmony_ci } 1045bf215546Sopenharmony_ci } 1046bf215546Sopenharmony_ci 1047bf215546Sopenharmony_ci ret = emit_constbuf(svga, index, shader, offset, size, buffer, 1048bf215546Sopenharmony_ci 0, 0, NULL); 1049bf215546Sopenharmony_ci if (ret != PIPE_OK) { 1050bf215546Sopenharmony_ci return ret; 1051bf215546Sopenharmony_ci } 1052bf215546Sopenharmony_ci } 1053bf215546Sopenharmony_ci svga->hud.num_const_buf_updates++; 1054bf215546Sopenharmony_ci } 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs; 1057bf215546Sopenharmony_ci svga->state.dirty_constbufs[shader] = 0; 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci return ret; 1060bf215546Sopenharmony_ci} 1061bf215546Sopenharmony_ci 1062bf215546Sopenharmony_cistatic enum pipe_error 1063bf215546Sopenharmony_ciemit_fs_consts(struct svga_context *svga, uint64_t dirty) 1064bf215546Sopenharmony_ci{ 1065bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.fs; 1066bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1067bf215546Sopenharmony_ci 1068bf215546Sopenharmony_ci /* SVGA_NEW_FS_VARIANT 1069bf215546Sopenharmony_ci */ 1070bf215546Sopenharmony_ci if (!variant) 1071bf215546Sopenharmony_ci return PIPE_OK; 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci /* SVGA_NEW_FS_CONSTS 1074bf215546Sopenharmony_ci */ 1075bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 1076bf215546Sopenharmony_ci ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT); 1077bf215546Sopenharmony_ci } 1078bf215546Sopenharmony_ci else { 1079bf215546Sopenharmony_ci ret = emit_consts_vgpu9(svga, PIPE_SHADER_FRAGMENT); 1080bf215546Sopenharmony_ci } 1081bf215546Sopenharmony_ci 1082bf215546Sopenharmony_ci return ret; 1083bf215546Sopenharmony_ci} 1084bf215546Sopenharmony_ci 1085bf215546Sopenharmony_cistatic enum pipe_error 1086bf215546Sopenharmony_ciemit_fs_constbuf(struct svga_context *svga, uint64_t dirty) 1087bf215546Sopenharmony_ci{ 1088bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.fs; 1089bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1090bf215546Sopenharmony_ci 1091bf215546Sopenharmony_ci /* SVGA_NEW_FS_VARIANT 1092bf215546Sopenharmony_ci */ 1093bf215546Sopenharmony_ci if (!variant) 1094bf215546Sopenharmony_ci return PIPE_OK; 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci /* SVGA_NEW_FS_CONSTBUF 1097bf215546Sopenharmony_ci */ 1098bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1099bf215546Sopenharmony_ci ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_FRAGMENT); 1100bf215546Sopenharmony_ci 1101bf215546Sopenharmony_ci return ret; 1102bf215546Sopenharmony_ci} 1103bf215546Sopenharmony_ci 1104bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_fs_constants = 1105bf215546Sopenharmony_ci{ 1106bf215546Sopenharmony_ci "hw fs params", 1107bf215546Sopenharmony_ci (SVGA_NEW_IMAGE_VIEW | 1108bf215546Sopenharmony_ci SVGA_NEW_FS_CONSTS | 1109bf215546Sopenharmony_ci SVGA_NEW_FS_VARIANT | 1110bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_CONSTS), 1111bf215546Sopenharmony_ci emit_fs_consts 1112bf215546Sopenharmony_ci}; 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_fs_constbufs = 1116bf215546Sopenharmony_ci{ 1117bf215546Sopenharmony_ci "hw fs params", 1118bf215546Sopenharmony_ci SVGA_NEW_FS_CONST_BUFFER, 1119bf215546Sopenharmony_ci emit_fs_constbuf 1120bf215546Sopenharmony_ci}; 1121bf215546Sopenharmony_ci 1122bf215546Sopenharmony_ci 1123bf215546Sopenharmony_cistatic enum pipe_error 1124bf215546Sopenharmony_ciemit_vs_consts(struct svga_context *svga, uint64_t dirty) 1125bf215546Sopenharmony_ci{ 1126bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.vs; 1127bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1128bf215546Sopenharmony_ci 1129bf215546Sopenharmony_ci /* SVGA_NEW_VS_VARIANT 1130bf215546Sopenharmony_ci */ 1131bf215546Sopenharmony_ci if (!variant) 1132bf215546Sopenharmony_ci return PIPE_OK; 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci /* SVGA_NEW_VS_CONST_BUFFER 1135bf215546Sopenharmony_ci */ 1136bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 1137bf215546Sopenharmony_ci ret = emit_consts_vgpu10(svga, PIPE_SHADER_VERTEX); 1138bf215546Sopenharmony_ci } 1139bf215546Sopenharmony_ci else { 1140bf215546Sopenharmony_ci ret = emit_consts_vgpu9(svga, PIPE_SHADER_VERTEX); 1141bf215546Sopenharmony_ci } 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci return ret; 1144bf215546Sopenharmony_ci} 1145bf215546Sopenharmony_ci 1146bf215546Sopenharmony_ci 1147bf215546Sopenharmony_cistatic enum pipe_error 1148bf215546Sopenharmony_ciemit_vs_constbuf(struct svga_context *svga, uint64_t dirty) 1149bf215546Sopenharmony_ci{ 1150bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.vs; 1151bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1152bf215546Sopenharmony_ci 1153bf215546Sopenharmony_ci /* SVGA_NEW_FS_VARIANT 1154bf215546Sopenharmony_ci */ 1155bf215546Sopenharmony_ci if (!variant) 1156bf215546Sopenharmony_ci return PIPE_OK; 1157bf215546Sopenharmony_ci 1158bf215546Sopenharmony_ci /* SVGA_NEW_FS_CONSTBUF 1159bf215546Sopenharmony_ci */ 1160bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1161bf215546Sopenharmony_ci ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_VERTEX); 1162bf215546Sopenharmony_ci 1163bf215546Sopenharmony_ci return ret; 1164bf215546Sopenharmony_ci} 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci 1167bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_vs_constants = 1168bf215546Sopenharmony_ci{ 1169bf215546Sopenharmony_ci "hw vs params", 1170bf215546Sopenharmony_ci (SVGA_NEW_PRESCALE | 1171bf215546Sopenharmony_ci SVGA_NEW_IMAGE_VIEW | 1172bf215546Sopenharmony_ci SVGA_NEW_VS_CONSTS | 1173bf215546Sopenharmony_ci SVGA_NEW_VS_VARIANT | 1174bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_CONSTS), 1175bf215546Sopenharmony_ci emit_vs_consts 1176bf215546Sopenharmony_ci}; 1177bf215546Sopenharmony_ci 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_vs_constbufs = 1180bf215546Sopenharmony_ci{ 1181bf215546Sopenharmony_ci "hw vs params", 1182bf215546Sopenharmony_ci SVGA_NEW_VS_CONST_BUFFER, 1183bf215546Sopenharmony_ci emit_vs_constbuf 1184bf215546Sopenharmony_ci}; 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci 1187bf215546Sopenharmony_cistatic enum pipe_error 1188bf215546Sopenharmony_ciemit_gs_consts(struct svga_context *svga, uint64_t dirty) 1189bf215546Sopenharmony_ci{ 1190bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.gs; 1191bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1192bf215546Sopenharmony_ci 1193bf215546Sopenharmony_ci /* SVGA_NEW_GS_VARIANT 1194bf215546Sopenharmony_ci */ 1195bf215546Sopenharmony_ci if (!variant) 1196bf215546Sopenharmony_ci return PIPE_OK; 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci /* SVGA_NEW_GS_CONST_BUFFER 1199bf215546Sopenharmony_ci */ 1200bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_ci /** 1203bf215546Sopenharmony_ci * If only the rasterizer state has changed and the current geometry 1204bf215546Sopenharmony_ci * shader does not emit wide points, then there is no reason to 1205bf215546Sopenharmony_ci * re-emit the GS constants, so skip it. 1206bf215546Sopenharmony_ci */ 1207bf215546Sopenharmony_ci if (dirty == SVGA_NEW_RAST && !variant->key.gs.wide_point) 1208bf215546Sopenharmony_ci return PIPE_OK; 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci ret = emit_consts_vgpu10(svga, PIPE_SHADER_GEOMETRY); 1211bf215546Sopenharmony_ci 1212bf215546Sopenharmony_ci return ret; 1213bf215546Sopenharmony_ci} 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_cistatic enum pipe_error 1217bf215546Sopenharmony_ciemit_gs_constbuf(struct svga_context *svga, uint64_t dirty) 1218bf215546Sopenharmony_ci{ 1219bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.gs; 1220bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci /* SVGA_NEW_GS_VARIANT 1223bf215546Sopenharmony_ci */ 1224bf215546Sopenharmony_ci if (!variant) 1225bf215546Sopenharmony_ci return PIPE_OK; 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci /* SVGA_NEW_GS_CONSTBUF 1228bf215546Sopenharmony_ci */ 1229bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1230bf215546Sopenharmony_ci ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_GEOMETRY); 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci return ret; 1233bf215546Sopenharmony_ci} 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ci 1236bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_gs_constants = 1237bf215546Sopenharmony_ci{ 1238bf215546Sopenharmony_ci "hw gs params", 1239bf215546Sopenharmony_ci (SVGA_NEW_PRESCALE | 1240bf215546Sopenharmony_ci SVGA_NEW_IMAGE_VIEW | 1241bf215546Sopenharmony_ci SVGA_NEW_GS_CONSTS | 1242bf215546Sopenharmony_ci SVGA_NEW_RAST | 1243bf215546Sopenharmony_ci SVGA_NEW_GS_VARIANT | 1244bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_CONSTS), 1245bf215546Sopenharmony_ci emit_gs_consts 1246bf215546Sopenharmony_ci}; 1247bf215546Sopenharmony_ci 1248bf215546Sopenharmony_ci 1249bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_gs_constbufs = 1250bf215546Sopenharmony_ci{ 1251bf215546Sopenharmony_ci "hw gs params", 1252bf215546Sopenharmony_ci SVGA_NEW_GS_CONST_BUFFER, 1253bf215546Sopenharmony_ci emit_gs_constbuf 1254bf215546Sopenharmony_ci}; 1255bf215546Sopenharmony_ci 1256bf215546Sopenharmony_ci 1257bf215546Sopenharmony_ci/** 1258bf215546Sopenharmony_ci * Emit constant buffer for tessellation control shader 1259bf215546Sopenharmony_ci */ 1260bf215546Sopenharmony_cistatic enum pipe_error 1261bf215546Sopenharmony_ciemit_tcs_consts(struct svga_context *svga, uint64_t dirty) 1262bf215546Sopenharmony_ci{ 1263bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.tcs; 1264bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1265bf215546Sopenharmony_ci 1266bf215546Sopenharmony_ci assert(svga_have_sm5(svga)); 1267bf215546Sopenharmony_ci 1268bf215546Sopenharmony_ci /* SVGA_NEW_TCS_VARIANT */ 1269bf215546Sopenharmony_ci if (!variant) 1270bf215546Sopenharmony_ci return PIPE_OK; 1271bf215546Sopenharmony_ci 1272bf215546Sopenharmony_ci /* SVGA_NEW_TCS_CONST_BUFFER */ 1273bf215546Sopenharmony_ci 1274bf215546Sopenharmony_ci ret = emit_consts_vgpu10(svga, PIPE_SHADER_TESS_CTRL); 1275bf215546Sopenharmony_ci 1276bf215546Sopenharmony_ci return ret; 1277bf215546Sopenharmony_ci} 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci 1280bf215546Sopenharmony_cistatic enum pipe_error 1281bf215546Sopenharmony_ciemit_tcs_constbuf(struct svga_context *svga, uint64_t dirty) 1282bf215546Sopenharmony_ci{ 1283bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.tcs; 1284bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ci /* SVGA_NEW_TCS_VARIANT 1287bf215546Sopenharmony_ci */ 1288bf215546Sopenharmony_ci if (!variant) 1289bf215546Sopenharmony_ci return PIPE_OK; 1290bf215546Sopenharmony_ci 1291bf215546Sopenharmony_ci /* SVGA_NEW_TCS_CONSTBUF 1292bf215546Sopenharmony_ci */ 1293bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1294bf215546Sopenharmony_ci ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_CTRL); 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_ci return ret; 1297bf215546Sopenharmony_ci} 1298bf215546Sopenharmony_ci 1299bf215546Sopenharmony_ci 1300bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tcs_constants = 1301bf215546Sopenharmony_ci{ 1302bf215546Sopenharmony_ci "hw tcs params", 1303bf215546Sopenharmony_ci (SVGA_NEW_IMAGE_VIEW | 1304bf215546Sopenharmony_ci SVGA_NEW_TCS_CONSTS | 1305bf215546Sopenharmony_ci SVGA_NEW_TCS_VARIANT), 1306bf215546Sopenharmony_ci emit_tcs_consts 1307bf215546Sopenharmony_ci}; 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci 1310bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tcs_constbufs = 1311bf215546Sopenharmony_ci{ 1312bf215546Sopenharmony_ci "hw tcs params", 1313bf215546Sopenharmony_ci SVGA_NEW_TCS_CONST_BUFFER, 1314bf215546Sopenharmony_ci emit_tcs_constbuf 1315bf215546Sopenharmony_ci}; 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ci 1318bf215546Sopenharmony_ci/** 1319bf215546Sopenharmony_ci * Emit constant buffer for tessellation evaluation shader 1320bf215546Sopenharmony_ci */ 1321bf215546Sopenharmony_cistatic enum pipe_error 1322bf215546Sopenharmony_ciemit_tes_consts(struct svga_context *svga, uint64_t dirty) 1323bf215546Sopenharmony_ci{ 1324bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.tes; 1325bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1326bf215546Sopenharmony_ci 1327bf215546Sopenharmony_ci assert(svga_have_sm5(svga)); 1328bf215546Sopenharmony_ci 1329bf215546Sopenharmony_ci /* SVGA_NEW_TES_VARIANT */ 1330bf215546Sopenharmony_ci if (!variant) 1331bf215546Sopenharmony_ci return PIPE_OK; 1332bf215546Sopenharmony_ci 1333bf215546Sopenharmony_ci ret = emit_consts_vgpu10(svga, PIPE_SHADER_TESS_EVAL); 1334bf215546Sopenharmony_ci 1335bf215546Sopenharmony_ci return ret; 1336bf215546Sopenharmony_ci} 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_ci 1339bf215546Sopenharmony_cistatic enum pipe_error 1340bf215546Sopenharmony_ciemit_tes_constbuf(struct svga_context *svga, uint64_t dirty) 1341bf215546Sopenharmony_ci{ 1342bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.tes; 1343bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci /* SVGA_NEW_TES_VARIANT 1346bf215546Sopenharmony_ci */ 1347bf215546Sopenharmony_ci if (!variant) 1348bf215546Sopenharmony_ci return PIPE_OK; 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_ci /* SVGA_NEW_TES_CONSTBUF 1351bf215546Sopenharmony_ci */ 1352bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1353bf215546Sopenharmony_ci ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_EVAL); 1354bf215546Sopenharmony_ci 1355bf215546Sopenharmony_ci return ret; 1356bf215546Sopenharmony_ci} 1357bf215546Sopenharmony_ci 1358bf215546Sopenharmony_ci 1359bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tes_constants = 1360bf215546Sopenharmony_ci{ 1361bf215546Sopenharmony_ci "hw tes params", 1362bf215546Sopenharmony_ci (SVGA_NEW_PRESCALE | 1363bf215546Sopenharmony_ci SVGA_NEW_IMAGE_VIEW | 1364bf215546Sopenharmony_ci SVGA_NEW_TES_CONSTS | 1365bf215546Sopenharmony_ci SVGA_NEW_TES_VARIANT), 1366bf215546Sopenharmony_ci emit_tes_consts 1367bf215546Sopenharmony_ci}; 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci 1370bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_tes_constbufs = 1371bf215546Sopenharmony_ci{ 1372bf215546Sopenharmony_ci "hw gs params", 1373bf215546Sopenharmony_ci SVGA_NEW_TES_CONST_BUFFER, 1374bf215546Sopenharmony_ci emit_tes_constbuf 1375bf215546Sopenharmony_ci}; 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_ci/** 1379bf215546Sopenharmony_ci * Emit constant buffer for compute shader 1380bf215546Sopenharmony_ci */ 1381bf215546Sopenharmony_cistatic enum pipe_error 1382bf215546Sopenharmony_ciemit_cs_consts(struct svga_context *svga, uint64_t dirty) 1383bf215546Sopenharmony_ci{ 1384bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.cs; 1385bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1386bf215546Sopenharmony_ci 1387bf215546Sopenharmony_ci assert(svga_have_sm5(svga)); 1388bf215546Sopenharmony_ci 1389bf215546Sopenharmony_ci /* SVGA_NEW_CS_VARIANT */ 1390bf215546Sopenharmony_ci if (!variant) 1391bf215546Sopenharmony_ci return PIPE_OK; 1392bf215546Sopenharmony_ci 1393bf215546Sopenharmony_ci /* SVGA_NEW_CS_CONST_BUFFER */ 1394bf215546Sopenharmony_ci ret = emit_consts_vgpu10(svga, PIPE_SHADER_COMPUTE); 1395bf215546Sopenharmony_ci 1396bf215546Sopenharmony_ci return ret; 1397bf215546Sopenharmony_ci} 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_cistatic enum pipe_error 1401bf215546Sopenharmony_ciemit_cs_constbuf(struct svga_context *svga, uint64_t dirty) 1402bf215546Sopenharmony_ci{ 1403bf215546Sopenharmony_ci const struct svga_shader_variant *variant = svga->state.hw_draw.cs; 1404bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 1405bf215546Sopenharmony_ci 1406bf215546Sopenharmony_ci /* SVGA_NEW_CS_VARIANT 1407bf215546Sopenharmony_ci */ 1408bf215546Sopenharmony_ci if (!variant) 1409bf215546Sopenharmony_ci return PIPE_OK; 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci /* SVGA_NEW_CS_CONSTBUF 1412bf215546Sopenharmony_ci */ 1413bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 1414bf215546Sopenharmony_ci ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_COMPUTE); 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci return ret; 1417bf215546Sopenharmony_ci} 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_cs_constants = 1421bf215546Sopenharmony_ci{ 1422bf215546Sopenharmony_ci "hw cs params", 1423bf215546Sopenharmony_ci (SVGA_NEW_IMAGE_VIEW | 1424bf215546Sopenharmony_ci SVGA_NEW_CS_CONSTS | 1425bf215546Sopenharmony_ci SVGA_NEW_CS_VARIANT | 1426bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_CONSTS), 1427bf215546Sopenharmony_ci emit_cs_consts 1428bf215546Sopenharmony_ci}; 1429bf215546Sopenharmony_ci 1430bf215546Sopenharmony_ci 1431bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_cs_constbufs = 1432bf215546Sopenharmony_ci{ 1433bf215546Sopenharmony_ci "hw cs params", 1434bf215546Sopenharmony_ci SVGA_NEW_CS_CONST_BUFFER, 1435bf215546Sopenharmony_ci emit_cs_constbuf 1436bf215546Sopenharmony_ci}; 1437bf215546Sopenharmony_ci 1438bf215546Sopenharmony_ci 1439bf215546Sopenharmony_ci/** 1440bf215546Sopenharmony_ci * A helper function to update the rawbuf for constbuf mask 1441bf215546Sopenharmony_ci */ 1442bf215546Sopenharmony_cistatic void 1443bf215546Sopenharmony_ciupdate_rawbuf_mask(struct svga_context *svga, enum pipe_shader_type shader) 1444bf215546Sopenharmony_ci{ 1445bf215546Sopenharmony_ci unsigned dirty_constbufs; 1446bf215546Sopenharmony_ci unsigned enabled_constbufs; 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_ci enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u; 1449bf215546Sopenharmony_ci dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u; 1450bf215546Sopenharmony_ci 1451bf215546Sopenharmony_ci while (dirty_constbufs) { 1452bf215546Sopenharmony_ci unsigned index = u_bit_scan(&dirty_constbufs); 1453bf215546Sopenharmony_ci struct svga_buffer *sbuf = 1454bf215546Sopenharmony_ci svga_buffer(svga->curr.constbufs[shader][index].buffer); 1455bf215546Sopenharmony_ci 1456bf215546Sopenharmony_ci if (sbuf && sbuf->uav) { 1457bf215546Sopenharmony_ci svga->state.raw_constbufs[shader] |= (1 << index); 1458bf215546Sopenharmony_ci } else { 1459bf215546Sopenharmony_ci svga->state.raw_constbufs[shader] &= ~(1 << index); 1460bf215546Sopenharmony_ci } 1461bf215546Sopenharmony_ci } 1462bf215546Sopenharmony_ci} 1463bf215546Sopenharmony_ci 1464bf215546Sopenharmony_ci 1465bf215546Sopenharmony_ci/** 1466bf215546Sopenharmony_ci * update_rawbuf is called at hw state update time to determine 1467bf215546Sopenharmony_ci * if any of the bound constant buffers need to be bound as 1468bf215546Sopenharmony_ci * raw buffer srv. This function is called after uav state is 1469bf215546Sopenharmony_ci * updated and before shader variants are bound. 1470bf215546Sopenharmony_ci */ 1471bf215546Sopenharmony_cistatic enum pipe_error 1472bf215546Sopenharmony_ciupdate_rawbuf(struct svga_context *svga, uint64 dirty) 1473bf215546Sopenharmony_ci{ 1474bf215546Sopenharmony_ci uint64_t rawbuf_dirtybit[] = { 1475bf215546Sopenharmony_ci SVGA_NEW_VS_RAW_BUFFER, /* PIPE_SHADER_VERTEX */ 1476bf215546Sopenharmony_ci SVGA_NEW_FS_RAW_BUFFER, /* PIPE_SHADER_FRAGMENT */ 1477bf215546Sopenharmony_ci SVGA_NEW_GS_RAW_BUFFER, /* PIPE_SHADER_GEOMETRY */ 1478bf215546Sopenharmony_ci SVGA_NEW_TCS_RAW_BUFFER, /* PIPE_SHADER_TESS_CTRL */ 1479bf215546Sopenharmony_ci SVGA_NEW_TES_RAW_BUFFER, /* PIPE_SHADER_TESS_EVAL */ 1480bf215546Sopenharmony_ci }; 1481bf215546Sopenharmony_ci 1482bf215546Sopenharmony_ci for (enum pipe_shader_type shader = PIPE_SHADER_VERTEX; 1483bf215546Sopenharmony_ci shader <= PIPE_SHADER_TESS_EVAL; shader++) { 1484bf215546Sopenharmony_ci unsigned rawbuf_mask = svga->state.raw_constbufs[shader]; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci update_rawbuf_mask(svga, shader); 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci /* If the rawbuf state is different for the shader stage, 1489bf215546Sopenharmony_ci * send SVGA_NEW_XX_RAW_BUFFER to trigger a new shader 1490bf215546Sopenharmony_ci * variant that will use srv for ubo access. 1491bf215546Sopenharmony_ci */ 1492bf215546Sopenharmony_ci if (svga->state.raw_constbufs[shader] != rawbuf_mask) 1493bf215546Sopenharmony_ci svga->dirty |= rawbuf_dirtybit[shader]; 1494bf215546Sopenharmony_ci } 1495bf215546Sopenharmony_ci 1496bf215546Sopenharmony_ci return PIPE_OK; 1497bf215546Sopenharmony_ci} 1498bf215546Sopenharmony_ci 1499bf215546Sopenharmony_ci 1500bf215546Sopenharmony_cistruct svga_tracked_state svga_need_rawbuf_srv = 1501bf215546Sopenharmony_ci{ 1502bf215546Sopenharmony_ci "raw buffer srv", 1503bf215546Sopenharmony_ci (SVGA_NEW_IMAGE_VIEW | 1504bf215546Sopenharmony_ci SVGA_NEW_SHADER_BUFFER | 1505bf215546Sopenharmony_ci SVGA_NEW_CONST_BUFFER), 1506bf215546Sopenharmony_ci update_rawbuf 1507bf215546Sopenharmony_ci}; 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci 1510bf215546Sopenharmony_ci/** 1511bf215546Sopenharmony_ci * update_cs_rawbuf is called at compute dispatch time to determine 1512bf215546Sopenharmony_ci * if any of the bound constant buffers need to be bound as 1513bf215546Sopenharmony_ci * raw buffer srv. This function is called after uav state is 1514bf215546Sopenharmony_ci * updated and before a compute shader variant is bound. 1515bf215546Sopenharmony_ci */ 1516bf215546Sopenharmony_cistatic enum pipe_error 1517bf215546Sopenharmony_ciupdate_cs_rawbuf(struct svga_context *svga, uint64 dirty) 1518bf215546Sopenharmony_ci{ 1519bf215546Sopenharmony_ci unsigned rawbuf_mask = svga->state.raw_constbufs[PIPE_SHADER_COMPUTE]; 1520bf215546Sopenharmony_ci 1521bf215546Sopenharmony_ci update_rawbuf_mask(svga, PIPE_SHADER_COMPUTE); 1522bf215546Sopenharmony_ci 1523bf215546Sopenharmony_ci /* if the rawbuf state is different for the shader stage, 1524bf215546Sopenharmony_ci * send SVGA_NEW_RAW_BUFFER to trigger a new shader 1525bf215546Sopenharmony_ci * variant to use srv for ubo access. 1526bf215546Sopenharmony_ci */ 1527bf215546Sopenharmony_ci if (svga->state.raw_constbufs[PIPE_SHADER_COMPUTE] != rawbuf_mask) 1528bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_CS_RAW_BUFFER; 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ci return PIPE_OK; 1531bf215546Sopenharmony_ci} 1532bf215546Sopenharmony_ci 1533bf215546Sopenharmony_ci 1534bf215546Sopenharmony_cistruct svga_tracked_state svga_cs_need_rawbuf_srv = 1535bf215546Sopenharmony_ci{ 1536bf215546Sopenharmony_ci "raw buffer srv", 1537bf215546Sopenharmony_ci (SVGA_NEW_IMAGE_VIEW | 1538bf215546Sopenharmony_ci SVGA_NEW_SHADER_BUFFER | 1539bf215546Sopenharmony_ci SVGA_NEW_CONST_BUFFER), 1540bf215546Sopenharmony_ci update_cs_rawbuf 1541bf215546Sopenharmony_ci}; 1542