00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00027 
#include <iostream>
00028 
00029 
#include "GlBackend.hpp"
00030 
#include "uberbuffers.hpp"
00031 
#include "UberStorage.hpp"
00032 
00033 
#include "ShDebug.hpp"
00034 
00035 
namespace shgl {
00036 
00037 UberUberTransfer* UberUberTransfer::instance = 
new UberUberTransfer();
00038 UberHostTransfer* UberHostTransfer::instance = 
new UberHostTransfer();
00039 HostUberTransfer* HostUberTransfer::instance = 
new HostUberTransfer();
00040 
00041 
int UberStorage::temp_fb[4] = {-1, -1, -1, -1};
00042 
00043 
bool UberStorage::m_firstTime = 
true;
00044 
00045 UberStorage::UberStorage(
int context,
00046                          
SH::ShMemory* memory, 
const GlTextureNamePtr& name,
00047                          
int width, 
int height, 
int pitch)
00048   : SH::ShStorage(memory),
00049     m_context(context),
00050     m_width(width), m_height(height), m_pitch(pitch), 
00051     m_mem(0), m_binding(SH_UBER_UNBOUND),
00052     m_textureName(name), m_auxTarget(0)
00053 {
00054   
00055   
if (m_firstTime) {
00056     m_firstTime = 
false;
00057   }
00058   
00059   alloc();
00060 }
00061 
00062 UberStorage::~UberStorage()
00063 {
00064   remove();
00065 }
00066 
00067 GLenum getFormat(
int pitch)
00068 {
00069   GLenum format;
00070   
switch(pitch) {
00071   
case 1: format = GL_LUMINANCE_FLOAT32_ATI; 
break;
00072   
case 2: format = GL_LUMINANCE_ALPHA_FLOAT32_ATI; 
break;
00073   
case 3: format = GL_RGB_FLOAT32_ATI; 
break;
00074   
case 4: format = GL_RGBA_FLOAT32_ATI; 
break;
00075   
default: format =  GL_RGBA_FLOAT32_ATI;
00076   }
00077   
return format;
00078 }
00079 
00080 
void UberStorage::bindAsTexture()
00081 {
00082 
00083   SH_DEBUG_PRINT(
"Bind the texture!");
00084 
00085   unbind(); 
00086 
00087   
00088   GlTextureName::Binding texbinding(m_textureName);
00089 
00090   
00091   SH_GL_CHECK_ERROR(glAttachMemATI(m_textureName->target(), GL_IMAGES_ATI, m_mem));
00092   
00093   m_binding = SH_UBER_TEXTURE;
00094 }
00095 
00096 
void UberStorage::bindAsAux(
unsigned int n)
00097 {
00098   unbind();
00099   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, allocfb(0)));
00100   SH_GL_CHECK_ERROR(glAttachMemATI( GL_DRAW_FRAMEBUFFER_ATI, n + GL_AUX0, m_mem));
00101   m_binding = SH_UBER_AUX;
00102   m_auxTarget = n;
00103 }
00104 
00105 
void UberStorage::unbind()
00106 {
00107   
switch (m_binding) {
00108   
case SH_UBER_UNBOUND:
00109     
00110     
break;
00111   
case SH_UBER_TEXTURE:
00112     {
00113       
00114       GlTextureName::Binding texbinding(m_textureName);
00115       
00116       SH_GL_CHECK_ERROR(glAttachMemATI(m_textureName->target(), GL_IMAGES_ATI, 0));
00117     }
00118     
break;
00119   
case SH_UBER_AUX:
00120     SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, temp_fb[0]));
00121     SH_GL_CHECK_ERROR(glAttachMemATI(GL_DRAW_FRAMEBUFFER_ATI, m_auxTarget + GL_AUX0, 0));
00122     
break;
00123   }
00124   m_binding = SH_UBER_UNBOUND;
00125 }
00126 
00127 UberStorage::Binding UberStorage::binding()
 const
00128 
{
00129   
return m_binding;
00130 }
00131 
00132 GlTextureNamePtr UberStorage::textureName()
 const
00133 
{
00134   
return m_textureName;
00135 }
00136 
00137 
int UberStorage::auxTarget()
 const
