programação em gpus (opengl/glsl cuda)

101
11 de maio de 2 022 Programação em GPUs (OpenGL/GLSL CUDA) Yalmar Ponce

Upload: brody-ayers

Post on 02-Jan-2016

33 views

Category:

Documents


0 download

DESCRIPTION

Programação em GPUs (OpenGL/GLSL CUDA). Yalmar Ponce. Roteiro. Introdução Tipos de dados, Estruturas, Funções Shaders Exemplos Luz (Direcional, Pontual, Spot) Efeitos (Parede de Tijolos, Madeira, Desenho animado) Modificando Geometria Textura e Multitextura Shader de Geometria Exemplos - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programação em GPUs (OpenGL/GLSL CUDA)

20 de abril de 2023

Programação em GPUs(OpenGL/GLSL

CUDA)

Yalmar Ponce

Page 2: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Roteiro

IntroduçãoTipos de dados, Estruturas, Funções

Shaders Exemplos

Luz (Direcional, Pontual, Spot)Efeitos (Parede de Tijolos, Madeira, Desenho animado)Modificando Geometria

Textura e Multitextura Shader de Geometria

Exemplos

FBO CUDA Projeto Final

Mapeamento de Sombra (Shadow mapping)

Page 3: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Introdução

AplicaçõesRenderização em tempo realEfeitosJogos

Page 4: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Introdução

GPUs são rápidas...3.0 GHz Intel Core Extreme

96 GFLOPS – pico Memory Bandwidth: 13 GB/s Preço: 800~ dólares

NVIDIA GeForce GTX 280:930 GFLOPS Memory Bandwidth: 141 GB/sPreço: 499 dólares

Page 5: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Introdução

Versão simplificada da pipeline

GPUCPU

ApplicationApplication Transform& Light

Transform& Light RasterizeRasterize ShadeShade Video

Memory(Textures)

VideoMemory

(Textures)

Xfo

rmed, Lit V

ertice

s (2

D)

Graphics State

Render-to-texture

AssemblePrimitivesAssemblePrimitives

Vertice

s (3

D)

Scre

ensp

ace

triangle

s (2

D)

Fra

gm

ents (p

re-p

ixels)

Fin

al P

ixels (C

olo

r, D

epth

)

Page 6: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Introdução

Processador deVértices Programável

GPU

Transform& Light

Transform& Light

CPU

ApplicationApplication RasterizeRasterize ShadeShade VideoMemory

(Textures)

VideoMemory

(Textures)

Xfo

rmed, Lit V

ertice

s (2

D)

Graphics State

Render-to-texture

AssemblePrimitivesAssemblePrimitives

Vertice

s (3

D)

Scre

ensp

ace

triangle

s (2

D)

Fra

gm

ents (p

re-p

ixels)

Fin

al P

ixels (C

olo

r, D

epth

)

FragmentProcessorFragmentProcessor

VertexProcessor

VertexProcessor

Processador defragmentosProgramável

Page 7: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Introdução

Geração de geometria programável

GPUCPU

ApplicationApplication VertexProcessor

VertexProcessor RasterizeRasterize Fragment

ProcessorFragmentProcessor

VideoMemory

(Textures)

VideoMemory

(Textures)

Xfo

rmed, Lit V

ertice

s (2

D)

Graphics State

Render-to-texture

Vertice

s (3

D)

Scre

ensp

ace

triangle

s (2

D)

Fra

gm

ents (p

re-p

ixels)

Fin

al P

ixels (C

olo

r, D

epth

)

AssemblePrimitivesAssemblePrimitives

GeometryProcessorGeometryProcessor

Acesso a memória mais flexível

Page 8: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Shaders são programas que executam em determinadas etapas do pipeline

Não são aplicações stand-alone

Necessitam de uma aplicação que utilize um API (OpenGL ou Direct3D)

Page 9: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

No caso:Vertex shader – Vertex ProcessorFragment shader – Fragment ProcessorGeometry shader – Geometry Processor

Page 10: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Vertex ProcessorTransforma do espaço de mundo para o espaço de telaCalcula iluminação per-vertex

