1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2019 Red Hat. 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 "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **************************************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "lp_context.h" 27bf215546Sopenharmony_ci#include "lp_state.h" 28bf215546Sopenharmony_ci#include "lp_texture.h" 29bf215546Sopenharmony_ci#include "lp_debug.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "pipe/p_defines.h" 32bf215546Sopenharmony_ci#include "util/u_memory.h" 33bf215546Sopenharmony_ci#include "util/u_inlines.h" 34bf215546Sopenharmony_ci#include "draw/draw_context.h" 35bf215546Sopenharmony_ci#include "tgsi/tgsi_dump.h" 36bf215546Sopenharmony_ci#include "tgsi/tgsi_scan.h" 37bf215546Sopenharmony_ci#include "tgsi/tgsi_parse.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_cistatic void * 41bf215546Sopenharmony_cillvmpipe_create_tcs_state(struct pipe_context *pipe, 42bf215546Sopenharmony_ci const struct pipe_shader_state *templ) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 45bf215546Sopenharmony_ci struct lp_tess_ctrl_shader *state; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci state = CALLOC_STRUCT(lp_tess_ctrl_shader); 48bf215546Sopenharmony_ci if (!state) 49bf215546Sopenharmony_ci goto no_state; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci /* debug */ 52bf215546Sopenharmony_ci if (LP_DEBUG & DEBUG_TGSI && templ->type == PIPE_SHADER_IR_TGSI) { 53bf215546Sopenharmony_ci debug_printf("llvmpipe: Create tess ctrl shader %p:\n", (void *)state); 54bf215546Sopenharmony_ci tgsi_dump(templ->tokens, 0); 55bf215546Sopenharmony_ci } 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci /* copy stream output info */ 58bf215546Sopenharmony_ci state->no_tokens = !templ->tokens; 59bf215546Sopenharmony_ci memcpy(&state->stream_output, &templ->stream_output, sizeof state->stream_output); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci if (templ->tokens || templ->type == PIPE_SHADER_IR_NIR) { 62bf215546Sopenharmony_ci state->dtcs = draw_create_tess_ctrl_shader(llvmpipe->draw, templ); 63bf215546Sopenharmony_ci if (state->dtcs == NULL) { 64bf215546Sopenharmony_ci goto no_dgs; 65bf215546Sopenharmony_ci } 66bf215546Sopenharmony_ci } 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci return state; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cino_dgs: 71bf215546Sopenharmony_ci FREE( state ); 72bf215546Sopenharmony_cino_state: 73bf215546Sopenharmony_ci return NULL; 74bf215546Sopenharmony_ci} 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_cistatic void 78bf215546Sopenharmony_cillvmpipe_bind_tcs_state(struct pipe_context *pipe, void *tcs) 79bf215546Sopenharmony_ci{ 80bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci llvmpipe->tcs = (struct lp_tess_ctrl_shader *)tcs; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci draw_bind_tess_ctrl_shader(llvmpipe->draw, 85bf215546Sopenharmony_ci (llvmpipe->tcs ? llvmpipe->tcs->dtcs : NULL)); 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci llvmpipe->dirty |= LP_NEW_TCS; 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_cistatic void 92bf215546Sopenharmony_cillvmpipe_delete_tcs_state(struct pipe_context *pipe, void *tcs) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci struct lp_tess_ctrl_shader *state = 97bf215546Sopenharmony_ci (struct lp_tess_ctrl_shader *)tcs; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci if (!state) { 100bf215546Sopenharmony_ci return; 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci draw_delete_tess_ctrl_shader(llvmpipe->draw, state->dtcs); 104bf215546Sopenharmony_ci FREE(state); 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_cistatic void * 109bf215546Sopenharmony_cillvmpipe_create_tes_state(struct pipe_context *pipe, 110bf215546Sopenharmony_ci const struct pipe_shader_state *templ) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 113bf215546Sopenharmony_ci struct lp_tess_eval_shader *state; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci state = CALLOC_STRUCT(lp_tess_eval_shader); 116bf215546Sopenharmony_ci if (!state) 117bf215546Sopenharmony_ci goto no_state; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci /* debug */ 120bf215546Sopenharmony_ci if (LP_DEBUG & DEBUG_TGSI) { 121bf215546Sopenharmony_ci debug_printf("llvmpipe: Create tess eval shader %p:\n", (void *)state); 122bf215546Sopenharmony_ci tgsi_dump(templ->tokens, 0); 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci /* copy stream output info */ 126bf215546Sopenharmony_ci state->no_tokens = !templ->tokens; 127bf215546Sopenharmony_ci memcpy(&state->stream_output, &templ->stream_output, sizeof state->stream_output); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci if (templ->tokens || templ->type == PIPE_SHADER_IR_NIR) { 130bf215546Sopenharmony_ci state->dtes = draw_create_tess_eval_shader(llvmpipe->draw, templ); 131bf215546Sopenharmony_ci if (state->dtes == NULL) { 132bf215546Sopenharmony_ci goto no_dgs; 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci return state; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_cino_dgs: 139bf215546Sopenharmony_ci FREE( state ); 140bf215546Sopenharmony_cino_state: 141bf215546Sopenharmony_ci return NULL; 142bf215546Sopenharmony_ci} 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_cistatic void 146bf215546Sopenharmony_cillvmpipe_bind_tes_state(struct pipe_context *pipe, void *tes) 147bf215546Sopenharmony_ci{ 148bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci llvmpipe->tes = (struct lp_tess_eval_shader *)tes; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci draw_bind_tess_eval_shader(llvmpipe->draw, 153bf215546Sopenharmony_ci (llvmpipe->tes ? llvmpipe->tes->dtes : NULL)); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci llvmpipe->dirty |= LP_NEW_TES; 156bf215546Sopenharmony_ci} 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_cistatic void 160bf215546Sopenharmony_cillvmpipe_delete_tes_state(struct pipe_context *pipe, void *tes) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci struct lp_tess_eval_shader *state = 165bf215546Sopenharmony_ci (struct lp_tess_eval_shader *)tes; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci if (!state) { 168bf215546Sopenharmony_ci return; 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci draw_delete_tess_eval_shader(llvmpipe->draw, state->dtes); 172bf215546Sopenharmony_ci FREE(state); 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_cistatic void 176bf215546Sopenharmony_cillvmpipe_set_tess_state(struct pipe_context *pipe, 177bf215546Sopenharmony_ci const float default_outer_level[4], 178bf215546Sopenharmony_ci const float default_inner_level[2]) 179bf215546Sopenharmony_ci{ 180bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 181bf215546Sopenharmony_ci draw_set_tess_state(llvmpipe->draw, default_outer_level, default_inner_level); 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_cistatic void 185bf215546Sopenharmony_cillvmpipe_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) 186bf215546Sopenharmony_ci{ 187bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci llvmpipe->patch_vertices = patch_vertices; 190bf215546Sopenharmony_ci} 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_civoid 193bf215546Sopenharmony_cillvmpipe_init_tess_funcs(struct llvmpipe_context *llvmpipe) 194bf215546Sopenharmony_ci{ 195bf215546Sopenharmony_ci llvmpipe->pipe.create_tcs_state = llvmpipe_create_tcs_state; 196bf215546Sopenharmony_ci llvmpipe->pipe.bind_tcs_state = llvmpipe_bind_tcs_state; 197bf215546Sopenharmony_ci llvmpipe->pipe.delete_tcs_state = llvmpipe_delete_tcs_state; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci llvmpipe->pipe.create_tes_state = llvmpipe_create_tes_state; 200bf215546Sopenharmony_ci llvmpipe->pipe.bind_tes_state = llvmpipe_bind_tes_state; 201bf215546Sopenharmony_ci llvmpipe->pipe.delete_tes_state = llvmpipe_delete_tes_state; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci llvmpipe->pipe.set_tess_state = llvmpipe_set_tess_state; 204bf215546Sopenharmony_ci llvmpipe->pipe.set_patch_vertices = llvmpipe_set_patch_vertices; 205bf215546Sopenharmony_ci} 206