radeonsi: implement polygon stippling
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
6895dfb184
commit
6c5af1dc4e
|
@ -53,6 +53,8 @@ static void si_destroy_context(struct pipe_context *context)
|
|||
si_pm4_delete_state(sctx, gs_onoff, sctx->gs_on);
|
||||
si_pm4_delete_state(sctx, gs_onoff, sctx->gs_off);
|
||||
|
||||
if (sctx->pstipple_sampler_state)
|
||||
sctx->b.b.delete_sampler_state(&sctx->b.b, sctx->pstipple_sampler_state);
|
||||
if (sctx->dummy_pixel_shader) {
|
||||
sctx->b.b.delete_fs_state(&sctx->b.b, sctx->dummy_pixel_shader);
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ struct si_context {
|
|||
void *custom_blend_resolve;
|
||||
void *custom_blend_decompress;
|
||||
void *custom_blend_fastclear;
|
||||
void *pstipple_sampler_state;
|
||||
struct si_screen *screen;
|
||||
struct si_pm4_state *init_config;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "radeon/radeon_elf_util.h"
|
||||
#include "radeon/radeon_llvm_emit.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_pstipple.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_util.h"
|
||||
#include "tgsi/tgsi_dump.h"
|
||||
|
@ -2742,16 +2743,26 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen,
|
|||
int si_shader_create(struct si_screen *sscreen, struct si_shader *shader)
|
||||
{
|
||||
struct si_shader_selector *sel = shader->selector;
|
||||
struct tgsi_token *tokens = sel->tokens;
|
||||
struct si_shader_context si_shader_ctx;
|
||||
struct lp_build_tgsi_context * bld_base;
|
||||
struct tgsi_shader_info stipple_shader_info;
|
||||
LLVMModuleRef mod;
|
||||
int r = 0;
|
||||
bool poly_stipple = sel->type == PIPE_SHADER_FRAGMENT &&
|
||||
shader->key.ps.poly_stipple;
|
||||
bool dump = r600_can_dump_shader(&sscreen->b, sel->tokens);
|
||||
|
||||
if (poly_stipple) {
|
||||
tokens = util_pstipple_create_fragment_shader(tokens, NULL,
|
||||
SI_POLY_STIPPLE_SAMPLER);
|
||||
tgsi_scan_shader(tokens, &stipple_shader_info);
|
||||
}
|
||||
|
||||
/* Dump TGSI code before doing TGSI->LLVM conversion in case the
|
||||
* conversion fails. */
|
||||
if (dump) {
|
||||
tgsi_dump(sel->tokens, 0);
|
||||
tgsi_dump(tokens, 0);
|
||||
si_dump_streamout(&sel->so);
|
||||
}
|
||||
|
||||
|
@ -2768,7 +2779,7 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader)
|
|||
shader->db_shader_control |= S_02880C_KILL_ENABLE(1);
|
||||
|
||||
shader->uses_instanceid = sel->info.uses_instanceid;
|
||||
bld_base->info = &sel->info;
|
||||
bld_base->info = poly_stipple ? &stipple_shader_info : &sel->info;
|
||||
bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant;
|
||||
|
||||
bld_base->op_actions[TGSI_OPCODE_TEX] = tex_action;
|
||||
|
@ -2799,7 +2810,7 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader)
|
|||
|
||||
si_shader_ctx.radeon_bld.load_system_value = declare_system_value;
|
||||
si_shader_ctx.shader = shader;
|
||||
si_shader_ctx.type = tgsi_get_processor_type(sel->tokens);
|
||||
si_shader_ctx.type = tgsi_get_processor_type(tokens);
|
||||
si_shader_ctx.screen = sscreen;
|
||||
|
||||
switch (si_shader_ctx.type) {
|
||||
|
@ -2848,7 +2859,7 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader)
|
|||
bld_base->uint_bld.elem_type, "");
|
||||
}
|
||||
|
||||
if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) {
|
||||
if (!lp_build_tgsi_llvm(bld_base, tokens)) {
|
||||
fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n");
|
||||
goto out;
|
||||
}
|
||||
|
@ -2880,7 +2891,8 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader)
|
|||
out:
|
||||
for (int i = 0; i < SI_NUM_CONST_BUFFERS; i++)
|
||||
FREE(si_shader_ctx.constants[i]);
|
||||
|
||||
if (poly_stipple)
|
||||
tgsi_free_tokens(tokens);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ union si_shader_key {
|
|||
unsigned color_two_side:1;
|
||||
unsigned alpha_func:3;
|
||||
unsigned alpha_to_one:1;
|
||||
unsigned poly_stipple:1;
|
||||
} ps;
|
||||
struct {
|
||||
unsigned instance_divisors[SI_NUM_VERTEX_BUFFERS];
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "util/u_format.h"
|
||||
#include "util/u_format_s3tc.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_pstipple.h"
|
||||
|
||||
static void si_init_atom(struct r600_atom *atom, struct r600_atom **list_elem,
|
||||
void (*emit)(struct si_context *ctx, struct r600_atom *state),
|
||||
|
@ -616,6 +617,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
|
|||
rs->multisample_enable = state->multisample;
|
||||
rs->clip_plane_enable = state->clip_plane_enable;
|
||||
rs->line_stipple_enable = state->line_stipple_enable;
|
||||
rs->poly_stipple_enable = state->poly_stipple_enable;
|
||||
|
||||
polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
|
||||
state->fill_back != PIPE_POLYGON_MODE_FILL);
|
||||
|
@ -2760,6 +2762,56 @@ static void si_set_index_buffer(struct pipe_context *ctx,
|
|||
static void si_set_polygon_stipple(struct pipe_context *ctx,
|
||||
const struct pipe_poly_stipple *state)
|
||||
{
|
||||
struct si_context *sctx = (struct si_context *)ctx;
|
||||
struct pipe_resource *tex;
|
||||
struct pipe_sampler_view *view;
|
||||
bool is_zero = true;
|
||||
bool is_one = true;
|
||||
int i;
|
||||
|
||||
/* The hardware obeys 0 and 1 swizzles in the descriptor even if
|
||||
* the resource is NULL/invalid. Take advantage of this fact and skip
|
||||
* texture allocation if the stipple pattern is constant.
|
||||
*
|
||||
* This is an optimization for the common case when stippling isn't
|
||||
* used but set_polygon_stipple is still called by st/mesa.
|
||||
*/
|
||||
for (i = 0; i < Elements(state->stipple); i++) {
|
||||
is_zero = is_zero && state->stipple[i] == 0;
|
||||
is_one = is_one && state->stipple[i] == 0xffffffff;
|
||||
}
|
||||
|
||||
if (is_zero || is_one) {
|
||||
struct pipe_sampler_view templ = {{0}};
|
||||
|
||||
templ.swizzle_r = PIPE_SWIZZLE_ZERO;
|
||||
templ.swizzle_g = PIPE_SWIZZLE_ZERO;
|
||||
templ.swizzle_b = PIPE_SWIZZLE_ZERO;
|
||||
/* The pattern should be inverted in the texture. */
|
||||
templ.swizzle_a = is_zero ? PIPE_SWIZZLE_ONE : PIPE_SWIZZLE_ZERO;
|
||||
|
||||
view = ctx->create_sampler_view(ctx, NULL, &templ);
|
||||
} else {
|
||||
/* Create a new texture. */
|
||||
tex = util_pstipple_create_stipple_texture(ctx, state->stipple);
|
||||
if (!tex)
|
||||
return;
|
||||
|
||||
view = util_pstipple_create_sampler_view(ctx, tex);
|
||||
pipe_resource_reference(&tex, NULL);
|
||||
}
|
||||
|
||||
ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT,
|
||||
SI_POLY_STIPPLE_SAMPLER, 1, &view);
|
||||
pipe_sampler_view_reference(&view, NULL);
|
||||
|
||||
/* Bind the sampler state if needed. */
|
||||
if (!sctx->pstipple_sampler_state) {
|
||||
sctx->pstipple_sampler_state = util_pstipple_create_sampler(ctx);
|
||||
ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT,
|
||||
SI_POLY_STIPPLE_SAMPLER, 1,
|
||||
&sctx->pstipple_sampler_state);
|
||||
}
|
||||
}
|
||||
|
||||
static void si_texture_barrier(struct pipe_context *ctx)
|
||||
|
|
|
@ -67,6 +67,7 @@ struct si_state_rasterizer {
|
|||
unsigned clip_plane_enable;
|
||||
float offset_units;
|
||||
float offset_scale;
|
||||
bool poly_stipple_enable;
|
||||
};
|
||||
|
||||
struct si_state_dsa {
|
||||
|
|
|
@ -376,6 +376,11 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
|
|||
sctx->queued.named.rasterizer->multisample_enable &&
|
||||
!sctx->framebuffer.cb0_is_integer;
|
||||
}
|
||||
|
||||
key->ps.poly_stipple = sctx->queued.named.rasterizer->poly_stipple_enable &&
|
||||
((sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES &&
|
||||
sctx->current_rast_prim <= PIPE_PRIM_POLYGON) ||
|
||||
sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES_ADJACENCY);
|
||||
}
|
||||
if (sctx->queued.named.dsa) {
|
||||
key->ps.alpha_func = sctx->queued.named.dsa->alpha_func;
|
||||
|
|
Loading…
Reference in New Issue