Cg and the GPU - Gammeter.com

gradebananaΛογισμικό & κατασκευή λογ/κού

2 Δεκ 2013 (πριν από 3 χρόνια και 6 μήνες)

72 εμφανίσεις

Old
-
school,
General
Purpose Use
of the GPU
for
Everything,
But …


Originally, Customizable Shaders were
Written in Assembly or a Specialized Vector
Languages.


C for Graphics is a high
-
level GPU shader
language designed, developed and
implemented by NVIDIA.


Simple C Syntax compiles out to assembly,
GLSL or HLSL code, in various formats, for
many versions of DirectX and OpenGL.



Constructors, e.g. float4 v = float4(
a,b,c,d
);


Array Operator, e.g. v[0], v[1], v[2], or v[3]


Swizzle Operator Can Reorder Data:


e.g. v.xyz,
v.xxxz
, v.yyx,
v.yx
,
v.xyzw


Replaceable with
rgba

instead of
xyzw


Vectorized

Primitives: float2, float3, float4


16
-
bit Floating Point Constructs: half, half2, …


Fixed Precision Decimals: fixed, fixed2, …



Matrices are Compounded Vector Classes,
e.g. float4x4, and are Constructed with
multiple vectors


float4 v = float4(
a,b,c,d
);


float4x4 m = float4x4(
v,v,v,v
);


Samplers Texture Data Type


sampler1D, sampler2D,
samplerRECT
, sampler3D


samplerRECT
: Same as sampler2D but uses pixel
locations as texture coordinates instead of [0,1]

struct

C2E1v_Output

{


float4 position : POSITION;


float4 color : COLOR;

};


C2E1v_Output C2E1v_green(float2 position : POSITION)

{


C2E1v_Output OUT;


OUT.position

= float4(position, 0, 1);


OUT.color

= float4(0, 1, 0, 1); // RGBA green


return OUT;

}

struct

C2E2f_Output

{


float4 color : COLOR;

};


C2E2f_Output C2E2f_passthrough(float4 color : COLOR)

{


C2E2f_Output OUT;


OUT.color

= color;


return OUT;

}

CPU

GPU

CPU

GPU

void

shScene
::
GPU_CreateTextureDataForModel
(
shObject

*
oi

) {


// determine the texture dimensions


modelTexColumnCount

=
numDataFromModel
*
floatArraySize
;


//formalize the texture's
modelHeight

and
modelWidth


modelWidth

=
numDataFromModel
;
//number of data pieces to store wide


modelHeight

=
oi
-
>
NList.size
;
//number of nodes to store high


modelTexSize

=
modelWidth
*
modelHeight
*
floatArraySize
;


textureData

=
new

float
[
modelTexSize
];


//Copy all the data from the cloth to the texture


int

i

= 0;


float

* position =
new

float

[
floatArraySize
];


float

* velocity =
new

float

[
floatArraySize
];


for
( node *
currentNode

=
oi
-
>
NList.head
;
currentNode

!= NULL;


currentNode

=
currentNode
-
>next ) {


currentNode
-
>
getPosition
(position);

//Model Data: 0
-
pos, 1
-
force, 2
-
vel


for
(
int

j = 0; j <
floatArraySize
; j++ ) {


textureData
[
i+j
] = position[j];


textureData
[
i+j+floatArraySize
] = 0.0f;
//force


textureData
[i+j+2*
floatArraySize
] = 0.0f;


}


i
+=
modelTexColumnCount
;


}


free(position);

}

void

shScene
::
GPU_ExecuteGPGPU
(
CGprogram

fragmentProgram
,
GLuint

springData
,
int

springIndex

)

{


//Prepare Frame Buffer Object (FBO)


glBindFramebufferEXT
( GL_FRAMEBUFFER_EXT,
GPUFrameBuffer

);


if
(
texSwap

) {
// Bind output texture


glDrawBuffer
( GL_COLOR_ATTACHMENT1_EXT );


}
else {

// Bind output texture


glDrawBuffer
( GL_COLOR_ATTACHMENT0_EXT );


}


// get ready to run this specific fragment program


cgGLBindProgram
(
fragmentProgram
);


cgGLEnableProfile
(
cgFragmentProfile
);


// Create and enable the TEXTURE parameter for the fragment program


cgTexture0 =
cgGetNamedParameter
(
fragmentProgram
,
"
modelData
"
);


if
(
texSwap

){


cgGLSetTextureParameter
(cgTexture0,


m_imageLoader
-
>
m_itexNum
[GPU_Data_Texture_0]);


}
else {


cgGLSetTextureParameter
(cgTexture0,


m_imageLoader
-
>
m_itexNum
[GPU_Data_Texture_1]);


}


cgGLEnableTextureParameter
(cgTexture0);


[
continued below …
]


}

