st/mesa: Add NIR versions of the drawpixels Z/stencil fragment shaders.
Reviewed-by: Marek Olšák <marek.olsak@amd.com> Tested-by: Rob Clark <robdclark@gmail.com> Tested-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
@@ -108,34 +108,97 @@
|
||||
*/
|
||||
#define USE_DRAWPIXELS_CACHE 1
|
||||
|
||||
static nir_ssa_def *
|
||||
sample_via_nir(nir_builder *b, nir_variable *texcoord,
|
||||
const char *name, int sampler)
|
||||
{
|
||||
const struct glsl_type *sampler2D =
|
||||
glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT);
|
||||
|
||||
nir_variable *var =
|
||||
nir_variable_create(b->shader, nir_var_uniform, sampler2D, name);
|
||||
var->data.binding = sampler;
|
||||
|
||||
nir_tex_instr *tex = nir_tex_instr_create(b->shader, 1);
|
||||
tex->op = nir_texop_tex;
|
||||
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
|
||||
tex->coord_components = 2;
|
||||
tex->sampler_index = sampler;
|
||||
tex->texture_index = sampler;
|
||||
tex->dest_type = nir_type_float;
|
||||
tex->src[0].src_type = nir_tex_src_coord;
|
||||
tex->src[0].src =
|
||||
nir_src_for_ssa(nir_channels(b, nir_load_var(b, texcoord),
|
||||
(1 << tex->coord_components) - 1));
|
||||
|
||||
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
|
||||
nir_builder_instr_insert(b, &tex->instr);
|
||||
return nir_channel(b, &tex->dest.ssa, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fragment program that does a TEX() instruction to get a Z and/or
|
||||
* stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
|
||||
* Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
|
||||
* Pass fragment color through as-is.
|
||||
*
|
||||
* \return CSO of the fragment shader.
|
||||
*/
|
||||
static void *
|
||||
get_drawpix_z_stencil_program(struct st_context *st,
|
||||
GLboolean write_depth,
|
||||
GLboolean write_stencil)
|
||||
make_drawpix_z_stencil_program_nir(struct st_context *st,
|
||||
bool write_depth,
|
||||
bool write_stencil)
|
||||
{
|
||||
struct nir_builder b;
|
||||
const nir_shader_compiler_options *options =
|
||||
st->ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions;
|
||||
|
||||
nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, options);
|
||||
|
||||
nir_variable *texcoord =
|
||||
nir_variable_create(b.shader, nir_var_shader_in, glsl_vec_type(2),
|
||||
"texcoord");
|
||||
texcoord->data.location = VARYING_SLOT_TEX0;
|
||||
|
||||
if (write_depth) {
|
||||
nir_variable *out =
|
||||
nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(),
|
||||
"gl_FragDepth");
|
||||
out->data.location = FRAG_RESULT_DEPTH;
|
||||
nir_ssa_def *depth = sample_via_nir(&b, texcoord, "depth", 0);
|
||||
nir_store_var(&b, out, depth, 0x1);
|
||||
|
||||
/* Also copy color */
|
||||
nir_variable *color_in =
|
||||
nir_variable_create(b.shader, nir_var_shader_in, glsl_vec_type(4),
|
||||
"v_color");
|
||||
color_in->data.location = VARYING_SLOT_COL0;
|
||||
|
||||
nir_variable *color_out =
|
||||
nir_variable_create(b.shader, nir_var_shader_out, glsl_vec_type(4),
|
||||
"gl_FragColor");
|
||||
color_out->data.location = FRAG_RESULT_COLOR;
|
||||
nir_copy_var(&b, color_out, color_in);
|
||||
}
|
||||
|
||||
if (write_stencil) {
|
||||
nir_variable *out =
|
||||
nir_variable_create(b.shader, nir_var_shader_out, glsl_uint_type(),
|
||||
"gl_FragStencilRefARB");
|
||||
out->data.location = FRAG_RESULT_STENCIL;
|
||||
nir_ssa_def *stencil = sample_via_nir(&b, texcoord, "stencil", 1);
|
||||
nir_store_var(&b, out, stencil, 0x1);
|
||||
}
|
||||
|
||||
char name[14];
|
||||
snprintf(name, 14, "drawpixels %s%s",
|
||||
write_depth ? "Z" : "", write_stencil ? "S" : "");
|
||||
|
||||
return st_nir_finish_builtin_shader(st, b.shader, name);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
make_drawpix_z_stencil_program_tgsi(struct st_context *st,
|
||||
bool write_depth,
|
||||
bool write_stencil)
|
||||
{
|
||||
struct ureg_program *ureg;
|
||||
struct ureg_src depth_sampler, stencil_sampler;
|
||||
struct ureg_src texcoord, color;
|
||||
struct ureg_dst out_color, out_depth, out_stencil;
|
||||
const GLuint shaderIndex = write_depth * 2 + write_stencil;
|
||||
void *cso;
|
||||
|
||||
assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
|
||||
|
||||
if (st->drawpix.zs_shaders[shaderIndex]) {
|
||||
/* already have the proper shader */
|
||||
return st->drawpix.zs_shaders[shaderIndex];
|
||||
}
|
||||
|
||||
ureg = ureg_create(PIPE_SHADER_FRAGMENT);
|
||||
if (ureg == NULL)
|
||||
@@ -184,7 +247,42 @@ get_drawpix_z_stencil_program(struct st_context *st,
|
||||
TGSI_TEXTURE_2D, texcoord, stencil_sampler);
|
||||
|
||||
ureg_END(ureg);
|
||||
cso = ureg_create_shader_and_destroy(ureg, st->pipe);
|
||||
return ureg_create_shader_and_destroy(ureg, st->pipe);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create fragment program that does a TEX() instruction to get a Z and/or
|
||||
* stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
|
||||
* Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
|
||||
* Pass fragment color through as-is.
|
||||
*
|
||||
* \return CSO of the fragment shader.
|
||||
*/
|
||||
static void *
|
||||
get_drawpix_z_stencil_program(struct st_context *st,
|
||||
bool write_depth,
|
||||
bool write_stencil)
|
||||
{
|
||||
struct pipe_screen *pscreen = st->pipe->screen;
|
||||
const GLuint shaderIndex = write_depth * 2 + write_stencil;
|
||||
void *cso;
|
||||
|
||||
assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
|
||||
|
||||
if (st->drawpix.zs_shaders[shaderIndex]) {
|
||||
/* already have the proper shader */
|
||||
return st->drawpix.zs_shaders[shaderIndex];
|
||||
}
|
||||
|
||||
enum pipe_shader_ir preferred_ir =
|
||||
pscreen->get_shader_param(pscreen, PIPE_SHADER_FRAGMENT,
|
||||
PIPE_SHADER_CAP_PREFERRED_IR);
|
||||
|
||||
if (preferred_ir == PIPE_SHADER_IR_NIR)
|
||||
cso = make_drawpix_z_stencil_program_nir(st, write_depth, write_stencil);
|
||||
else
|
||||
cso = make_drawpix_z_stencil_program_tgsi(st, write_depth, write_stencil);
|
||||
|
||||
/* save the new shader */
|
||||
st->drawpix.zs_shaders[shaderIndex] = cso;
|
||||
|
Reference in New Issue
Block a user