st/mesa: Drop the TGSI paths for PBOs and use nir-to-tgsi if needed.

Now that we have a NIR translator in gallium, we can drop this duplicated
code in the API implementation.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6477>
This commit is contained in:
Eric Anholt 2020-08-26 12:42:36 -07:00 committed by Marge Bot
parent da4c4c0e67
commit 57effa342b
4 changed files with 39 additions and 239 deletions

View file

@ -89,7 +89,7 @@
#include "util/u_memory.h"
#include "cso_cache/cso_context.h"
#include "compiler/glsl/glsl_parser_extras.h"
#include "nir/nir_to_tgsi.h"
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)
@ -1147,3 +1147,18 @@ st_destroy_context(struct st_context *st)
_mesa_make_current(save_ctx, save_drawbuffer, save_readbuffer);
}
}
const struct nir_shader_compiler_options *
st_get_nir_compiler_options(struct st_context *st, gl_shader_stage stage)
{
const struct nir_shader_compiler_options *options =
st->ctx->Const.ShaderCompilerOptions[stage].NirOptions;
if (options) {
return options;
} else {
return nir_to_tgsi_get_compiler_options(st->pipe->screen,
PIPE_SHADER_IR_NIR,
pipe_shader_type_from_mesa(stage));
}
}

View file

