util: add version of u_blit_pixels which takes a writemask

Values outside the writemask are set in the destination to {0,0,0,1}
This commit is contained in:
Keith Whitwell 2009-09-02 17:58:52 +01:00
parent 1d7a989b10
commit de343680a3
4 changed files with 100 additions and 15 deletions

View File

@ -62,7 +62,7 @@ struct blit_state
struct pipe_viewport_state viewport;
void *vs;
void *fs;
void *fs[TGSI_WRITEMASK_XYZW + 1];
struct pipe_buffer *vbuf; /**< quad vertices */
unsigned vbuf_slot;
@ -125,7 +125,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
}
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe);
ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@ -146,9 +146,13 @@ void
util_destroy_blit(struct blit_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
unsigned i;
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
for (i = 0; i < Elements(ctx->fs); i++)
if (ctx->fs[i])
pipe->delete_fs_state(pipe, ctx->fs[i]);
pipe_buffer_reference(&ctx->vbuf, NULL);
@ -299,14 +303,15 @@ regions_overlap(int srcX0, int srcY0,
* XXX need some control over blitting Z and/or stencil.
*/
void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
float z, uint filter)
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
float z, uint filter,
uint writemask)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
@ -426,8 +431,11 @@ util_blit_pixels(struct blit_state *ctx,
/* texture */
cso_set_sampler_textures(ctx->cso, 1, &tex);
if (ctx->fs[writemask] == NULL)
ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* drawing dest */
@ -462,6 +470,27 @@ util_blit_pixels(struct blit_state *ctx,
}
void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
float z, uint filter )
{
util_blit_pixels_writemask( ctx, src,
srcX0, srcY0,
srcX1, srcY1,
dst,
dstX0, dstY0,
dstX1, dstY1,
z, filter,
TGSI_WRITEMASK_XYZW );
}
/* Release vertex buffer at end of frame to avoid synchronous
* rendering.
*/
@ -535,7 +564,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_sampler_textures(ctx->cso, 1, &tex);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* drawing dest */

View File

@ -60,6 +60,17 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter);
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
float z, uint filter,
uint writemask);
extern void
util_blit_pixels_tex(struct blit_state *ctx,
struct pipe_texture *tex,

View File

@ -152,11 +152,14 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/**
* Make simple fragment texture shader:
* TEX OUT[0], IN[0], SAMP[0], 2D;
* 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;
* END;
*/
void *
util_make_fragment_tex_shader(struct pipe_context *pipe)
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned writemask )
{
struct pipe_shader_state shader;
struct tgsi_token tokens[100];
@ -217,12 +220,43 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
header,
Elements(tokens) - ti);
if (writemask != TGSI_WRITEMASK_XYZW) {
struct tgsi_full_immediate imm;
static const float value[4] = { 0, 0, 0, 1 };
imm = tgsi_default_full_immediate();
imm.Immediate.NrTokens += 4;
imm.Immediate.DataType = TGSI_IMM_FLOAT32;
imm.u.Pointer = value;
ti += tgsi_build_full_immediate(&imm,
&tokens[ti],
header,
Elements(tokens) - ti );
/* MOV instruction */
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_MOV;
inst.Instruction.NumDstRegs = 1;
inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
inst.FullDstRegisters[0].DstRegister.Index = 0;
inst.Instruction.NumSrcRegs = 1;
inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_IMMEDIATE;
inst.FullSrcRegisters[0].SrcRegister.Index = 0;
ti += tgsi_build_full_instruction(&inst,
&tokens[ti],
header,
Elements(tokens) - ti );
}
/* TEX instruction */
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_TEX;
inst.Instruction.NumDstRegs = 1;
inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
inst.FullDstRegisters[0].DstRegister.Index = 0;
inst.FullDstRegisters[0].DstRegister.WriteMask = writemask;
inst.Instruction.NumSrcRegs = 2;
inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
@ -253,6 +287,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
return pipe->create_fs_state(pipe, &shader);
}
void *
util_make_fragment_tex_shader(struct pipe_context *pipe )
{
return util_make_fragment_tex_shader_writemask( pipe,
TGSI_WRITEMASK_XYZW );
}

View File

@ -49,6 +49,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
const uint *semantic_indexes);
extern void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned writemask );
extern void *
util_make_fragment_tex_shader(struct pipe_context *pipe);