Page 11: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Geometry ProcessorComo os vértices se conectam para formar a geometriaOperações por primitiva

Page 12: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Fragment ProcessorCalcula a cor de cada pixelObtém cores de texturas

Page 13: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Hoje a programação de shaders é feita em linguagens de alto nível

No estilo de c/c++

As principais que temos hoje:GLSL – OpenGL Shader LanguageHLSL – High Level Shader LanguageCg – C for Graphics

Page 14: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Temos algumas ferramentas que servem tanto para criação e edição de shaders:

NVIDIA FX Composer 2.5RenderMonkey ATI

Page 15: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Page 16: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Shaders

Page 17: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Tipos de dados

Estruturas bem intuitivas

Vetores:vec2, vec3 e vec4 – floating pointivec2, ivec3 e ivec4 – intergerbvec2, bvec3 e bvec4 – boolean

Matrizesmat2, mat3 e mat4 – floating point

Page 18: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Tipos de dados

TexturasSampler1D, Sampler2D, Sampler3D -

texturas 1D, 2D e 3DSamplerCube – Cube map texturesSampler1Dshadow, Sampler2DShadow –

mapa de profundidade 1D e 2D

Page 19: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Existem 3 tipos de input em um shader:UniformsVaryingsAttributes

Page 20: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

UniformsNão mudam durante o renderingEx: Posição da luz ou cor da luzEsta presente em todos os tipos de shader

VaryingsUsado para passar dados do vertex shader para o

fragment shader ou geometry shader

Page 21: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

VaryingsSão read-only no fragment e geometry shader mas

read/write no vertex shaderDeve-se declarar a mesma varying em todos os

programas

AttributesEstão presentes apenas nos Vertex shadersSão valores (possivelmente diferentes) associados a cada

vértice

Page 22: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

AttributesEx: Posição do vértice ou normaisSão apenas read-only

Page 23: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Exemplos de Attributes no vertex shadergl_Vertex – vetor 4D, posição do vérticegl_Normal – vetor 3D, Normal do vérticegl_Color – vetor 4D, cor do vérticegl_MultiTexCoordX – vetor 4D, coordenada de textura na

unit X

Existem vários outros atributos

Page 24: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Exemplos de Uniforms gl_ModelViewMatrixgl_ModelViewProjectionMatrixgl_NormalMatrix

Page 25: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Exemplos de Varyings gl_FrontColor - vetor 4D com a cor frontal das primitivasgl_BackColor – vetor 4D com a cor de trás das primitivasgl_TexCoord[N] – vetor 4D representando a n-ésima

coordenada de textura

Page 26: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Exemplos de output:gl_Position – vetor 4D representando a posição final do

vérticegl_FragColor – vetor 4D representando a cor final que

será escrita no frame buffergl_FragDepth – float representando o depth que será

escrito do depth buffer

Page 27: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Também é possível definir attributes, uniforms e varyings

Ex: Passar um vetor tangente 3D por todos os vértices da sua aplicação

É possível especificar o atributo “tangente”attribute vec3 tangente;

Page 28: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Input/Output

Alguns outros exemplos:uniform sampler2D my_color_texture; varying vec3 vertex_to_light_vector; varying vec3 vertex_to_eye_vector; attribute vec3 binormal;

Page 29: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Funções e Estruturas de Controle

Similar a linguagem C

Suporta estruturas de repetição e decisãoIf/elseForDo/whileBreakContinue

Page 30: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Funções e Estruturas de Controle

Possui funções como:Seno (sin)Cosseno (cos)Tangente (tan)Potencia (pow)Logaritmo (log)Logaritmo (log2)Raiz (sqrt)

Page 31: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

GLSL-Setup

Antes de criar os shaders é necessário implementar uma função (no caso do GLSL) para ler e enviar os shaders para o hardware

Page 32: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

GLSL-Setup