@ -418,6 +418,8 @@ st_save_zombie_shader(struct st_context *st,
void
st_context_free_zombie_objects(struct st_context *st);
const struct nir_shader_compiler_options *
st_get_nir_compiler_options(struct st_context *st, gl_shader_stage stage);
/**

View file

@ -25,6 +25,7 @@
#include "compiler/nir/nir_builder.h"
#include "compiler/glsl/gl_nir.h"
#include "nir/nir_to_tgsi.h"
struct pipe_shader_state *
st_nir_finish_builtin_shader(struct st_context *st,
@ -33,6 +34,7 @@ st_nir_finish_builtin_shader(struct st_context *st,
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
enum pipe_shader_type sh = pipe_shader_type_from_mesa(nir->info.stage);
nir->info.name = ralloc_strdup(nir, name);
nir->info.separate_shader = true;
@ -73,6 +75,13 @@ st_nir_finish_builtin_shader(struct st_context *st,
.ir.nir = nir,
};
if (PIPE_SHADER_IR_NIR !=
screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_PREFERRED_IR)) {
state.type = PIPE_SHADER_IR_TGSI;
state.tokens = nir_to_tgsi(nir, screen);
ralloc_free(nir);
}
switch (nir->info.stage) {
case MESA_SHADER_VERTEX:
return pipe->create_vs_state(pipe, &state);
@ -106,7 +115,7 @@ st_nir_make_passthrough_shader(struct st_context *st,
struct nir_builder b;
const struct glsl_type *vec4 = glsl_vec4_type();
const nir_shader_compiler_options *options =
st->ctx->Const.ShaderCompilerOptions[stage].NirOptions;
st_get_nir_compiler_options(st, stage);
nir_builder_init_simple_shader(&b, NULL, stage, options);

View file

@ -292,12 +292,6 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr,
void *
st_pbo_create_vs(struct st_context *st)
{
struct pipe_screen *pscreen = st->pipe->screen;
bool use_nir = PIPE_SHADER_IR_NIR ==
pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_PREFERRED_IR);
if (use_nir) {
unsigned inputs[] = { VERT_ATTRIB_POS, SYSTEM_VALUE_INSTANCE_ID, };
unsigned outputs[] = { VARYING_SLOT_POS, VARYING_SLOT_LAYER };
@ -307,47 +301,6 @@ st_pbo_create_vs(struct st_context *st)
inputs, outputs, NULL, (1 << 1));
}
struct ureg_program *ureg;
struct ureg_src in_pos;
struct ureg_src in_instanceid;
struct ureg_dst out_pos;
struct ureg_dst out_layer;
ureg = ureg_create(PIPE_SHADER_VERTEX);
if (!ureg)
return NULL;
in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION);
out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
if (st->pbo.layers) {
in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);
if (!st->pbo.use_gs)
out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);
}
/* out_pos = in_pos */
ureg_MOV(ureg, out_pos, in_pos);
if (st->pbo.layers) {
if (st->pbo.use_gs) {
/* out_pos.z = i2f(gl_InstanceID) */
ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z),
ureg_scalar(in_instanceid, TGSI_SWIZZLE_X));
} else {
/* out_layer = gl_InstanceID */
ureg_MOV(ureg, ureg_writemask(out_layer, TGSI_WRITEMASK_X),
ureg_scalar(in_instanceid, TGSI_SWIZZLE_X));
}
}
ureg_END(ureg);
return ureg_create_shader_and_destroy(ureg, st->pipe);
}
void *
st_pbo_create_gs(struct st_context *st)
{
@ -392,23 +345,6 @@ st_pbo_create_gs(struct st_context *st)
return ureg_create_shader_and_destroy(ureg, st->pipe);
}
static void
build_conversion(struct ureg_program *ureg, const struct ureg_dst *temp,
enum st_pbo_conversion conversion)
{
switch (conversion) {
case ST_PBO_CONVERT_SINT_TO_UINT:
ureg_IMAX(ureg, *temp, ureg_src(*temp), ureg_imm1i(ureg, 0));
break;
case ST_PBO_CONVERT_UINT_TO_SINT:
ureg_UMIN(ureg, *temp, ureg_src(*temp), ureg_imm1u(ureg, (1u << 31) - 1));
break;
default:
/* no-op */
break;
}
}
static const struct glsl_type *
sampler_type_for_target(enum pipe_texture_target target)
{
@ -428,16 +364,16 @@ sampler_type_for_target(enum pipe_texture_target target)
return glsl_sampler_type(dim[target], false, is_array, GLSL_TYPE_FLOAT);
}
static void *
create_fs_nir(struct st_context *st,
bool download,
create_fs(struct st_context *st, bool download,
enum pipe_texture_target target,
enum st_pbo_conversion conversion)
{
struct pipe_screen *screen = st->pipe->screen;
struct nir_builder b;
const nir_shader_compiler_options *options =
st->ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions;
st_get_nir_compiler_options(st, MESA_SHADER_FRAGMENT);
bool pos_is_sysval =
screen->get_param(screen, PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL);
@ -575,168 +511,6 @@ create_fs_nir(struct st_context *st,
"st/pbo upload FS");
}
static void *
create_fs_tgsi(struct st_context *st, bool download,
enum pipe_texture_target target,
enum st_pbo_conversion conversion)
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct ureg_program *ureg;
bool have_layer;
struct ureg_dst out;
struct ureg_src sampler;
struct ureg_src pos;
struct ureg_src layer;
struct ureg_src const0;
struct ureg_src const1;
struct ureg_dst temp0;
have_layer =
st->pbo.layers &&
(!download || target == PIPE_TEXTURE_1D_ARRAY
|| target == PIPE_TEXTURE_2D_ARRAY
|| target == PIPE_TEXTURE_3D
|| target == PIPE_TEXTURE_CUBE
|| target == PIPE_TEXTURE_CUBE_ARRAY);
ureg = ureg_create(PIPE_SHADER_FRAGMENT);
if (!ureg)
return NULL;
if (!download) {
out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
} else {
struct ureg_src image;
/* writeonly images do not require an explicitly given format. */
image = ureg_DECL_image(ureg, 0, TGSI_TEXTURE_BUFFER, PIPE_FORMAT_NONE,
true, false);
out = ureg_dst(image);
}
sampler = ureg_DECL_sampler(ureg, 0);
if (screen->get_param(screen, PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL)) {
pos = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_POSITION, 0);
} else {
pos = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
TGSI_INTERPOLATE_LINEAR);
}
if (have_layer) {
layer = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_LAYER, 0,
TGSI_INTERPOLATE_CONSTANT);
}
const0 = ureg_DECL_constant(ureg, 0);
const1 = ureg_DECL_constant(ureg, 1);
temp0 = ureg_DECL_temporary(ureg);
/* Note: const0 = [ -xoffset + skip_pixels, -yoffset, stride, image_height ] */
/* temp0.xy = f2i(temp0.xy) */
ureg_F2I(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY),
ureg_swizzle(pos,
TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y,
TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y));
/* temp0.xy = temp0.xy + const0.xy */
ureg_UADD(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY),
ureg_swizzle(ureg_src(temp0),
TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y,
TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y),
ureg_swizzle(const0,
TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y,
TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y));
/* temp0.x = const0.z * temp0.y + temp0.x */
ureg_UMAD(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_X),
ureg_scalar(const0, TGSI_SWIZZLE_Z),
ureg_scalar(ureg_src(temp0), TGSI_SWIZZLE_Y),
ureg_scalar(ureg_src(temp0), TGSI_SWIZZLE_X));
if (have_layer) {
/* temp0.x = const0.w * layer + temp0.x */
ureg_UMAD(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_X),
ureg_scalar(const0, TGSI_SWIZZLE_W),
ureg_scalar(layer, TGSI_SWIZZLE_X),
ureg_scalar(ureg_src(temp0), TGSI_SWIZZLE_X));
}
/* temp0.w = 0 */
ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_W), ureg_imm1u(ureg, 0));
if (download) {
struct ureg_dst temp1;
struct ureg_src op[2];
temp1 = ureg_DECL_temporary(ureg);
/* temp1.xy = pos.xy */
ureg_F2I(ureg, ureg_writemask(temp1, TGSI_WRITEMASK_XY), pos);
/* temp1.zw = 0 */
ureg_MOV(ureg, ureg_writemask(temp1, TGSI_WRITEMASK_ZW), ureg_imm1u(ureg, 0));
if (have_layer) {
struct ureg_dst temp1_layer =
ureg_writemask(temp1, target == PIPE_TEXTURE_1D_ARRAY ? TGSI_WRITEMASK_Y
: TGSI_WRITEMASK_Z);
/* temp1.y/z = layer */
ureg_MOV(ureg, temp1_layer, ureg_scalar(layer, TGSI_SWIZZLE_X));
if (target == PIPE_TEXTURE_3D) {
/* temp1.z += layer_offset */
ureg_UADD(ureg, temp1_layer,
ureg_scalar(ureg_src(temp1), TGSI_SWIZZLE_Z),
ureg_scalar(const1, TGSI_SWIZZLE_X));
}
}
/* temp1 = txf(sampler, temp1) */
ureg_TXF(ureg, temp1, util_pipe_tex_to_tgsi_tex(target, 1),
ureg_src(temp1), sampler);
build_conversion(ureg, &temp1, conversion);
/* store(out, temp0, temp1) */
op[0] = ureg_src(temp0);
op[1] = ureg_src(temp1);
ureg_memory_insn(ureg, TGSI_OPCODE_STORE, &out, 1, op, 2, 0,
TGSI_TEXTURE_BUFFER, PIPE_FORMAT_NONE);
ureg_release_temporary(ureg, temp1);
} else {
/* out = txf(sampler, temp0.x) */
ureg_TXF(ureg, temp0, TGSI_TEXTURE_BUFFER, ureg_src(temp0), sampler);
build_conversion(ureg, &temp0, conversion);
ureg_MOV(ureg, out, ureg_src(temp0));
}
ureg_release_temporary(ureg, temp0);
ureg_END(ureg);
return ureg_create_shader_and_destroy(ureg, pipe);
}
static void *
create_fs(struct st_context *st, bool download,
enum pipe_texture_target target,
enum st_pbo_conversion conversion)
{
struct pipe_screen *pscreen = st->pipe->screen;
bool use_nir = PIPE_SHADER_IR_NIR ==
pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
PIPE_SHADER_CAP_PREFERRED_IR);
if (use_nir)
return create_fs_nir(st, download, target, conversion);
return create_fs_tgsi(st, download, target, conversion);
}
static enum st_pbo_conversion
get_pbo_conversion(enum pipe_format src_format, enum pipe_format dst_format)
{