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 "nir/nir_to_tgsi.h" 27bf215546Sopenharmony_ci#include "util/u_inlines.h" 28bf215546Sopenharmony_ci#include "util/u_memory.h" 29bf215546Sopenharmony_ci#include "util/u_bitmask.h" 30bf215546Sopenharmony_ci#include "tgsi/tgsi_parse.h" 31bf215546Sopenharmony_ci#include "tgsi/tgsi_text.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "svga_context.h" 34bf215546Sopenharmony_ci#include "svga_cmd.h" 35bf215546Sopenharmony_ci#include "svga_debug.h" 36bf215546Sopenharmony_ci#include "svga_shader.h" 37bf215546Sopenharmony_ci#include "svga_streamout.h" 38bf215546Sopenharmony_ci#include "svga_resource_buffer.h" 39bf215546Sopenharmony_ci#include "svga_tgsi.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci/** 42bf215546Sopenharmony_ci * Create the compute program. 43bf215546Sopenharmony_ci */ 44bf215546Sopenharmony_cistatic void * 45bf215546Sopenharmony_cisvga_create_compute_state(struct pipe_context *pipe, 46bf215546Sopenharmony_ci const struct pipe_compute_state *templ) 47bf215546Sopenharmony_ci{ 48bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci struct svga_compute_shader *cs = CALLOC_STRUCT(svga_compute_shader); 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci if (!cs) 53bf215546Sopenharmony_ci return NULL; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATECS); 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci if (templ->ir_type == PIPE_SHADER_IR_NIR) { 58bf215546Sopenharmony_ci cs->base.tokens = nir_to_tgsi((void *)templ->prog, pipe->screen); 59bf215546Sopenharmony_ci } else { 60bf215546Sopenharmony_ci assert(templ->ir_type == PIPE_SHADER_IR_TGSI); 61bf215546Sopenharmony_ci /* we need to keep a local copy of the tokens */ 62bf215546Sopenharmony_ci cs->base.tokens = tgsi_dup_tokens(templ->prog); 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci assert(templ->ir_type == PIPE_SHADER_IR_TGSI); 65bf215546Sopenharmony_ci struct svga_shader *shader = &cs->base; 66bf215546Sopenharmony_ci shader->id = svga->debug.shader_id++; 67bf215546Sopenharmony_ci shader->type = templ->ir_type; 68bf215546Sopenharmony_ci shader->stage = PIPE_SHADER_COMPUTE; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci /* Collect shader basic info */ 71bf215546Sopenharmony_ci svga_tgsi_scan_shader(&cs->base); 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci cs->shared_mem_size = templ->req_local_mem; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 76bf215546Sopenharmony_ci return cs; 77bf215546Sopenharmony_ci} 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci/** 81bf215546Sopenharmony_ci * Bind the compute program. 82bf215546Sopenharmony_ci */ 83bf215546Sopenharmony_cistatic void 84bf215546Sopenharmony_cisvga_bind_compute_state(struct pipe_context *pipe, void *shader) 85bf215546Sopenharmony_ci{ 86bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 87bf215546Sopenharmony_ci struct svga_compute_shader *cs = (struct svga_compute_shader *)shader; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci svga->curr.cs = cs; 90bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_CS; 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci/** 95bf215546Sopenharmony_ci * Delete the compute program. 96bf215546Sopenharmony_ci */ 97bf215546Sopenharmony_cistatic void 98bf215546Sopenharmony_cisvga_delete_compute_state(struct pipe_context *pipe, void *shader) 99bf215546Sopenharmony_ci{ 100bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 101bf215546Sopenharmony_ci struct svga_compute_shader *cs = (struct svga_compute_shader *)shader; 102bf215546Sopenharmony_ci struct svga_compute_shader *next_cs; 103bf215546Sopenharmony_ci struct svga_shader_variant *variant, *tmp; 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci svga_hwtnl_flush_retry(svga); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci /* Free the list of compute shaders */ 108bf215546Sopenharmony_ci while (cs) { 109bf215546Sopenharmony_ci next_cs = (struct svga_compute_shader *)cs->base.next; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci for (variant = cs->base.variants; variant; variant = tmp) { 112bf215546Sopenharmony_ci tmp = variant->next; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci /* Check if deleting currently bound shader */ 115bf215546Sopenharmony_ci if (variant == svga->state.hw_draw.cs) { 116bf215546Sopenharmony_ci SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, NULL)); 117bf215546Sopenharmony_ci svga->state.hw_draw.cs = NULL; 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci svga_destroy_shader_variant(svga, variant); 121bf215546Sopenharmony_ci } 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci FREE((void *)cs->base.tokens); 124bf215546Sopenharmony_ci FREE(cs); 125bf215546Sopenharmony_ci cs = next_cs; 126bf215546Sopenharmony_ci } 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci/** 131bf215546Sopenharmony_ci * Bind an array of shader resources that will be used by the 132bf215546Sopenharmony_ci * compute program. Any resources that were previously bound to 133bf215546Sopenharmony_ci * the specified range will be unbound after this call. 134bf215546Sopenharmony_ci */ 135bf215546Sopenharmony_cistatic void 136bf215546Sopenharmony_cisvga_set_compute_resources(struct pipe_context *pipe, 137bf215546Sopenharmony_ci unsigned start, unsigned count, 138bf215546Sopenharmony_ci struct pipe_surface **resources) 139bf215546Sopenharmony_ci{ 140bf215546Sopenharmony_ci //TODO 141bf215546Sopenharmony_ci return; 142bf215546Sopenharmony_ci} 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci/** 146bf215546Sopenharmony_ci * Bind an array of buffers to be mapped into the address space of 147bf215546Sopenharmony_ci * the GLOBAL resource. Any buffers that were previously bound 148bf215546Sopenharmony_ci * between [first, first + count - 1] are unbound after this call. 149bf215546Sopenharmony_ci */ 150bf215546Sopenharmony_cistatic void 151bf215546Sopenharmony_cisvga_set_global_binding(struct pipe_context *pipe, 152bf215546Sopenharmony_ci unsigned first, unsigned count, 153bf215546Sopenharmony_ci struct pipe_resource **resources, 154bf215546Sopenharmony_ci uint32_t **handles) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci //TODO 157bf215546Sopenharmony_ci return; 158bf215546Sopenharmony_ci} 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci/** 162bf215546Sopenharmony_ci */ 163bf215546Sopenharmony_cistatic void 164bf215546Sopenharmony_cisvga_validate_compute_resources(struct svga_context *svga) 165bf215546Sopenharmony_ci{ 166bf215546Sopenharmony_ci /* validate sampler view resources */ 167bf215546Sopenharmony_ci SVGA_RETRY(svga, 168bf215546Sopenharmony_ci svga_validate_sampler_resources(svga, SVGA_PIPE_COMPUTE)); 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci /* validate constant buffer resources */ 171bf215546Sopenharmony_ci SVGA_RETRY(svga, 172bf215546Sopenharmony_ci svga_validate_constant_buffers(svga, SVGA_PIPE_COMPUTE)); 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci /* validate image view resources */ 175bf215546Sopenharmony_ci SVGA_RETRY(svga, 176bf215546Sopenharmony_ci svga_validate_image_views(svga, SVGA_PIPE_COMPUTE)); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci /* validate shader buffer resources */ 179bf215546Sopenharmony_ci SVGA_RETRY(svga, 180bf215546Sopenharmony_ci svga_validate_shader_buffers(svga, SVGA_PIPE_COMPUTE)); 181bf215546Sopenharmony_ci} 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci/** 185bf215546Sopenharmony_ci * Launch the compute kernel starting from instruction pc of the 186bf215546Sopenharmony_ci * currently bound compute program. 187bf215546Sopenharmony_ci */ 188bf215546Sopenharmony_cistatic void 189bf215546Sopenharmony_cisvga_launch_grid(struct pipe_context *pipe, 190bf215546Sopenharmony_ci const struct pipe_grid_info *info) 191bf215546Sopenharmony_ci{ 192bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 193bf215546Sopenharmony_ci struct svga_winsys_context *swc = svga->swc; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci assert(svga_have_gl43(svga)); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_LAUNCHGRID); 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci if (info->indirect) { 200bf215546Sopenharmony_ci svga->curr.grid_info.indirect= info->indirect; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci svga_update_compute_state(svga); 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci /* validate compute resources */ 206bf215546Sopenharmony_ci svga_validate_compute_resources(svga); 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci if (info->indirect) { 209bf215546Sopenharmony_ci struct svga_winsys_surface *indirect_surf; 210bf215546Sopenharmony_ci indirect_surf = svga_buffer_handle(svga, info->indirect, 211bf215546Sopenharmony_ci PIPE_BIND_COMMAND_ARGS_BUFFER); 212bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_sm5_DispatchIndirect(swc, indirect_surf, 213bf215546Sopenharmony_ci info->indirect_offset)); 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci else { 216bf215546Sopenharmony_ci svga->curr.grid_info.size[0] = info->grid[0]; 217bf215546Sopenharmony_ci svga->curr.grid_info.size[1] = info->grid[1]; 218bf215546Sopenharmony_ci svga->curr.grid_info.size[2] = info->grid[2]; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_sm5_Dispatch(swc, info->grid)); 221bf215546Sopenharmony_ci } 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci SVGA_STATS_TIME_POP(svga_sws(svga)); 224bf215546Sopenharmony_ci return; 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci/** 229bf215546Sopenharmony_ci * Initialize the compute interface function pointers. 230bf215546Sopenharmony_ci */ 231bf215546Sopenharmony_civoid 232bf215546Sopenharmony_cisvga_init_cs_functions(struct svga_context *svga) 233bf215546Sopenharmony_ci{ 234bf215546Sopenharmony_ci svga->pipe.create_compute_state = svga_create_compute_state; 235bf215546Sopenharmony_ci svga->pipe.bind_compute_state = svga_bind_compute_state; 236bf215546Sopenharmony_ci svga->pipe.delete_compute_state = svga_delete_compute_state; 237bf215546Sopenharmony_ci svga->pipe.set_compute_resources = svga_set_compute_resources; 238bf215546Sopenharmony_ci svga->pipe.set_global_binding = svga_set_global_binding; 239bf215546Sopenharmony_ci svga->pipe.launch_grid = svga_launch_grid; 240bf215546Sopenharmony_ci} 241