Path: blob/21.2-virgl/src/gallium/drivers/freedreno/freedreno_program.c
4570 views
/*1* Copyright (C) 2014 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*22* Authors:23* Rob Clark <[email protected]>24*/2526#include "tgsi/tgsi_text.h"27#include "tgsi/tgsi_ureg.h"2829#include "util/u_simple_shaders.h"3031#include "freedreno_context.h"32#include "freedreno_program.h"3334static void35update_bound_stage(struct fd_context *ctx, enum pipe_shader_type shader,36bool bound) assert_dt37{38if (bound) {39ctx->bound_shader_stages |= BIT(shader);40} else {41ctx->bound_shader_stages &= ~BIT(shader);42}43}4445static void46fd_vs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt47{48struct fd_context *ctx = fd_context(pctx);49ctx->prog.vs = hwcso;50fd_context_dirty_shader(ctx, PIPE_SHADER_VERTEX, FD_DIRTY_SHADER_PROG);51update_bound_stage(ctx, PIPE_SHADER_VERTEX, !!hwcso);52}5354static void55fd_tcs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt56{57struct fd_context *ctx = fd_context(pctx);58ctx->prog.hs = hwcso;59fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_CTRL, FD_DIRTY_SHADER_PROG);60update_bound_stage(ctx, PIPE_SHADER_TESS_CTRL, !!hwcso);61}6263static void64fd_tes_state_bind(struct pipe_context *pctx, void *hwcso) in_dt65{66struct fd_context *ctx = fd_context(pctx);67ctx->prog.ds = hwcso;68fd_context_dirty_shader(ctx, PIPE_SHADER_TESS_EVAL, FD_DIRTY_SHADER_PROG);69update_bound_stage(ctx, PIPE_SHADER_TESS_EVAL, !!hwcso);70}7172static void73fd_gs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt74{75struct fd_context *ctx = fd_context(pctx);76ctx->prog.gs = hwcso;77fd_context_dirty_shader(ctx, PIPE_SHADER_GEOMETRY, FD_DIRTY_SHADER_PROG);78update_bound_stage(ctx, PIPE_SHADER_GEOMETRY, !!hwcso);79}8081static void82fd_fs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt83{84struct fd_context *ctx = fd_context(pctx);85ctx->prog.fs = hwcso;86fd_context_dirty_shader(ctx, PIPE_SHADER_FRAGMENT, FD_DIRTY_SHADER_PROG);87update_bound_stage(ctx, PIPE_SHADER_FRAGMENT, !!hwcso);88}8990static const char *solid_fs = "FRAG \n"91"PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1 \n"92"DCL CONST[0] \n"93"DCL OUT[0], COLOR \n"94" 0: MOV OUT[0], CONST[0] \n"95" 1: END \n";9697static const char *solid_vs = "VERT \n"98"DCL IN[0] \n"99"DCL OUT[0], POSITION \n"100" 0: MOV OUT[0], IN[0] \n"101" 1: END \n";102103static void *104assemble_tgsi(struct pipe_context *pctx, const char *src, bool frag)105{106struct tgsi_token toks[32];107struct pipe_shader_state cso = {108.tokens = toks,109};110111bool ret = tgsi_text_translate(src, toks, ARRAY_SIZE(toks));112assume(ret);113114if (frag)115return pctx->create_fs_state(pctx, &cso);116else117return pctx->create_vs_state(pctx, &cso);118}119120/* the correct semantic to use for the texcoord varying depends on pipe-cap: */121static enum tgsi_semantic122texcoord_semantic(struct pipe_context *pctx)123{124struct pipe_screen *pscreen = pctx->screen;125126if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_TEXCOORD)) {127return TGSI_SEMANTIC_TEXCOORD;128} else {129return TGSI_SEMANTIC_GENERIC;130}131}132133static void *134fd_prog_blit_vs(struct pipe_context *pctx)135{136struct ureg_program *ureg;137138ureg = ureg_create(PIPE_SHADER_VERTEX);139if (!ureg)140return NULL;141142struct ureg_src in0 = ureg_DECL_vs_input(ureg, 0);143struct ureg_src in1 = ureg_DECL_vs_input(ureg, 1);144145struct ureg_dst out0 = ureg_DECL_output(ureg, texcoord_semantic(pctx), 0);146struct ureg_dst out1 = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 1);147148ureg_MOV(ureg, out0, in0);149ureg_MOV(ureg, out1, in1);150151ureg_END(ureg);152153return ureg_create_shader_and_destroy(ureg, pctx);154}155156static void *157fd_prog_blit_fs(struct pipe_context *pctx, int rts, bool depth)158{159int i;160struct ureg_src tc;161struct ureg_program *ureg;162163debug_assert(rts <= MAX_RENDER_TARGETS);164165ureg = ureg_create(PIPE_SHADER_FRAGMENT);166if (!ureg)167return NULL;168169tc = ureg_DECL_fs_input(ureg, texcoord_semantic(pctx), 0,170TGSI_INTERPOLATE_PERSPECTIVE);171for (i = 0; i < rts; i++)172ureg_TEX(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, i),173TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, i));174if (depth)175ureg_TEX(ureg,176ureg_writemask(ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0),177TGSI_WRITEMASK_Z),178TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, rts));179180ureg_END(ureg);181182return ureg_create_shader_and_destroy(ureg, pctx);183}184185void186fd_prog_init(struct pipe_context *pctx)187{188struct fd_context *ctx = fd_context(pctx);189int i;190191pctx->bind_vs_state = fd_vs_state_bind;192pctx->bind_tcs_state = fd_tcs_state_bind;193pctx->bind_tes_state = fd_tes_state_bind;194pctx->bind_gs_state = fd_gs_state_bind;195pctx->bind_fs_state = fd_fs_state_bind;196197ctx->solid_prog.fs = assemble_tgsi(pctx, solid_fs, true);198ctx->solid_prog.vs = assemble_tgsi(pctx, solid_vs, false);199200if (ctx->screen->gpu_id >= 600) {201ctx->solid_layered_prog.fs = assemble_tgsi(pctx, solid_fs, true);202ctx->solid_layered_prog.vs = util_make_layered_clear_vertex_shader(pctx);203}204205if (ctx->screen->gpu_id >= 500)206return;207208ctx->blit_prog[0].vs = fd_prog_blit_vs(pctx);209ctx->blit_prog[0].fs = fd_prog_blit_fs(pctx, 1, false);210211if (ctx->screen->gpu_id < 300)212return;213214for (i = 1; i < ctx->screen->max_rts; i++) {215ctx->blit_prog[i].vs = ctx->blit_prog[0].vs;216ctx->blit_prog[i].fs = fd_prog_blit_fs(pctx, i + 1, false);217}218219ctx->blit_z.vs = ctx->blit_prog[0].vs;220ctx->blit_z.fs = fd_prog_blit_fs(pctx, 0, true);221ctx->blit_zs.vs = ctx->blit_prog[0].vs;222ctx->blit_zs.fs = fd_prog_blit_fs(pctx, 1, true);223}224225void226fd_prog_fini(struct pipe_context *pctx)227{228struct fd_context *ctx = fd_context(pctx);229int i;230231pctx->delete_vs_state(pctx, ctx->solid_prog.vs);232pctx->delete_fs_state(pctx, ctx->solid_prog.fs);233234if (ctx->screen->gpu_id >= 600) {235pctx->delete_vs_state(pctx, ctx->solid_layered_prog.vs);236pctx->delete_fs_state(pctx, ctx->solid_layered_prog.fs);237}238239if (ctx->screen->gpu_id >= 500)240return;241242pctx->delete_vs_state(pctx, ctx->blit_prog[0].vs);243pctx->delete_fs_state(pctx, ctx->blit_prog[0].fs);244245if (ctx->screen->gpu_id < 300)246return;247248for (i = 1; i < ctx->screen->max_rts; i++)249pctx->delete_fs_state(pctx, ctx->blit_prog[i].fs);250pctx->delete_fs_state(pctx, ctx->blit_z.fs);251pctx->delete_fs_state(pctx, ctx->blit_zs.fs);252}253254255