00138 
{
00139   
if (m_binding != SH_UBER_AUX) 
return -1;
00140   
return m_auxTarget;
00141 }
00142 
00143 
int UberStorage::allocfb(
int n, 
bool bForce){
00144   
00145   
if (temp_fb[n]<0 || bForce) {
00146     temp_fb[n] = SH_GL_CHECK_ERROR(glCreateFramebufferATI());
00147   }
00148 
00149   
return temp_fb[n];
00150 }
00151 
00152 
unsigned int UberStorage::alloc(
int bForce)
00153 {
00154   
if (m_mem && !bForce) {
00155     
return m_mem;
00156   }
00158   GLint propsArray[4] = {GL_TEXTURE_2D, GL_TRUE, GL_COLOR_BUFFER_ATI, GL_TRUE};
00159   GLenum format = getFormat(m_pitch);
00160   
00161   SH_DEBUG_PRINT(
"Allocate uberbuffer: "<<m_width<<
" "<<m_height<<
" "<<m_pitch);
00162 
00163   m_mem = SH_GL_CHECK_ERROR(glAllocMem2DATI(format, m_width, m_height, 2, propsArray));
00164 
00165   
return m_mem;
00166 }
00167 
00168 
unsigned int UberStorage::remove()
00169 {
00170   
if (m_mem) {
00171     SH_GL_CHECK_ERROR(glDeleteMemATI(m_mem));
00172   }
00173   
00174   
return 0;
00175 }
00176 
00177 
00178 
void UberStorage::clearBuffer(
float* col){
00179   
00180   
if(m_mem<=0) 
return;
00181   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, allocfb(3)));
00182 
00183   
00184   glAttachMemATI(GL_DRAW_FRAMEBUFFER_ATI, GL_AUX2, m_mem);
00185          
00186   glDrawBuffer(GL_AUX2); 
00187   
00188   
float local[4];
00189    
if(!col){
00190      col = local;
00191      glGetFloatv(GL_COLOR_CLEAR_VALUE, col);
00192    }
00193 
00195    
00196    
00197    glClear(GL_DEPTH_BUFFER_BIT);
00198 
00199    
00200   glMatrixMode(GL_PROJECTION);
00201   glPushMatrix();
00202   glLoadIdentity();
00203   glOrtho(0.0, width(), 0.0, height(), -1.0, 1.0);
00204  
00205   glMatrixMode(GL_MODELVIEW);
00206   glPushMatrix();
00207   glLoadIdentity();
00208 
00209   
00210   SH_GL_CHECK_ERROR(glPushAttrib(GL_COLOR_BUFFER_BIT | 
00211                                  GL_PIXEL_MODE_BIT | 
00212                                  GL_POLYGON_BIT | 
00213                                  GL_ENABLE_BIT 
00214                                  ));
00215     
00216   glDisable(GL_VERTEX_PROGRAM_ARB);
00217   glDisable(GL_FRAGMENT_PROGRAM_ARB);
00218   glDisable(GL_LIGHTING);
00219   glDisable(GL_TEXTURE_2D);
00220   glDisable(GL_DEPTH_TEST);
00221 
00222   glBegin(GL_QUADS);  
00223   glColor4f(col[0], col[1], col[2], col[3]);
00224   glVertex3f(0.0, 0.0, 0.0);
00225   glVertex3f(width(), 0.0 , 0.0);
00226   glVertex3f(width(), height(), 0.0);
00227   glVertex3f(0.0, height(), 0.0);
00228   glEnd(); 
00229 
00230   SH_GL_CHECK_ERROR(glPopAttrib());
00231   glMatrixMode(GL_PROJECTION);
00232   glPopMatrix();
00233   glMatrixMode(GL_MODELVIEW);
00234   glPopMatrix();
00235 
00236   glDrawBuffer(GL_BACK); 
00237   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, 0));
00238   glDrawBuffer(GL_BACK); 
00239 
00240 }
00241 
00242 
bool UberUberTransfer::transfer(
const SH::ShStorage* from, 
SH::ShStorage* to)
00243 {
00244 
00245   SH_DEBUG_PRINT(
"Inside UberUber transfer");
00246 
00247   
const UberStorage* src_storage = dynamic_cast<const UberStorage*>(from);
00248   UberStorage* dst_storage = dynamic_cast<UberStorage*>(to);
00249   
00250   
if (!dst_storage || !src_storage) {
00251     SH_DEBUG_WARN(
"Invalid Storage");
00252     
return false;
00253   }
00254 
00255   
unsigned int srcmem = src_storage->mem();;
00256   
unsigned int destmem = dst_storage->alloc();
00257   
int width = src_storage->width();
00258   
int height = src_storage->height();
00259   
int pitch = src_storage->pitch();
00260   GLenum format = getFormat(src_storage->pitch());
00261 
00262   
if (!srcmem || !destmem) {
00263     SH_DEBUG_WARN(
"Cannot copy unininitialized uber buffer\n");
00264   }
00265 
00266   
00267   SH_GL_CHECK_ERROR(glPushAttrib(GL_COLOR_BUFFER_BIT | 
00268                                  GL_PIXEL_MODE_BIT | 
00269                                  GL_POLYGON_BIT | 
00270                                  GL_ENABLE_BIT 
00271                                  ));
00272     
00273   glDisable(GL_VERTEX_PROGRAM_ARB);
00274   glDisable(GL_FRAGMENT_PROGRAM_ARB);
00275   glDisable(GL_LIGHTING);
00276   glFrontFace(GL_CCW);
00277 
00278   {
00279     
00280     GlTextureName::Binding texbinding(src_storage->textureName());
00281 
00282     
00283     glEnable(GL_TEXTURE_2D);
00284 
00285     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00286     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00287     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00288     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00289     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00290     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00291 
00292     glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, 0);
00293     
00294     
00295     UberStorage::allocfb(2);
00296 
00297     
00298     SH_GL_CHECK_ERROR(glAttachMemATI(GL_TEXTURE_2D, GL_IMAGES_ATI, srcmem));
00299 
00300     SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, UberStorage::temp_fb[2]));
00301 
00302 
00303     SH_GL_CHECK_ERROR(glAttachMemATI(GL_DRAW_FRAMEBUFFER_ATI, GL_AUX3, destmem));
00304     SH_DEBUG_PRINT(
"Attach GL_AUX3 temporarily to dest mem " << destmem);
00305 
00306     SH_GL_CHECK_ERROR(glDrawBuffer(GL_AUX3)); 
00307 
00308     SH_GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
00309 
00310     
00311     glMatrixMode(GL_PROJECTION);
00312     glPushMatrix();
00313     glLoadIdentity();
00314     glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
00315 
00316     glMatrixMode(GL_MODELVIEW);
00317     glPushMatrix();
00318     glLoadIdentity();
00319 
00320     
00321     glBegin(GL_QUADS);
00322     glMultiTexCoord2fARB(GL_TEXTURE7, 0, 1); 
00323     glVertex3f(0, 0, 0.0);
00324     glMultiTexCoord2fARB(GL_TEXTURE7, 1, 1);
00325     glVertex3f(width, 0, 0.0);
00326     glMultiTexCoord2fARB(GL_TEXTURE7, 1, 0); 
00327     glVertex3f(width, height, 0.0);
00328     glMultiTexCoord2fARB(GL_TEXTURE7, 0, 0); 
00329     glVertex3f(0, height, 0.0);
00330     glEnd(); 
00331 
00332     
00333     SH_GL_CHECK_ERROR(glAttachMemATI(GL_TEXTURE_2D, GL_IMAGES_ATI, 0));
00334     SH_GL_CHECK_ERROR(glAttachMemATI(GL_DRAW_FRAMEBUFFER_ATI, GL_AUX3, 0));
00335     SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, 0));
00336   }
00337   
00339   glPopAttrib();
00340 
00341   glMatrixMode(GL_PROJECTION);
00342   glPopMatrix();
00343 
00344   glMatrixMode(GL_MODELVIEW);
00345   glPopMatrix();
00346 
00347 
00348   
return true;
00349 }
00350 
00351 
00352 
bool UberHostTransfer::transfer(
const SH::ShStorage* from, 
SH::ShStorage* to)
00353 {
00354    SH_DEBUG_PRINT(
"Inside UberHost transfer");
00355 
00356   
const UberStorage* ustorage = dynamic_cast<const UberStorage*>(from);
00357   
SH::ShHostStorage* hstorage = dynamic_cast<SH::ShHostStorage*>(to);
00358   
00359   
if (!ustorage || !hstorage) {
00360     SH_DEBUG_WARN(
"Invalid Storage");
00361     
return false;
00362   }
00363 
00364   
unsigned int mem = ustorage->mem();
00365   
int width = ustorage->width();
00366   
int height = ustorage->height();
00367   
int pitch = ustorage->pitch();
00368   GLenum format = getFormat(ustorage->pitch());
00369 
00370   
if (!mem) {
00371     SH_DEBUG_WARN(
"Un-initialized memory");
00372     
return false;
00373   }
00374 
00375   
00376   SH_GL_CHECK_ERROR(glPushAttrib(GL_COLOR_BUFFER_BIT | 
00377                                  GL_PIXEL_MODE_BIT | 
00378                                  GL_POLYGON_BIT | 
00379                                  GL_ENABLE_BIT 
00380                                  ));
00381 
00382   
00383   glDisable(GL_VERTEX_PROGRAM_ARB);
00384   glDisable(GL_FRAGMENT_PROGRAM_ARB);
00385   glDisable(GL_LIGHTING);
00386   glFrontFace(GL_CCW);
00387   SH_DEBUG_PRINT(
"Temporarily glDisabled vertex/fragment programs and GL lighting");
00388 
00389   GlTextureName::Binding binding(ustorage->textureName());
00390 
00391   
00392   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00393   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00394   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00395   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00396   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00397   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00398 
00399   glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, 0);
00400   SH_DEBUG_PRINT(
"Temporarily unbind framebuffer fb " << ustorage->temp_fb[0]);
00401   
00402   
00403   
00404   GLint propsArray[] = {GL_TEXTURE_2D, GL_TRUE, GL_COLOR_BUFFER_ATI, GL_TRUE};
00405   GLmem dummyMem = glAllocMem2DATI(format, width, height, 2, propsArray);
00406   
00407   UberStorage::allocfb(1);
00408 
00409   SH_GL_CHECK_ERROR(glAttachMemATI(GL_TEXTURE_2D, GL_IMAGES_ATI, mem));
00410   SH_DEBUG_PRINT(
"Attach GL_TEXTURE_2D temporarily to mem " << mem);
00411   
00412   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI,ustorage-> temp_fb[1]));
00413   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_READ_FRAMEBUFFER_ATI, ustorage->temp_fb[1]));
00414   SH_DEBUG_PRINT(
"Bind GL_DRAW_FRAMEBUFFER_ATI to temp fb " << ustorage->temp_fb[1]);
00415 
00416   SH_GL_CHECK_ERROR(glAttachMemATI(GL_DRAW_FRAMEBUFFER_ATI, GL_AUX3, dummyMem));
00417   SH_DEBUG_PRINT(
"Attach GL_AUX3 temporarily to dummy mem " << dummyMem);
00418   
00419   SH_GL_CHECK_ERROR(glDrawBuffer(GL_AUX3)); 
00420 
00421   SH_GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
00422 
00423   
00424   glMatrixMode(GL_PROJECTION);
00425   glPushMatrix();
00426   glLoadIdentity();
00427   glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
00428 
00429   glMatrixMode(GL_MODELVIEW);
00430   glPushMatrix();
00431   glLoadIdentity();
00432 
00433   
00434   
double tcx1 = 0;
00435   
double tcy1 = 0;
00436   
double tcx2 = 1;
00437   
double tcy2 = 1;
00438 
00439   glBegin(GL_QUADS);
00440   glMultiTexCoord2fARB(GL_TEXTURE7, tcx1, tcy1); 
00441   glVertex3f(0.0,0.0, 0.0);
00442   glMultiTexCoord2fARB(GL_TEXTURE7, tcx2, tcy1);
00443   glVertex3f(0 + width, 0, 0.0);
00444   glMultiTexCoord2fARB(GL_TEXTURE7, tcx2, tcy2); 
00445   glVertex3f(0 + width, 0 + height, 0.0);
00446   glMultiTexCoord2fARB(GL_TEXTURE7, tcx1, tcy2); 
00447   glVertex3f(0, 0 + height, 0.0);
00448   glEnd(); 
00449 
00450   SH_GL_CHECK_ERROR(glReadBuffer(GL_AUX3));
00451 
00452   GLenum format2;
00453   
switch (pitch) {
00454   
case 1: format2 = GL_LUMINANCE; 
break;
00455   
case 2: format2 = GL_LUMINANCE_ALPHA; 
break;
00456   
case 3: format2 = GL_RGB; 
break;
00457   
case 4: format2 = GL_RGBA; 
break;
00458   
default: format2 = 0; 
break;
00459   }
00460  
00461   
00462   
if (hstorage->
length() != width*height*pitch*
sizeof(
float)) {
00463     std::cout<<
"{}{}{}{}{}{}{}{}{}{}{}{}{}Big problem!"<<std::endl;
00464   }
00465 
00466   SH_GL_CHECK_ERROR(glReadPixels(0, 0, width, height, format2, GL_FLOAT, hstorage->
data())); 
00467 
00468   
00469   SH_GL_CHECK_ERROR(glAttachMemATI(GL_TEXTURE_2D, GL_IMAGES_ATI, 0));
00470 
00471   SH_GL_CHECK_ERROR(glAttachMemATI(GL_DRAW_FRAMEBUFFER_ATI, GL_AUX3, 0));
00472 
00473   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_DRAW_FRAMEBUFFER_ATI, 0));
00474   SH_GL_CHECK_ERROR(glBindFramebufferATI(GL_READ_FRAMEBUFFER_ATI, 0));
00475 
00476   
00477   glPopAttrib();
00478 
00479   glMatrixMode(GL_PROJECTION);
00480   glPopMatrix();
00481 
00482   glMatrixMode(GL_MODELVIEW);
00483   glPopMatrix();
00484 
00485   SH_GL_CHECK_ERROR(glDeleteMemATI(dummyMem));
00486   SH_DEBUG_PRINT(
"Delete dummy mem " << dummyMem); 
00487 
00488   
return true;
00489 }
00490 
00491 
00492 
bool HostUberTransfer::transfer(
const SH::ShStorage* from, 
SH::ShStorage* to)
00493 {
00494 
00495    SH_DEBUG_PRINT(
"Inside HostUber transfer");
00496 
00497   
const SH::ShHostStorage* hstorage = dynamic_cast<const SH::ShHostStorage*>(from);
00498   UberStorage* ustorage = dynamic_cast<UberStorage*>(to);
00499   
00500   
if (!ustorage || !hstorage) {
00501     SH_DEBUG_WARN(
"Invalid Storage");
00502     
return false;
00503   }
00504 
00505   
00506   
unsigned int mem = ustorage->mem();
00507 
00508   
if (!mem) {
00509     SH_DEBUG_WARN(
"Unable to allocate Memory");
00510     
return false;
00511   }
00512 
00513   
int width = ustorage->width();
00514   
int height = ustorage->height();
00515   
int pitch = ustorage->pitch();
00516   GLenum format = getFormat(ustorage->pitch());
00517 
00518   GlTextureName::Binding binding(ustorage->textureName());
00519 
00520   
00521   SH_GL_CHECK_ERROR(glAttachMemATI(GL_TEXTURE_2D, GL_IMAGES_ATI, mem)); 
00522   SH_DEBUG_PRINT(
"Attach GL_TEXTURE_2D temporarily to mem " << mem); 
00523 
00524   
00525   
00526   GLenum format2;
00527   
switch (ustorage->pitch()) {
00528   
case 1: format2 = GL_LUMINANCE; 
break;
00529   
case 2: format2 = GL_LUMINANCE_ALPHA; 
break;
00530   
case 3: format2 = GL_RGB; 
break;
00531   
case 4: format2 = GL_RGBA; 
break;
00532   
default: format2 = 0; 
break;
00533   }
00534 
00535   SH_GL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format2, GL_FLOAT,
00536                                     hstorage->
data()));
00537 
00538   
00539   SH_GL_CHECK_ERROR(glAttachMemATI(GL_TEXTURE_2D, GL_IMAGES_ATI, 0));
00540   SH_DEBUG_PRINT(
"Detach GL_TEXTURE_2D from mem " << mem); 
00541 
00542   
return true;
00543 
00544 }
00545 
00546 }