void setShaders(){char *vs = NULL,*fs = NULL,*fs2 = NULL;

v = glCreateShader(GL_VERTEX_SHADER);f = glCreateShader(GL_FRAGMENT_SHADER);

vs = textFileRead("minimal.vert");fs = textFileRead("minimal.frag");

const char * vv = vs;const char * ff = fs;

glShaderSource(v, 1, &vv,NULL);glShaderSource(f, 1, &ff,NULL);

free(vs);free(fs);

glCompileShader(v);glCompileShader(f);

p = glCreateProgram();glAttachShader(p,v);glAttachShader(p,f);

glLinkProgram(p);glUseProgram(p);

}

Page 33: Programação em GPUs (OpenGL/GLSL CUDA)

20 de abril de 2023

Exemplos simples

Page 34: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Hello World

O código shader mais simplesVertex Shadervoid main() {

gl_Position = ftransform();

} Fragment Shadervoid main(){

gl_FragColor = vec4(0.4,0.4,0.8,1.0);

}

Page 35: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Modificando a geometria

Achatar o modelo 3D, ou seja, z = 0void main(void) {

vec4 v = vec4(gl_Vertex);v.z = 0.0;

gl_Position = gl_ModelViewProjectionMatrix * v;}

Page 36: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Modificando a geometria II

void main(void){

vec4 v = vec4(gl_Vertex);

v.z = sin(5.0*v.x )*0.25;

gl_Position = gl_ModelViewProjectionMatrix * v;

}

Page 37: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Animação

É necessário manter a passagem do tempo nos frames

No vertex shader não é possível guardar valores a variável é definida na aplicação OpenGL

Page 38: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Animação

O shader recebe o valor time numa variável Uniform

uniform float time;

void main(void){

vec4 v = vec4(gl_Vertex);

v.z = sin(5.0*v.x + time*0.01)*0.25;

gl_Position = gl_ModelViewProjectionMatrix*v;

}

A função de render:

void renderScene(void){

...

glUniform1fARB(loc, time);

glutSolidTeapot(1);

time+=0.01;

glutSwapBuffers();

}

Page 39: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Manipulação de Texturas

GLSL permite acesso as coordenadas de textura por vértice

GLSL provê variáveis do tipo Attribute, para cada unidade de textura (max 8)

attribute vec4 gl_MultiTexCoord[0..8]

Page 40: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Manipulação de Texturas

Precisa calcular a coordenada de textura

Armazenar numa variável varying gl_TexCoord[i] onde i é a unidade de textura utilizada

gl_TexCoord[0] = gl_MultiTexCoord0;

Um simples código para definir coordenadas de textura para uma textura utilizando a unit 0

Vertex Shadervoid main(){

gl_TexCoord[0] = gl_MultiTexCoord0;

gl_Position = ftransform();

}

Page 41: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Manipulação de Texturas

gl_TexCoord é uma variável varying

Será utilizada no fragment shader para acessar as coordenadas de textura interpoladas

Para acessar os valores de textura temos que declarar uma variável do tipo uniform no fragment shader

Para uma textura 2D temos:uniform sampler2D tex;

Page 42: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Manipulação de Texturas

A função que nos retorna um textel é a texture2D

Os valores retornados levam em consideração todos as definições de textura feitos no OpenGL (filtering, mipmap, clamp, etc)

Page 43: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Manipulação de Texturas

Vertex Shadervoid main(){

gl_TexCoord[0] = gl_MultiTexCoord0;

gl_Position = ftransform();

}

Fragment shaderuniform sampler2D tex;

void main() {

vec4 color = texture2D(tex,gl_TexCoord[0].st);

gl_FragColor = color;

}

Page 44: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Múltiplas Texturas

Definir as texturasglGenTextures(1, &Textura); glBindTexture(GL_TEXTURE_2D, Textura); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, level, format, Width, Height, 0, GL_RGB,GL_UNSIGNED_BYTE, TexureInfo);

Na aplicação OpenGL, é necessário habilitar as texturas que serão usadas.glActivateTexture(GL_TEXTUREi) onde i = 0..8

Page 45: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Múltiplas Texturas

Multi TexturingglEnable (GL_TEXTURE_2D);glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texid0);

glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texid1);

...

glBegin(GLenum Mode);...

glEnd();

glDisable (GL_TEXTURE_2D);

Page 46: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

GLSL e Multi-Textura

