1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 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/u_inlines.h" 27bf215546Sopenharmony_ci#include "util/u_memory.h" 28bf215546Sopenharmony_ci#include "util/u_bitmask.h" 29bf215546Sopenharmony_ci#include "translate/translate.h" 30bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "svga_context.h" 33bf215546Sopenharmony_ci#include "svga_cmd.h" 34bf215546Sopenharmony_ci#include "svga_shader.h" 35bf215546Sopenharmony_ci#include "svga_tgsi.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci/** 39bf215546Sopenharmony_ci * Create compute shader compile key. 40bf215546Sopenharmony_ci */ 41bf215546Sopenharmony_cistatic void 42bf215546Sopenharmony_cimake_cs_key(struct svga_context *svga, 43bf215546Sopenharmony_ci struct svga_compile_key *key) 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci struct svga_compute_shader *cs = svga->curr.cs; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci memset(key, 0, sizeof *key); 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci svga_init_shader_key_common(svga, PIPE_SHADER_COMPUTE, &cs->base, key); 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci key->cs.grid_size[0] = svga->curr.grid_info.size[0]; 52bf215546Sopenharmony_ci key->cs.grid_size[1] = svga->curr.grid_info.size[1]; 53bf215546Sopenharmony_ci key->cs.grid_size[2] = svga->curr.grid_info.size[2]; 54bf215546Sopenharmony_ci key->cs.mem_size = cs->shared_mem_size; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci if (svga->curr.grid_info.indirect && cs->base.info.uses_grid_size) { 57bf215546Sopenharmony_ci struct pipe_transfer *transfer = NULL; 58bf215546Sopenharmony_ci const void *map = NULL; 59bf215546Sopenharmony_ci map = pipe_buffer_map(&svga->pipe, svga->curr.grid_info.indirect, 60bf215546Sopenharmony_ci PIPE_MAP_READ, &transfer); 61bf215546Sopenharmony_ci memcpy(key->cs.grid_size, map, 3 * sizeof(uint)); 62bf215546Sopenharmony_ci pipe_buffer_unmap(&svga->pipe, transfer); 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci} 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci/** 68bf215546Sopenharmony_ci * Emit current compute shader to device. 69bf215546Sopenharmony_ci */ 70bf215546Sopenharmony_cistatic enum pipe_error 71bf215546Sopenharmony_ciemit_hw_cs(struct svga_context *svga, uint64_t dirty) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci struct svga_shader_variant *variant; 74bf215546Sopenharmony_ci struct svga_compute_shader *cs = svga->curr.cs; 75bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 76bf215546Sopenharmony_ci struct svga_compile_key key; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci assert(svga_have_sm5(svga)); 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITCS); 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci if (!cs) { 83bf215546Sopenharmony_ci if (svga->state.hw_draw.cs != NULL) { 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci /** The previous compute shader is made inactive. 86bf215546Sopenharmony_ci * Needs to unbind the compute shader. 87bf215546Sopenharmony_ci */ 88bf215546Sopenharmony_ci ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, NULL); 89bf215546Sopenharmony_ci if (ret != PIPE_OK) 90bf215546Sopenharmony_ci goto done; 91bf215546Sopenharmony_ci svga->state.hw_draw.cs = NULL; 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci goto done; 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci make_cs_key(svga, &key); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci /* See if we already have a CS variant that matches the key */ 99bf215546Sopenharmony_ci variant = svga_search_shader_key(&cs->base, &key); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci if (!variant) { 102bf215546Sopenharmony_ci ret = svga_compile_shader(svga, &cs->base, &key, &variant); 103bf215546Sopenharmony_ci if (ret != PIPE_OK) 104bf215546Sopenharmony_ci goto done; 105bf215546Sopenharmony_ci } 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci if (variant != svga->state.hw_draw.cs) { 108bf215546Sopenharmony_ci /* Bind the new variant */ 109bf215546Sopenharmony_ci ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, variant); 110bf215546Sopenharmony_ci if (ret != PIPE_OK) 111bf215546Sopenharmony_ci goto done; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci svga->rebind.flags.cs = FALSE; 114bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_CS_VARIANT; 115bf215546Sopenharmony_ci svga->state.hw_draw.cs = variant; 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_cidone: 119bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 120bf215546Sopenharmony_ci return ret; 121bf215546Sopenharmony_ci} 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_cistruct svga_tracked_state svga_hw_cs = 124bf215546Sopenharmony_ci{ 125bf215546Sopenharmony_ci "compute shader", 126bf215546Sopenharmony_ci (SVGA_NEW_CS | 127bf215546Sopenharmony_ci SVGA_NEW_TEXTURE_BINDING | 128bf215546Sopenharmony_ci SVGA_NEW_SAMPLER | 129bf215546Sopenharmony_ci SVGA_NEW_CS_RAW_BUFFER), 130bf215546Sopenharmony_ci emit_hw_cs 131bf215546Sopenharmony_ci}; 132