X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_simple_shaders.c;h=d62a65579ae41e1267dfd39e0333f7d97b116e7b;hb=a17c1ae165a9344e8679b24c8925f5e669ad51fc;hp=280ed8f4cb9b265ace5a311ba42cf66da17fe09a;hpb=717f2dd69fadc8ba07b0b8f4612f28a547fb7a4c;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 280ed8f4cb9..d62a65579ae 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -41,6 +41,7 @@ #include "util/u_simple_shaders.h" #include "util/u_debug.h" #include "util/u_memory.h" +#include "util/u_string.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_strings.h" #include "tgsi/tgsi_ureg.h" @@ -58,33 +59,33 @@ void * util_make_vertex_passthrough_shader(struct pipe_context *pipe, uint num_attribs, - const uint *semantic_names, + const enum tgsi_semantic *semantic_names, const uint *semantic_indexes, bool window_space) { return util_make_vertex_passthrough_shader_with_so(pipe, num_attribs, semantic_names, semantic_indexes, - window_space, NULL); + window_space, false, NULL); } void * util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, uint num_attribs, - const uint *semantic_names, + const enum tgsi_semantic *semantic_names, const uint *semantic_indexes, - bool window_space, + bool window_space, bool layered, const struct pipe_stream_output_info *so) { struct ureg_program *ureg; uint i; - ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); - if (ureg == NULL) + ureg = ureg_create( PIPE_SHADER_VERTEX ); + if (!ureg) return NULL; if (window_space) - ureg_property_vs_window_space_position(ureg, TRUE); + ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE); for (i = 0; i < num_attribs; i++) { struct ureg_src src; @@ -99,6 +100,15 @@ util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, ureg_MOV( ureg, dst, src ); } + if (layered) { + struct ureg_src instance_id = + ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0); + struct ureg_dst layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0); + + ureg_MOV(ureg, ureg_writemask(layer, TGSI_WRITEMASK_X), + ureg_scalar(instance_id, TGSI_SWIZZLE_X)); + } + ureg_END( ureg ); return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); @@ -106,6 +116,20 @@ util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe) +{ + const enum tgsi_semantic semantic_names[] = {TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC}; + const unsigned semantic_indices[] = {0, 0}; + + return util_make_vertex_passthrough_shader_with_so(pipe, 2, semantic_names, + semantic_indices, false, + true, NULL); +} + +/** + * Takes position and color, and outputs position, color, and instance id. + */ +void *util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe) { static const char text[] = "VERT\n" @@ -114,54 +138,178 @@ void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe) "DCL SV[0], INSTANCEID\n" "DCL OUT[0], POSITION\n" "DCL OUT[1], GENERIC[0]\n" - "DCL OUT[2], LAYER\n" + "DCL OUT[2], GENERIC[1]\n" "MOV OUT[0], IN[0]\n" "MOV OUT[1], IN[1]\n" - "MOV OUT[2], SV[0]\n" + "MOV OUT[2].x, SV[0].xxxx\n" "END\n"; struct tgsi_token tokens[1000]; - struct pipe_shader_state state = {tokens}; + struct pipe_shader_state state; - if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { assert(0); return NULL; } + pipe_shader_state_from_tgsi(&state, tokens); return pipe->create_vs_state(pipe, &state); } +/** + * Takes position, color, and target layer, and emits vertices on that target + * layer, with the specified color. + */ +void *util_make_layered_clear_geometry_shader(struct pipe_context *pipe) +{ + static const char text[] = + "GEOM\n" + "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n" + "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n" + "PROPERTY GS_MAX_OUTPUT_VERTICES 3\n" + "PROPERTY GS_INVOCATIONS 1\n" + "DCL IN[][0], POSITION\n" /* position */ + "DCL IN[][1], GENERIC[0]\n" /* color */ + "DCL IN[][2], GENERIC[1]\n" /* vs invocation */ + "DCL OUT[0], POSITION\n" + "DCL OUT[1], GENERIC[0]\n" + "DCL OUT[2], LAYER\n" + "IMM[0] INT32 {0, 0, 0, 0}\n" + + "MOV OUT[0], IN[0][0]\n" + "MOV OUT[1], IN[0][1]\n" + "MOV OUT[2].x, IN[0][2].xxxx\n" + "EMIT IMM[0].xxxx\n" + "MOV OUT[0], IN[1][0]\n" + "MOV OUT[1], IN[1][1]\n" + "MOV OUT[2].x, IN[1][2].xxxx\n" + "EMIT IMM[0].xxxx\n" + "MOV OUT[0], IN[2][0]\n" + "MOV OUT[1], IN[2][1]\n" + "MOV OUT[2].x, IN[2][2].xxxx\n" + "EMIT IMM[0].xxxx\n" + "END\n"; + struct tgsi_token tokens[1000]; + struct pipe_shader_state state; + + if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { + assert(0); + return NULL; + } + pipe_shader_state_from_tgsi(&state, tokens); + return pipe->create_gs_state(pipe, &state); +} + +static void +ureg_load_tex(struct ureg_program *ureg, struct ureg_dst out, + struct ureg_src coord, struct ureg_src sampler, + enum tgsi_texture_type tex_target, + bool load_level_zero, bool use_txf) +{ + if (use_txf) { + struct ureg_dst temp = ureg_DECL_temporary(ureg); + + ureg_F2I(ureg, temp, coord); + + if (load_level_zero) + ureg_TXF_LZ(ureg, out, tex_target, ureg_src(temp), sampler); + else + ureg_TXF(ureg, out, tex_target, ureg_src(temp), sampler); + } else { + if (load_level_zero) + ureg_TEX_LZ(ureg, out, tex_target, coord, sampler); + else + ureg_TEX(ureg, out, tex_target, coord, sampler); + } +} + +/** + * Make simple fragment texture shader, with xrbias->float conversion: + * IMM {1023/510, -384/510, 0, 1} + * TEX TEMP[0], IN[0], SAMP[0], 2D; + * MAD TEMP[0].xyz TEMP[0], IMM[0].xxxx, IMM[0].yyyy + * MOV OUT[0], TEMP[0] + * END; + * + * \param tex_target one of PIPE_TEXTURE_x + */ +void * +util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe, + enum tgsi_texture_type tex_target) +{ + struct ureg_program *ureg; + struct ureg_src sampler; + struct ureg_src coord; + struct ureg_dst temp; + struct ureg_dst out; + struct ureg_src imm; + enum tgsi_return_type stype = TGSI_RETURN_TYPE_FLOAT; + + ureg = ureg_create(PIPE_SHADER_FRAGMENT); + if (!ureg) + return NULL; + + imm = ureg_imm4f(ureg, 1023.0f/510.0f, -384.0f/510.0f, 0.0f, 1.0f); + sampler = ureg_DECL_sampler(ureg, 0); + ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype); + coord = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_GENERIC, 0, + TGSI_INTERPOLATE_LINEAR); + out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); + temp = ureg_DECL_temporary(ureg); + + ureg_TEX(ureg, temp, tex_target, coord, sampler); + ureg_MAD(ureg, ureg_writemask(temp, TGSI_WRITEMASK_XYZ), + ureg_src(temp), + ureg_scalar(imm, TGSI_SWIZZLE_X), + ureg_scalar(imm, TGSI_SWIZZLE_Y)); + ureg_MOV(ureg, out, ureg_src(temp)); + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + /** * Make simple fragment texture shader: * IMM {0,0,0,1} // (if writemask != 0xf) - * MOV OUT[0], IMM[0] // (if writemask != 0xf) - * TEX OUT[0].writemask, IN[0], SAMP[0], 2D; + * MOV TEMP[0], IMM[0] // (if writemask != 0xf) + * TEX TEMP[0].writemask, IN[0], SAMP[0], 2D; + * .. optional SINT <-> UINT clamping .. + * MOV OUT[0], TEMP[0] * END; * - * \param tex_target one of PIPE_TEXTURE_x + * \param tex_target one of TGSI_TEXTURE_x * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE * \param writemask mask of TGSI_WRITEMASK_x */ void * util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode, - unsigned writemask ) + enum tgsi_texture_type tex_target, + enum tgsi_interpolate_mode interp_mode, + unsigned writemask, + enum tgsi_return_type stype, + enum tgsi_return_type dtype, + bool load_level_zero, + bool use_txf) { struct ureg_program *ureg; struct ureg_src sampler; struct ureg_src tex; + struct ureg_dst temp; struct ureg_dst out; + assert((stype == TGSI_RETURN_TYPE_FLOAT) == (dtype == TGSI_RETURN_TYPE_FLOAT)); assert(interp_mode == TGSI_INTERPOLATE_LINEAR || interp_mode == TGSI_INTERPOLATE_PERSPECTIVE); - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) + ureg = ureg_create( PIPE_SHADER_FRAGMENT ); + if (!ureg) return NULL; sampler = ureg_DECL_sampler( ureg, 0 ); + ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype); + tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, interp_mode ); @@ -170,15 +318,37 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, TGSI_SEMANTIC_COLOR, 0 ); + temp = ureg_DECL_temporary(ureg); + if (writemask != TGSI_WRITEMASK_XYZW) { struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); - ureg_MOV( ureg, out, imm ); + ureg_MOV(ureg, temp, imm); } - ureg_TEX( ureg, - ureg_writemask(out, writemask), - tex_target, tex, sampler ); + if (tex_target == TGSI_TEXTURE_BUFFER) + ureg_TXF(ureg, + ureg_writemask(temp, writemask), + tex_target, tex, sampler); + else + ureg_load_tex(ureg, ureg_writemask(temp, writemask), tex, sampler, + tex_target, load_level_zero, use_txf); + + if (stype != dtype) { + if (stype == TGSI_RETURN_TYPE_SINT) { + assert(dtype == TGSI_RETURN_TYPE_UINT); + + ureg_IMAX(ureg, temp, ureg_src(temp), ureg_imm1i(ureg, 0)); + } else { + assert(stype == TGSI_RETURN_TYPE_UINT); + assert(dtype == TGSI_RETURN_TYPE_SINT); + + ureg_UMIN(ureg, temp, ureg_src(temp), ureg_imm1u(ureg, (1u << 31) - 1)); + } + } + + ureg_MOV(ureg, out, ureg_src(temp)); + ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); @@ -188,16 +358,23 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, /** * Make a simple fragment shader that sets the output color to a color * taken from a texture. - * \param tex_target one of PIPE_TEXTURE_x + * \param tex_target one of TGSI_TEXTURE_x */ void * -util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, - unsigned interp_mode) +util_make_fragment_tex_shader(struct pipe_context *pipe, + enum tgsi_texture_type tex_target, + enum tgsi_interpolate_mode interp_mode, + enum tgsi_return_type stype, + enum tgsi_return_type dtype, + bool load_level_zero, + bool use_txf) { return util_make_fragment_tex_shader_writemask( pipe, tex_target, interp_mode, - TGSI_WRITEMASK_XYZW ); + TGSI_WRITEMASK_XYZW, + stype, dtype, load_level_zero, + use_txf); } @@ -207,8 +384,10 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, */ void * util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode) + enum tgsi_texture_type tex_target, + enum tgsi_interpolate_mode interp_mode, + bool load_level_zero, + bool use_txf) { struct ureg_program *ureg; struct ureg_src sampler; @@ -216,12 +395,18 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, struct ureg_dst out, depth; struct ureg_src imm; - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) + ureg = ureg_create( PIPE_SHADER_FRAGMENT ); + if (!ureg) return NULL; sampler = ureg_DECL_sampler( ureg, 0 ); + ureg_DECL_sampler_view(ureg, 0, tex_target, + TGSI_RETURN_TYPE_FLOAT, + TGSI_RETURN_TYPE_FLOAT, + TGSI_RETURN_TYPE_FLOAT, + TGSI_RETURN_TYPE_FLOAT); + tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, interp_mode ); @@ -238,9 +423,8 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, ureg_MOV( ureg, out, imm ); - ureg_TEX( ureg, - ureg_writemask(depth, TGSI_WRITEMASK_Z), - tex_target, tex, sampler ); + ureg_load_tex(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), tex, sampler, + tex_target, load_level_zero, use_txf); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); @@ -253,8 +437,10 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, */ void * util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode) + enum tgsi_texture_type tex_target, + enum tgsi_interpolate_mode interp_mode, + bool load_level_zero, + bool use_txf) { struct ureg_program *ureg; struct ureg_src depth_sampler, stencil_sampler; @@ -262,12 +448,22 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, struct ureg_dst out, depth, stencil; struct ureg_src imm; - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) + ureg = ureg_create( PIPE_SHADER_FRAGMENT ); + if (!ureg) return NULL; depth_sampler = ureg_DECL_sampler( ureg, 0 ); + ureg_DECL_sampler_view(ureg, 0, tex_target, + TGSI_RETURN_TYPE_FLOAT, + TGSI_RETURN_TYPE_FLOAT, + TGSI_RETURN_TYPE_FLOAT, + TGSI_RETURN_TYPE_FLOAT); stencil_sampler = ureg_DECL_sampler( ureg, 1 ); + ureg_DECL_sampler_view(ureg, 0, tex_target, + TGSI_RETURN_TYPE_UINT, + TGSI_RETURN_TYPE_UINT, + TGSI_RETURN_TYPE_UINT, + TGSI_RETURN_TYPE_UINT); tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, @@ -289,12 +485,10 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, ureg_MOV( ureg, out, imm ); - ureg_TEX( ureg, - ureg_writemask(depth, TGSI_WRITEMASK_Z), - tex_target, tex, depth_sampler ); - ureg_TEX( ureg, - ureg_writemask(stencil, TGSI_WRITEMASK_Y), - tex_target, tex, stencil_sampler ); + ureg_load_tex(ureg, ureg_writemask(depth, TGSI_WRITEMASK_Z), tex, + depth_sampler, tex_target, load_level_zero, use_txf); + ureg_load_tex(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), tex, + stencil_sampler, tex_target, load_level_zero, use_txf); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); @@ -307,8 +501,10 @@ util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, */ void * util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, - unsigned tex_target, - unsigned interp_mode) + enum tgsi_texture_type tex_target, + enum tgsi_interpolate_mode interp_mode, + bool load_level_zero, + bool use_txf) { struct ureg_program *ureg; struct ureg_src stencil_sampler; @@ -316,12 +512,18 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, struct ureg_dst out, stencil; struct ureg_src imm; - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) + ureg = ureg_create( PIPE_SHADER_FRAGMENT ); + if (!ureg) return NULL; stencil_sampler = ureg_DECL_sampler( ureg, 0 ); + ureg_DECL_sampler_view(ureg, 0, tex_target, + TGSI_RETURN_TYPE_UINT, + TGSI_RETURN_TYPE_UINT, + TGSI_RETURN_TYPE_UINT, + TGSI_RETURN_TYPE_UINT); + tex = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_GENERIC, 0, interp_mode ); @@ -338,9 +540,8 @@ util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, ureg_MOV( ureg, out, imm ); - ureg_TEX( ureg, - ureg_writemask(stencil, TGSI_WRITEMASK_Y), - tex_target, tex, stencil_sampler ); + ureg_load_tex(ureg, ureg_writemask(stencil, TGSI_WRITEMASK_Y), tex, + stencil_sampler, tex_target, load_level_zero, use_txf); ureg_END( ureg ); return ureg_create_shader_and_destroy( ureg, pipe ); @@ -368,17 +569,18 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe, char text[sizeof(shader_templ)+100]; struct tgsi_token tokens[1000]; - struct pipe_shader_state state = {tokens}; + struct pipe_shader_state state; sprintf(text, shader_templ, write_all_cbufs ? "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" : "", tgsi_semantic_names[input_semantic], tgsi_interpolate_names[input_interpolate]); - if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { assert(0); return NULL; } + pipe_shader_state_from_tgsi(&state, tokens); #if 0 tgsi_dump(state.tokens, 0); #endif @@ -390,8 +592,8 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe, void * util_make_empty_fragment_shader(struct pipe_context *pipe) { - struct ureg_program *ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); - if (ureg == NULL) + struct ureg_program *ureg = ureg_create(PIPE_SHADER_FRAGMENT); + if (!ureg) return NULL; ureg_END(ureg); @@ -414,8 +616,8 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); - if (ureg == NULL) + ureg = ureg_create( PIPE_SHADER_FRAGMENT ); + if (!ureg) return NULL; src = ureg_DECL_fs_input( ureg, input_semantic, 0, @@ -435,36 +637,45 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, static void * util_make_fs_blit_msaa_gen(struct pipe_context *pipe, - unsigned tgsi_tex, + enum tgsi_texture_type tgsi_tex, + const char *samp_type, const char *output_semantic, - const char *output_mask) + const char *output_mask, + const char *conversion_decl, + const char *conversion) { static const char shader_templ[] = "FRAG\n" "DCL IN[0], GENERIC[0], LINEAR\n" "DCL SAMP[0]\n" + "DCL SVIEW[0], %s, %s\n" "DCL OUT[0], %s\n" "DCL TEMP[0]\n" + "%s" "F2U TEMP[0], IN[0]\n" - "TXF OUT[0]%s, TEMP[0], SAMP[0], %s\n" + "TXF TEMP[0], TEMP[0], SAMP[0], %s\n" + "%s" + "MOV OUT[0]%s, TEMP[0]\n" "END\n"; const char *type = tgsi_texture_names[tgsi_tex]; char text[sizeof(shader_templ)+100]; struct tgsi_token tokens[1000]; - struct pipe_shader_state state = {tokens}; + struct pipe_shader_state state; assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); - sprintf(text, shader_templ, output_semantic, output_mask, type); + util_snprintf(text, sizeof(text), shader_templ, type, samp_type, + output_semantic, conversion_decl, type, conversion, output_mask); - if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { puts(text); assert(0); return NULL; } + pipe_shader_state_from_tgsi(&state, tokens); #if 0 tgsi_dump(state.tokens, 0); #endif @@ -480,10 +691,36 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe, */ void * util_make_fs_blit_msaa_color(struct pipe_context *pipe, - unsigned tgsi_tex) + enum tgsi_texture_type tgsi_tex, + enum tgsi_return_type stype, + enum tgsi_return_type dtype) { - return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, - "COLOR[0]", ""); + const char *samp_type; + const char *conversion_decl = ""; + const char *conversion = ""; + + if (stype == TGSI_RETURN_TYPE_UINT) { + samp_type = "UINT"; + + if (dtype == TGSI_RETURN_TYPE_SINT) { + conversion_decl = "IMM[0] UINT32 {2147483647, 0, 0, 0}\n"; + conversion = "UMIN TEMP[0], TEMP[0], IMM[0].xxxx\n"; + } + } else if (stype == TGSI_RETURN_TYPE_SINT) { + samp_type = "SINT"; + + if (dtype == TGSI_RETURN_TYPE_UINT) { + conversion_decl = "IMM[0] INT32 {0, 0, 0, 0}\n"; + conversion = "IMAX TEMP[0], TEMP[0], IMM[0].xxxx\n"; + } + } else { + assert(dtype == TGSI_RETURN_TYPE_FLOAT); + samp_type = "FLOAT"; + } + + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, samp_type, + "COLOR[0]", "", conversion_decl, + conversion); } @@ -494,10 +731,10 @@ util_make_fs_blit_msaa_color(struct pipe_context *pipe, */ void * util_make_fs_blit_msaa_depth(struct pipe_context *pipe, - unsigned tgsi_tex) + enum tgsi_texture_type tgsi_tex) { - return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, - "POSITION", ".z"); + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "FLOAT", + "POSITION", ".z", "", ""); } @@ -508,10 +745,10 @@ util_make_fs_blit_msaa_depth(struct pipe_context *pipe, */ void * util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, - unsigned tgsi_tex) + enum tgsi_texture_type tgsi_tex) { - return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, - "STENCIL", ".y"); + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "UINT", + "STENCIL", ".y", "", ""); } @@ -524,12 +761,13 @@ util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, */ void * util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, - unsigned tgsi_tex) + enum tgsi_texture_type tgsi_tex) { static const char shader_templ[] = "FRAG\n" "DCL IN[0], GENERIC[0], LINEAR\n" "DCL SAMP[0..1]\n" + "DCL SVIEW[0..1], %s, FLOAT\n" "DCL OUT[0], POSITION\n" "DCL OUT[1], STENCIL\n" "DCL TEMP[0]\n" @@ -542,17 +780,18 @@ util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, const char *type = tgsi_texture_names[tgsi_tex]; char text[sizeof(shader_templ)+100]; struct tgsi_token tokens[1000]; - struct pipe_shader_state state = {tokens}; + struct pipe_shader_state state; assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); - sprintf(text, shader_templ, type, type); + sprintf(text, shader_templ, type, type, type); - if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { assert(0); return NULL; } + pipe_shader_state_from_tgsi(&state, tokens); #if 0 tgsi_dump(state.tokens, 0); #endif @@ -563,20 +802,21 @@ util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, void * util_make_fs_msaa_resolve(struct pipe_context *pipe, - unsigned tgsi_tex, unsigned nr_samples, - boolean is_uint, boolean is_sint) + enum tgsi_texture_type tgsi_tex, unsigned nr_samples, + enum tgsi_return_type stype) { struct ureg_program *ureg; struct ureg_src sampler, coord; struct ureg_dst out, tmp_sum, tmp_coord, tmp; - int i; + unsigned i; - ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + ureg = ureg_create(PIPE_SHADER_FRAGMENT); if (!ureg) return NULL; /* Declarations. */ sampler = ureg_DECL_sampler(ureg, 0); + ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype); coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); @@ -594,9 +834,9 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe, ureg_imm1u(ureg, i)); ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord), sampler); - if (is_uint) + if (stype == TGSI_RETURN_TYPE_UINT) ureg_U2F(ureg, tmp, ureg_src(tmp)); - else if (is_sint) + else if (stype == TGSI_RETURN_TYPE_SINT) ureg_I2F(ureg, tmp, ureg_src(tmp)); /* Add it to the sum.*/ @@ -607,9 +847,9 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe, ureg_MUL(ureg, tmp_sum, ureg_src(tmp_sum), ureg_imm1f(ureg, 1.0 / nr_samples)); - if (is_uint) + if (stype == TGSI_RETURN_TYPE_UINT) ureg_F2U(ureg, out, ureg_src(tmp_sum)); - else if (is_sint) + else if (stype == TGSI_RETURN_TYPE_SINT) ureg_F2I(ureg, out, ureg_src(tmp_sum)); else ureg_MOV(ureg, out, ureg_src(tmp_sum)); @@ -622,21 +862,23 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe, void * util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, - unsigned tgsi_tex, unsigned nr_samples, - boolean is_uint, boolean is_sint) + enum tgsi_texture_type tgsi_tex, + unsigned nr_samples, + enum tgsi_return_type stype) { struct ureg_program *ureg; struct ureg_src sampler, coord; struct ureg_dst out, tmp, top, bottom; struct ureg_dst tmp_coord[4], tmp_sum[4]; - int i, c; + unsigned i, c; - ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + ureg = ureg_create(PIPE_SHADER_FRAGMENT); if (!ureg) return NULL; /* Declarations. */ sampler = ureg_DECL_sampler(ureg, 0); + ureg_DECL_sampler_view(ureg, 0, tgsi_tex, stype, stype, stype, stype); coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); @@ -668,9 +910,9 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, ureg_imm1u(ureg, i)); ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord[c]), sampler); - if (is_uint) + if (stype == TGSI_RETURN_TYPE_UINT) ureg_U2F(ureg, tmp, ureg_src(tmp)); - else if (is_sint) + else if (stype == TGSI_RETURN_TYPE_SINT) ureg_I2F(ureg, tmp, ureg_src(tmp)); /* Add it to the sum.*/ @@ -702,9 +944,9 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, ureg_src(top)); /* Convert to the texture format and return. */ - if (is_uint) + if (stype == TGSI_RETURN_TYPE_UINT) ureg_F2U(ureg, out, ureg_src(tmp)); - else if (is_sint) + else if (stype == TGSI_RETURN_TYPE_SINT) ureg_F2I(ureg, out, ureg_src(tmp)); else ureg_MOV(ureg, out, ureg_src(tmp)); @@ -713,3 +955,54 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, return ureg_create_shader_and_destroy(ureg, pipe); } + +void * +util_make_geometry_passthrough_shader(struct pipe_context *pipe, + uint num_attribs, + const ubyte *semantic_names, + const ubyte *semantic_indexes) +{ + static const unsigned zero[4] = {0, 0, 0, 0}; + + struct ureg_program *ureg; + struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS]; + struct ureg_src src[PIPE_MAX_SHADER_INPUTS]; + struct ureg_src imm; + + unsigned i; + + ureg = ureg_create(PIPE_SHADER_GEOMETRY); + if (!ureg) + return NULL; + + ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_POINTS); + ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_POINTS); + ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 1); + ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 1); + imm = ureg_DECL_immediate_uint(ureg, zero, 4); + + /** + * Loop over all the attribs and declare the corresponding + * declarations in the geometry shader + */ + for (i = 0; i < num_attribs; i++) { + src[i] = ureg_DECL_input(ureg, semantic_names[i], + semantic_indexes[i], 0, 1); + src[i] = ureg_src_dimension(src[i], 0); + dst[i] = ureg_DECL_output(ureg, semantic_names[i], semantic_indexes[i]); + } + + /* MOV dst[i] src[i] */ + for (i = 0; i < num_attribs; i++) { + ureg_MOV(ureg, dst[i], src[i]); + } + + /* EMIT IMM[0] */ + ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0); + + /* END */ + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} +