mirror of
https://github.com/libretro/RetroArch
synced 2025-03-24 04:44:02 +00:00
(GCMGL) Cleanups
This commit is contained in:
parent
ab3ea28b2a
commit
94dbb8264c
@ -624,7 +624,7 @@ typedef struct
|
||||
GLuint indexMax; // 0==glDrawElements; 0!=glDrawRangeElements
|
||||
GLsizei indexCount;
|
||||
|
||||
// internal draw parameters (set by rglPlatformRequiresSlowPath):
|
||||
// internal draw parameters
|
||||
// client-side array transfer buffer params
|
||||
GLuint xferTotalSize;
|
||||
GLuint indexXferOffset;
|
||||
|
@ -142,11 +142,6 @@ void* rglPlatformRasterInit (void);
|
||||
void rglPlatformRasterExit (void* data);
|
||||
void rglPlatformRasterDestroyResources (void);
|
||||
GLboolean rglPlatformNeedsConversion (const rglAttributeState* as, GLuint index);
|
||||
// [YLIN] Try to avoid LHS inside this function.
|
||||
// In oringinal implementation, indexType and indexCount will be stored right before this function
|
||||
// and since we will load them right after enter this function, there are LHS.
|
||||
GLboolean rglPlatformRequiresSlowPath (void *data, const GLenum indexType, uint32_t indexCount);
|
||||
void rglPlatformRasterGetIntegerv( GLenum pname, GLint* params );
|
||||
void rglInvalidateAttributes (void);
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -3564,68 +3564,6 @@ void rglImageFreeCPUStorage(void *data)
|
||||
image->dataState &= ~RGL_IMAGE_DATASTATE_HOST;
|
||||
}
|
||||
|
||||
static void rglSetImage(void *data, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei alignment, GLenum format, GLenum type, const void *pixels )
|
||||
{
|
||||
rglImage *image = (rglImage*)data;
|
||||
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->depth = depth;
|
||||
image->alignment = alignment;
|
||||
|
||||
image->xblk = 0;
|
||||
image->yblk = 0;
|
||||
|
||||
image->xstride = 0;
|
||||
image->ystride = 0;
|
||||
image->zstride = 0;
|
||||
|
||||
image->format = 0;
|
||||
image->type = 0;
|
||||
image->internalFormat = 0;
|
||||
|
||||
rglPlatformChooseInternalStorage( image, internalFormat);
|
||||
|
||||
image->data = NULL;
|
||||
image->mallocData = NULL;
|
||||
image->mallocStorageSize = 0;
|
||||
|
||||
image->isSet = GL_TRUE;
|
||||
|
||||
{
|
||||
if ( image->xstride == 0 )
|
||||
image->xstride = rglGetPixelSize( image->format, image->type );
|
||||
if ( image->ystride == 0 )
|
||||
image->ystride = image->width * image->xstride;
|
||||
if ( image->zstride == 0 )
|
||||
image->zstride = image->height * image->ystride;
|
||||
}
|
||||
|
||||
if (pixels)
|
||||
{
|
||||
rglImageAllocCPUStorage( image );
|
||||
if ( !image->data )
|
||||
return;
|
||||
|
||||
rglRaster raster;
|
||||
raster.format = format;
|
||||
raster.type = type;
|
||||
raster.width = width;
|
||||
raster.height = height;
|
||||
raster.depth = depth;
|
||||
raster.data = (void*)pixels;
|
||||
|
||||
raster.xstride = rglGetPixelSize( raster.format, raster.type );
|
||||
raster.ystride = (raster.width * raster.xstride + alignment - 1) / alignment * alignment;
|
||||
raster.zstride = raster.height * raster.ystride;
|
||||
|
||||
rglRawRasterToImage( &raster, image, 0, 0, 0 );
|
||||
image->dataState = RGL_IMAGE_DATASTATE_HOST;
|
||||
}
|
||||
else
|
||||
image->dataState = RGL_IMAGE_DATASTATE_UNSET;
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
ENGINE
|
||||
============================================================ */
|
||||
@ -4257,13 +4195,62 @@ GLAPI void APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalForm
|
||||
(( const GLubyte* )pixels - ( const GLubyte* )NULL );
|
||||
}
|
||||
|
||||
rglSetImage(
|
||||
image,
|
||||
internalFormat,
|
||||
width, height, 1,
|
||||
LContext->unpackAlignment,
|
||||
format, type,
|
||||
pixels );
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->depth = 1;
|
||||
image->alignment = LContext->unpackAlignment;
|
||||
|
||||
image->xblk = 0;
|
||||
image->yblk = 0;
|
||||
|
||||
image->xstride = 0;
|
||||
image->ystride = 0;
|
||||
image->zstride = 0;
|
||||
|
||||
image->format = 0;
|
||||
image->type = 0;
|
||||
image->internalFormat = 0;
|
||||
|
||||
rglPlatformChooseInternalStorage( image, internalFormat);
|
||||
|
||||
image->data = NULL;
|
||||
image->mallocData = NULL;
|
||||
image->mallocStorageSize = 0;
|
||||
|
||||
image->isSet = GL_TRUE;
|
||||
|
||||
{
|
||||
if ( image->xstride == 0 )
|
||||
image->xstride = rglGetPixelSize( image->format, image->type );
|
||||
if ( image->ystride == 0 )
|
||||
image->ystride = image->width * image->xstride;
|
||||
if ( image->zstride == 0 )
|
||||
image->zstride = image->height * image->ystride;
|
||||
}
|
||||
|
||||
if (pixels)
|
||||
{
|
||||
rglImageAllocCPUStorage( image );
|
||||
if (image->data )
|
||||
{
|
||||
rglRaster raster;
|
||||
raster.format = format;
|
||||
raster.type = type;
|
||||
raster.width = width;
|
||||
raster.height = height;
|
||||
raster.depth = 1;
|
||||
raster.data = (void*)pixels;
|
||||
|
||||
raster.xstride = rglGetPixelSize( raster.format, raster.type );
|
||||
raster.ystride = (raster.width * raster.xstride + LContext->unpackAlignment - 1) / LContext->unpackAlignment * LContext->unpackAlignment;
|
||||
raster.zstride = raster.height * raster.ystride;
|
||||
|
||||
rglRawRasterToImage( &raster, image, 0, 0, 0 );
|
||||
image->dataState = RGL_IMAGE_DATASTATE_HOST;
|
||||
}
|
||||
}
|
||||
else
|
||||
image->dataState = RGL_IMAGE_DATASTATE_UNSET;
|
||||
|
||||
|
||||
if ( LContext->PixelUnpackBuffer != 0 )
|
||||
|
@ -945,9 +945,11 @@ GLboolean rglPlatformBufferObjectUnmap (void *data)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static void rglPlatformBufferObjectSetDataTextureReference(void *buf_data, GLintptr offset, GLsizeiptr size, const GLvoid *data, GLboolean tryImmediateCopy)
|
||||
GLAPI void APIENTRY glBufferSubDataTextureReferenceRA( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data )
|
||||
{
|
||||
rglBufferObject *bufferObject = (rglBufferObject*)buf_data;
|
||||
RGLcontext *LContext = (RGLcontext*)_CurrentContext;
|
||||
GLuint name = LContext->TextureBuffer;
|
||||
rglBufferObject* bufferObject = (rglBufferObject*)LContext->bufferObjectNameSpace.data[name];
|
||||
rglGcmDriver *driver = (rglGcmDriver*)_CurrentDevice->rasterDriver;
|
||||
rglGcmBufferObject *rglBuffer = ( rglGcmBufferObject * )bufferObject->platformBufferObject;
|
||||
CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext;
|
||||
@ -977,15 +979,6 @@ static void rglPlatformBufferObjectSetDataTextureReference(void *buf_data, GLint
|
||||
}
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glBufferSubDataTextureReferenceRA( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data )
|
||||
{
|
||||
RGLcontext *LContext = (RGLcontext*)_CurrentContext;
|
||||
GLuint name = LContext->TextureBuffer;
|
||||
|
||||
rglBufferObject* bufferObject = (rglBufferObject*)LContext->bufferObjectNameSpace.data[name];
|
||||
rglPlatformBufferObjectSetDataTextureReference( bufferObject, offset, size, data, GL_FALSE );
|
||||
}
|
||||
|
||||
char *rglPlatformBufferObjectMapTextureReference(void *data, GLenum access)
|
||||
{
|
||||
rglBufferObject *bufferObject = (rglBufferObject*)data;
|
||||
@ -1018,83 +1011,6 @@ GLboolean rglPlatformBufferObjectUnmapTextureReference (void *data)
|
||||
============================================================ */
|
||||
static void rglPlatformValidateTextureResources (void *data);
|
||||
|
||||
void rglFramebuffer_validate (void *fb_data, void *data)
|
||||
{
|
||||
rglFramebuffer *fb = (rglFramebuffer*)fb_data;
|
||||
RGLcontext *LContext = (RGLcontext*)data;
|
||||
fb->complete = (rglPlatformFramebufferCheckStatus(fb) == GL_FRAMEBUFFER_COMPLETE_OES);
|
||||
|
||||
if (!fb->complete)
|
||||
return;
|
||||
|
||||
GLuint width = CELL_GCM_MAX_RT_DIMENSION;
|
||||
GLuint height = CELL_GCM_MAX_RT_DIMENSION;
|
||||
|
||||
// color
|
||||
fb->rt.colorBufferCount = 0;
|
||||
fb->rt.colorFormat = RGLGCM_NONE;
|
||||
GLuint defaultPitch = 0;
|
||||
GLuint defaultId = GMM_ERROR;
|
||||
GLuint defaultIdOffset = 0;
|
||||
|
||||
for ( int i = 0; i < RGLGCM_SETRENDERTARGET_MAXCOUNT; ++i )
|
||||
{
|
||||
// get the texture and face
|
||||
rglTexture* colorTexture = NULL;
|
||||
GLuint face = 0;
|
||||
rglFramebufferGetAttachmentTexture( LContext, &fb->color[i], &colorTexture, &face );
|
||||
|
||||
if (colorTexture == NULL)
|
||||
continue;
|
||||
|
||||
rglGcmTexture* nvTexture = ( rglGcmTexture * )colorTexture->platformTexture;
|
||||
|
||||
// make sure texture is resident in a supported layout
|
||||
// Some restrictions are added if a texture is used as a
|
||||
// render target:
|
||||
//
|
||||
// - no swizzled semifat or fat formats
|
||||
// - no swizzled smaller than 16x16
|
||||
// - no mipmapped cube maps in tiled memory
|
||||
// - no cube maps with height not a multiple of 16 in tiled
|
||||
// memory
|
||||
//
|
||||
// We may need to reallocate the texture if any of these
|
||||
// are true.
|
||||
//
|
||||
// TODO: Measure time spent here and optimize if indicated.
|
||||
if ( !colorTexture->isRenderTarget )
|
||||
{
|
||||
colorTexture->isRenderTarget = GL_TRUE;
|
||||
colorTexture->revalidate |= RGL_TEXTURE_REVALIDATE_LAYOUT;
|
||||
}
|
||||
rglPlatformValidateTextureResources( colorTexture );
|
||||
colorTexture->image->dataState = RGL_IMAGE_DATASTATE_GPU;
|
||||
|
||||
// set the render target
|
||||
fb->rt.colorId[i] = nvTexture->gpuAddressId;
|
||||
fb->rt.colorIdOffset[i] = nvTexture->gpuAddressIdOffset;
|
||||
fb->rt.colorPitch[i] = nvTexture->gpuLayout.pitch ? nvTexture->gpuLayout.pitch : nvTexture->gpuLayout.pixelBits * nvTexture->gpuLayout.baseWidth / 8;
|
||||
|
||||
width = MIN( width, nvTexture->gpuLayout.baseWidth );
|
||||
height = MIN( height, nvTexture->gpuLayout.baseHeight );
|
||||
fb->rt.colorFormat = nvTexture->gpuLayout.internalFormat;
|
||||
fb->rt.colorBufferCount = i + 1;
|
||||
defaultId = fb->rt.colorId[i];
|
||||
defaultIdOffset = fb->rt.colorIdOffset[i];
|
||||
defaultPitch = fb->rt.colorPitch[i];
|
||||
}
|
||||
|
||||
// framebuffer dimensions are the intersection of attachments
|
||||
fb->rt.width = width;
|
||||
fb->rt.height = height;
|
||||
|
||||
fb->rt.yInverted = false;
|
||||
fb->rt.xOffset = 0;
|
||||
fb->rt.yOffset = 0;
|
||||
fb->needValidate = GL_FALSE;
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glClear( GLbitfield mask )
|
||||
{
|
||||
unsigned int offset_bytes = 0;
|
||||
@ -1122,7 +1038,79 @@ GLAPI void APIENTRY glClear( GLbitfield mask )
|
||||
rglFramebuffer* framebuffer = (rglFramebuffer *)rglGetFramebuffer(LContext, LContext->framebuffer);
|
||||
|
||||
if (framebuffer->needValidate)
|
||||
rglFramebuffer_validate(framebuffer, LContext);
|
||||
{
|
||||
framebuffer->complete = (rglPlatformFramebufferCheckStatus(framebuffer) == GL_FRAMEBUFFER_COMPLETE_OES);
|
||||
|
||||
if (!framebuffer->complete)
|
||||
return;
|
||||
|
||||
GLuint width = CELL_GCM_MAX_RT_DIMENSION;
|
||||
GLuint height = CELL_GCM_MAX_RT_DIMENSION;
|
||||
|
||||
// color
|
||||
framebuffer->rt.colorBufferCount = 0;
|
||||
framebuffer->rt.colorFormat = RGLGCM_NONE;
|
||||
GLuint defaultPitch = 0;
|
||||
GLuint defaultId = GMM_ERROR;
|
||||
GLuint defaultIdOffset = 0;
|
||||
|
||||
for ( int i = 0; i < RGLGCM_SETRENDERTARGET_MAXCOUNT; ++i )
|
||||
{
|
||||
// get the texture and face
|
||||
rglTexture* colorTexture = NULL;
|
||||
GLuint face = 0;
|
||||
rglFramebufferGetAttachmentTexture( LContext, &framebuffer->color[i], &colorTexture, &face );
|
||||
|
||||
if (colorTexture == NULL)
|
||||
continue;
|
||||
|
||||
rglGcmTexture* nvTexture = ( rglGcmTexture * )colorTexture->platformTexture;
|
||||
|
||||
// make sure texture is resident in a supported layout
|
||||
// Some restrictions are added if a texture is used as a
|
||||
// render target:
|
||||
//
|
||||
// - no swizzled semifat or fat formats
|
||||
// - no swizzled smaller than 16x16
|
||||
// - no mipmapped cube maps in tiled memory
|
||||
// - no cube maps with height not a multiple of 16 in tiled
|
||||
// memory
|
||||
//
|
||||
// We may need to reallocate the texture if any of these
|
||||
// are true.
|
||||
//
|
||||
// TODO: Measure time spent here and optimize if indicated.
|
||||
if ( !colorTexture->isRenderTarget )
|
||||
{
|
||||
colorTexture->isRenderTarget = GL_TRUE;
|
||||
colorTexture->revalidate |= RGL_TEXTURE_REVALIDATE_LAYOUT;
|
||||
}
|
||||
rglPlatformValidateTextureResources( colorTexture );
|
||||
colorTexture->image->dataState = RGL_IMAGE_DATASTATE_GPU;
|
||||
|
||||
// set the render target
|
||||
framebuffer->rt.colorId[i] = nvTexture->gpuAddressId;
|
||||
framebuffer->rt.colorIdOffset[i] = nvTexture->gpuAddressIdOffset;
|
||||
framebuffer->rt.colorPitch[i] = nvTexture->gpuLayout.pitch ? nvTexture->gpuLayout.pitch : nvTexture->gpuLayout.pixelBits * nvTexture->gpuLayout.baseWidth / 8;
|
||||
|
||||
width = MIN( width, nvTexture->gpuLayout.baseWidth );
|
||||
height = MIN( height, nvTexture->gpuLayout.baseHeight );
|
||||
framebuffer->rt.colorFormat = nvTexture->gpuLayout.internalFormat;
|
||||
framebuffer->rt.colorBufferCount = i + 1;
|
||||
defaultId = framebuffer->rt.colorId[i];
|
||||
defaultIdOffset = framebuffer->rt.colorIdOffset[i];
|
||||
defaultPitch = framebuffer->rt.colorPitch[i];
|
||||
}
|
||||
|
||||
// framebuffer dimensions are the intersection of attachments
|
||||
framebuffer->rt.width = width;
|
||||
framebuffer->rt.height = height;
|
||||
|
||||
framebuffer->rt.yInverted = false;
|
||||
framebuffer->rt.xOffset = 0;
|
||||
framebuffer->rt.yOffset = 0;
|
||||
framebuffer->needValidate = GL_FALSE;
|
||||
}
|
||||
|
||||
driver->rt = framebuffer->rt;
|
||||
}
|
||||
@ -1229,9 +1217,6 @@ GLenum rglPlatformFramebufferCheckStatus (void *data)
|
||||
return GL_FRAMEBUFFER_COMPLETE_OES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*============================================================
|
||||
PLATFORM RASTER
|
||||
============================================================ */
|
||||
@ -1624,6 +1609,7 @@ GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
RGLcontext* LContext = (RGLcontext*)_CurrentContext;
|
||||
CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext;
|
||||
rglGcmDriver *driver = (rglGcmDriver*)_CurrentDevice->rasterDriver;
|
||||
|
||||
if (RGL_UNLIKELY(!RGLBIT_GET(LContext->attribs->EnabledMask, RGL_ATTRIB_POSITION_INDEX)))
|
||||
return;
|
||||
@ -1642,10 +1628,40 @@ GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count)
|
||||
if (LContext->needValidate)
|
||||
update_state_validation();
|
||||
|
||||
GLboolean slowPath = rglPlatformRequiresSlowPath( dparams, 0, 0);
|
||||
(void)slowPath;
|
||||
GLenum indexType = 0;
|
||||
uint32_t indexCount = 0;
|
||||
|
||||
rglGcmDriver *driver = (rglGcmDriver*)_CurrentDevice->rasterDriver;
|
||||
rglAttributeState *as = (rglAttributeState*)LContext->attribs;
|
||||
|
||||
// are any enabled attributes on the client-side?
|
||||
const GLuint clientSideMask = as->EnabledMask & ~as->HasVBOMask;
|
||||
|
||||
if (RGL_UNLIKELY(clientSideMask))
|
||||
{
|
||||
// determine transfer buffer requirements for client-side attributes
|
||||
for ( int i = 0; i < RGL_MAX_VERTEX_ATTRIBS; ++i )
|
||||
{
|
||||
if (clientSideMask & (1 << i))
|
||||
{
|
||||
rglAttribute* attrib = as->attrib + i;
|
||||
const GLuint freq = attrib->frequency;
|
||||
GLuint count = ( (dparams->firstVertex + dparams->vertexCount) + freq - 1 ) / freq;
|
||||
|
||||
const GLuint numBytes = attrib->clientStride * count;
|
||||
dparams->attribXferOffset[i] = dparams->xferTotalSize;
|
||||
dparams->attribXferSize[i] = numBytes;
|
||||
|
||||
const GLuint numBytesPadded = rglPad( numBytes, 128 );
|
||||
dparams->xferTotalSize += numBytesPadded;
|
||||
dparams->attribXferTotalSize += numBytesPadded;
|
||||
}
|
||||
else
|
||||
{
|
||||
dparams->attribXferOffset[i] = 0;
|
||||
dparams->attribXferSize[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RGL_UNLIKELY(!driver->rtValid))
|
||||
return;
|
||||
@ -1662,7 +1678,6 @@ GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count)
|
||||
|
||||
// validates attributes for specified draw paramaters
|
||||
// gpuOffset is pointer to index buffer
|
||||
rglAttributeState* as = LContext->attribs;
|
||||
|
||||
// allocate upload transfer buffer if necessary
|
||||
// The higher level bounce buffer allocator is used, which means that
|
||||
@ -1840,46 +1855,6 @@ GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count)
|
||||
rglGcmSetDrawArrays(thisContext, gcmMode, dparams->firstVertex, dparams->vertexCount );
|
||||
}
|
||||
|
||||
// must always call this before rglPlatformDraw() to setup rglDrawParams
|
||||
GLboolean rglPlatformRequiresSlowPath (void *data, const GLenum indexType, uint32_t indexCount)
|
||||
{
|
||||
rglDrawParams *dparams = (rglDrawParams*)data;
|
||||
RGLcontext* LContext = (RGLcontext*)_CurrentContext;
|
||||
rglAttributeState* as = (rglAttributeState*)LContext->attribs;
|
||||
|
||||
// are any enabled attributes on the client-side?
|
||||
const GLuint clientSideMask = as->EnabledMask & ~as->HasVBOMask;
|
||||
|
||||
if (RGL_UNLIKELY(clientSideMask))
|
||||
{
|
||||
// determine transfer buffer requirements for client-side attributes
|
||||
for ( int i = 0; i < RGL_MAX_VERTEX_ATTRIBS; ++i )
|
||||
{
|
||||
if (clientSideMask & (1 << i))
|
||||
{
|
||||
rglAttribute* attrib = as->attrib + i;
|
||||
const GLuint freq = attrib->frequency;
|
||||
GLuint count = ( (dparams->firstVertex + dparams->vertexCount) + freq - 1 ) / freq;
|
||||
|
||||
const GLuint numBytes = attrib->clientStride * count;
|
||||
dparams->attribXferOffset[i] = dparams->xferTotalSize;
|
||||
dparams->attribXferSize[i] = numBytes;
|
||||
|
||||
const GLuint numBytesPadded = rglPad( numBytes, 128 );
|
||||
dparams->xferTotalSize += numBytesPadded;
|
||||
dparams->attribXferTotalSize += numBytesPadded;
|
||||
}
|
||||
else
|
||||
{
|
||||
dparams->attribXferOffset[i] = 0;
|
||||
dparams->attribXferSize[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GL_FALSE; // we are finally qualified for the fast path
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
PLATFORM TEXTURE
|
||||
============================================================ */
|
||||
@ -2533,30 +2508,25 @@ GLAPI void APIENTRY glTextureReferenceSCE( GLenum target, GLuint levels,
|
||||
image->height = baseHeight;
|
||||
image->depth = 1;
|
||||
image->alignment = LContext->unpackAlignment;
|
||||
|
||||
image->xblk = 0;
|
||||
image->yblk = 0;
|
||||
|
||||
image->xstride = 0;
|
||||
image->ystride = 0;
|
||||
image->zstride = 0;
|
||||
|
||||
image->format = 0;
|
||||
image->type = 0;
|
||||
image->internalFormat = 0;
|
||||
|
||||
const GLenum status = rglPlatformChooseInternalStorage( image, internalFormat );
|
||||
(( void )status );
|
||||
|
||||
image->data = NULL;
|
||||
image->mallocData = NULL;
|
||||
image->mallocStorageSize = 0;
|
||||
|
||||
image->isSet = GL_TRUE;
|
||||
|
||||
image->xstride = rglGetPixelSize( image->format, image->type );
|
||||
image->ystride = image->width * image->xstride;
|
||||
image->zstride = image->height * image->ystride;
|
||||
|
||||
image->dataState = RGL_IMAGE_DATASTATE_UNSET;
|
||||
|
||||
texture->maxLevel = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user