void

shScene
::
GPU_ExecuteGPGPU
(
CGprogram

fragmentProgram
,
GLuint

springData
,


int

springIndex

)

{

[
continued from above …
]


//enable additional custom options


if
(
fragmentProgram

==
cgCalculateSpringForcesOnGPU

) {


// Create and enable the STANDARD parameters for the fragment program


cgTextureSpringIndex

=
cgGetNamedParameter
(
fragmentProgram
,
"
springIndex
"
);


cgGLSetParameter1f(
cgTextureSpringIndex
,
springIndex
);


// Create and enable the TEXTURE parameter for the fragment program


cgTexture1 =
cgGetNamedParameter
(
fragmentProgram
,
"
springData
"
);


cgGLSetTextureParameter
(cgTexture1,
m_imageLoader
-
>
m_itexNum
[
springData
]);


cgGLEnableTextureParameter
(cgTexture1);


}
else

if
(
fragmentProgram

==
cgUpdateVelocityOnGPU

) {


// Create and enable the STANDARD parameters for the fragment program


cgEnforceFixedNode

=
cgGetNamedParameter
(
fragmentProgram
,
"
enforceFixed
"
);


//static for now, make this dynamic later


cgGLSetParameter1f(
cgEnforceFixedNode
, 1.0f);


}


// Render the Texture to the Buffer on a Simple Quad


GPU_WriteQuadAndTextureToBuffer
(
modelWidth
,
modelHeight
);



// Disable the Texture Parameter for this specific Fragment Program


cgGLDisableTextureParameter
(cgTexture0);



if
(
fragmentProgram

==
cgCalculateSpringForcesOnGPU

)


cgGLDisableTextureParameter
(cgTexture1);


cgGLDisableProfile
(
cgFragmentProfile
);


texSwap

= !
texSwap
;

}

//Fragment Program used to add gravity force to Y force vector

Fragment_Output

CalculateGravityForcesOnGPU
(


float2
textCoord

: TEXCOORD0, uniform
samplerRECT

modelData

)

{


//simply pass the data through if not force fragment


Fragment_Output

OUT;


OUT.color

=
texRECT
(
modelData
,
textCoord

);


//Model Data: 0
-
position, 1
-
force, 2
-
velocity


if
(
CorrectFragment
(
textCoord.x
, FORCE_5f ) )


{


//we are at the force position, index set by adding 2


OUT.color

+= MASS*
gravityVector
;
//F=MA


}


return

OUT;

}


void

shScene
::
GPU_RestoreDataFromTexture
(
shObject

*
oi

)

{


glBindFramebufferEXT
( GL_FRAMEBUFFER_EXT, 0 );

//Restore render buffer


float

* texture =
new

float
[
modelTexSize
];


if
( RESET_MODEL ) {
// Reset texture data on the graphics card with original text


glBindTexture
( GL_TEXTURE_RECTANGLE_NV,


m_imageLoader
-
>
m_itexNum
[
GPU_Data_Texture_RESET
] );


RESET_MODEL =
false
;
//our damage is done here


}
else

{


glBindTexture
( GL_TEXTURE_RECTANGLE_NV,


m_imageLoader
-
>
m_itexNum
[GPU_Data_Texture_1] );


}


glGetTexImage
( GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB, GL_FLOAT, texture );


resize(
m_iwidth
,
m_iheight
);

// Change to PROJ


float

* position =
new

float

[
floatArraySize
];


for
( node *
currentNode

=
oi
-
>
NList.head
;
currentNode

!= NULL;


currentNode

=
currentNode
-
>next ) {


for
(
int

j = 0; j <
floatArraySize
; j++ ) {


position[j] = texture[
i+j
];


}


currentNode
-
>
setPosition
(position);


i
+=
modelTexColumnCount
;


}


glDisable
(GL_FRAGMENT_PROGRAM_NV);

//Disable our Custom GPU Rendering


glDisable
(GL_TEXTURE_RECTANGLE_NV);

}