1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "sp_context.h" 29bf215546Sopenharmony_ci#include "sp_screen.h" 30bf215546Sopenharmony_ci#include "sp_state.h" 31bf215546Sopenharmony_ci#include "sp_fs.h" 32bf215546Sopenharmony_ci#include "sp_texture.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "nir.h" 35bf215546Sopenharmony_ci#include "nir/nir_to_tgsi.h" 36bf215546Sopenharmony_ci#include "pipe/p_defines.h" 37bf215546Sopenharmony_ci#include "util/ralloc.h" 38bf215546Sopenharmony_ci#include "util/u_memory.h" 39bf215546Sopenharmony_ci#include "util/u_inlines.h" 40bf215546Sopenharmony_ci#include "draw/draw_context.h" 41bf215546Sopenharmony_ci#include "draw/draw_vs.h" 42bf215546Sopenharmony_ci#include "draw/draw_gs.h" 43bf215546Sopenharmony_ci#include "tgsi/tgsi_dump.h" 44bf215546Sopenharmony_ci#include "tgsi/tgsi_from_mesa.h" 45bf215546Sopenharmony_ci#include "tgsi/tgsi_scan.h" 46bf215546Sopenharmony_ci#include "tgsi/tgsi_parse.h" 47bf215546Sopenharmony_ci#include "compiler/shader_enums.h" 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci/** 51bf215546Sopenharmony_ci * Create a new fragment shader variant. 52bf215546Sopenharmony_ci */ 53bf215546Sopenharmony_cistatic struct sp_fragment_shader_variant * 54bf215546Sopenharmony_cicreate_fs_variant(struct softpipe_context *softpipe, 55bf215546Sopenharmony_ci struct sp_fragment_shader *fs, 56bf215546Sopenharmony_ci const struct sp_fragment_shader_variant_key *key) 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci struct sp_fragment_shader_variant *var; 59bf215546Sopenharmony_ci struct pipe_shader_state *curfs = &fs->shader; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci /* codegen, create variant object */ 62bf215546Sopenharmony_ci var = softpipe_create_fs_variant_exec(softpipe); 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci if (var) { 65bf215546Sopenharmony_ci var->key = *key; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci var->tokens = tgsi_dup_tokens(curfs->tokens); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci tgsi_scan_shader(var->tokens, &var->info); 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci /* See comments elsewhere about draw fragment shaders */ 72bf215546Sopenharmony_ci#if 0 73bf215546Sopenharmony_ci /* draw's fs state */ 74bf215546Sopenharmony_ci var->draw_shader = draw_create_fragment_shader(softpipe->draw, 75bf215546Sopenharmony_ci &fs->shader); 76bf215546Sopenharmony_ci if (!var->draw_shader) { 77bf215546Sopenharmony_ci var->delete(var); 78bf215546Sopenharmony_ci FREE((void *) var->tokens); 79bf215546Sopenharmony_ci return NULL; 80bf215546Sopenharmony_ci } 81bf215546Sopenharmony_ci#endif 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci /* insert variant into linked list */ 84bf215546Sopenharmony_ci var->next = fs->variants; 85bf215546Sopenharmony_ci fs->variants = var; 86bf215546Sopenharmony_ci } 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci return var; 89bf215546Sopenharmony_ci} 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_cistruct sp_fragment_shader_variant * 93bf215546Sopenharmony_cisoftpipe_find_fs_variant(struct softpipe_context *sp, 94bf215546Sopenharmony_ci struct sp_fragment_shader *fs, 95bf215546Sopenharmony_ci const struct sp_fragment_shader_variant_key *key) 96bf215546Sopenharmony_ci{ 97bf215546Sopenharmony_ci struct sp_fragment_shader_variant *var; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci for (var = fs->variants; var; var = var->next) { 100bf215546Sopenharmony_ci if (memcmp(&var->key, key, sizeof(*key)) == 0) { 101bf215546Sopenharmony_ci /* found it */ 102bf215546Sopenharmony_ci return var; 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci return create_fs_variant(sp, fs, key); 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_cistatic void 110bf215546Sopenharmony_cisoftpipe_shader_db(struct pipe_context *pipe, const struct tgsi_token *tokens) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci struct tgsi_shader_info info; 115bf215546Sopenharmony_ci tgsi_scan_shader(tokens, &info); 116bf215546Sopenharmony_ci util_debug_message(&softpipe->debug, SHADER_INFO, "%s shader: %d inst, %d loops, %d temps, %d const, %d imm", 117bf215546Sopenharmony_ci _mesa_shader_stage_to_abbrev(tgsi_processor_to_shader_stage(info.processor)), 118bf215546Sopenharmony_ci info.num_instructions, 119bf215546Sopenharmony_ci info.opcode_count[TGSI_OPCODE_BGNLOOP], 120bf215546Sopenharmony_ci info.file_max[TGSI_FILE_TEMPORARY] + 1, 121bf215546Sopenharmony_ci info.file_max[TGSI_FILE_CONSTANT] + 1, 122bf215546Sopenharmony_ci info.immediate_count); 123bf215546Sopenharmony_ci} 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_cistatic void 126bf215546Sopenharmony_cisoftpipe_create_shader_state(struct pipe_context *pipe, 127bf215546Sopenharmony_ci struct pipe_shader_state *shader, 128bf215546Sopenharmony_ci const struct pipe_shader_state *templ, 129bf215546Sopenharmony_ci bool debug) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci if (templ->type == PIPE_SHADER_IR_NIR) { 132bf215546Sopenharmony_ci if (debug) 133bf215546Sopenharmony_ci nir_print_shader(templ->ir.nir, stderr); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci shader->tokens = nir_to_tgsi(templ->ir.nir, pipe->screen); 136bf215546Sopenharmony_ci } else { 137bf215546Sopenharmony_ci assert(templ->type == PIPE_SHADER_IR_TGSI); 138bf215546Sopenharmony_ci /* we need to keep a local copy of the tokens */ 139bf215546Sopenharmony_ci shader->tokens = tgsi_dup_tokens(templ->tokens); 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci shader->type = PIPE_SHADER_IR_TGSI; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci shader->stream_output = templ->stream_output; 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci if (debug) 147bf215546Sopenharmony_ci tgsi_dump(shader->tokens, 0); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci softpipe_shader_db(pipe, shader->tokens); 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cistatic void * 153bf215546Sopenharmony_cisoftpipe_create_fs_state(struct pipe_context *pipe, 154bf215546Sopenharmony_ci const struct pipe_shader_state *templ) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 157bf215546Sopenharmony_ci struct sp_fragment_shader *state = CALLOC_STRUCT(sp_fragment_shader); 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci softpipe_create_shader_state(pipe, &state->shader, templ, 160bf215546Sopenharmony_ci sp_debug & SP_DBG_FS); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci /* draw's fs state */ 163bf215546Sopenharmony_ci state->draw_shader = draw_create_fragment_shader(softpipe->draw, 164bf215546Sopenharmony_ci &state->shader); 165bf215546Sopenharmony_ci if (!state->draw_shader) { 166bf215546Sopenharmony_ci tgsi_free_tokens(state->shader.tokens); 167bf215546Sopenharmony_ci FREE(state); 168bf215546Sopenharmony_ci return NULL; 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci return state; 172bf215546Sopenharmony_ci} 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_cistatic void 176bf215546Sopenharmony_cisoftpipe_bind_fs_state(struct pipe_context *pipe, void *fs) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 179bf215546Sopenharmony_ci struct sp_fragment_shader *state = (struct sp_fragment_shader *) fs; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (softpipe->fs == fs) 182bf215546Sopenharmony_ci return; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci draw_flush(softpipe->draw); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci softpipe->fs = fs; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci /* This depends on the current fragment shader and must always be 189bf215546Sopenharmony_ci * re-validated before use. 190bf215546Sopenharmony_ci */ 191bf215546Sopenharmony_ci softpipe->fs_variant = NULL; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci if (state) 194bf215546Sopenharmony_ci draw_bind_fragment_shader(softpipe->draw, 195bf215546Sopenharmony_ci state->draw_shader); 196bf215546Sopenharmony_ci else 197bf215546Sopenharmony_ci draw_bind_fragment_shader(softpipe->draw, NULL); 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci softpipe->dirty |= SP_NEW_FS; 200bf215546Sopenharmony_ci} 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_cistatic void 204bf215546Sopenharmony_cisoftpipe_delete_fs_state(struct pipe_context *pipe, void *fs) 205bf215546Sopenharmony_ci{ 206bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 207bf215546Sopenharmony_ci struct sp_fragment_shader *state = fs; 208bf215546Sopenharmony_ci struct sp_fragment_shader_variant *var, *next_var; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci assert(fs != softpipe->fs); 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci /* delete variants */ 213bf215546Sopenharmony_ci for (var = state->variants; var; var = next_var) { 214bf215546Sopenharmony_ci next_var = var->next; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci assert(var != softpipe->fs_variant); 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci /* See comments elsewhere about draw fragment shaders */ 219bf215546Sopenharmony_ci#if 0 220bf215546Sopenharmony_ci draw_delete_fragment_shader(softpipe->draw, var->draw_shader); 221bf215546Sopenharmony_ci#endif 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci var->delete(var, softpipe->fs_machine); 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci draw_delete_fragment_shader(softpipe->draw, state->draw_shader); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci tgsi_free_tokens(state->shader.tokens); 229bf215546Sopenharmony_ci FREE(state); 230bf215546Sopenharmony_ci} 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_cistatic void * 234bf215546Sopenharmony_cisoftpipe_create_vs_state(struct pipe_context *pipe, 235bf215546Sopenharmony_ci const struct pipe_shader_state *templ) 236bf215546Sopenharmony_ci{ 237bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 238bf215546Sopenharmony_ci struct sp_vertex_shader *state; 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci state = CALLOC_STRUCT(sp_vertex_shader); 241bf215546Sopenharmony_ci if (!state) 242bf215546Sopenharmony_ci goto fail; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci softpipe_create_shader_state(pipe, &state->shader, templ, 245bf215546Sopenharmony_ci sp_debug & SP_DBG_VS); 246bf215546Sopenharmony_ci if (!state->shader.tokens) 247bf215546Sopenharmony_ci goto fail; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci state->draw_data = draw_create_vertex_shader(softpipe->draw, &state->shader); 250bf215546Sopenharmony_ci if (state->draw_data == NULL) 251bf215546Sopenharmony_ci goto fail; 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci return state; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_cifail: 258bf215546Sopenharmony_ci if (state) { 259bf215546Sopenharmony_ci tgsi_free_tokens(state->shader.tokens); 260bf215546Sopenharmony_ci FREE( state->draw_data ); 261bf215546Sopenharmony_ci FREE( state ); 262bf215546Sopenharmony_ci } 263bf215546Sopenharmony_ci return NULL; 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_cistatic void 268bf215546Sopenharmony_cisoftpipe_bind_vs_state(struct pipe_context *pipe, void *vs) 269bf215546Sopenharmony_ci{ 270bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci softpipe->vs = (struct sp_vertex_shader *) vs; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci draw_bind_vertex_shader(softpipe->draw, 275bf215546Sopenharmony_ci (softpipe->vs ? softpipe->vs->draw_data : NULL)); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci softpipe->dirty |= SP_NEW_VS; 278bf215546Sopenharmony_ci} 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_cistatic void 282bf215546Sopenharmony_cisoftpipe_delete_vs_state(struct pipe_context *pipe, void *vs) 283bf215546Sopenharmony_ci{ 284bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs; 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci draw_delete_vertex_shader(softpipe->draw, state->draw_data); 289bf215546Sopenharmony_ci tgsi_free_tokens(state->shader.tokens); 290bf215546Sopenharmony_ci FREE( state ); 291bf215546Sopenharmony_ci} 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_cistatic void * 295bf215546Sopenharmony_cisoftpipe_create_gs_state(struct pipe_context *pipe, 296bf215546Sopenharmony_ci const struct pipe_shader_state *templ) 297bf215546Sopenharmony_ci{ 298bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 299bf215546Sopenharmony_ci struct sp_geometry_shader *state; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci state = CALLOC_STRUCT(sp_geometry_shader); 302bf215546Sopenharmony_ci if (!state) 303bf215546Sopenharmony_ci goto fail; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci softpipe_create_shader_state(pipe, &state->shader, templ, 306bf215546Sopenharmony_ci sp_debug & SP_DBG_GS); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci if (state->shader.tokens) { 309bf215546Sopenharmony_ci state->draw_data = draw_create_geometry_shader(softpipe->draw, 310bf215546Sopenharmony_ci &state->shader); 311bf215546Sopenharmony_ci if (state->draw_data == NULL) 312bf215546Sopenharmony_ci goto fail; 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci return state; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_cifail: 320bf215546Sopenharmony_ci if (state) { 321bf215546Sopenharmony_ci tgsi_free_tokens(state->shader.tokens); 322bf215546Sopenharmony_ci FREE( state->draw_data ); 323bf215546Sopenharmony_ci FREE( state ); 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci return NULL; 326bf215546Sopenharmony_ci} 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_cistatic void 330bf215546Sopenharmony_cisoftpipe_bind_gs_state(struct pipe_context *pipe, void *gs) 331bf215546Sopenharmony_ci{ 332bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci softpipe->gs = (struct sp_geometry_shader *)gs; 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci draw_bind_geometry_shader(softpipe->draw, 337bf215546Sopenharmony_ci (softpipe->gs ? softpipe->gs->draw_data : NULL)); 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci softpipe->dirty |= SP_NEW_GS; 340bf215546Sopenharmony_ci} 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_cistatic void 344bf215546Sopenharmony_cisoftpipe_delete_gs_state(struct pipe_context *pipe, void *gs) 345bf215546Sopenharmony_ci{ 346bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci struct sp_geometry_shader *state = 349bf215546Sopenharmony_ci (struct sp_geometry_shader *)gs; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci draw_delete_geometry_shader(softpipe->draw, 352bf215546Sopenharmony_ci (state) ? state->draw_data : 0); 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci tgsi_free_tokens(state->shader.tokens); 355bf215546Sopenharmony_ci FREE(state); 356bf215546Sopenharmony_ci} 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_cistatic void 360bf215546Sopenharmony_cisoftpipe_set_constant_buffer(struct pipe_context *pipe, 361bf215546Sopenharmony_ci enum pipe_shader_type shader, uint index, 362bf215546Sopenharmony_ci bool take_ownership, 363bf215546Sopenharmony_ci const struct pipe_constant_buffer *cb) 364bf215546Sopenharmony_ci{ 365bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 366bf215546Sopenharmony_ci struct pipe_resource *constants = cb ? cb->buffer : NULL; 367bf215546Sopenharmony_ci unsigned size; 368bf215546Sopenharmony_ci const void *data; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci assert(shader < PIPE_SHADER_TYPES); 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci if (cb && cb->user_buffer) { 373bf215546Sopenharmony_ci constants = softpipe_user_buffer_create(pipe->screen, 374bf215546Sopenharmony_ci (void *) cb->user_buffer, 375bf215546Sopenharmony_ci cb->buffer_size, 376bf215546Sopenharmony_ci PIPE_BIND_CONSTANT_BUFFER); 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci size = cb ? cb->buffer_size : 0; 380bf215546Sopenharmony_ci data = constants ? softpipe_resource_data(constants) : NULL; 381bf215546Sopenharmony_ci if (data) 382bf215546Sopenharmony_ci data = (const char *) data + cb->buffer_offset; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci draw_flush(softpipe->draw); 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci /* note: reference counting */ 387bf215546Sopenharmony_ci if (take_ownership) { 388bf215546Sopenharmony_ci pipe_resource_reference(&softpipe->constants[shader][index], NULL); 389bf215546Sopenharmony_ci softpipe->constants[shader][index] = constants; 390bf215546Sopenharmony_ci } else { 391bf215546Sopenharmony_ci pipe_resource_reference(&softpipe->constants[shader][index], constants); 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { 395bf215546Sopenharmony_ci draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size); 396bf215546Sopenharmony_ci } 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci softpipe->mapped_constants[shader][index] = data; 399bf215546Sopenharmony_ci softpipe->const_buffer_size[shader][index] = size; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci softpipe->dirty |= SP_NEW_CONSTANTS; 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci if (cb && cb->user_buffer) { 404bf215546Sopenharmony_ci pipe_resource_reference(&constants, NULL); 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci} 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_cistatic void * 409bf215546Sopenharmony_cisoftpipe_create_compute_state(struct pipe_context *pipe, 410bf215546Sopenharmony_ci const struct pipe_compute_state *templ) 411bf215546Sopenharmony_ci{ 412bf215546Sopenharmony_ci struct sp_compute_shader *state = CALLOC_STRUCT(sp_compute_shader); 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci state->shader = *templ; 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci if (templ->ir_type == PIPE_SHADER_IR_NIR) { 417bf215546Sopenharmony_ci nir_shader *s = (void *)templ->prog; 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci if (sp_debug & SP_DBG_CS) 420bf215546Sopenharmony_ci nir_print_shader(s, stderr); 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci state->tokens = (void *)nir_to_tgsi(s, pipe->screen); 423bf215546Sopenharmony_ci } else { 424bf215546Sopenharmony_ci assert(templ->ir_type == PIPE_SHADER_IR_TGSI); 425bf215546Sopenharmony_ci /* we need to keep a local copy of the tokens */ 426bf215546Sopenharmony_ci state->tokens = tgsi_dup_tokens(templ->prog); 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci if (sp_debug & SP_DBG_CS) 430bf215546Sopenharmony_ci tgsi_dump(state->tokens, 0); 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci softpipe_shader_db(pipe, state->tokens); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci tgsi_scan_shader(state->tokens, &state->info); 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci state->max_sampler = state->info.file_max[TGSI_FILE_SAMPLER]; 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci return state; 439bf215546Sopenharmony_ci} 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_cistatic void 442bf215546Sopenharmony_cisoftpipe_bind_compute_state(struct pipe_context *pipe, 443bf215546Sopenharmony_ci void *cs) 444bf215546Sopenharmony_ci{ 445bf215546Sopenharmony_ci struct softpipe_context *softpipe = softpipe_context(pipe); 446bf215546Sopenharmony_ci struct sp_compute_shader *state = (struct sp_compute_shader *)cs; 447bf215546Sopenharmony_ci if (softpipe->cs == state) 448bf215546Sopenharmony_ci return; 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci softpipe->cs = state; 451bf215546Sopenharmony_ci} 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_cistatic void 454bf215546Sopenharmony_cisoftpipe_delete_compute_state(struct pipe_context *pipe, 455bf215546Sopenharmony_ci void *cs) 456bf215546Sopenharmony_ci{ 457bf215546Sopenharmony_ci ASSERTED struct softpipe_context *softpipe = softpipe_context(pipe); 458bf215546Sopenharmony_ci struct sp_compute_shader *state = (struct sp_compute_shader *)cs; 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci assert(softpipe->cs != state); 461bf215546Sopenharmony_ci tgsi_free_tokens(state->tokens); 462bf215546Sopenharmony_ci FREE(state); 463bf215546Sopenharmony_ci} 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_civoid 466bf215546Sopenharmony_cisoftpipe_init_shader_funcs(struct pipe_context *pipe) 467bf215546Sopenharmony_ci{ 468bf215546Sopenharmony_ci pipe->create_fs_state = softpipe_create_fs_state; 469bf215546Sopenharmony_ci pipe->bind_fs_state = softpipe_bind_fs_state; 470bf215546Sopenharmony_ci pipe->delete_fs_state = softpipe_delete_fs_state; 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci pipe->create_vs_state = softpipe_create_vs_state; 473bf215546Sopenharmony_ci pipe->bind_vs_state = softpipe_bind_vs_state; 474bf215546Sopenharmony_ci pipe->delete_vs_state = softpipe_delete_vs_state; 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci pipe->create_gs_state = softpipe_create_gs_state; 477bf215546Sopenharmony_ci pipe->bind_gs_state = softpipe_bind_gs_state; 478bf215546Sopenharmony_ci pipe->delete_gs_state = softpipe_delete_gs_state; 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci pipe->set_constant_buffer = softpipe_set_constant_buffer; 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci pipe->create_compute_state = softpipe_create_compute_state; 483bf215546Sopenharmony_ci pipe->bind_compute_state = softpipe_bind_compute_state; 484bf215546Sopenharmony_ci pipe->delete_compute_state = softpipe_delete_compute_state; 485bf215546Sopenharmony_ci} 486