Textures are the main structure for saving data on a GPU. Textures can be 1 to 3 dimensional data fields containing up to 4 channels of data (RGBA). Every channel may consist of one variable with currently single precision floating point values. As render targets (textures where to save computational results) two dimensional textures are still more practical then three dimensional textures, because in the three dimensional case the calculation has to be done slice by slice. That drastically slows down the overall performance.
Currently two different texture classes exist, one for two dimensional and one for three dimensional data structures. In the three dimensional case the spacial data is mapped on a two dimensional texture slice by slice. This enables us to do calculations for the whole three dimensional volume in one single render pass.
The constructor needs the size of the texture object to be created. Be careful, nx*nz has to be lower than 8192 on ATI 4xxx and 16384 on ATI 5xxx. The texture constructed currently has 4 channels per pixel. In general we are using pointers, because that makes binding the textures to shaders more nicely.
texture *z=new texture(nx,ny,nz);
access to data
The data for the texture on the cpu side is saved in the “data” field
z->data[getindex(x,y,z)+c] // x,y,z => position c=>channel
z->data[4*(x+sx*z+sx*sz*y)+c] // sx,sz size of texture
to up- and download the data from cpu memory to gpu memory and back the class provides two methods
z->ram2gpu(); // upload data field from cpu ram to gpu memory
z->gpu2ram(); // download texture data from gpu to cpu memory
The data is copied over the PCIe 16x V2.0 Bus, which provides about 8 GB/s bandwith. This is the bottleneck of the architecture, so use with care, because this may slow down the overall performance a lot.
To access a certain cell in the cpu memory, the class provides a get and set method
z->set(x,y,z,0,0.1); // sets the first(red) channel at position x,y,z to 0.1
z->set(x,y,z,1,65e5); // sets the second(green) channel at position x,y,z to 65e5
u=z->get(x,y,z,0); // gives the first(red) channel at position x,y,z to u
In addition any OpenGL drawing function can be used to manipulate texture data on GPU Memory by the CPU program, if the texture is selected as the render target.