mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-26 05:40:33 +01:00
swr: Add polygon stipple support
Add polygon stipple functionality to the fragment shader. Explicitly turn off polygon stipple for lines and points, since we do them using tris. Reviewed-by: Bruce Cherniak <bruce.cherniak@intel.com>
This commit is contained in:
parent
8973ae3162
commit
d7a1f01db3
5 changed files with 84 additions and 9 deletions
|
|
@ -98,6 +98,8 @@ struct swr_draw_context {
|
|||
|
||||
float userClipPlanes[PIPE_MAX_CLIP_PLANES][4];
|
||||
|
||||
uint32_t polyStipple[32];
|
||||
|
||||
SWR_SURFACE_STATE renderTargets[SWR_NUM_ATTACHMENTS];
|
||||
void *pStats;
|
||||
};
|
||||
|
|
@ -127,7 +129,7 @@ struct swr_context {
|
|||
struct pipe_constant_buffer
|
||||
constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_poly_stipple poly_stipple;
|
||||
struct swr_poly_stipple poly_stipple;
|
||||
struct pipe_scissor_state scissor;
|
||||
SWR_RECT swr_scissor;
|
||||
struct pipe_sampler_view *
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ swr_generate_fs_key(struct swr_jit_fs_key &key,
|
|||
sizeof(key.vs_output_semantic_idx));
|
||||
|
||||
swr_generate_sampler_key(swr_fs->info, ctx, PIPE_SHADER_FRAGMENT, key);
|
||||
|
||||
key.poly_stipple_enable = ctx->rasterizer->poly_stipple_enable &&
|
||||
ctx->poly_stipple.prim_is_poly;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1099,17 +1102,58 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
|
|||
memset(&system_values, 0, sizeof(system_values));
|
||||
|
||||
struct lp_build_mask_context mask;
|
||||
bool uses_mask = false;
|
||||
|
||||
if (swr_fs->info.base.uses_kill) {
|
||||
Value *mask_val = LOAD(pPS, {0, SWR_PS_CONTEXT_activeMask}, "activeMask");
|
||||
if (swr_fs->info.base.uses_kill ||
|
||||
key.poly_stipple_enable) {
|
||||
Value *vActiveMask = NULL;
|
||||
if (swr_fs->info.base.uses_kill) {
|
||||
vActiveMask = LOAD(pPS, {0, SWR_PS_CONTEXT_activeMask}, "activeMask");
|
||||
}
|
||||
if (key.poly_stipple_enable) {
|
||||
// first get fragment xy coords and clip to stipple bounds
|
||||
Value *vXf = LOAD(pPS, {0, SWR_PS_CONTEXT_vX, PixelPositions_UL});
|
||||
Value *vYf = LOAD(pPS, {0, SWR_PS_CONTEXT_vY, PixelPositions_UL});
|
||||
Value *vXu = FP_TO_UI(vXf, mSimdInt32Ty);
|
||||
Value *vYu = FP_TO_UI(vYf, mSimdInt32Ty);
|
||||
|
||||
// stipple pattern is 32x32, which means that one line of stipple
|
||||
// is stored in one word:
|
||||
// vXstipple is bit offset inside 32-bit stipple word
|
||||
// vYstipple is word index is stipple array
|
||||
Value *vXstipple = AND(vXu, VIMMED1(0x1f)); // & (32-1)
|
||||
Value *vYstipple = AND(vYu, VIMMED1(0x1f)); // & (32-1)
|
||||
|
||||
// grab stipple pattern base address
|
||||
Value *stipplePtr = GEP(hPrivateData, {0, swr_draw_context_polyStipple, 0});
|
||||
stipplePtr = BITCAST(stipplePtr, mInt8PtrTy);
|
||||
|
||||
// peform a gather to grab stipple words for each lane
|
||||
Value *vStipple = GATHERDD(VUNDEF_I(), stipplePtr, vYstipple,
|
||||
VIMMED1(0xffffffff), C((char)4));
|
||||
|
||||
// create a mask with one bit corresponding to the x stipple
|
||||
// and AND it with the pattern, to see if we have a bit
|
||||
Value *vBitMask = LSHR(VIMMED1(0x80000000), vXstipple);
|
||||
Value *vStippleMask = AND(vStipple, vBitMask);
|
||||
vStippleMask = ICMP_NE(vStippleMask, VIMMED1(0));
|
||||
vStippleMask = VMASK(vStippleMask);
|
||||
|
||||
if (swr_fs->info.base.uses_kill) {
|
||||
vActiveMask = AND(vActiveMask, vStippleMask);
|
||||
} else {
|
||||
vActiveMask = vStippleMask;
|
||||
}
|
||||
}
|
||||
lp_build_mask_begin(
|
||||
&mask, gallivm, lp_type_float_vec(32, 32 * 8), wrap(mask_val));
|
||||
&mask, gallivm, lp_type_float_vec(32, 32 * 8), wrap(vActiveMask));
|
||||
uses_mask = true;
|
||||
}
|
||||
|
||||
lp_build_tgsi_soa(gallivm,
|
||||
swr_fs->pipe.tokens,
|
||||
lp_type_float_vec(32, 32 * 8),
|
||||
swr_fs->info.base.uses_kill ? &mask : NULL, // mask
|
||||
uses_mask ? &mask : NULL, // mask
|
||||
wrap(consts_ptr),
|
||||
wrap(const_sizes_ptr),
|
||||
&system_values,
|
||||
|
|
@ -1172,13 +1216,13 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
|
|||
}
|
||||
|
||||
LLVMValueRef mask_result = 0;
|
||||
if (swr_fs->info.base.uses_kill) {
|
||||
if (uses_mask) {
|
||||
mask_result = lp_build_mask_end(&mask);
|
||||
}
|
||||
|
||||
IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder)));
|
||||
|
||||
if (swr_fs->info.base.uses_kill) {
|
||||
if (uses_mask) {
|
||||
STORE(unwrap(mask_result), pPS, {0, SWR_PS_CONTEXT_activeMask});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ struct swr_jit_fs_key : swr_jit_sampler_key {
|
|||
unsigned sprite_coord_enable;
|
||||
ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
|
||||
ubyte vs_output_semantic_idx[PIPE_MAX_SHADER_OUTPUTS];
|
||||
bool poly_stipple_enable;
|
||||
};
|
||||
|
||||
struct swr_jit_vs_key : swr_jit_sampler_key {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "util/u_helpers.h"
|
||||
#include "util/u_framebuffer.h"
|
||||
#include "util/u_viewport.h"
|
||||
#include "util/u_prim.h"
|
||||
|
||||
#include "swr_state.h"
|
||||
#include "swr_context.h"
|
||||
|
|
@ -609,7 +610,7 @@ swr_set_polygon_stipple(struct pipe_context *pipe,
|
|||
{
|
||||
struct swr_context *ctx = swr_context(pipe);
|
||||
|
||||
ctx->poly_stipple = *stipple; /* struct copy */
|
||||
ctx->poly_stipple.pipe = *stipple; /* struct copy */
|
||||
ctx->dirty |= SWR_NEW_STIPPLE;
|
||||
}
|
||||
|
||||
|
|
@ -986,6 +987,17 @@ swr_user_vbuf_range(const struct pipe_draw_info *info,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
swr_update_poly_stipple(struct swr_context *ctx)
|
||||
{
|
||||
struct swr_draw_context *pDC = &ctx->swrDC;
|
||||
|
||||
assert(sizeof(ctx->poly_stipple.pipe.stipple) == sizeof(pDC->polyStipple));
|
||||
memcpy(pDC->polyStipple,
|
||||
ctx->poly_stipple.pipe.stipple,
|
||||
sizeof(ctx->poly_stipple.pipe.stipple));
|
||||
}
|
||||
|
||||
void
|
||||
swr_update_derived(struct pipe_context *pipe,
|
||||
const struct pipe_draw_info *p_draw_info)
|
||||
|
|
@ -1407,6 +1419,17 @@ swr_update_derived(struct pipe_context *pipe,
|
|||
}
|
||||
}
|
||||
|
||||
/* work around the fact that poly stipple also affects lines */
|
||||
/* and points, since we rasterize them as triangles, too */
|
||||
/* Has to be before fragment shader, since it sets SWR_NEW_FS */
|
||||
if (p_draw_info) {
|
||||
bool new_prim_is_poly = (u_reduced_prim(p_draw_info->mode) == PIPE_PRIM_TRIANGLES);
|
||||
if (new_prim_is_poly != ctx->poly_stipple.prim_is_poly) {
|
||||
ctx->dirty |= SWR_NEW_FS;
|
||||
ctx->poly_stipple.prim_is_poly = new_prim_is_poly;
|
||||
}
|
||||
}
|
||||
|
||||
/* FragmentShader */
|
||||
if (ctx->dirty & (SWR_NEW_FS |
|
||||
SWR_NEW_VS |
|
||||
|
|
@ -1661,7 +1684,7 @@ swr_update_derived(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
if (ctx->dirty & SWR_NEW_STIPPLE) {
|
||||
/* XXX What to do with this one??? SWR doesn't stipple */
|
||||
swr_update_poly_stipple(ctx);
|
||||
}
|
||||
|
||||
if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_SO | SWR_NEW_RASTERIZER)) {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ struct swr_blend_state {
|
|||
RENDER_TARGET_BLEND_COMPILE_STATE compileState[PIPE_MAX_COLOR_BUFS];
|
||||
};
|
||||
|
||||
struct swr_poly_stipple {
|
||||
struct pipe_poly_stipple pipe;
|
||||
bool prim_is_poly;
|
||||
};
|
||||
|
||||
/*
|
||||
* Derived SWR API DrawState
|
||||
* For convenience of making simple changes without re-deriving state.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue