struct pipe_viewport_state viewport;
void *vs;
- void *fs;
+ void *fs[TGSI_WRITEMASK_XYZW + 1];
struct pipe_buffer *vbuf; /**< quad vertices */
unsigned vbuf_slot;
}
/* 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 */
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);
* 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;
/* 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 */
}
+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.
*/
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 */
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,
/**
* 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];
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;
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 );
+}
+
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);