Cada textura que será usada no programa GLSL deve ser associada a uma textura na aplicação OpenGL.

Vertex/Fragment Shaderuniform sampler2D textureName1, textureName2;

Programa OpenGL (inicialiazação)GLuint tex1, tex2; GLint texLoc1, texLoc2; texLoc1 = glGetUniformLocation(programObj, "textureName1");texLoc2 = glGetUniformLocation(programObj, "textureName2");glUniform1i(texLoc1, 0); // a primeira deve ser 0glUniform1i(texLoc2, 1);

Programa OpenGL ( ativar multitextura)glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); // habilita para uso tex1 glActiveTexture(GL_TEXTURE1); // habilita para uso tex2

drawQuad();

Note que a textura atribuída com a função glUniform1i(texLoc1, i) i = 0, 1, ... deve ser ativada com glActiveTexture(GL_TEXTUREi) antes de usar um programa GLSL

Page 47: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Textura 3D

glGenTextures(1, &TexName);glBindTexture(GL_TEXTURE_3D, TexName);       glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, TexSize, TexSize, TexSize,

0, GL_RGBA,GL_UNSIGNED_BYTE, data);

Page 48: Programação em GPUs (OpenGL/GLSL CUDA)

20 de abril de 2023

Exemplos mais complexos

Page 49: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Efeito tijolo

Vertex Shaderhttp://www.3dshaders.com/shaders

2ndEd/CH06-brick.vert.txt

Fragment Shaderhttp://www.3dshaders.com/shaders

2ndEd/CH06-brick.frag.txt

Page 50: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Effeito madeira

Vertex Shaderhttp://www.3dshaders.com/

shaders2ndEd/CH15-wood.vert.txt

Fragment Shaderhttp://www.3dshaders.com/

shaders2ndEd/CH15-wood.frag.txt

Page 51: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Efeito nuvem

Vertex Shaderhttp://www.3dshaders.

com/shaders2ndEd/CH15-cloud.vert.txt

Fragment Shaderhttp://www.3dshaders.com/sha

ders2ndEd/CH15-cloud.frag.txt

Page 52: Programação em GPUs (OpenGL/GLSL CUDA)

20 de abril de 2023

Geometry Shader

Page 53: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Geometry Shader Permite mudar a geometria de entrada

Necessário especificar a geometria de entrada e saidaglProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_INPUT_TYPE_EXT, GL_LINES_ADJACENCY_EXT);

glProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP);

Adicionalmente deve ser especificado o número máximo de vértices a serem criadosglGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp);

glProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_VERTICES_OUT_EXT,temp);

Page 54: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Geometry Shader Convenções

#version 120 #extension GL_EXT_geometry_shader4 : enable

Geometry language built-in outputs:varying out vec4 gl_FrontColor;varying out vec4 gl_BackColor;varying out vec4 gl_FrontSecondaryColor;varying out vec4 gl_BackSecondaryColor;varying out vec4 gl_TexCoord[]; // at most gl_MaxTextureCoordsvarying out float gl_FogFragCoord;

Geometry language input varying variables:varying in vec4 gl_FrontColorIn[gl_VerticesIn];varying in vec4 gl_BackColorIn[gl_VerticesIn];varying in vec4 gl_FrontSecondaryColorIn[gl_VerticesIn];varying in vec4 gl_BackSecondaryColorIn[gl_VerticesIn];varying in vec4 gl_TexCoordIn[gl_VerticesIn][]; varying in float gl_FogFragCoordIn[gl_VerticesIn];varying in vec4 gl_PositionIn[gl_VerticesIn];varying in float gl_PointSizeIn[gl_VerticesIn];varying in vec4 gl_ClipVertexIn[gl_VerticesIn];

Page 55: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Exemplo#version 120#extension GL_EXT_geometry_shader4:enable#extension GL_EXT_gpu_shader4:enable

varying out vec3 eyeNormal;varying out vec3 vNormal;varying out vec3 eyePosition;varying out vec3 LightPosition;

