Implemented global dynamic texture LOD selection to constrain texture memory usage within bounds
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40108
This commit is contained in:
@@ -132,7 +132,7 @@ void KRCamera::setPosition(const KRVector3 &position) {
|
||||
|
||||
void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
|
||||
{
|
||||
m_pContext->rotateBuffers();
|
||||
m_pContext->rotateBuffers(true);
|
||||
KRMat4 invViewMatrix = viewMatrix;
|
||||
invViewMatrix.invert();
|
||||
|
||||
@@ -234,7 +234,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
||||
backToFrontOrder[i] = frontToBackOrder[7-i];
|
||||
}
|
||||
|
||||
fprintf(stderr, "Draw Order: %i%i%i%i%i%i%i%i ", frontToBackOrder[0], frontToBackOrder[1], frontToBackOrder[2], frontToBackOrder[3], frontToBackOrder[4], frontToBackOrder[5], frontToBackOrder[6], frontToBackOrder[7]);
|
||||
//fprintf(stderr, "Draw Order: %i%i%i%i%i%i%i%i ", frontToBackOrder[0], frontToBackOrder[1], frontToBackOrder[2], frontToBackOrder[3], frontToBackOrder[4], frontToBackOrder[5], frontToBackOrder[6], frontToBackOrder[7]);
|
||||
|
||||
KRBoundingVolume frustrumVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz, perspective_farz);
|
||||
|
||||
@@ -281,10 +281,10 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
||||
GLDEBUG(glDepthMask(GL_FALSE));
|
||||
|
||||
// Set source to buffers from pass 1
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE6));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture));
|
||||
m_pContext->getTextureManager()->selectTexture(7, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(7, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE7));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
|
||||
|
||||
@@ -304,7 +304,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
||||
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT));
|
||||
|
||||
// Set source to buffers from pass 2
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE6));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, lightAccumulationTexture));
|
||||
|
||||
@@ -325,10 +325,10 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
||||
scene.render(this, frontToBackOrder, emptyBoundsSet, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
|
||||
|
||||
// Deactivate source buffer texture units
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE6));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
m_pContext->getTextureManager()->selectTexture(7, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(7, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE7));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
} else {
|
||||
@@ -446,7 +446,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
||||
GLDEBUG(glDepthMask(GL_TRUE));
|
||||
|
||||
|
||||
fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i Kbyte Shader Handles: %i Visible Bounds: %i\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size());
|
||||
fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap());
|
||||
}
|
||||
|
||||
|
||||
@@ -666,11 +666,11 @@ void KRCamera::renderPost()
|
||||
KRVector3 vec4Temp; // Value not used by postshader
|
||||
postShader->bind(this, matIdentity, matIdentity, m_position, vec4Temp, NULL, NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE1));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture));
|
||||
|
||||
@@ -679,11 +679,11 @@ void KRCamera::renderPost()
|
||||
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE1));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
@@ -691,7 +691,7 @@ void KRCamera::renderPost()
|
||||
if(bShowShadowBuffer) {
|
||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
|
||||
|
||||
@@ -701,7 +701,7 @@ void KRCamera::renderPost()
|
||||
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, 0, KRENGINE_VERTICES_2D_SQUARE_UV));
|
||||
|
||||
for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) {
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE1));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVerticesShadow[iShadow]));
|
||||
@@ -709,11 +709,11 @@ void KRCamera::renderPost()
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
}
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE1));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
}
|
||||
@@ -726,11 +726,11 @@ void KRCamera::renderPost()
|
||||
|
||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(1, pFontTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(1, pFontTexture, 2048);
|
||||
|
||||
const char *pChar = szText;
|
||||
int iPos=0;
|
||||
@@ -766,7 +766,7 @@ void KRCamera::renderPost()
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ void KRContext::loadResource(std::string path) {
|
||||
}
|
||||
}
|
||||
|
||||
void KRContext::rotateBuffers() {
|
||||
void KRContext::rotateBuffers(bool new_frame) {
|
||||
//fprintf(stderr, "Rotating Buffers...\n");
|
||||
GLDEBUG(glFinish());
|
||||
|
||||
m_pModelManager->rotateBuffers();
|
||||
m_pTextureManager->rotateBuffers();
|
||||
m_pModelManager->rotateBuffers(new_frame);
|
||||
m_pTextureManager->rotateBuffers(new_frame);
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
|
||||
KRCamera *createCamera(int width, int height);
|
||||
|
||||
void rotateBuffers();
|
||||
void rotateBuffers(bool new_frame);
|
||||
|
||||
private:
|
||||
KRBundleManager *m_pBundleManager;
|
||||
|
||||
@@ -99,7 +99,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume
|
||||
}
|
||||
|
||||
if(cShadowBuffers == 0 && m_pLightMap && pCamera->bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP) {
|
||||
m_pContext->getTextureManager()->selectTexture(3, m_pLightMap);
|
||||
m_pContext->getTextureManager()->selectTexture(3, m_pLightMap, 0);
|
||||
}
|
||||
|
||||
KRMat4 mvpmatrix = m_modelMatrix * viewMatrix * projectionMatrix;
|
||||
|
||||
@@ -151,7 +151,7 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &f
|
||||
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
|
||||
m_flareSize
|
||||
));
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture, 2048);
|
||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
}
|
||||
|
||||
@@ -397,20 +397,20 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
|
||||
GLDEBUG(glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_REFLECTIVITY], m_reflectionFactor));
|
||||
|
||||
if(bDiffuseMap) {
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap);
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, 2048);
|
||||
}
|
||||
|
||||
if(bSpecMap) {
|
||||
m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap);
|
||||
m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, 2048);
|
||||
}
|
||||
|
||||
if(bNormalMap) {
|
||||
m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap);
|
||||
m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, 2048);
|
||||
}
|
||||
|
||||
if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) {
|
||||
// GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering
|
||||
m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap);
|
||||
m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap, 2048);
|
||||
}
|
||||
|
||||
*prevBoundMaterial = this;
|
||||
|
||||
@@ -104,14 +104,14 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex,
|
||||
while(m_vbosPool.size() + m_vbosActive.size() >= KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed >= KRENGINE_MAX_VBO_MEM) {
|
||||
if(m_vbosPool.empty()) {
|
||||
fprintf(stderr, "flushBuffers due to VBO exhaustion...\n");
|
||||
m_pContext->rotateBuffers();
|
||||
m_pContext->rotateBuffers(false);
|
||||
}
|
||||
std::map<GLvoid *, vbo_info_type>::iterator first_itr = m_vbosPool.begin();
|
||||
vbo_info_type firstVBO = first_itr->second;
|
||||
GLDEBUG(glDeleteBuffers(1, &firstVBO.handle));
|
||||
m_vboMemUsed -= firstVBO.size;
|
||||
m_vbosPool.erase(first_itr);
|
||||
//fprintf(stderr, "VBO Swapping...\n");
|
||||
fprintf(stderr, "VBO Swapping...\n");
|
||||
}
|
||||
|
||||
m_currentVBO.handle = -1;
|
||||
@@ -231,7 +231,7 @@ long KRModelManager::getMemUsed()
|
||||
return m_vboMemUsed;
|
||||
}
|
||||
|
||||
void KRModelManager::rotateBuffers()
|
||||
void KRModelManager::rotateBuffers(bool new_frame)
|
||||
{
|
||||
m_vbosPool.insert(m_vbosActive.begin(), m_vbosActive.end());
|
||||
m_vbosActive.clear();
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#define KRMODELMANAGER_H
|
||||
|
||||
#define KRENGINE_MAX_VBO_HANDLES 10000
|
||||
#define KRENGINE_MAX_VBO_MEM 50000000
|
||||
#define KRENGINE_MAX_VBO_MEM 128000000
|
||||
|
||||
#import "KREngine-common.h"
|
||||
#import "KRContextObject.h"
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
KRModelManager(KRContext &context);
|
||||
virtual ~KRModelManager();
|
||||
|
||||
void rotateBuffers();
|
||||
void rotateBuffers(bool new_frame);
|
||||
|
||||
KRModel *loadModel(const char *szName, KRDataBlock *pData);
|
||||
KRModel *getModel(const char *szName);
|
||||
|
||||
@@ -63,7 +63,7 @@ void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visi
|
||||
if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) {
|
||||
|
||||
if(cShadowBuffers > 0) {
|
||||
m_pContext->getTextureManager()->selectTexture(3, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(3, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE3));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[0]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
@@ -73,7 +73,7 @@ void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visi
|
||||
}
|
||||
|
||||
if(cShadowBuffers > 1) {
|
||||
m_pContext->getTextureManager()->selectTexture(4, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(4, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE4));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[1]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
@@ -83,7 +83,7 @@ void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visi
|
||||
}
|
||||
|
||||
if(cShadowBuffers > 2) {
|
||||
m_pContext->getTextureManager()->selectTexture(5, NULL);
|
||||
m_pContext->getTextureManager()->selectTexture(5, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE5));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[2]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
|
||||
@@ -140,12 +140,12 @@ void KRSkyBox::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &
|
||||
// KRShader *pShader = pContext->getShaderManager()->getShader("sky_box", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass);
|
||||
// pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, NULL, NULL, NULL, 0, renderPass);
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pFrontTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(1, m_pBackTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(2, m_pTopTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(3, m_pBottomTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(4, m_pLeftTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(5, m_pRightTexture);
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pFrontTexture, 2048);
|
||||
m_pContext->getTextureManager()->selectTexture(1, m_pBackTexture, 2048);
|
||||
m_pContext->getTextureManager()->selectTexture(2, m_pTopTexture, 2048);
|
||||
m_pContext->getTextureManager()->selectTexture(3, m_pBottomTexture, 2048);
|
||||
m_pContext->getTextureManager()->selectTexture(4, m_pLeftTexture, 2048);
|
||||
m_pContext->getTextureManager()->selectTexture(5, m_pRightTexture, 2048);
|
||||
|
||||
// Disable z-buffer write
|
||||
GLDEBUG(glDepthMask(GL_FALSE));
|
||||
|
||||
@@ -71,8 +71,10 @@ typedef struct _PVRTexHeader
|
||||
|
||||
KRTexture::KRTexture(KRDataBlock *data, KRTextureManager *manager) {
|
||||
m_pData = data;
|
||||
m_iName = 0;
|
||||
m_iHandle = 0;
|
||||
m_pManager = manager;
|
||||
m_current_lod_max_dim = 0;
|
||||
m_textureMemUsed = 0;
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -154,6 +156,9 @@ bool KRTexture::load() {
|
||||
height = 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight;
|
||||
m_min_lod_max_dim = width >> height ? width : height;
|
||||
#endif
|
||||
return true;
|
||||
|
||||
@@ -161,7 +166,8 @@ bool KRTexture::load() {
|
||||
|
||||
|
||||
|
||||
bool KRTexture::createGLTexture() {
|
||||
bool KRTexture::createGLTexture(int lod_max_dim) {
|
||||
m_current_lod_max_dim = 0;
|
||||
int width = m_iWidth;
|
||||
int height = m_iHeight;
|
||||
GLenum err;
|
||||
@@ -170,11 +176,11 @@ bool KRTexture::createGLTexture() {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLDEBUG(glGenTextures(1, &m_iName));
|
||||
if(m_iName == 0) {
|
||||
GLDEBUG(glGenTextures(1, &m_iHandle));
|
||||
if(m_iHandle == 0) {
|
||||
return false;
|
||||
}
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iName));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iHandle));
|
||||
|
||||
if (m_blocks.size() > 1) {
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
|
||||
@@ -184,14 +190,26 @@ bool KRTexture::createGLTexture() {
|
||||
int i=0;
|
||||
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
dataBlockStruct block = *itr;
|
||||
GLDEBUG(glCompressedTexImage2D(GL_TEXTURE_2D, i, m_internalFormat, width, height, 0, block.length, block.start));
|
||||
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
GLDEBUG(glDeleteTextures(1, &m_iName));
|
||||
m_iName = 0;
|
||||
return false;
|
||||
}
|
||||
if(width <= lod_max_dim && height <= lod_max_dim) {
|
||||
if(width > m_current_lod_max_dim) {
|
||||
m_current_lod_max_dim = width;
|
||||
}
|
||||
if(height > m_current_lod_max_dim) {
|
||||
m_current_lod_max_dim = height;
|
||||
}
|
||||
GLDEBUG(glCompressedTexImage2D(GL_TEXTURE_2D, i, m_internalFormat, width, height, 0, block.length, block.start));
|
||||
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
GLDEBUG(glDeleteTextures(1, &m_iHandle));
|
||||
m_textureMemUsed = 0;
|
||||
m_iHandle = 0;
|
||||
lod_max_dim = 0;
|
||||
return false;
|
||||
}
|
||||
m_textureMemUsed += block.length;
|
||||
i++;
|
||||
}
|
||||
|
||||
width = width >> 1;
|
||||
if(width < 1) {
|
||||
@@ -201,16 +219,22 @@ bool KRTexture::createGLTexture() {
|
||||
if(height < 1) {
|
||||
height = 1;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GLuint KRTexture::getHandle(long &textureMemUsed) {
|
||||
if(m_iName == 0) {
|
||||
if(createGLTexture()) {
|
||||
GLuint KRTexture::getHandle(long &textureMemUsed, int max_dim, bool can_resize) {
|
||||
// Constrain target LOD to be within mipmap levels of texture
|
||||
int target_dim = max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
|
||||
if(target_dim > m_max_lod_max_dim) target_dim = m_max_lod_max_dim;
|
||||
|
||||
if(can_resize && m_current_lod_max_dim != target_dim) {
|
||||
releaseHandle(textureMemUsed);
|
||||
}
|
||||
if(m_iHandle == 0) {
|
||||
if(createGLTexture(target_dim)) {
|
||||
textureMemUsed += getMemSize();
|
||||
} else {
|
||||
assert(false);
|
||||
@@ -218,17 +242,18 @@ GLuint KRTexture::getHandle(long &textureMemUsed) {
|
||||
|
||||
//createGLTexture();
|
||||
}
|
||||
return m_iName;
|
||||
return m_iHandle;
|
||||
}
|
||||
|
||||
void KRTexture::releaseHandle(long &textureMemUsed) {
|
||||
if(m_iName != 0) {
|
||||
if(m_iHandle != 0) {
|
||||
textureMemUsed -= getMemSize();
|
||||
GLDEBUG(glDeleteTextures(1, &m_iName));
|
||||
m_iName = 0;
|
||||
GLDEBUG(glDeleteTextures(1, &m_iHandle));
|
||||
m_iHandle = 0;
|
||||
m_textureMemUsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
long KRTexture::getMemSize() {
|
||||
return m_pData->getSize(); // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory
|
||||
return m_textureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory
|
||||
}
|
||||
|
||||
@@ -48,15 +48,15 @@ public:
|
||||
KRTexture(KRDataBlock *data, KRTextureManager *manager);
|
||||
~KRTexture();
|
||||
|
||||
bool createGLTexture();
|
||||
GLuint getHandle(long &textureMemUsed);
|
||||
bool createGLTexture(int lod_max_dim);
|
||||
GLuint getHandle(long &textureMemUsed, int max_dim, bool can_resize);
|
||||
void releaseHandle(long &textureMemUsed);
|
||||
|
||||
long getMemSize();
|
||||
|
||||
private:
|
||||
|
||||
GLuint m_iName;
|
||||
GLuint m_iHandle;
|
||||
uint32_t m_iWidth;
|
||||
uint32_t m_iHeight;
|
||||
GLenum m_internalFormat;
|
||||
@@ -74,7 +74,13 @@ private:
|
||||
bool load();
|
||||
|
||||
KRTextureManager *m_pManager;
|
||||
|
||||
|
||||
int m_current_lod_max_dim;
|
||||
|
||||
uint32_t m_max_lod_max_dim;
|
||||
uint32_t m_min_lod_max_dim;
|
||||
|
||||
uint32_t m_textureMemUsed;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context) {
|
||||
m_textureMemUsed = 0;
|
||||
m_activeTextureMemUsed = 0;
|
||||
m_lod_max_dim_cap = 2048;
|
||||
for(int iTexture=0; iTexture<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) {
|
||||
m_boundTextures[iTexture] = NULL;
|
||||
}
|
||||
@@ -79,16 +81,25 @@ KRTexture *KRTextureManager::getTexture(const char *szName) {
|
||||
|
||||
}
|
||||
|
||||
void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) {
|
||||
void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture, int lod_max_dim) {
|
||||
|
||||
if(m_boundTextures[iTextureUnit] != pTexture) {
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0 + iTextureUnit));
|
||||
if(pTexture != NULL) {
|
||||
m_poolTextures.erase(pTexture);
|
||||
bool bActive = true;
|
||||
if(m_activeTextures.find(pTexture) == m_activeTextures.end()) {
|
||||
bActive = false;
|
||||
m_activeTextures.insert(pTexture);
|
||||
}
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, pTexture->getHandle(m_textureMemUsed)));
|
||||
long textureMemChange = 0;
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, pTexture->getHandle(textureMemChange, lod_max_dim < m_lod_max_dim_cap ? lod_max_dim : m_lod_max_dim_cap, !bActive)));
|
||||
m_textureMemUsed += textureMemChange;
|
||||
if(bActive) {
|
||||
m_activeTextureMemUsed += textureMemChange;
|
||||
} else {
|
||||
m_activeTextureMemUsed += pTexture->getMemSize();
|
||||
}
|
||||
// TODO - These texture parameters should be assigned by the material or texture parameters
|
||||
GLDEBUG(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
|
||||
@@ -99,8 +110,9 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) {
|
||||
m_boundTextures[iTextureUnit] = pTexture;
|
||||
while(m_activeTextures.size() + m_poolTextures.size() > KRENGINE_MAX_TEXTURE_HANDLES || m_textureMemUsed > KRENGINE_MAX_TEXTURE_MEM) {
|
||||
if(m_poolTextures.empty()) {
|
||||
//fprintf(stderr, "flushBuffers due to texture exhaustion...\n");
|
||||
m_pContext->rotateBuffers();
|
||||
fprintf(stderr, "Kraken - Texture swapping...\n");
|
||||
decreaseLODCap();
|
||||
m_pContext->rotateBuffers(false);
|
||||
}
|
||||
// Keep texture size within limits
|
||||
KRTexture *droppedTexture = (*m_poolTextures.begin());
|
||||
@@ -117,11 +129,22 @@ long KRTextureManager::getMemUsed() {
|
||||
return m_textureMemUsed;
|
||||
}
|
||||
|
||||
long KRTextureManager::getActiveMemUsed() {
|
||||
return m_activeTextureMemUsed;
|
||||
}
|
||||
|
||||
void KRTextureManager::rotateBuffers()
|
||||
|
||||
void KRTextureManager::rotateBuffers(bool new_frame)
|
||||
{
|
||||
if(new_frame && m_activeTextureMemUsed < KRENGINE_TARGET_TEXTURE_MEM_MIN && m_activeTextureMemUsed * 4 < KRENGINE_TARGET_TEXTURE_MEM_MAX) {
|
||||
// Increasing the LOD level will generally increase active texture memory usage by 4 times, don't increase the texture level until we can ensure that the LOD won't immediately be dropped back to the current level
|
||||
increaseLODCap();
|
||||
} else if(new_frame && m_activeTextureMemUsed > KRENGINE_TARGET_TEXTURE_MEM_MAX) {
|
||||
decreaseLODCap();
|
||||
}
|
||||
m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end());
|
||||
m_activeTextures.clear();
|
||||
m_activeTextureMemUsed = 0;
|
||||
|
||||
for(int iTexture=0; iTexture < KRENGINE_MAX_TEXTURE_UNITS; iTexture++) {
|
||||
KRTexture *pBoundTexture = m_boundTextures[iTexture];
|
||||
@@ -129,7 +152,28 @@ void KRTextureManager::rotateBuffers()
|
||||
m_poolTextures.erase(pBoundTexture);
|
||||
if(m_activeTextures.find(pBoundTexture) == m_activeTextures.end()) {
|
||||
m_activeTextures.insert(pBoundTexture);
|
||||
m_activeTextureMemUsed += pBoundTexture->getMemSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KRTextureManager::decreaseLODCap()
|
||||
{
|
||||
if(m_lod_max_dim_cap > KRENGINE_MIN_TEXTURE_DIM) {
|
||||
m_lod_max_dim_cap = m_lod_max_dim_cap >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
void KRTextureManager::increaseLODCap()
|
||||
{
|
||||
if(m_lod_max_dim_cap < KRENGINE_MAX_TEXTURE_DIM) {
|
||||
m_lod_max_dim_cap = m_lod_max_dim_cap << 1;
|
||||
}
|
||||
}
|
||||
|
||||
int KRTextureManager::getLODDimCap()
|
||||
{
|
||||
return m_lod_max_dim_cap;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,11 @@
|
||||
|
||||
#define KRENGINE_MAX_TEXTURE_UNITS 8
|
||||
#define KRENGINE_MAX_TEXTURE_HANDLES 10000
|
||||
#define KRENGINE_MAX_TEXTURE_MEM 128000000
|
||||
#define KRENGINE_MAX_TEXTURE_MEM 96000000
|
||||
#define KRENGINE_TARGET_TEXTURE_MEM_MAX 64000000
|
||||
#define KRENGINE_TARGET_TEXTURE_MEM_MIN 32000000
|
||||
#define KRENGINE_MAX_TEXTURE_DIM 2048
|
||||
#define KRENGINE_MIN_TEXTURE_DIM 16
|
||||
|
||||
#ifndef KRTEXTUREMANAGER_H
|
||||
#define KRTEXTUREMANAGER_H
|
||||
@@ -49,9 +53,9 @@ public:
|
||||
KRTextureManager(KRContext &context);
|
||||
virtual ~KRTextureManager();
|
||||
|
||||
void rotateBuffers();
|
||||
void rotateBuffers(bool new_frame);
|
||||
|
||||
void selectTexture(int iTextureUnit, KRTexture *pTexture);
|
||||
void selectTexture(int iTextureUnit, KRTexture *pTexture, int lod_max_dim);
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
@@ -62,8 +66,14 @@ public:
|
||||
KRTexture *getTexture(const char *szFile);
|
||||
|
||||
long getMemUsed();
|
||||
long getActiveMemUsed();
|
||||
|
||||
int getLODDimCap();
|
||||
|
||||
private:
|
||||
void decreaseLODCap();
|
||||
void increaseLODCap();
|
||||
|
||||
std::map<std::string, KRTexture *> m_textures;
|
||||
|
||||
KRTexture *m_boundTextures[KRENGINE_MAX_TEXTURE_UNITS];
|
||||
@@ -71,6 +81,9 @@ private:
|
||||
std::set<KRTexture *> m_poolTextures;
|
||||
|
||||
long m_textureMemUsed;
|
||||
long m_activeTextureMemUsed;
|
||||
|
||||
int m_lod_max_dim_cap;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
}
|
||||
|
||||
[self.engine setNearZ: 5.0];
|
||||
[self.engine setFarZ: 5000.0];
|
||||
[self.engine setFarZ: 1000.0];
|
||||
//[renderEngine setNearZ: 1.0];
|
||||
//[renderEngine setFarZ: 3000.0];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user