My favorites | Sign in
fog
Project Home Downloads Wiki Issues Source
Search
for
Design_Shaders  
Design and implementation of Fog-SL - Fog Shader Language.
Phase-Design
Updated Sep 9, 2010 by mike.taj...@gmail.com

Introduction

This document contains design and implementation notes of incoming 2d shaders module. It should cover the shader language, all functionality and possibility for future extensions to improve the performance.

Shader Assembly Language

Their are many variations of shader assembly language:

  • !!ARBvp
  • !!NVvp
  • !!ARBcp
  • !!NVfp
  • !!NVgp4
  • others

We are starting with the !!ARBfp1.0 syntax.

We imagine that shaders may be built with assembly, or generated via Cg.

Language

Scalar variable types:

  • bool (32-bit integer type)
  • float (32-bit floating point type)
  • int (32-bit integer type)

Vector variable types:

  • bool2, bool3, bool4
  • float2, float3, float4
  • int2, int3, int4
  • Each variable type can be vector of 2, 3 or 4 elements. Vectors are normally accessed through:
    • 0 - x, r
    • 1 - y, g
    • 2 - z, b
    • 3 - w, a
  • Notice that for compatibility with opengl shaders we are using RGBA, in standard Fog API the ARGB notation is used instead.

Mike: I am not sure if the array braces syntax is available for !!ARBfp1.0. I now think that the array braces are used exclusively for PARAM array and program variable access operations.

Shader Assembly Language Quick Reference Guild.

Structures:

  • Structure definition similar to C, using DOT (.) to access members. There is not possibility to make vectorized structure.

Control Flow

I think that basic control flow blocks should be supported. I'm not sure about loops, but I'm sure about IFs.

Fog Shader Extensions / Hints

It is needed to define some hints that will allow us to generate integer only code, instead of floating point code. Nearly all graphics operations are currently in integer only math and there must be possibility to do that in shaders too (to fit into pipeline the Fog can generate).

We can include typedef extension (for example called pixel) which can be used instead of int or float. For 8-bit pixel formats the width of the pixel type must be 16 bits and for 16-bit formats it must be 32, because the pixel value can be multiplied by other pixel value, dividing it later by 255 or 65535 to match floating point implementation.

The following code should work with 8-bit pixels, 16-bit pixels and 32-bit pixels (floats). If the engine will locate pixel type then this will be signal that implementation is generic and doesn't need floating point unit.

pixel4 shader(pixel4 dst, pixel4 src)
{
  pixel4 result = dst * src;
  return result;
}

Fog-SL Program Type

At this time there are only two program types:

  • Composite Shader - Shader which can do composition of source pixels with destination pixels. The resulting pixels are written into destination pixels or someewhere else (this depends to Fog pipiline used). Result = program(dst, src)
  • Source Shader - Shader that is responsible for generating source pixels (any pattern you can describe mathematically).

Fog-SL Program Structure

Composite Shader:

pixel4 shader(pixel4 dst, pixel4 src)
{
  pixel4 result;
  ...
  return result;
}

Source Shader:

pixel4 source()
{
  pixel4 result;
  ...
  return result;
}

Portability with OpenGL

This document should reveal all portability issues. The Fog-SL is defined to be shader language for 2d graphics, so for example we don't work with full 3d (4x4 matrix) transformations. The Fog-SL should be directly compilable into any language which can be executed by the GPU, so, this is reason why there are similar types and why there isn't loops.

Create Shader with Cg

Using the Windows or Linux Cg SDK:

CGprogram   myCgFragmentProgram;
myCgFragmentProgram = cgCreateProgram(
    myCgContext,                /* Cg runtime context */
    CG_SOURCE,                  /* Program in human-readable form */
    pcszCode,                   /* Cg Code */
    CG_PROFILE_ARBFP1,          /* Profile: ARBfp1.0 */
    pcszFuncName,               /* Entry function name */
    NULL);                      /* No extra compiler options */
    
const char *pcszARB = cgGetProgramString(myCgFragmentProgram, CG_COMPILED_PROGRAM);

// pcszARB now points to string of ARBfp1 Assembly Language

// Use the Code

// Cleanup
cgDestroyProgram(myCgFragmentProgram);

Project Details

This module (library) requires AsmJit for the code generator. The parser is built with yard (a public domain template based parsing library).

Parser Grammar

Yard is a templated parser. It is very easy to use, and understand. It is also public domain, so there are no licenses to worry about.

The Yard Parser library uses RTTI to discover what rule resolved by the parser. I decided to change this to remove the RTTI. Now, I use a static const int to identify the rule.

Some of the rules used:

struct ARBComment;

struct NewLine
: Or<CharSeq<'\r', '\n'>, CharSeq<'\n'> >
{		
};

This will match '\r\n' or '\n'.

struct WhiteSpace
: Star<Or<Char<' '>, Char<'\t'>, NewLine, ARBComment, Char<'\r'>, Char<'\v'>, Char<'\f'> > >
{
};

Note: these don't have a const int because I don't process them.

struct DecNumber
: Seq<Opt<Char<'-'> >, Plus<Digit>, Opt<Seq<Char<'.'>, Star<Digit> > >, NotAlphaNum, WhiteSpace>
{
RULE_TYPE(ARB_DecNumber);
};

#define RULE_TYPE(p) \
	static const int eType_ = p; \
	static int type() { return eType_; }	

This uses an enum with the rule names. In the Match method, this is used to figure out what rule satisfied the input.

Code Generator

TBC

External API

TBC


Sign in to add a comment
Powered by Google Project Hosting