@ -763,17 +763,6 @@ CGLMTex::CGLMTex( GLMContext *ctx, GLMTexLayout *layout, uint levels, const char
m_pBlitSrcFBO = NULL ;
m_pBlitSrcFBO = NULL ;
m_pBlitDstFBO = NULL ;
m_pBlitDstFBO = NULL ;
m_mapped = NULL ;
m_pbo = 0 ;
if ( m_layout - > m_key . m_texFlags & kGLMTexDynamic )
{
gGL - > glGenBuffersARB ( 1 , & m_pbo ) ;
gGL - > glBindBufferARB ( GL_PIXEL_UNPACK_BUFFER , m_pbo ) ;
gGL - > glBufferDataARB ( GL_PIXEL_UNPACK_BUFFER , m_layout - > m_storageTotalSize , 0 , GL_STATIC_DRAW ) ;
gGL - > glBindBufferARB ( GL_PIXEL_UNPACK_BUFFER , 0 ) ;
}
// Sense whether to try and apply client storage upon teximage/subimage.
// Sense whether to try and apply client storage upon teximage/subimage.
// This should only be true if we're running on OSX 10.6 or it was explicitly
// This should only be true if we're running on OSX 10.6 or it was explicitly
// enabled with -gl_texclientstorage on the command line.
// enabled with -gl_texclientstorage on the command line.
@ -837,7 +826,8 @@ CGLMTex::CGLMTex( GLMContext *ctx, GLMTexLayout *layout, uint levels, const char
if ( ! ( layout - > m_key . m_texFlags & kGLMTexRenderable ) & & m_texClientStorage )
if ( ! ( layout - > m_key . m_texFlags & kGLMTexRenderable ) & & m_texClientStorage )
{
{
m_backing = ( char * ) malloc ( m_layout - > m_storageTotalSize ) ;
m_backing = ( char * ) malloc ( m_layout - > m_storageTotalSize ) ;
memset ( m_backing , 0 , m_layout - > m_storageTotalSize ) ;
// track bytes allocated for non-RT's
// track bytes allocated for non-RT's
int formindex = sEncodeLayoutAsIndex ( & layout - > m_key ) ;
int formindex = sEncodeLayoutAsIndex ( & layout - > m_key ) ;
@ -1049,10 +1039,7 @@ CGLMTex::~CGLMTex( )
free ( m_debugLabel ) ;
free ( m_debugLabel ) ;
m_debugLabel = NULL ;
m_debugLabel = NULL ;
}
}
if ( m_pbo )
gGL - > glDeleteBuffersARB ( 1 , & m_pbo ) ;
m_ctx = NULL ;
m_ctx = NULL ;
}
}
@ -1117,11 +1104,10 @@ void CGLMTex::CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z
* zStrideOut = zStride ;
* zStrideOut = zStride ;
}
}
GLubyte * CGLMTex : : ReadTexels ( GLMTexLockDesc * desc , bool readWholeSlice , bool readOnly )
void CGLMTex : : ReadTexels ( GLMTexLockDesc * desc , bool readWholeSlice )
{
{
GLMRegion readBox ;
GLMRegion readBox ;
GLubyte * data = NULL ;
if ( readWholeSlice )
if ( readWholeSlice )
{
{
readBox . xmin = readBox . ymin = readBox . zmin = 0 ;
readBox . xmin = readBox . ymin = readBox . zmin = 0 ;
@ -1134,7 +1120,7 @@ GLubyte *CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice, bool re
{
{
readBox = desc - > m_req . m_region ;
readBox = desc - > m_req . m_region ;
}
}
CGLMTex * pPrevTex = m_ctx - > m_samplers [ 0 ] . m_pBoundTex ;
CGLMTex * pPrevTex = m_ctx - > m_samplers [ 0 ] . m_pBoundTex ;
m_ctx - > BindTexToTMU ( this , 0 ) ; // SelectTMU(n) is a side effect
m_ctx - > BindTexToTMU ( this , 0 ) ; // SelectTMU(n) is a side effect
@ -1146,52 +1132,46 @@ GLubyte *CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice, bool re
GLMTexFormatDesc * format = m_layout - > m_format ;
GLMTexFormatDesc * format = m_layout - > m_format ;
GLenum target = m_layout - > m_key . m_texGLTarget ;
GLenum target = m_layout - > m_key . m_texGLTarget ;
if ( readOnly )
void * sliceAddress = m_backing + m_layout - > m_slices [ desc - > m_sliceIndex ] . m_storageOffset ; // this would change for PBO
//int sliceSize = m_layout->m_slices[ desc->m_sliceIndex ].m_storageSize;
// interestingly enough, we can use the same path for both 2D and 3D fetch
switch ( target )
{
{
data = ( GLubyte * ) ( m_backing + m_layout - > m_slices [ desc - > m_sliceIndex ] . m_storageOffset ) ; // this would change for PBO
case GL_TEXTURE_CUBE_MAP :
//int sliceSize = m_layout->m_slices[ desc->m_sliceIndex ].m_storageSize;
// interestingly enough, we can use the same path for both 2D and 3D fetch
switch ( target )
// adjust target to steer to the proper face, then fall through to the 2D texture path.
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc - > m_req . m_face ;
case GL_TEXTURE_2D :
case GL_TEXTURE_3D :
{
{
case GL_TEXTURE_CUBE_MAP :
// check compressed or not
if ( format - > m_chunkSize ! = 1 )
// adjust target to steer to the proper face, then fall through to the 2D texture path.
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc - > m_req . m_face ;
case GL_TEXTURE_2D :
case GL_TEXTURE_3D :
{
{
// check compressed or not
// compressed path
if ( format - > m_chunkSize ! = 1 )
// http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml
{
// compressed path
gGL - > glGetCompressedTexImage ( target , // target
// http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml
gGL - > glGetCompressedTexImage ( target , // target
desc - > m_req . m_mip , // level
desc - > m_req . m_mip , // level
data ) ; // destination
sliceAddress ) ; // destination
}
}
else
else
{
{
// uncompressed path
// uncompressed path
// http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml
// http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml
gGL - > glGetTexImage ( target , // target
gGL - > glGetTexImage ( target , // target
desc - > m_req . m_mip , // level
desc - > m_req . m_mip , // level
format - > m_glDataFormat , // dataformat
format - > m_glDataFormat , // dataformat
format - > m_glDataType , // datatype
format - > m_glDataType , // datatype
data ) ; // destination
sliceAddress ) ; // destination
}
}
}
break ;
}
}
break ;
}
}
else
{
gGL - > glBindBufferARB ( GL_PIXEL_UNPACK_BUFFER , m_pbo ) ;
data = ( GLubyte * ) gGL - > glMapBufferRange ( GL_PIXEL_UNPACK_BUFFER , 0 , m_layout - > m_slices [ desc - > m_sliceIndex ] . m_storageSize , GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT ) ;
}
}
}
else
else
{
{
@ -1199,8 +1179,6 @@ GLubyte *CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice, bool re
}
}
m_ctx - > BindTexToTMU ( pPrevTex , 0 ) ;
m_ctx - > BindTexToTMU ( pPrevTex , 0 ) ;
return data ;
}
}
// TexSubImage should work properly on every driver stack and GPU--enabling by default.
// TexSubImage should work properly on every driver stack and GPU--enabling by default.
@ -1255,14 +1233,8 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
GLenum glDataFormat = format - > m_glDataFormat ; // this could change if expansion kicks in
GLenum glDataFormat = format - > m_glDataFormat ; // this could change if expansion kicks in
GLenum glDataType = format - > m_glDataType ;
GLenum glDataType = format - > m_glDataType ;
GLMTexLayoutSlice * slice = & m_layout - > m_slices [ desc - > m_sliceIndex ] ;
GLMTexLayoutSlice * slice = & m_layout - > m_slices [ desc - > m_sliceIndex ] ;
void * sliceAddress = m_backing ? ( m_backing + slice - > m_storageOffset ) : NULL ; // this would change for PBO
void * sliceAddress = NULL ;
if ( m_mapped )
sliceAddress = m_mapped ;
else if ( m_backing )
sliceAddress = m_backing + slice - > m_storageOffset ;
// allow use of subimage if the target is texture2D and it has already been teximage'd
// allow use of subimage if the target is texture2D and it has already been teximage'd
bool mayUseSubImage = false ;
bool mayUseSubImage = false ;
@ -1309,7 +1281,7 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
gGL - > glTexParameteri ( target , GL_TEXTURE_BASE_LEVEL , desc - > m_req . m_mip ) ;
gGL - > glTexParameteri ( target , GL_TEXTURE_BASE_LEVEL , desc - > m_req . m_mip ) ;
}
}
if ( needsExpand & & ! m_mapped )
if ( needsExpand )
{
{
int expandSize = 0 ;
int expandSize = 0 ;
@ -1389,30 +1361,12 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
{
{
// go subimage2D if it's a replacement, not a creation
// go subimage2D if it's a replacement, not a creation
if ( ! m_mapped )
{
gGL - > glPixelStorei ( GL_UNPACK_ROW_LENGTH , slice - > m_xSize ) ; // in pixels
gGL - > glPixelStorei ( GL_UNPACK_SKIP_PIXELS , writeBox . xmin ) ; // in pixels
gGL - > glPixelStorei ( GL_UNPACK_SKIP_ROWS , writeBox . ymin ) ; // in pixels
gGL - > glTexSubImage2D ( target ,
gGL - > glPixelStorei ( GL_UNPACK_ROW_LENGTH , slice - > m_xSize ) ; // in pixels
desc - > m_req . m_mip , // level
gGL - > glPixelStorei ( GL_UNPACK_SKIP_PIXELS , writeBox . xmin ) ; // in pixels
writeBox . xmin , // xoffset into dest
gGL - > glPixelStorei ( GL_UNPACK_SKIP_ROWS , writeBox . ymin ) ; // in pixels
writeBox . ymin , // yoffset into dest
writeBox . xmax - writeBox . xmin , // width (was slice->m_xSize)
writeBox . ymax - writeBox . ymin , // height (was slice->m_ySize)
glDataFormat , // format
glDataType , // type
sliceAddress // data (will be offsetted by the SKIP_PIXELS and SKIP_ROWS - let GL do the math to find the first source texel)
) ;
gGL - > glPixelStorei ( GL_UNPACK_ROW_LENGTH , 0 ) ;
gGL - > glTexSubImage2D ( target ,
gGL - > glPixelStorei ( GL_UNPACK_SKIP_PIXELS , 0 ) ;
gGL - > glPixelStorei ( GL_UNPACK_SKIP_ROWS , 0 ) ;
}
else
{
gGL - > glTexSubImage2D ( target ,
desc - > m_req . m_mip , // level
desc - > m_req . m_mip , // level
writeBox . xmin , // xoffset into dest
writeBox . xmin , // xoffset into dest
writeBox . ymin , // yoffset into dest
writeBox . ymin , // yoffset into dest
@ -1420,9 +1374,26 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
writeBox . ymax - writeBox . ymin , // height (was slice->m_ySize)
writeBox . ymax - writeBox . ymin , // height (was slice->m_ySize)
glDataFormat , // format
glDataFormat , // format
glDataType , // type
glDataType , // type
0
sliceAddress // data (will be offsetted by the SKIP_PIXELS and SKIP_ROWS - let GL do the math to find the first source texel)
) ;
) ;
}
gGL - > glPixelStorei ( GL_UNPACK_ROW_LENGTH , 0 ) ;
gGL - > glPixelStorei ( GL_UNPACK_SKIP_PIXELS , 0 ) ;
gGL - > glPixelStorei ( GL_UNPACK_SKIP_ROWS , 0 ) ;
/*
//http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml
glTexSubImage2D ( target ,
desc - > m_req . m_mip , // level
0 , // xoffset
0 , // yoffset
slice - > m_xSize , // width
slice - > m_ySize , // height
glDataFormat , // format
glDataType , // type
sliceAddress // data
) ;
*/
}
}
else
else
{
{
@ -1485,6 +1456,8 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
}
}
else
else
{
{
// uncompressed path
// http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml
gGL - > glTexImage3D ( target , // target
gGL - > glTexImage3D ( target , // target
desc - > m_req . m_mip , // level
desc - > m_req . m_mip , // level
intformat , // internalformat
intformat , // internalformat
@ -1567,11 +1540,11 @@ void CGLMTex::Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut
unStoragePow2 | = unStoragePow2 > > 8 ;
unStoragePow2 | = unStoragePow2 > > 8 ;
unStoragePow2 | = unStoragePow2 > > 16 ;
unStoragePow2 | = unStoragePow2 > > 16 ;
unStoragePow2 + + ;
unStoragePow2 + + ;
m_backing = ( char * ) m alloc( unStoragePow2 ) ;
m_backing = ( char * ) c alloc( unStoragePow2 , 1 ) ;
}
}
else
else
{
{
m_backing = ( char * ) m alloc( m_layout - > m_storageTotalSize ) ;
m_backing = ( char * ) c alloc( m_layout - > m_storageTotalSize , 1 ) ;
}
}
// clear the kSliceStorageValid bit on all slices
// clear the kSliceStorageValid bit on all slices
@ -1666,18 +1639,14 @@ void CGLMTex::Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut
desc - > m_sliceRegionOffset = offsetInSlice + desc - > m_sliceBaseOffset ;
desc - > m_sliceRegionOffset = offsetInSlice + desc - > m_sliceBaseOffset ;
if ( copyout & & ( ( m_layout - > m_key . m_texFlags & kGLMTexDynamic ) | | params - > m_readonly ) )
if ( copyout )
{
* addressOut = ( char * ) ReadTexels ( desc , true , params - > m_readonly ) ;
if ( params - > m_readonly = = false )
m_mapped = ( GLubyte * ) * addressOut ;
}
else
{
{
* addressOut = m_backing + desc - > m_sliceRegionOffset ;
// read the whole slice
}
// (odds are we'll never request anything but a whole slice to be read..)
ReadTexels ( desc , true ) ;
} // this would be a good place to fill with scrub value if in debug...
* addressOut = m_backing + desc - > m_sliceRegionOffset ;
* yStrideOut = yStride ;
* yStrideOut = yStride ;
* zStrideOut = zStride ;
* zStrideOut = zStride ;
@ -1763,16 +1732,7 @@ void CGLMTex::Unlock( GLMTexLockParams *params )
// fullyDirty |= (m_sliceFlags[ desc->m_sliceIndex ] & kSliceStorageValid);
// fullyDirty |= (m_sliceFlags[ desc->m_sliceIndex ] & kSliceStorageValid);
if ( m_layout - > m_key . m_texFlags & kGLMTexDynamic & & m_mapped )
WriteTexels ( desc , fullyDirty ) ;
{
gGL - > glUnmapBuffer ( GL_PIXEL_UNPACK_BUFFER ) ;
WriteTexels ( desc , fullyDirty ) ;
m_mapped = NULL ;
gGL - > glBindBufferARB ( GL_PIXEL_UNPACK_BUFFER , 0 ) ;
}
else
WriteTexels ( desc , fullyDirty ) ;
// logical place to trigger preloading
// logical place to trigger preloading
// only do it for an RT tex, if it is not yet attached to any FBO.
// only do it for an RT tex, if it is not yet attached to any FBO.