void main(void){ vec4 v = gl_PositionIn[0]; LightPosition = gl_LightSource[0].position; vec4 p0 = texture2D(vtx_tex, getPos(v.x)); vec4 p1 = texture2D(vtx_tex, getPos(v.y)); vec4 p2 = texture2D(vtx_tex, getPos(v.z)); vec4 p3 = texture2D(vtx_tex, getPos(v.w));

...

...

eyeNormal = n0; vNormal = vn0; eyePosition = py0; gl_Position = pt0; EmitVertex(); vNormal = vn1; eyePosition = py1; gl_Position = pt1; EmitVertex(); vNormal = vn2; eyePosition = py2; gl_Position = pt2; EmitVertex();

vNormal = vn2; eyePosition = py2; gl_Position = pt2; EmitVertex();

EndPrimitive(); }

Page 56: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Exemplo#version 120#extension EXT_gpu_shader4 : require

varying vec3 eyeNormal;varying vec3 vNormal;varying vec3 eyePosition;varying vec3 LightPosition;

void main() { vec3 light = normalize( LightPosition ); vec3 r = reflect( eyePosition, eyeNormal)*0.5; vec3 red = vec3( 0.23, 0.52, 0.72); const vec3 white = vec3( 1, 1, 1); float ndotl = max(dot( eyeNormal, light), 0.0); if (ndotl == 0.0) ndotl = dot( eyeNormal, -light); ndotl = min( max( ndotl, 0.0) + 0.2, 1.0); float spec = pow( max( 0.0, dot( r, light)), 32.0); vec3 color = clamp( ndotl*red + spec*white, 0.0, 1.0); gl_FragColor = vec4( color, 1.0); }

Page 57: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Conclusões

Diversos tipos de aplicações

Page 58: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Conclusões

Page 59: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Classe C++ para o Setup GLSLLCG Toolkit

http://code.google.com/u/andmax/

Page 60: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Exemplo de uso#include "glslkernel.h“

GLSLKernel VBOShader;

VBOShader.vertex_source("vertex.glsl");VBOShader.geometry_source("geometry.glsl");VBOShader.fragment_source("fragment.glsl");VBOShader.set_geom_max_output_vertices(12);VBOShader.set_geom_input_type(GL_POINTS);VBOShader.set_geom_output_type(GL_TRIANGLE_STRIP);VBOShader.install(true);VBOShader.use(true);VBOShader.set_uniform("vtx_tex", 0);

VBOShader.use(true);glDrawElements( GL_POINTS, n_points, GL_UNSIGNED_INT, 0);VBOShader.use(false);

Page 61: Programação em GPUs (OpenGL/GLSL CUDA)

20 de abril de 2023

Framebuffers

Page 62: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Frame bufferFrame buffer

Escrita em memória é feito pelo processador de fragmentos

Memória GPU apenas de escrita

Vertex BufferVertex

ProcessorRasterizer

FragmentProcessor

Texture

Frame Buffer(s)

VS 3.0 GPUs

Page 63: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 63

OpenGL Framebuffer OpenGL Framebuffer ObjectsObjects Ideia Geral

Framebuffer object pode ser visto como uma estrutura de ponteiros

Associar memória da GPU a um framebuffer como write-only

A memória não pode ser lida enquanto estiver associada ao framebuffer

Qual memória? Texture Renderbuffer Vertex buffer??

Texture(RGBA)

Renderbuffer(Depth)

FramebufferObject

Page 64: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 64

Framebuffer ObjectsFramebuffer Objects

O que é um FBO? Uma estrutura que manipula ponteiros e objetos

memória Cada objeto memória associado pode ser usado

como um framebuffer para rendering

Page 65: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 65

Framebuffer Objects (FBOs)Framebuffer Objects (FBOs)

OpenGL extension Habilita render-to-texture in OpenGL Mix-and-match depth/stencil buffers Substitui pbuffers! Platform-independent

http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt

Page 66: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 66

Framebuffer ObjectsFramebuffer Objects

Quais tipos de memória podem ser associados a um FBO? Textures Renderbuffers

Depth, stencil, color Framebuffers de escrita tradicionais

Page 67: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 67

Que é um Renderbuffer?Que é um Renderbuffer?

