mirror of
https://github.com/nillerusr/source-engine.git
synced 2025-01-13 00:28:18 +00:00
togl/togles: use PBO for DYNAMIC textures
This commit is contained in:
parent
a269b89168
commit
7a26688494
@ -126,6 +126,7 @@ enum EGLMTexFlags
|
|||||||
kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
|
kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
|
||||||
// actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
|
// actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
|
||||||
// have mipmaps generated.
|
// have mipmaps generated.
|
||||||
|
kGLMTexDynamic = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
//===============================================================================
|
//===============================================================================
|
||||||
@ -204,6 +205,7 @@ struct GLMTexLockParams
|
|||||||
// tells GLM to force re-read of the texels back from GL
|
// tells GLM to force re-read of the texels back from GL
|
||||||
// i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
|
// i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
|
||||||
bool m_readback;
|
bool m_readback;
|
||||||
|
bool m_readonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLMTexLockDesc
|
struct GLMTexLockDesc
|
||||||
@ -485,7 +487,7 @@ protected:
|
|||||||
int CalcSliceIndex( int face, int mip );
|
int CalcSliceIndex( int face, int mip );
|
||||||
void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
|
void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
|
||||||
|
|
||||||
void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true );
|
GLubyte *ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true, bool readOnly=false );
|
||||||
void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
|
void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
|
||||||
// last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
|
// last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
|
||||||
// this helps out ResetSRGB.
|
// this helps out ResetSRGB.
|
||||||
@ -505,6 +507,8 @@ protected:
|
|||||||
// noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
|
// noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
|
||||||
|
|
||||||
GLuint m_texName; // name of this texture in the context
|
GLuint m_texName; // name of this texture in the context
|
||||||
|
GLuint m_pbo;
|
||||||
|
GLubyte *m_mapped;
|
||||||
GLenum m_texGLTarget;
|
GLenum m_texGLTarget;
|
||||||
uint m_nSamplerType; // SAMPLER_2D, etc.
|
uint m_nSamplerType; // SAMPLER_2D, etc.
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@ enum EGLMTexFlags
|
|||||||
kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
|
kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
|
||||||
// actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
|
// actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
|
||||||
// have mipmaps generated.
|
// have mipmaps generated.
|
||||||
|
kGLMTexDynamic = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
//===============================================================================
|
//===============================================================================
|
||||||
@ -204,6 +205,7 @@ struct GLMTexLockParams
|
|||||||
// tells GLM to force re-read of the texels back from GL
|
// tells GLM to force re-read of the texels back from GL
|
||||||
// i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
|
// i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
|
||||||
bool m_readback;
|
bool m_readback;
|
||||||
|
bool m_readonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLMTexLockDesc
|
struct GLMTexLockDesc
|
||||||
@ -485,7 +487,7 @@ protected:
|
|||||||
int CalcSliceIndex( int face, int mip );
|
int CalcSliceIndex( int face, int mip );
|
||||||
void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
|
void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
|
||||||
|
|
||||||
void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true );
|
GLubyte *ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true, bool readOnly=false );
|
||||||
void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
|
void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
|
||||||
// last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
|
// last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
|
||||||
// this helps out ResetSRGB.
|
// this helps out ResetSRGB.
|
||||||
@ -505,6 +507,8 @@ protected:
|
|||||||
// noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
|
// noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
|
||||||
|
|
||||||
GLuint m_texName; // name of this texture in the context
|
GLuint m_texName; // name of this texture in the context
|
||||||
|
GLuint m_pbo;
|
||||||
|
GLubyte *m_mapped;
|
||||||
GLenum m_texGLTarget;
|
GLenum m_texGLTarget;
|
||||||
uint m_nSamplerType; // SAMPLER_2D, etc.
|
uint m_nSamplerType; // SAMPLER_2D, etc.
|
||||||
|
|
||||||
|
@ -763,6 +763,17 @@ 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.
|
||||||
@ -826,7 +837,6 @@ 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 );
|
||||||
@ -1040,6 +1050,9 @@ CGLMTex::~CGLMTex( )
|
|||||||
m_debugLabel = NULL;
|
m_debugLabel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_pbo )
|
||||||
|
gGL->glDeleteBuffersARB( 1, &m_pbo );
|
||||||
|
|
||||||
m_ctx = NULL;
|
m_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1104,9 +1117,10 @@ void CGLMTex::CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z
|
|||||||
*zStrideOut = zStride;
|
*zStrideOut = zStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
GLubyte *CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice, bool readOnly )
|
||||||
{
|
{
|
||||||
GLMRegion readBox;
|
GLMRegion readBox;
|
||||||
|
GLubyte* data = NULL;
|
||||||
|
|
||||||
if (readWholeSlice)
|
if (readWholeSlice)
|
||||||
{
|
{
|
||||||
@ -1133,7 +1147,9 @@ void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
|||||||
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;
|
||||||
|
|
||||||
void *sliceAddress = m_backing + m_layout->m_slices[ desc->m_sliceIndex ].m_storageOffset; // this would change for PBO
|
if( readOnly )
|
||||||
|
{
|
||||||
|
data = 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;
|
//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
|
// interestingly enough, we can use the same path for both 2D and 3D fetch
|
||||||
@ -1144,7 +1160,6 @@ void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
|||||||
|
|
||||||
// adjust target to steer to the proper face, then fall through to the 2D texture path.
|
// 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;
|
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc->m_req.m_face;
|
||||||
|
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
case GL_TEXTURE_3D:
|
case GL_TEXTURE_3D:
|
||||||
{
|
{
|
||||||
@ -1153,32 +1168,39 @@ void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
|||||||
{
|
{
|
||||||
// compressed path
|
// compressed path
|
||||||
// http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml
|
// http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml
|
||||||
|
|
||||||
gGL->glGetCompressedTexImage( target, // target
|
gGL->glGetCompressedTexImage( target, // target
|
||||||
desc->m_req.m_mip, // level
|
desc->m_req.m_mip, // level
|
||||||
sliceAddress ); // destination
|
data ); // 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
|
||||||
sliceAddress ); // destination
|
data ); // destination
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
||||||
{
|
{
|
||||||
GLMStop();
|
GLMStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
||||||
@ -1234,7 +1256,13 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
|
|||||||
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;
|
||||||
@ -1281,7 +1309,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)
|
if (needsExpand && !m_mapped)
|
||||||
{
|
{
|
||||||
int expandSize = 0;
|
int expandSize = 0;
|
||||||
|
|
||||||
@ -1361,7 +1389,8 @@ 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_ROW_LENGTH, slice->m_xSize ); // in pixels
|
||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, writeBox.xmin ); // in pixels
|
gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, writeBox.xmin ); // in pixels
|
||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, writeBox.ymin ); // in pixels
|
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, writeBox.ymin ); // in pixels
|
||||||
@ -1380,20 +1409,20 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
|
|||||||
gGL->glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
|
gGL->glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
|
||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
|
gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
|
||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
|
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
|
||||||
|
}
|
||||||
/*
|
else
|
||||||
//http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml
|
{
|
||||||
glTexSubImage2D( target,
|
gGL->glTexSubImage2D( target,
|
||||||
desc->m_req.m_mip, // level
|
desc->m_req.m_mip, // level
|
||||||
0, // xoffset
|
writeBox.xmin, // xoffset into dest
|
||||||
0, // yoffset
|
writeBox.ymin, // yoffset into dest
|
||||||
slice->m_xSize, // width
|
writeBox.xmax - writeBox.xmin, // width (was slice->m_xSize)
|
||||||
slice->m_ySize, // height
|
writeBox.ymax - writeBox.ymin, // height (was slice->m_ySize)
|
||||||
glDataFormat, // format
|
glDataFormat, // format
|
||||||
glDataType, // type
|
glDataType, // type
|
||||||
sliceAddress // data
|
0
|
||||||
);
|
);
|
||||||
*/
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1456,8 +1485,6 @@ 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
|
||||||
@ -1540,11 +1567,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 *)calloc( unStoragePow2, 1 );
|
m_backing = (char *)malloc( unStoragePow2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_backing = (char *)calloc( m_layout->m_storageTotalSize, 1 );
|
m_backing = (char *)malloc( m_layout->m_storageTotalSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the kSliceStorageValid bit on all slices
|
// clear the kSliceStorageValid bit on all slices
|
||||||
@ -1639,14 +1666,18 @@ 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)
|
if ( copyout && ( (m_layout->m_key.m_texFlags & kGLMTexDynamic) || params->m_readonly ) )
|
||||||
{
|
{
|
||||||
// read the whole slice
|
*addressOut = ReadTexels( desc, true, params->m_readonly );
|
||||||
// (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...
|
|
||||||
|
|
||||||
|
if( !params->m_readonly )
|
||||||
|
m_mapped = *addressOut;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*addressOut = m_backing + desc->m_sliceRegionOffset;
|
*addressOut = m_backing + desc->m_sliceRegionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
*yStrideOut = yStride;
|
*yStrideOut = yStride;
|
||||||
*zStrideOut = zStride;
|
*zStrideOut = zStride;
|
||||||
|
|
||||||
@ -1732,6 +1763,15 @@ 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 )
|
||||||
|
{
|
||||||
|
gGL->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
|
||||||
|
WriteTexels( desc, fullyDirty );
|
||||||
|
m_mapped = NULL;
|
||||||
|
gGL->glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
WriteTexels( desc, fullyDirty );
|
WriteTexels( desc, fullyDirty );
|
||||||
|
|
||||||
// logical place to trigger preloading
|
// logical place to trigger preloading
|
||||||
|
@ -404,7 +404,7 @@ HRESULT IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD
|
|||||||
|
|
||||||
if (Usage & D3DUSAGE_DYNAMIC)
|
if (Usage & D3DUSAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
// GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME
|
key.m_texFlags |= kGLMTexDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
||||||
@ -617,7 +617,7 @@ HRESULT IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Us
|
|||||||
|
|
||||||
if (Usage & D3DUSAGE_DYNAMIC)
|
if (Usage & D3DUSAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
//GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME
|
key.m_texFlags |= kGLMTexDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
||||||
@ -823,7 +823,7 @@ HRESULT IDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,
|
|||||||
|
|
||||||
if (Usage & D3DUSAGE_DYNAMIC)
|
if (Usage & D3DUSAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME
|
key.m_texFlags |= kGLMTexDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
||||||
@ -1041,6 +1041,8 @@ HRESULT IDirect3DSurface9::LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRec
|
|||||||
lockreq.m_readback = true;
|
lockreq.m_readback = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockreq.m_readonly = Flags & D3DLOCK_READONLY;
|
||||||
|
|
||||||
char *lockAddress;
|
char *lockAddress;
|
||||||
int yStride;
|
int yStride;
|
||||||
int zStride;
|
int zStride;
|
||||||
|
@ -768,6 +768,17 @@ 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->glGenBuffers(1, &m_pbo);
|
||||||
|
gGL->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo);
|
||||||
|
gGL->glBufferData(GL_PIXEL_UNPACK_BUFFER, m_layout->m_storageTotalSize, 0, GL_DYNAMIC_DRAW);
|
||||||
|
gGL->glBindBuffer(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.
|
||||||
@ -831,7 +842,6 @@ 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 );
|
||||||
@ -1042,6 +1052,9 @@ CGLMTex::~CGLMTex( )
|
|||||||
m_debugLabel = NULL;
|
m_debugLabel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_pbo )
|
||||||
|
gGL->glDeleteBuffers( 1, &m_pbo );
|
||||||
|
|
||||||
m_ctx = NULL;
|
m_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,9 +1121,10 @@ void CGLMTex::CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z
|
|||||||
|
|
||||||
extern void convert_texture( GLenum &internalformat, GLsizei width, GLsizei height, GLenum &format, GLenum &type, void *data );
|
extern void convert_texture( GLenum &internalformat, GLsizei width, GLsizei height, GLenum &format, GLenum &type, void *data );
|
||||||
|
|
||||||
void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
GLubyte *CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice, bool readOnly )
|
||||||
{
|
{
|
||||||
GLMRegion readBox;
|
GLMRegion readBox;
|
||||||
|
GLubyte* data = NULL;
|
||||||
|
|
||||||
if (readWholeSlice)
|
if (readWholeSlice)
|
||||||
{
|
{
|
||||||
@ -1137,7 +1151,9 @@ void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
|||||||
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;
|
||||||
|
|
||||||
void *sliceAddress = m_backing + m_layout->m_slices[ desc->m_sliceIndex ].m_storageOffset; // this would change for PBO
|
if( readOnly )
|
||||||
|
{
|
||||||
|
data = 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;
|
//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
|
// interestingly enough, we can use the same path for both 2D and 3D fetch
|
||||||
@ -1145,26 +1161,10 @@ void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
|||||||
switch( target )
|
switch( target )
|
||||||
{
|
{
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
|
|
||||||
// adjust target to steer to the proper face, then fall through to the 2D texture path.
|
// 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;
|
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc->m_req.m_face;
|
||||||
|
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
case GL_TEXTURE_3D:
|
case GL_TEXTURE_3D:
|
||||||
{
|
|
||||||
// check compressed or not
|
|
||||||
if (format->m_chunkSize != 1)
|
|
||||||
{
|
|
||||||
// compressed path
|
|
||||||
// http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml
|
|
||||||
// TODO(nillerusr): implement me!
|
|
||||||
/*
|
|
||||||
gGL->glGetCompressedTexImage( target, // target
|
|
||||||
desc->m_req.m_mip, // level
|
|
||||||
sliceAddress ); // destination
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
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
|
||||||
@ -1182,23 +1182,30 @@ void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice )
|
|||||||
GLenum dataType = format->m_glDataType;
|
GLenum dataType = format->m_glDataType;
|
||||||
|
|
||||||
convert_texture(fmt, 0, 0, fmt, dataType, NULL);
|
convert_texture(fmt, 0, 0, fmt, dataType, NULL);
|
||||||
gGL->glReadPixels(0, 0, m_layout->m_slices[ desc->m_sliceIndex ].m_xSize, m_layout->m_slices[ desc->m_sliceIndex ].m_ySize, fmt, dataType, sliceAddress);
|
gGL->glReadPixels(0, 0, m_layout->m_slices[ desc->m_sliceIndex ].m_xSize, m_layout->m_slices[ desc->m_sliceIndex ].m_ySize, fmt, dataType, data);
|
||||||
|
|
||||||
gGL->glBindFramebuffer(GL_READ_FRAMEBUFFER, Rfbo);
|
gGL->glBindFramebuffer(GL_READ_FRAMEBUFFER, Rfbo);
|
||||||
gGL->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Dfbo);
|
gGL->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Dfbo);
|
||||||
|
|
||||||
gGL->glDeleteFramebuffers(1, &fbo);
|
gGL->glDeleteFramebuffers(1, &fbo);
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gGL->glBindBuffer(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
|
||||||
{
|
{
|
||||||
GLMStop();
|
GLMStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ctx->BindTexToTMU( pPrevTex, 0 );
|
m_ctx->BindTexToTMU( pPrevTex, 0 );
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mem_s
|
struct mem_s
|
||||||
@ -3546,7 +3553,13 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
|
|||||||
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;
|
||||||
@ -3592,7 +3605,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)
|
if (needsExpand && !m_mapped)
|
||||||
{
|
{
|
||||||
int expandSize = 0;
|
int expandSize = 0;
|
||||||
|
|
||||||
@ -3660,6 +3673,8 @@ 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_ROW_LENGTH, slice->m_xSize ); // in pixels
|
||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, writeBox.xmin ); // in pixels
|
gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, writeBox.xmin ); // in pixels
|
||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, writeBox.ymin ); // in pixels
|
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, writeBox.ymin ); // in pixels
|
||||||
@ -3682,6 +3697,22 @@ void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDa
|
|||||||
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
|
gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
convert_texture(intformat, writeBox.xmax - writeBox.xmin, writeBox.ymax - writeBox.ymin, glDataFormat, glDataType, NULL);
|
||||||
|
|
||||||
|
gGL->glTexSubImage2D( target,
|
||||||
|
desc->m_req.m_mip, // level
|
||||||
|
writeBox.xmin, // xoffset into dest
|
||||||
|
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
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// uncompressed path
|
// uncompressed path
|
||||||
// http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/teximage2d.html
|
// http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/teximage2d.html
|
||||||
@ -3810,11 +3841,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 *)calloc( unStoragePow2, 1 );
|
m_backing = (char *)malloc( unStoragePow2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_backing = (char *)calloc( m_layout->m_storageTotalSize, 1 );
|
m_backing = (char *)malloc( m_layout->m_storageTotalSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the kSliceStorageValid bit on all slices
|
// clear the kSliceStorageValid bit on all slices
|
||||||
@ -3909,14 +3940,20 @@ 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)
|
if ( copyout && ( (m_layout->m_key.m_texFlags & kGLMTexDynamic) || params->m_readonly ) )
|
||||||
{
|
{
|
||||||
// read the whole slice
|
// read the whole slice
|
||||||
// (odds are we'll never request anything but a whole slice to be read..)
|
// (odds are we'll never request anything but a whole slice to be read..)
|
||||||
ReadTexels( desc, true );
|
*addressOut = ReadTexels( desc, true, params->m_readonly );
|
||||||
} // this would be a good place to fill with scrub value if in debug...
|
|
||||||
|
|
||||||
|
if( !params->m_readonly )
|
||||||
|
m_mapped = *addressOut;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*addressOut = m_backing + desc->m_sliceRegionOffset;
|
*addressOut = m_backing + desc->m_sliceRegionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
*yStrideOut = yStride;
|
*yStrideOut = yStride;
|
||||||
*zStrideOut = zStride;
|
*zStrideOut = zStride;
|
||||||
|
|
||||||
@ -4002,6 +4039,15 @@ 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 )
|
||||||
|
{
|
||||||
|
gGL->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
|
||||||
|
WriteTexels( desc, fullyDirty );
|
||||||
|
m_mapped = NULL;
|
||||||
|
gGL->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
WriteTexels( desc, fullyDirty );
|
WriteTexels( desc, fullyDirty );
|
||||||
|
|
||||||
// logical place to trigger preloading
|
// logical place to trigger preloading
|
||||||
|
@ -404,7 +404,7 @@ HRESULT IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD
|
|||||||
|
|
||||||
if (Usage & D3DUSAGE_DYNAMIC)
|
if (Usage & D3DUSAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
// GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME
|
key.m_texFlags |= kGLMTexDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
||||||
@ -617,7 +617,7 @@ HRESULT IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Us
|
|||||||
|
|
||||||
if (Usage & D3DUSAGE_DYNAMIC)
|
if (Usage & D3DUSAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
//GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME
|
key.m_texFlags |= kGLMTexDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
||||||
@ -823,7 +823,7 @@ HRESULT IDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,
|
|||||||
|
|
||||||
if (Usage & D3DUSAGE_DYNAMIC)
|
if (Usage & D3DUSAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME
|
key.m_texFlags |= kGLMTexDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
if (Usage & D3DUSAGE_TEXTURE_SRGB)
|
||||||
@ -1041,6 +1041,8 @@ HRESULT IDirect3DSurface9::LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRec
|
|||||||
lockreq.m_readback = true;
|
lockreq.m_readback = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockreq.m_readonly = Flags & D3DLOCK_READONLY;
|
||||||
|
|
||||||
char *lockAddress;
|
char *lockAddress;
|
||||||
int yStride;
|
int yStride;
|
||||||
int zStride;
|
int zStride;
|
||||||
|
Loading…
Reference in New Issue
Block a user