forked from KolibriOS/kolibrios
edb28b33f3
git-svn-id: svn://kolibrios.org@3770 a494cfbc-eb01-0410-851d-a64ba20cac60
464 lines
14 KiB
C
464 lines
14 KiB
C
/**************************************************************************
|
|
*
|
|
* Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
* All Rights Reserved.
|
|
* Copyright 2009-2010 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 TUNGSTEN GRAPHICS 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_EXEC_H
|
|
#define TGSI_EXEC_H
|
|
|
|
#include "pipe/p_compiler.h"
|
|
#include "pipe/p_state.h"
|
|
#include "pipe/p_shader_tokens.h"
|
|
|
|
#if defined __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define TGSI_CHAN_X 0
|
|
#define TGSI_CHAN_Y 1
|
|
#define TGSI_CHAN_Z 2
|
|
#define TGSI_CHAN_W 3
|
|
|
|
#define TGSI_NUM_CHANNELS 4 /* R,G,B,A */
|
|
#define TGSI_QUAD_SIZE 4 /* 4 pixel/quad */
|
|
|
|
#define TGSI_FOR_EACH_CHANNEL( CHAN )\
|
|
for (CHAN = 0; CHAN < TGSI_NUM_CHANNELS; CHAN++)
|
|
|
|
#define TGSI_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
|
|
((INST)->Dst[0].Register.WriteMask & (1 << (CHAN)))
|
|
|
|
#define TGSI_IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
|
|
if (TGSI_IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
|
|
|
|
#define TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
|
|
TGSI_FOR_EACH_CHANNEL( CHAN )\
|
|
TGSI_IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
|
|
|
|
|
|
/**
|
|
* Registers may be treated as float, signed int or unsigned int.
|
|
*/
|
|
union tgsi_exec_channel
|
|
{
|
|
float f[TGSI_QUAD_SIZE];
|
|
int i[TGSI_QUAD_SIZE];
|
|
unsigned u[TGSI_QUAD_SIZE];
|
|
};
|
|
|
|
/**
|
|
* A vector[RGBA] of channels[4 pixels]
|
|
*/
|
|
struct tgsi_exec_vector
|
|
{
|
|
union tgsi_exec_channel xyzw[TGSI_NUM_CHANNELS];
|
|
};
|
|
|
|
/**
|
|
* For fragment programs, information for computing fragment input
|
|
* values from plane equation of the triangle/line.
|
|
*/
|
|
struct tgsi_interp_coef
|
|
{
|
|
float a0[TGSI_NUM_CHANNELS]; /* in an xyzw layout */
|
|
float dadx[TGSI_NUM_CHANNELS];
|
|
float dady[TGSI_NUM_CHANNELS];
|
|
};
|
|
|
|
enum tgsi_sampler_control {
|
|
tgsi_sampler_lod_none,
|
|
tgsi_sampler_lod_bias,
|
|
tgsi_sampler_lod_explicit,
|
|
tgsi_sampler_lod_zero,
|
|
tgsi_sampler_derivs_explicit
|
|
};
|
|
|
|
/**
|
|
* Information for sampling textures, which must be implemented
|
|
* by code outside the TGSI executor.
|
|
*/
|
|
struct tgsi_sampler
|
|
{
|
|
/** Get samples for four fragments in a quad */
|
|
/* this interface contains 5 sets of channels that vary
|
|
* depending on the sampler.
|
|
* s - the first texture coordinate for sampling.
|
|
* t - the second texture coordinate for sampling - unused for 1D,
|
|
layer for 1D arrays.
|
|
* r - the third coordinate for sampling for 3D, cube, cube arrays,
|
|
* layer for 2D arrays. Compare value for 1D/2D shadows.
|
|
* c0 - Compare value for shadow cube and shadow 2d arrays,
|
|
* layer for cube arrays.
|
|
* derivs - explicit derivatives.
|
|
* offset - texel offsets
|
|
* lod - lod value, except for shadow cube arrays (compare value there).
|
|
*/
|
|
void (*get_samples)(struct tgsi_sampler *sampler,
|
|
const unsigned sview_index,
|
|
const unsigned sampler_index,
|
|
const float s[TGSI_QUAD_SIZE],
|
|
const float t[TGSI_QUAD_SIZE],
|
|
const float r[TGSI_QUAD_SIZE],
|
|
const float c0[TGSI_QUAD_SIZE],
|
|
const float c1[TGSI_QUAD_SIZE],
|
|
float derivs[3][2][TGSI_QUAD_SIZE],
|
|
const int8_t offset[3],
|
|
enum tgsi_sampler_control control,
|
|
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
|
|
void (*get_dims)(struct tgsi_sampler *sampler,
|
|
const unsigned sview_index,
|
|
int level, int dims[4]);
|
|
void (*get_texel)(struct tgsi_sampler *sampler,
|
|
const unsigned sview_index,
|
|
const int i[TGSI_QUAD_SIZE],
|
|
const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
|
|
const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
|
|
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
|
|
};
|
|
|
|
#define TGSI_EXEC_NUM_TEMPS 4096
|
|
#define TGSI_EXEC_NUM_IMMEDIATES 256
|
|
|
|
/*
|
|
* Locations of various utility registers (_I = Index, _C = Channel)
|
|
*/
|
|
#define TGSI_EXEC_TEMP_00000000_I (TGSI_EXEC_NUM_TEMPS + 0)
|
|
#define TGSI_EXEC_TEMP_00000000_C 0
|
|
|
|
#define TGSI_EXEC_TEMP_7FFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0)
|
|
#define TGSI_EXEC_TEMP_7FFFFFFF_C 1
|
|
|
|
#define TGSI_EXEC_TEMP_80000000_I (TGSI_EXEC_NUM_TEMPS + 0)
|
|
#define TGSI_EXEC_TEMP_80000000_C 2
|
|
|
|
#define TGSI_EXEC_TEMP_FFFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0)
|
|
#define TGSI_EXEC_TEMP_FFFFFFFF_C 3
|
|
|
|
#define TGSI_EXEC_TEMP_ONE_I (TGSI_EXEC_NUM_TEMPS + 1)
|
|
#define TGSI_EXEC_TEMP_ONE_C 0
|
|
|
|
#define TGSI_EXEC_TEMP_TWO_I (TGSI_EXEC_NUM_TEMPS + 1)
|
|
#define TGSI_EXEC_TEMP_TWO_C 1
|
|
|
|
#define TGSI_EXEC_TEMP_128_I (TGSI_EXEC_NUM_TEMPS + 1)
|
|
#define TGSI_EXEC_TEMP_128_C 2
|
|
|
|
#define TGSI_EXEC_TEMP_MINUS_128_I (TGSI_EXEC_NUM_TEMPS + 1)
|
|
#define TGSI_EXEC_TEMP_MINUS_128_C 3
|
|
|
|
#define TGSI_EXEC_TEMP_KILMASK_I (TGSI_EXEC_NUM_TEMPS + 2)
|
|
#define TGSI_EXEC_TEMP_KILMASK_C 0
|
|
|
|
#define TGSI_EXEC_TEMP_OUTPUT_I (TGSI_EXEC_NUM_TEMPS + 2)
|
|
#define TGSI_EXEC_TEMP_OUTPUT_C 1
|
|
|
|
#define TGSI_EXEC_TEMP_PRIMITIVE_I (TGSI_EXEC_NUM_TEMPS + 2)
|
|
#define TGSI_EXEC_TEMP_PRIMITIVE_C 2
|
|
|
|
#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 2)
|
|
#define TGSI_EXEC_TEMP_THREE_C 3
|
|
|
|
#define TGSI_EXEC_TEMP_HALF_I (TGSI_EXEC_NUM_TEMPS + 3)
|
|
#define TGSI_EXEC_TEMP_HALF_C 0
|
|
|
|
/* execution mask, each value is either 0 or ~0 */
|
|
#define TGSI_EXEC_MASK_I (TGSI_EXEC_NUM_TEMPS + 3)
|
|
#define TGSI_EXEC_MASK_C 1
|
|
|
|
/* 4 register buffer for various purposes */
|
|
#define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4)
|
|
#define TGSI_EXEC_NUM_TEMP_R 4
|
|
|
|
#define TGSI_EXEC_TEMP_ADDR (TGSI_EXEC_NUM_TEMPS + 8)
|
|
#define TGSI_EXEC_NUM_ADDRS 1
|
|
|
|
/* predicate register */
|
|
#define TGSI_EXEC_TEMP_P0 (TGSI_EXEC_NUM_TEMPS + 9)
|
|
#define TGSI_EXEC_NUM_PREDS 1
|
|
|
|
#define TGSI_EXEC_NUM_TEMP_EXTRAS 10
|
|
|
|
|
|
|
|
#define TGSI_EXEC_MAX_NESTING 32
|
|
#define TGSI_EXEC_MAX_COND_NESTING TGSI_EXEC_MAX_NESTING
|
|
#define TGSI_EXEC_MAX_LOOP_NESTING TGSI_EXEC_MAX_NESTING
|
|
#define TGSI_EXEC_MAX_SWITCH_NESTING TGSI_EXEC_MAX_NESTING
|
|
#define TGSI_EXEC_MAX_CALL_NESTING TGSI_EXEC_MAX_NESTING
|
|
|
|
/* The maximum number of input attributes per vertex. For 2D
|
|
* input register files, this is the stride between two 1D
|
|
* arrays.
|
|
*/
|
|
#define TGSI_EXEC_MAX_INPUT_ATTRIBS 17
|
|
|
|
/* The maximum number of constant vectors per constant buffer.
|
|
*/
|
|
#define TGSI_EXEC_MAX_CONST_BUFFER 4096
|
|
|
|
/* The maximum number of vertices per primitive */
|
|
#define TGSI_MAX_PRIM_VERTICES 6
|
|
|
|
/* The maximum number of primitives to be generated */
|
|
#define TGSI_MAX_PRIMITIVES 64
|
|
|
|
/* The maximum total number of vertices */
|
|
#define TGSI_MAX_TOTAL_VERTICES (TGSI_MAX_PRIM_VERTICES * TGSI_MAX_PRIMITIVES * PIPE_MAX_ATTRIBS)
|
|
|
|
#define TGSI_MAX_MISC_INPUTS 8
|
|
|
|
/** function call/activation record */
|
|
struct tgsi_call_record
|
|
{
|
|
uint CondStackTop;
|
|
uint LoopStackTop;
|
|
uint ContStackTop;
|
|
int SwitchStackTop;
|
|
int BreakStackTop;
|
|
uint ReturnAddr;
|
|
};
|
|
|
|
|
|
/* Switch-case block state. */
|
|
struct tgsi_switch_record {
|
|
uint mask; /**< execution mask */
|
|
union tgsi_exec_channel selector; /**< a value case statements are compared to */
|
|
uint defaultMask; /**< non-execute mask for default case */
|
|
};
|
|
|
|
|
|
enum tgsi_break_type {
|
|
TGSI_EXEC_BREAK_INSIDE_LOOP,
|
|
TGSI_EXEC_BREAK_INSIDE_SWITCH
|
|
};
|
|
|
|
|
|
#define TGSI_EXEC_MAX_BREAK_STACK (TGSI_EXEC_MAX_LOOP_NESTING + TGSI_EXEC_MAX_SWITCH_NESTING)
|
|
|
|
|
|
/**
|
|
* Run-time virtual machine state for executing TGSI shader.
|
|
*/
|
|
struct tgsi_exec_machine
|
|
{
|
|
/* Total = program temporaries + internal temporaries
|
|
*/
|
|
struct tgsi_exec_vector Temps[TGSI_EXEC_NUM_TEMPS +
|
|
TGSI_EXEC_NUM_TEMP_EXTRAS];
|
|
|
|
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
|
|
|
|
float ImmArray[TGSI_EXEC_NUM_IMMEDIATES][4];
|
|
|
|
struct tgsi_exec_vector *Inputs;
|
|
struct tgsi_exec_vector *Outputs;
|
|
|
|
/* System values */
|
|
unsigned SysSemanticToIndex[TGSI_SEMANTIC_COUNT];
|
|
union tgsi_exec_channel SystemValue[TGSI_MAX_MISC_INPUTS];
|
|
|
|
struct tgsi_exec_vector *Addrs;
|
|
struct tgsi_exec_vector *Predicates;
|
|
|
|
struct tgsi_sampler *Sampler;
|
|
|
|
unsigned ImmLimit;
|
|
|
|
const void *Consts[PIPE_MAX_CONSTANT_BUFFERS];
|
|
unsigned ConstsSize[PIPE_MAX_CONSTANT_BUFFERS];
|
|
|
|
const struct tgsi_token *Tokens; /**< Declarations, instructions */
|
|
unsigned Processor; /**< TGSI_PROCESSOR_x */
|
|
|
|
/* GEOMETRY processor only. */
|
|
unsigned *Primitives;
|
|
unsigned NumOutputs;
|
|
unsigned MaxGeometryShaderOutputs;
|
|
|
|
/* FRAGMENT processor only. */
|
|
const struct tgsi_interp_coef *InterpCoefs;
|
|
struct tgsi_exec_vector QuadPos;
|
|
float Face; /**< +1 if front facing, -1 if back facing */
|
|
bool flatshade_color;
|
|
/* Conditional execution masks */
|
|
uint CondMask; /**< For IF/ELSE/ENDIF */
|
|
uint LoopMask; /**< For BGNLOOP/ENDLOOP */
|
|
uint ContMask; /**< For loop CONT statements */
|
|
uint FuncMask; /**< For function calls */
|
|
uint ExecMask; /**< = CondMask & LoopMask */
|
|
|
|
/* Current switch-case state. */
|
|
struct tgsi_switch_record Switch;
|
|
|
|
/* Current break type. */
|
|
enum tgsi_break_type BreakType;
|
|
|
|
/** Condition mask stack (for nested conditionals) */
|
|
uint CondStack[TGSI_EXEC_MAX_COND_NESTING];
|
|
int CondStackTop;
|
|
|
|
/** Loop mask stack (for nested loops) */
|
|
uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
|
int LoopStackTop;
|
|
|
|
/** Loop label stack */
|
|
uint LoopLabelStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
|
int LoopLabelStackTop;
|
|
|
|
/** Loop continue mask stack (see comments in tgsi_exec.c) */
|
|
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
|
int ContStackTop;
|
|
|
|
/** Switch case stack */
|
|
struct tgsi_switch_record SwitchStack[TGSI_EXEC_MAX_SWITCH_NESTING];
|
|
int SwitchStackTop;
|
|
|
|
enum tgsi_break_type BreakStack[TGSI_EXEC_MAX_BREAK_STACK];
|
|
int BreakStackTop;
|
|
|
|
/** Function execution mask stack (for executing subroutine code) */
|
|
uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING];
|
|
int FuncStackTop;
|
|
|
|
/** Function call stack for saving/restoring the program counter */
|
|
struct tgsi_call_record CallStack[TGSI_EXEC_MAX_CALL_NESTING];
|
|
int CallStackTop;
|
|
|
|
struct tgsi_full_instruction *Instructions;
|
|
uint NumInstructions;
|
|
|
|
struct tgsi_full_declaration *Declarations;
|
|
uint NumDeclarations;
|
|
|
|
struct tgsi_declaration_sampler_view
|
|
SamplerViews[PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
|
|
|
boolean UsedGeometryShader;
|
|
};
|
|
|
|
struct tgsi_exec_machine *
|
|
tgsi_exec_machine_create( void );
|
|
|
|
void
|
|
tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach);
|
|
|
|
|
|
void
|
|
tgsi_exec_machine_bind_shader(
|
|
struct tgsi_exec_machine *mach,
|
|
const struct tgsi_token *tokens,
|
|
struct tgsi_sampler *sampler);
|
|
|
|
uint
|
|
tgsi_exec_machine_run(
|
|
struct tgsi_exec_machine *mach );
|
|
|
|
|
|
void
|
|
tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach);
|
|
|
|
|
|
boolean
|
|
tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst);
|
|
|
|
|
|
static INLINE void
|
|
tgsi_set_kill_mask(struct tgsi_exec_machine *mach, unsigned mask)
|
|
{
|
|
mach->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0] =
|
|
mask;
|
|
}
|
|
|
|
|
|
/** Set execution mask values prior to executing the shader */
|
|
static INLINE void
|
|
tgsi_set_exec_mask(struct tgsi_exec_machine *mach,
|
|
boolean ch0, boolean ch1, boolean ch2, boolean ch3)
|
|
{
|
|
int *mask = mach->Temps[TGSI_EXEC_MASK_I].xyzw[TGSI_EXEC_MASK_C].i;
|
|
mask[0] = ch0 ? ~0 : 0;
|
|
mask[1] = ch1 ? ~0 : 0;
|
|
mask[2] = ch2 ? ~0 : 0;
|
|
mask[3] = ch3 ? ~0 : 0;
|
|
}
|
|
|
|
|
|
extern void
|
|
tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach,
|
|
unsigned num_bufs,
|
|
const void **bufs,
|
|
const unsigned *buf_sizes);
|
|
|
|
|
|
static INLINE int
|
|
tgsi_exec_get_shader_param(enum pipe_shader_cap param)
|
|
{
|
|
switch(param) {
|
|
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
|
|
case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
|
|
case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
|
|
case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
|
|
return INT_MAX;
|
|
case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
|
|
return TGSI_EXEC_MAX_NESTING;
|
|
case PIPE_SHADER_CAP_MAX_INPUTS:
|
|
return TGSI_EXEC_MAX_INPUT_ATTRIBS;
|
|
case PIPE_SHADER_CAP_MAX_CONSTS:
|
|
return TGSI_EXEC_MAX_CONST_BUFFER;
|
|
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
|
|
return PIPE_MAX_CONSTANT_BUFFERS;
|
|
case PIPE_SHADER_CAP_MAX_TEMPS:
|
|
return TGSI_EXEC_NUM_TEMPS;
|
|
case PIPE_SHADER_CAP_MAX_ADDRS:
|
|
return TGSI_EXEC_NUM_ADDRS;
|
|
case PIPE_SHADER_CAP_MAX_PREDS:
|
|
return TGSI_EXEC_NUM_PREDS;
|
|
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
|
|
return 1;
|
|
case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
|
|
case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
|
|
case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
|
|
case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
|
|
return 1;
|
|
case PIPE_SHADER_CAP_SUBROUTINES:
|
|
return 1;
|
|
case PIPE_SHADER_CAP_INTEGERS:
|
|
return 1;
|
|
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
|
|
return PIPE_MAX_SAMPLERS;
|
|
case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#if defined __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
#endif /* TGSI_EXEC_H */
|