Modelo “Traditional” de memória framebuffer Memória GPU Write-only

Color buffer Depth buffer Stencil buffer

Novo objeto de memória OpenGL Parte do Framebuffer Object extension

Page 68: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 68

RenderbufferRenderbuffer

Operações suportadas CPU interface

Allocate Free Copia GPU CPU Associar para acesos write-only no framebuffer

Page 69: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 69

Framebuffer ObjectsFramebuffer Objects

Modo de uso Pode ter N texturas associadas a um FBO (até 16)

destinos de rendering são cambiados com glDrawBuffers

Manter uma FBO para cada tamanho/formato Mudar destinos de rendering

attach/unattach textures

Pode ter diferentes FBOs com texturas vinculadas Mudar destinos de rendering ligando (bind) FBOs

Page 70: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 70

Framebuffer ObjectsFramebuffer Objects

Performance Render-to-texture

glDrawBuffers

Mais eficientes que pbuffers Attach/unattach texturas é mais eficiente que mudar de

FBO

Manter formato/tamanho idêntico para todas as memórias associadas ao FBO

Readback glReadPixels

Page 71: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 71

Framebuffer ObjectFramebuffer Object

Exemplos e maiores detalhes Classes C++ de FBO e Renderbuffer

http://gpgpu.sourceforge.net/

OpenGL Spechttp://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt

Page 72: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 72

Pixel Buffer ObjectsPixel Buffer Objects

Mecanismo eficiente para transferir pixel data API parecido com vertex buffer objects

Vertex BufferVertex

ProcessorRasterizer

FragmentProcessor

Texture

Frame Buffer(s)

VS 3.0 GPUs

Page 73: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 73

Pixel Buffer ObjectsPixel Buffer Objects

Usos Render-to-vertex-array

glReadPixels no GPU-based pixel buffer Usar pixel buffer como vertex buffer

Streaming de textures rápido Mapear PBO na memória da CPU Escrever diretamente ao PBO Reduz uma ou mais cópias

Readback asincrono Cópia de dados GPU CPU não-bloqueante glReadPixels no PBO não bloqueiado É bloqueiado quando PBO é mapeiado na memória da CPU

Page 74: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Resumo : Render-to-TextureResumo : Render-to-Texture

Operação básica em apps GPGPU

Suporte OpenGL Valores de 16, 32-bit por pixel

Multiple Render Targets (MRTs) e Copy-to-texture glCopyTexSubImage

Render-to-texture GL_EXT_framebuffer_object

Page 75: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 75

Resumo : Render-To-Vertex-ArrayResumo : Render-To-Vertex-Array

Habilita retro-alimentação

Suporte OpenGL Copy-to-vertex-array

GL_ARB_pixel_buffer_object NVIDIA e ATI

Render-to-vertex-array Não disponível

Page 76: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 76

Estruturas de dados básicas na GPUEstruturas de dados básicas na GPU

“Implementing Efficient Parallel Data Structures on GPUs” Chapter 33, GPU Gems II

Low-level details

Page 77: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 77

GPU ArraysGPU Arrays

Large 1D Arrays Limite das GPUs em array 1D até 2048 ou 4096 Empacotados em memória 2D Precisa de mapear o endereço 1D-to-2D

Page 78: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023 78

GPU ArraysGPU Arrays

3D Arrays Problem

GPUs não possuem 3D frame buffers Soluções

1. Empilhar fatias 2D

2. Múltiplas fatias de buffers 2D

3. Render-to-slice-of-3D-texture (NVidia G8)

Page 79: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Exemplo: Simulação de Tecido

Integration de Verlet Jakobsen, GDC 2001

Evita guardar velocidade explicita new_x = x + (x – old_x)*damping + a*dt*dt

Não é exato, mas sim estável!

Precisa guardar a posição atual é a anterior para cada partícula 2 RGB float textures

O Fragment shader calcula a nova posição e escreve o resultado em outra textura textura (float buffer)

Logo, intercambia as texturas atual e anterior

Page 80: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Algoritmo

Requer de 4 passos A cada passo renderiza uma quad com o fragment

