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 }