/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef TGSI_UREG_H
#define TGSI_UREG_H
#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_debug.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ureg_program;
struct pipe_stream_output_info;
/* Almost a tgsi_src_register, but we need to pull in the Absolute
* flag from the _ext token. Indirect flag always implies ADDR[0].
*/
struct ureg_src
{
unsigned File : 4; /* TGSI_FILE_ */
unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */
unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
unsigned Indirect : 1; /* BOOL */
unsigned DimIndirect : 1; /* BOOL */
unsigned Dimension : 1; /* BOOL */
unsigned Absolute : 1; /* BOOL */
unsigned Negate : 1; /* BOOL */
unsigned IndirectFile : 4; /* TGSI_FILE_ */
unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
unsigned DimIndFile : 4; /* TGSI_FILE_ */
unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */
int Index : 16; /* SINT */
int IndirectIndex : 16; /* SINT */
int DimensionIndex : 16; /* SINT */
int DimIndIndex : 16; /* SINT */
};
/* Very similar to a tgsi_dst_register, removing unsupported fields
* and adding a Saturate flag. It's easier to push saturate into the
* destination register than to try and create a _SAT variant of each
* instruction function.
*/
struct ureg_dst
{
unsigned File : 4; /* TGSI_FILE_ */
unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
unsigned Indirect : 1; /* BOOL */
unsigned Saturate : 1; /* BOOL */
unsigned Predicate : 1;
unsigned PredNegate : 1; /* BOOL */
unsigned PredSwizzleX: 2; /* TGSI_SWIZZLE_ */
unsigned PredSwizzleY: 2; /* TGSI_SWIZZLE_ */
unsigned PredSwizzleZ: 2; /* TGSI_SWIZZLE_ */
unsigned PredSwizzleW: 2; /* TGSI_SWIZZLE_ */
int Index : 16; /* SINT */
int IndirectIndex : 16; /* SINT */
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
};
struct pipe_context;
struct ureg_program *
ureg_create( unsigned processor );
const struct tgsi_token *
ureg_finalize( struct ureg_program * );
/* Create and return a shader:
*/
void *
ureg_create_shader( struct ureg_program *,
struct pipe_context *pipe,
const struct pipe_stream_output_info *so );
/* Alternately, return the built token stream and hand ownership of
* that memory to the caller:
*/
const struct tgsi_token *
ureg_get_tokens( struct ureg_program *ureg,
unsigned *nr_tokens );
/* Free the tokens created by ureg_get_tokens() */
void ureg_free_tokens( const struct tgsi_token *tokens );
void
ureg_destroy( struct ureg_program * );
/***********************************************************************
* Convenience routine:
*/
static INLINE void *
ureg_create_shader_with_so_and_destroy( struct ureg_program *p,
struct pipe_context *pipe,
const struct pipe_stream_output_info *so )
{
void *result = ureg_create_shader( p, pipe, so );
ureg_destroy( p );
return result;
}
static INLINE void *
ureg_create_shader_and_destroy( struct ureg_program *p,
struct pipe_context *pipe )
{
return ureg_create_shader_with_so_and_destroy(p, pipe, NULL);
}
/***********************************************************************
* Build shader properties:
*/
void
ureg_property_gs_input_prim(struct ureg_program *ureg,
unsigned input_prim);
void
ureg_property_gs_output_prim(struct ureg_program *ureg,
unsigned output_prim);
void
ureg_property_gs_max_vertices(struct ureg_program *ureg,
unsigned max_vertices);
void
ureg_property_fs_coord_origin(struct ureg_program *ureg,
unsigned fs_coord_origin);
void
ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
unsigned fs_coord_pixel_center);
void
ureg_property_fs_color0_writes_all_cbufs(struct ureg_program *ureg,
unsigned fs_color0_writes_all_cbufs);
void
ureg_property_fs_depth_layout(struct ureg_program *ureg,
unsigned fs_depth_layout);
/***********************************************************************
* Build shader declarations:
*/
struct ureg_src
ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,
unsigned semantic_name,
unsigned semantic_index,
unsigned interp_mode,
unsigned cylindrical_wrap,
unsigned centroid);
static INLINE struct ureg_src
ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
unsigned semantic_name,
unsigned semantic_index,
unsigned interp_mode,
unsigned cylindrical_wrap)
{
return ureg_DECL_fs_input_cyl_centroid(ureg,
semantic_name,
semantic_index,
interp_mode,
cylindrical_wrap,
0);
}
static INLINE struct ureg_src
ureg_DECL_fs_input(struct ureg_program *ureg,
unsigned semantic_name,
unsigned semantic_index,
unsigned interp_mode)
{
return ureg_DECL_fs_input_cyl_centroid(ureg,
semantic_name,
semantic_index,
interp_mode,
0, 0);
}
struct ureg_src
ureg_DECL_vs_input( struct ureg_program *,
unsigned index );
struct ureg_src
ureg_DECL_gs_input(struct ureg_program *,
unsigned index,
unsigned semantic_name,
unsigned semantic_index);
struct ureg_src
ureg_DECL_system_value(struct ureg_program *,
unsigned index,
unsigned semantic_name,
unsigned semantic_index);
struct ureg_dst
ureg_DECL_output_masked( struct ureg_program *,
unsigned semantic_name,
unsigned semantic_index,
unsigned usage_mask );
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
unsigned semantic_name,
unsigned semantic_index );
struct ureg_src
ureg_DECL_immediate( struct ureg_program *,
const float *v,
unsigned nr );
struct ureg_src
ureg_DECL_immediate_uint( struct ureg_program *,
const unsigned *v,
unsigned nr );
struct ureg_src
ureg_DECL_immediate_block_uint( struct ureg_program *,
const unsigned *v,
unsigned nr );
struct ureg_src
ureg_DECL_immediate_int( struct ureg_program *,
const int *v,
unsigned nr );
void
ureg_DECL_constant2D(struct ureg_program *ureg,
unsigned first,
unsigned last,
unsigned index2D);
struct ureg_src
ureg_DECL_constant( struct ureg_program *,
unsigned index );
struct ureg_dst
ureg_DECL_temporary( struct ureg_program * );
/**
* Emit a temporary with the LOCAL declaration flag set. For use when
* the register value is not required to be preserved across
* subroutine boundaries.
*/
struct ureg_dst
ureg_DECL_local_temporary( struct ureg_program * );
void
ureg_release_temporary( struct ureg_program *ureg,
struct ureg_dst tmp );
struct ureg_dst
ureg_DECL_address( struct ureg_program * );
struct ureg_dst
ureg_DECL_predicate(struct ureg_program *);
/* Supply an index to the sampler declaration as this is the hook to
* the external pipe_sampler state. Users of this function probably
* don't want just any sampler, but a specific one which they've set
* up state for in the context.
*/
struct ureg_src
ureg_DECL_sampler( struct ureg_program *,
unsigned index );
struct ureg_src
ureg_DECL_sampler_view(struct ureg_program *,
unsigned index,
unsigned target,
unsigned return_type_x,
unsigned return_type_y,
unsigned return_type_z,
unsigned return_type_w );
static INLINE struct ureg_src
ureg_imm4f( struct ureg_program *ureg,
float a, float b,
float c, float d)
{
float v[4];
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
return ureg_DECL_immediate( ureg, v, 4 );
}
static INLINE struct ureg_src
ureg_imm3f( struct ureg_program *ureg,
float a, float b,
float c)
{
float v[3];
v[0] = a;
v[1] = b;
v[2] = c;
return ureg_DECL_immediate( ureg, v, 3 );
}
static INLINE struct ureg_src
ureg_imm2f( struct ureg_program *ureg,
float a, float b)
{
float v[2];
v[0] = a;
v[1] = b;
return ureg_DECL_immediate( ureg, v, 2 );
}
static INLINE struct ureg_src
ureg_imm1f( struct ureg_program *ureg,
float a)
{
float v[1];
v[0] = a;
return ureg_DECL_immediate( ureg, v, 1 );
}
static INLINE struct ureg_src
ureg_imm4u( struct ureg_program *ureg,
unsigned a, unsigned b,
unsigned c, unsigned d)
{
unsigned v[4];
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
return ureg_DECL_immediate_uint( ureg, v, 4 );
}
static INLINE struct ureg_src
ureg_imm3u( struct ureg_program *ureg,
unsigned a, unsigned b,
unsigned c)
{
unsigned v[3];
v[0] = a;
v[1] = b;
v[2] = c;
return ureg_DECL_immediate_uint( ureg, v, 3 );
}
static INLINE struct ureg_src
ureg_imm2u( struct ureg_program *ureg,
unsigned a, unsigned b)
{
unsigned v[2];
v[0] = a;
v[1] = b;
return ureg_DECL_immediate_uint( ureg, v, 2 );
}
static INLINE struct ureg_src
ureg_imm1u( struct ureg_program *ureg,
unsigned a)
{
return ureg_DECL_immediate_uint( ureg, &a, 1 );
}
static INLINE struct ureg_src
ureg_imm4i( struct ureg_program *ureg,
int a, int b,
int c, int d)
{
int v[4];
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
return ureg_DECL_immediate_int( ureg, v, 4 );
}
static INLINE struct ureg_src
ureg_imm3i( struct ureg_program *ureg,
int a, int b,
int c)
{
int v[3];
v[0] = a;
v[1] = b;
v[2] = c;
return ureg_DECL_immediate_int( ureg, v, 3 );
}
static INLINE struct ureg_src
ureg_imm2i( struct ureg_program *ureg,
int a, int b)
{
int v[2];
v[0] = a;
v[1] = b;
return ureg_DECL_immediate_int( ureg, v, 2 );
}
static INLINE struct ureg_src
ureg_imm1i( struct ureg_program *ureg,
int a)
{
return ureg_DECL_immediate_int( ureg, &a, 1 );
}
/***********************************************************************
* Functions for patching up labels
*/
/* Will return a number which can be used in a label to point to the
* next instruction to be emitted.
*/
unsigned
ureg_get_instruction_number( struct ureg_program *ureg );
/* Patch a given label (expressed as a token number) to point to a
* given instruction (expressed as an instruction number).
*
* Labels are obtained from instruction emitters, eg ureg_CAL().
* Instruction numbers are obtained from ureg_get_instruction_number(),
* above.
*/
void
ureg_fixup_label(struct ureg_program *ureg,
unsigned label_token,
unsigned instruction_number );
/* Generic instruction emitter. Use if you need to pass the opcode as
* a parameter, rather than using the emit_OP() variants below.
*/
void
ureg_insn(struct ureg_program *ureg,
unsigned opcode,
const struct ureg_dst *dst,
unsigned nr_dst,
const struct ureg_src *src,
unsigned nr_src );
void
ureg_tex_insn(struct ureg_program *ureg,
unsigned opcode,
const struct ureg_dst *dst,
unsigned nr_dst,
unsigned target,
const struct tgsi_texture_offset *texoffsets,
unsigned nr_offset,
const struct ureg_src *src,
unsigned nr_src );
void
ureg_label_insn(struct ureg_program *ureg,
unsigned opcode,
const struct ureg_src *src,
unsigned nr_src,
unsigned *label);
/***********************************************************************
* Internal instruction helpers, don't call these directly:
*/
struct ureg_emit_insn_result {
unsigned insn_token; /*< Used to fixup insn size. */
unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */
};
struct ureg_emit_insn_result
ureg_emit_insn(struct ureg_program *ureg,
unsigned opcode,
boolean saturate,
boolean predicate,
boolean pred_negate,
unsigned pred_swizzle_x,
unsigned pred_swizzle_y,
unsigned pred_swizzle_z,
unsigned pred_swizzle_w,
unsigned num_dst,
unsigned num_src );
void
ureg_emit_label(struct ureg_program *ureg,
unsigned insn_token,
unsigned *label_token );
void
ureg_emit_texture(struct ureg_program *ureg,
unsigned insn_token,
unsigned target, unsigned num_offsets);
void
ureg_emit_texture_offset(struct ureg_program *ureg,
const struct tgsi_texture_offset *offset);
void
ureg_emit_dst( struct ureg_program *ureg,
struct ureg_dst dst );
void
ureg_emit_src( struct ureg_program *ureg,
struct ureg_src src );
void
ureg_fixup_insn_size(struct ureg_program *ureg,
unsigned insn );
#define OP00( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
FALSE, \
FALSE, \
FALSE, \
TGSI_SWIZZLE_X, \
TGSI_SWIZZLE_Y, \
TGSI_SWIZZLE_Z, \
TGSI_SWIZZLE_W, \
0, \
0).insn_token; \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP01( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_src src ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
FALSE, \
FALSE, \
FALSE, \
TGSI_SWIZZLE_X, \
TGSI_SWIZZLE_Y, \
TGSI_SWIZZLE_Z, \
TGSI_SWIZZLE_W, \
0, \
1).insn_token; \
ureg_emit_src( ureg, src ); \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP00_LBL( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
unsigned *label_token ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
struct ureg_emit_insn_result insn; \
insn = ureg_emit_insn(ureg, \
opcode, \
FALSE, \
FALSE, \
FALSE, \
TGSI_SWIZZLE_X, \
TGSI_SWIZZLE_Y, \
TGSI_SWIZZLE_Z, \
TGSI_SWIZZLE_W, \
0, \
0); \
ureg_emit_label( ureg, insn.extended_token, label_token ); \
ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP01_LBL( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_src src, \
unsigned *label_token ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
struct ureg_emit_insn_result insn; \
insn = ureg_emit_insn(ureg, \
opcode, \
FALSE, \
FALSE, \
FALSE, \
TGSI_SWIZZLE_X, \
TGSI_SWIZZLE_Y, \
TGSI_SWIZZLE_Z, \
TGSI_SWIZZLE_W, \
0, \
1); \
ureg_emit_label( ureg, insn.extended_token, label_token ); \
ureg_emit_src( ureg, src ); \
ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP10( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
0).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP11( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
struct ureg_src src ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
1).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src ); \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP12( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
struct ureg_src src0, \
struct ureg_src src1 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
2).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP12_TEX( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
unsigned target, \
struct ureg_src src0, \
struct ureg_src src1 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
struct ureg_emit_insn_result insn; \
insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
2); \
ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP13( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
struct ureg_src src0, \
struct ureg_src src1, \
struct ureg_src src2 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
3).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_emit_src( ureg, src2 ); \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP14_TEX( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
unsigned target, \
struct ureg_src src0, \
struct ureg_src src1, \
struct ureg_src src2, \
struct ureg_src src3 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
struct ureg_emit_insn_result insn; \
insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
4); \
ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_emit_src( ureg, src2 ); \
ureg_emit_src( ureg, src3 ); \
ureg_fixup_insn_size( ureg, insn.insn_token ); \
}
#define OP14( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
struct ureg_src src0, \
struct ureg_src src1, \
struct ureg_src src2, \
struct ureg_src src3 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
4).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_emit_src( ureg, src2 ); \
ureg_emit_src( ureg, src3 ); \
ureg_fixup_insn_size( ureg, insn ); \
}
#define OP15( op ) \
static INLINE void ureg_##op( struct ureg_program *ureg, \
struct ureg_dst dst, \
struct ureg_src src0, \
struct ureg_src src1, \
struct ureg_src src2, \
struct ureg_src src3, \
struct ureg_src src4 ) \
{ \
unsigned opcode = TGSI_OPCODE_##op; \
unsigned insn = ureg_emit_insn(ureg, \
opcode, \
dst.Saturate, \
dst.Predicate, \
dst.PredNegate, \
dst.PredSwizzleX, \
dst.PredSwizzleY, \
dst.PredSwizzleZ, \
dst.PredSwizzleW, \
1, \
5).insn_token; \
ureg_emit_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \
ureg_emit_src( ureg, src2 ); \
ureg_emit_src( ureg, src3 ); \
ureg_emit_src( ureg, src4 ); \
ureg_fixup_insn_size( ureg, insn ); \
}
/* Use a template include to generate a correctly-typed ureg_OP()
* function for each TGSI opcode:
*/
#include "tgsi_opcode_tmp.h"
/***********************************************************************
* Inline helpers for manipulating register structs:
*/
static INLINE struct ureg_src
ureg_negate( struct ureg_src reg )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Negate ^= 1;
return reg;
}
static INLINE struct ureg_src
ureg_abs( struct ureg_src reg )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Absolute = 1;
reg.Negate = 0;
return reg;
}
static INLINE struct ureg_src
ureg_swizzle( struct ureg_src reg,
int x, int y, int z, int w )
{
unsigned swz = ( (reg.SwizzleX << 0) |
(reg.SwizzleY << 2) |
(reg.SwizzleZ << 4) |
(reg.SwizzleW << 6));
assert(reg.File != TGSI_FILE_NULL);
assert(x < 4);
assert(y < 4);
assert(z < 4);
assert(w < 4);
reg.SwizzleX = (swz >> (x*2)) & 0x3;
reg.SwizzleY = (swz >> (y*2)) & 0x3;
reg.SwizzleZ = (swz >> (z*2)) & 0x3;
reg.SwizzleW = (swz >> (w*2)) & 0x3;
return reg;
}
static INLINE struct ureg_src
ureg_scalar( struct ureg_src reg, int x )
{
return ureg_swizzle(reg, x, x, x, x);
}
static INLINE struct ureg_dst
ureg_writemask( struct ureg_dst reg,
unsigned writemask )
{
assert(reg.File != TGSI_FILE_NULL);
reg.WriteMask &= writemask;
return reg;
}
static INLINE struct ureg_dst
ureg_saturate( struct ureg_dst reg )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Saturate = 1;
return reg;
}
static INLINE struct ureg_dst
ureg_predicate(struct ureg_dst reg,
boolean negate,
unsigned swizzle_x,
unsigned swizzle_y,
unsigned swizzle_z,
unsigned swizzle_w)
{
assert(reg.File != TGSI_FILE_NULL);
reg.Predicate = 1;
reg.PredNegate = negate;
reg.PredSwizzleX = swizzle_x;
reg.PredSwizzleY = swizzle_y;
reg.PredSwizzleZ = swizzle_z;
reg.PredSwizzleW = swizzle_w;
return reg;
}
static INLINE struct ureg_dst
ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
{
assert(reg.File != TGSI_FILE_NULL);
assert(addr.File == TGSI_FILE_ADDRESS);
reg.Indirect = 1;
reg.IndirectIndex = addr.Index;
reg.IndirectSwizzle = addr.SwizzleX;
return reg;
}
static INLINE struct ureg_src
ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
{
assert(reg.File != TGSI_FILE_NULL);
assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
reg.Indirect = 1;
reg.IndirectFile = addr.File;
reg.IndirectIndex = addr.Index;
reg.IndirectSwizzle = addr.SwizzleX;
return reg;
}
static INLINE struct ureg_src
ureg_src_dimension( struct ureg_src reg, int index )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Dimension = 1;
reg.DimIndirect = 0;
reg.DimensionIndex = index;
return reg;
}
static INLINE struct ureg_src
ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
int index )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Dimension = 1;
reg.DimIndirect = 1;
reg.DimensionIndex = index;
reg.DimIndFile = addr.File;
reg.DimIndIndex = addr.Index;
reg.DimIndSwizzle = addr.SwizzleX;
return reg;
}
static INLINE struct ureg_dst
ureg_dst( struct ureg_src src )
{
struct ureg_dst dst;
assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
dst.File = src.File;
dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = src.Indirect;
dst.IndirectIndex = src.IndirectIndex;
dst.IndirectSwizzle = src.IndirectSwizzle;
dst.Saturate = 0;
dst.Predicate = 0;
dst.PredNegate = 0;
dst.PredSwizzleX = TGSI_SWIZZLE_X;
dst.PredSwizzleY = TGSI_SWIZZLE_Y;
dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
dst.PredSwizzleW = TGSI_SWIZZLE_W;
dst.Index = src.Index;
return dst;
}
static INLINE struct ureg_src
ureg_src_register(unsigned file,
unsigned index)
{
struct ureg_src src;
src.File = file;
src.SwizzleX = TGSI_SWIZZLE_X;
src.SwizzleY = TGSI_SWIZZLE_Y;
src.SwizzleZ = TGSI_SWIZZLE_Z;
src.SwizzleW = TGSI_SWIZZLE_W;
src.Indirect = 0;
src.IndirectFile = TGSI_FILE_NULL;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0;
src.Index = index;
src.Negate = 0;
src.Dimension = 0;
src.DimensionIndex = 0;
src.DimIndirect = 0;
src.DimIndFile = TGSI_FILE_NULL;
src.DimIndIndex = 0;
src.DimIndSwizzle = 0;
return src;
}
static INLINE struct ureg_src
ureg_src( struct ureg_dst dst )
{
struct ureg_src src;
src.File = dst.File;
src.SwizzleX = TGSI_SWIZZLE_X;
src.SwizzleY = TGSI_SWIZZLE_Y;
src.SwizzleZ = TGSI_SWIZZLE_Z;
src.SwizzleW = TGSI_SWIZZLE_W;
src.Indirect = dst.Indirect;
src.IndirectFile = TGSI_FILE_ADDRESS;
src.IndirectIndex = dst.IndirectIndex;
src.IndirectSwizzle = dst.IndirectSwizzle;
src.Absolute = 0;
src.Index = dst.Index;
src.Negate = 0;
src.Dimension = 0;
src.DimensionIndex = 0;
src.DimIndirect = 0;
src.DimIndFile = TGSI_FILE_NULL;
src.DimIndIndex = 0;
src.DimIndSwizzle = 0;
return src;
}
static INLINE struct ureg_dst
ureg_dst_undef( void )
{
struct ureg_dst dst;
dst.File = TGSI_FILE_NULL;
dst.WriteMask = 0;
dst.Indirect = 0;
dst.IndirectIndex = 0;
dst.IndirectSwizzle = 0;
dst.Saturate = 0;
dst.Predicate = 0;
dst.PredNegate = 0;
dst.PredSwizzleX = TGSI_SWIZZLE_X;
dst.PredSwizzleY = TGSI_SWIZZLE_Y;
dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
dst.PredSwizzleW = TGSI_SWIZZLE_W;
dst.Index = 0;
return dst;
}
static INLINE struct ureg_src
ureg_src_undef( void )
{
struct ureg_src src;
src.File = TGSI_FILE_NULL;
src.SwizzleX = 0;
src.SwizzleY = 0;
src.SwizzleZ = 0;
src.SwizzleW = 0;
src.Indirect = 0;
src.IndirectFile = TGSI_FILE_NULL;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0;
src.Index = 0;
src.Negate = 0;
src.Dimension = 0;
src.DimensionIndex = 0;
src.DimIndirect = 0;
src.DimIndFile = TGSI_FILE_NULL;
src.DimIndIndex = 0;
src.DimIndSwizzle = 0;
return src;
}
static INLINE boolean
ureg_src_is_undef( struct ureg_src src )
{
return src.File == TGSI_FILE_NULL;
}
static INLINE boolean
ureg_dst_is_undef( struct ureg_dst dst )
{
return dst.File == TGSI_FILE_NULL;
}
#ifdef __cplusplus
}
#endif
#endif