shader: 1.Executa a integração (move as partículas) 2.Aplica restrições (constraints):

Restrição de distância entre partículas Colisão com os obstáculos (piso, esfera)

3.Calcula as normais 4. Renderiza a malha do tecido usando VBO

Page 81: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Código da Integraçãouniform sampler2DRect oldp_tex;uniform sampler2DRect currp_tex;

// Verlet integration stepvoid Integrate(inout vec3 x, inout vec3 oldx, vec3 a, float timestep2){ vec3 tmpx = x; x = 2*x - oldx + a*timestep2; oldx = tmpx;}

void main(){ float timestep = 0.02; vec3 gravity = vec3(0.0, -9.8, 0.0);

vec2 uv = gl_TexCoord[0].st;

// get current and previous position vec3 oldx = texture2DRect(oldp_tex, uv).rgb; vec3 x = texture2DRect(currp_tex, uv).rgb;

// move the particle Integrate(x, oldx, gravity, timestep*timestep);

gl_FragColor = vec4(x, 1.0);}

Page 82: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Código das restriçõesvoid main(){ const float stiffness = 0.2; // this should really be 0.5 vec2 uv = gl_TexCoord[0].st; vec3 x = texture2DRect(x_tex, uv).rgb; // get current position x = clamp(x, worldMin, worldMax); // satisfy world constraints SphereConstraint(x, spherePos, 1.0); // collision constraint with the sphere

// get positions of neighbouring particles vec3 x1 = texture2DRect(x_tex, uv + vec2(1.0, 0.0)).rgb; vec3 x2 = texture2DRect(x_tex, uv + vec2(-1.0, 0.0)).rgb; vec3 x3 = texture2DRect(x_tex, uv + vec2(0.0, 1.0)).rgb; vec3 x4 = texture2DRect(x_tex, uv + vec2(0.0, -1.0)).rgb; vec3 x5 = texture2DRect(x_tex, uv + vec2(-1.0, -1.0)).rgb; vec3 x6 = texture2DRect(x_tex, uv + vec2(1.0, 1.0)).rgb;

// apply distance constraints vec3 dx = vec3(0.0); if (uv.x < meshSize.x) dx = DistanceConstraint(x, x1, dist, stiffness); if (uv.x > 0.5) dx = dx + DistanceConstraint(x, x2, dist, stiffness); if (uv.y < meshSize.y) dx = dx + DistanceConstraint(x, x3, dist, stiffness); if (uv.y > 0.5) dx = dx + DistanceConstraint(x, x4, dist, stiffness); if (uv.x > 0.5 && uv.y > 0.5) dx = dx + DistanceConstraint(x, x5, dist2, stiffness); if (uv.x < meshSize.x && uv.y < meshSize.y) dx = dx + DistanceConstraint(x, x6, dist2, stiffness);

x = x + dx; gl_FragColor = vec4(x, 1.0);}

Page 83: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Resultado

Page 84: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Objetos deformáveis

A abordagem massa-mola usada na simulação de tecido pode ser estendida para simular objetos deformáveis.

O objeto é representado por uma malha tetraédrica (sem slivers)

Define-se uma restrição de distância (constraint) para cada aresta da malha.

Cada vértice requer a lista de arestas incidentes (processo de relaxamento)

Page 85: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Objetos deformáveis

Page 86: Programação em GPUs (OpenGL/GLSL CUDA)

20 de abril de 2023

Introdução à API CUDA

Page 87: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

GeForce 6 Architecture

Page 88: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Unidades programáveis

Shader unificado

GeForce 8800 GPU

Page 89: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

GPU Architecture

Page 90: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

CUDA–C Sem limitações dos shaders!

Aplicações integradas host + device C program Partes serial e paralelo no código C host Partes totalmente em paralelo no código C device kernel C

Código Serial (host)

. . .

. . .

Kernel Paralelo (device)

KernelA<<< nBlk, nTid >>>(args);

Código Serial (host)

Kernel Paralelo (device)

KernelB<<< nBlk, nTid >>>(args);

Page 91: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Page 92: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Host

Kernel 1

Kernel 2

Device

Grid 1

Block(0, 0)

Block(1, 0)

Block(0, 1)

Block(1, 1)

Grid 2

Courtesy: NDVIA

Figure 3.2. An Example of CUDA Thread Organization.

Block (1, 1)

Thread(0,1,0)

Thread(1,1,0)

Thread(2,1,0)

Thread(3,1,0)

Thread(0,0,0)

Thread(1,0,0)

Thread(2,0,0)

Thread(3,0,0)

(0,0,1) (1,0,1) (2,0,1) (3,0,1)

IDs de Blocos e IDs de Threads

Cada thread usa IDs para decidir os dados com os que deve trabalhar Block ID: 1D ou 2D Thread ID: 1D, 2D, ou 3D

Memoria simplificada Endereçamento Dados multidimensionais

Page 93: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Visão geral do Modelo de Memória do CUDA

Memória Global Permite a comunicação de dados R/W entre host e device Visível a todos os threads Access não é rápido

Memória Constante

Memória compartilhada

Registradores locais

Grid

Global Memory

Block (0, 0)

Shared Memory

Thread (0, 0)

Registers

Thread (1, 0)

Registers

Block (1, 0)

Shared Memory

Thread (0, 0)

Registers

Thread (1, 0)

Registers

Host

Page 94: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

CUDA Exemplo: Multiplicação de matrizes – Versão Host simples em C

M

N

P

WID

TH

WID

TH

WIDTH WIDTH

void MatrixMulOnHost(float* M, float* N, float* P, int Width){ for (int i = 0; i < Width; ++i) for (int j = 0; j < Width; ++j) { double sum = 0; for (int k = 0; k < Width; ++k) { double a = M[i * width + k]; double b = N[k * width + j]; sum += a * b; } P[i * Width + j] = sum; }}

i

k

k

j

Page 95: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

void MatrixMulOnDevice(float* M, float* N, float* P, int Width){ int size = Width * Width * sizeof(float);

float* Md, Nd, Pd; // Allocate and Load M, N to device memory

cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size);

dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel<<<dimGrid, dimBlock>>>(Md, Nd, Pd, Width);

cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd);}

CUDA Exemplo: Multiplicação de matrizes – Versão GPU

Page 96: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

void MatrixMulOnDevice(float* M, float* N, float* P, int Width){ int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory

cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size);

dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel<<<dimGrid, dimBlock>>>(Md, Nd, Pd, Width);

cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd);}

Allocate memory on

device

CUDA Exemplo: Multiplicação de matrizes – Versão GPU

Page 97: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

void MatrixMulOnDevice(float* M, float* N, float* P, int Width){ int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory

cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size);

dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel<<<dimGrid, dimBlock>>>(Md, Nd, Pd, Width);

cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd);}

Do Matrix multiplication

on device

CUDA Exemplo: Multiplicação de matrizes – Versão GPU

Page 98: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

void MatrixMulOnDevice(float* M, float* N, float* P, int Width){ int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory

cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size);

dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel<<<dimGrid, dimBlock>>>(Md, Nd, Pd, Width);

cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd);}

Free device memory

CUDA Exemplo: Multiplicação de matrizes – Versão GPU

Page 99: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Nd

Md Pd

WID

TH

WID

TH

WIDTH WIDTH

// Matrix multiplication kernel – per thread code__global__ void MatrixMulKernel(float* Md, float* Nd, float* Pd, int Width){ // Pvalue is used to store the element of the matrix // that is computed by the thread float Pval = 0;

for (int k = 0; k < Width; ++k) { float Melement = Md[threadIdx.y*Width+k]; float Nelement = Nd[k*Width+threadIdx.x]; Pval += Melement * Nelement; } Pd[threadIdx.y*Width+threadIdx.x] = Pval;}

ty

tx

ty

tx

k

k

CUDA Exemplo: Multiplicação de matrizes – Versão GPU

Page 100: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Exemplos

Page 101: Programação em GPUs (OpenGL/GLSL CUDA)

April 20, 2023

Referências

http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu

http://www.gpgpu.org

http://developer.nvidia.com/object/sdk_home

http://www.nvidia.com/object/cuda_home.html