summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolbump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolbump.cpp')
-rw-r--r--indra/newview/lldrawpoolbump.cpp943
1 files changed, 379 insertions, 564 deletions
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 14069fa6c2..8db6a10e26 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -47,12 +47,16 @@
#include "pipeline.h"
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
+#include "llmodel.h"
//#include "llimagebmp.h"
//#include "../tools/imdebug/imdebug.h"
// static
LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
+LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
+LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
+LLRenderTarget LLBumpImageList::sRenderTarget;
// static
U32 LLStandardBumpmap::sStandardBumpmapCount = 0;
@@ -73,6 +77,8 @@ static S32 cube_channel = -1;
static S32 diffuse_channel = -1;
static S32 bump_channel = -1;
+#define LL_BUMPLIST_MULTITHREADED 0 // TODO -- figure out why this doesn't work
+
// static
void LLStandardBumpmap::init()
{
@@ -199,32 +205,7 @@ void LLDrawPoolBump::prerender()
// static
S32 LLDrawPoolBump::numBumpPasses()
{
- if (gSavedSettings.getBOOL("RenderObjectBump"))
- {
- if (mShaderLevel > 1)
- {
- if (LLPipeline::sImpostorRender)
- {
- return 2;
- }
- else
- {
- return 3;
- }
- }
- else if (LLPipeline::sImpostorRender)
- {
- return 1;
- }
- else
- {
- return 2;
- }
- }
- else
- {
- return 0;
- }
+ return 1;
}
S32 LLDrawPoolBump::getNumPasses()
@@ -232,140 +213,79 @@ S32 LLDrawPoolBump::getNumPasses()
return numBumpPasses();
}
-void LLDrawPoolBump::beginRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- switch( pass )
- {
- case 0:
- beginShiny();
- break;
- case 1:
- if (mShaderLevel > 1)
- {
- beginFullbrightShiny();
- }
- else
- {
- beginBump();
- }
- break;
- case 2:
- beginBump();
- break;
- default:
- llassert(0);
- break;
- }
-}
-
void LLDrawPoolBump::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-
- if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
- {
- return;
- }
-
- switch( pass )
- {
- case 0:
- renderShiny();
- break;
- case 1:
- if (mShaderLevel > 1)
- {
- renderFullbrightShiny();
- }
- else
- {
- renderBump();
- }
- break;
- case 2:
- renderBump();
- break;
- default:
- llassert(0);
- break;
- }
-}
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-void LLDrawPoolBump::endRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- switch( pass )
- {
- case 0:
- endShiny();
- break;
- case 1:
- if (mShaderLevel > 1)
- {
- endFullbrightShiny();
- }
- else
- {
- endBump();
- }
- break;
- case 2:
- endBump();
- break;
- default:
- llassert(0);
- break;
- }
+ if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
+ {
+ return;
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ mRigged = i == 1;
+
+ // first pass -- shiny
+ beginShiny();
+ renderShiny();
+ endShiny();
- //to cleanup texture channels
- LLRenderPass::endRenderPass(pass);
+ //second pass -- fullbright shiny
+ if (mShaderLevel > 1)
+ {
+ beginFullbrightShiny();
+ renderFullbrightShiny();
+ endFullbrightShiny();
+ }
+
+ //third pass -- bump
+ beginBump();
+ renderBump(LLRenderPass::PASS_BUMP);
+ endBump();
+ }
}
+
//static
-void LLDrawPoolBump::beginShiny(bool invisible)
+void LLDrawPoolBump::beginShiny()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
- (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
- {
- return;
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
+
mShiny = TRUE;
sVertexMask = VERTEX_MASK_SHINY;
// Second pass: environment map
- if (!invisible && mShaderLevel > 1)
+ if (mShaderLevel > 1)
{
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
}
- if (getShaderLevel() > 0)
+ if (LLPipeline::sUnderWaterRender)
{
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectShinyWaterProgram;
- }
- else
- {
- shader = &gObjectShinyProgram;
- }
- shader->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ shader = &gObjectShinyWaterProgram;
}
else
{
- shader = NULL;
+ shader = &gObjectShinyProgram;
}
- bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
+ if (mRigged)
+ {
+ llassert(shader->mRiggedVariant);
+ shader = shader->mRiggedVariant;
+ }
+
+ shader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
+ bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
if (mShaderLevel > 1)
{ //indexed texture rendering, channel 0 is always diffuse
@@ -374,12 +294,12 @@ void LLDrawPoolBump::beginShiny(bool invisible)
}
//static
-void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
+void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
- if (!invisible && shader )
+ if (shader )
{
LLMatrix4 mat;
mat.initRows(LLVector4(gGLModelView+0),
@@ -391,19 +311,18 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
if (shader_level > 1)
{
- cube_map->setMatrix(1);
+ cube_map->setMatrix(1);
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
// the cube map in the one pass shiny shaders
cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
cube_map->enableTexture(cube_channel);
- cube_map->enableTextureCoords(1);
diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
else
{
+ cube_map->setMatrix(0);
cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
diffuse_channel = -1;
- cube_map->setMatrix(0);
cube_map->enable(cube_channel);
}
gGL.getTexUnit(cube_channel)->bind(cube_map);
@@ -415,49 +334,51 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di
diffuse_channel = -1;
gGL.getTexUnit(0)->disable();
cube_map->enable(0);
- cube_map->setMatrix(0);
+ cube_map->setMatrix(0);
gGL.getTexUnit(0)->bind(cube_map);
-
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_VERT_ALPHA);
}
}
}
-void LLDrawPoolBump::renderShiny(bool invisible)
+void LLDrawPoolBump::renderShiny()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
- (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
- {
- return;
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
+
if( gSky.mVOSkyp->getCubeMap() )
{
LLGLEnable blend_enable(GL_BLEND);
- if (!invisible && mShaderLevel > 1)
+ if (mShaderLevel > 1)
{
- LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ if (mRigged)
+ {
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
+ else
+ {
+ LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
}
- else if (!invisible)
+ else
{
- renderGroups(LLRenderPass::PASS_SHINY, sVertexMask);
+ if (mRigged)
+ {
+ gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, sVertexMask, TRUE);
+ }
+ else
+ {
+ gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, sVertexMask, TRUE);
+ }
}
- //else // invisible (deprecated)
- //{
- //renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask);
- //}
}
}
//static
-void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
+void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
- if (!invisible && shader_level > 1)
+ if (shader_level > 1)
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@@ -472,29 +393,15 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
// Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
// MAINT-755
cube_map->disable();
- cube_map->restoreMatrix();
- }
-
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.getTexUnit(diffuse_channel)->disable();
- gGL.getTexUnit(cube_channel)->disable();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+ cube_map->restoreMatrix();
}
}
-void LLDrawPoolBump::endShiny(bool invisible)
+void LLDrawPoolBump::endShiny()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
- (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
- {
- return;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
+ unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
if (shader)
{
shader->unbind();
@@ -507,12 +414,8 @@ void LLDrawPoolBump::endShiny(bool invisible)
void LLDrawPoolBump::beginFullbrightShiny()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
- {
- return;
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
+
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
// Second pass: environment map
@@ -533,6 +436,12 @@ void LLDrawPoolBump::beginFullbrightShiny()
}
}
+ if (mRigged)
+ {
+ llassert(shader->mRiggedVariant);
+ shader = shader->mRiggedVariant;
+ }
+
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
@@ -553,15 +462,14 @@ void LLDrawPoolBump::beginFullbrightShiny()
LLVector3 vec = LLVector3(gShinyOrigin) * mat;
LLVector4 vec4(vec, gShinyOrigin.mV[3]);
- shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
+ shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
- cube_map->setMatrix(1);
+ cube_map->setMatrix(1);
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
// the cube map in the one pass shiny shaders
gGL.getTexUnit(1)->disable();
cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
cube_map->enableTexture(cube_channel);
- cube_map->enableTextureCoords(1);
diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(cube_channel)->bind(cube_map);
@@ -578,11 +486,7 @@ void LLDrawPoolBump::beginFullbrightShiny()
void LLDrawPoolBump::renderFullbrightShiny()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
- {
- return;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
if( gSky.mVOSkyp->getCubeMap() )
{
@@ -590,43 +494,41 @@ void LLDrawPoolBump::renderFullbrightShiny()
if (mShaderLevel > 1)
{
- LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ if (mRigged)
+ {
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
+ else
+ {
+ LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
}
else
{
- LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask);
+ if (mRigged)
+ {
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask);
+ }
+ else
+ {
+ LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask);
+ }
}
}
}
void LLDrawPoolBump::endFullbrightShiny()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
- {
- return;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
cube_map->disable();
- cube_map->restoreMatrix();
-
- /*if (diffuse_channel != 0)
- {
- shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);*/
-
+ cube_map->restoreMatrix();
shader->unbind();
- //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
- //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
diffuse_channel = -1;
cube_channel = 0;
mShiny = FALSE;
@@ -677,6 +579,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel)
//static
BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
//Note: texture atlas does not support bump texture now.
LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ;
if(!tex)
@@ -693,7 +596,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
- bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
+ bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
break;
default:
@@ -709,12 +612,13 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
{
if (channel == -2)
{
- gGL.getTexUnit(1)->bind(bump);
- gGL.getTexUnit(0)->bind(bump);
+ gGL.getTexUnit(1)->bindFast(bump);
+ gGL.getTexUnit(0)->bindFast(bump);
}
else
{
- gGL.getTexUnit(channel)->bind(bump);
+ // NOTE: do not use bindFast here (see SL-16222)
+ gGL.getTexUnit(channel)->bind(bump);
}
return TRUE;
@@ -724,53 +628,22 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
}
//static
-void LLDrawPoolBump::beginBump(U32 pass)
-{
- if (!gPipeline.hasRenderBatches(pass))
- {
- return;
- }
-
+void LLDrawPoolBump::beginBump()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
sVertexMask = VERTEX_MASK_BUMP;
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
// Optional second pass: emboss bump map
stop_glerror();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gObjectBumpProgram.bind();
- }
- else
- {
- // TEXTURE UNIT 0
- // Output.rgb = texture at texture coord 0
- gGL.getTexUnit(0)->activate();
-
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
+ shader = &gObjectBumpProgram;
- // TEXTURE UNIT 1
- gGL.getTexUnit(1)->activate();
-
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ if (mRigged)
+ {
+ llassert(shader->mRiggedVariant);
+ shader = shader->mRiggedVariant;
+ }
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
- // src = tex0 + (1 - tex1) - 0.5
- // = (bump0/2 + 0.5) + (1 - (bump1/2 + 0.5)) - 0.5
- // = (1 + bump0 - bump1) / 2
-
-
- // Blend: src * dst + dst * src
- // = 2 * src * dst
- // = 2 * ((1 + bump0 - bump1) / 2) * dst [0 - 2 * dst]
- // = (1 + bump0 - bump1) * dst.rgb
- // = dst.rgb + dst.rgb * (bump0 - bump1)
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ shader->bind();
gGL.setSceneBlendType(LLRender::BT_MULT_X2);
stop_glerror();
@@ -779,12 +652,7 @@ void LLDrawPoolBump::beginBump(U32 pass)
//static
void LLDrawPoolBump::renderBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(pass))
- {
- return;
- }
-
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
LLGLDisable fog(GL_FOG);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
LLGLEnable blend(GL_BLEND);
@@ -798,28 +666,9 @@ void LLDrawPoolBump::renderBump(U32 pass)
//static
void LLDrawPoolBump::endBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(pass))
- {
- return;
- }
+ gObjectBumpProgram.unbind();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gObjectBumpProgram.unbind();
- }
- else
- {
- // Disable texture blending on unit 1
- gGL.getTexUnit(1)->activate();
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
-
- // Disable texture blending on unit 0
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
-
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
S32 LLDrawPoolBump::getNumDeferredPasses()
@@ -834,101 +683,81 @@ S32 LLDrawPoolBump::getNumDeferredPasses()
}
}
-void LLDrawPoolBump::beginDeferredPass(S32 pass)
-{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
- {
- return;
- }
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- mShiny = TRUE;
- gDeferredBumpProgram.bind();
- diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- bump_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::BUMP_MAP);
- gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
-}
-
-void LLDrawPoolBump::endDeferredPass(S32 pass)
-{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
- {
- return;
- }
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- mShiny = FALSE;
- gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP);
- gDeferredBumpProgram.unbind();
- gGL.getTexUnit(0)->activate();
-}
-
void LLDrawPoolBump::renderDeferred(S32 pass)
{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
- {
- return;
- }
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- U32 type = LLRenderPass::PASS_BUMP;
- LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+ mShiny = TRUE;
+ for (int i = 0; i < 2; ++i)
+ {
+ bool rigged = i == 1;
+ gDeferredBumpProgram.bind(rigged);
+ diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
-
- for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
- {
- LLDrawInfo& params = **i;
+ U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP;
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff);
- LLDrawPoolBump::bindBumpMap(params, bump_channel);
- pushBatch(params, mask, TRUE);
- }
-}
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
-void LLDrawPoolBump::beginPostDeferredPass(S32 pass)
-{
- switch (pass)
- {
- case 0:
- beginFullbrightShiny();
- break;
- case 1:
- beginBump(LLRenderPass::PASS_POST_BUMP);
- break;
- }
-}
+ LLVOAvatar* avatar = nullptr;
+ U64 skin = 0;
-void LLDrawPoolBump::endPostDeferredPass(S32 pass)
-{
- switch (pass)
- {
- case 0:
- endFullbrightShiny();
- break;
- case 1:
- endBump(LLRenderPass::PASS_POST_BUMP);
- break;
- }
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo& params = **i;
+
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
+ LLDrawPoolBump::bindBumpMap(params, bump_channel);
+
+ if (rigged)
+ {
+ if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
+ {
+ uploadMatrixPalette(params);
+ avatar = params.mAvatar;
+ skin = params.mSkinInfo->mHash;
+ }
+ pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE);
+ }
+ else
+ {
+ pushBatch(params, mask, TRUE, FALSE);
+ }
+ }
- //to disable texture channels
- LLRenderPass::endRenderPass(pass);
+ LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP);
+ LLGLSLShader::sCurBoundShaderPtr->unbind();
+ gGL.getTexUnit(0)->activate();
+ }
+
+ mShiny = FALSE;
}
+
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
- switch (pass)
- {
- case 0:
- renderFullbrightShiny();
- break;
- case 1:
- renderBump(LLRenderPass::PASS_POST_BUMP);
- break;
- }
+ for (int i = 0; i < 2; ++i)
+ { // two passes -- static and rigged
+ mRigged = (i == 1);
+
+ // render shiny
+ beginFullbrightShiny();
+ renderFullbrightShiny();
+ endFullbrightShiny();
+
+ //render bump
+ beginBump();
+ renderBump(LLRenderPass::PASS_POST_BUMP);
+ endBump();
+ }
}
+
////////////////////////////////////////////////////////////////
// List of bump-maps created from other textures.
@@ -943,6 +772,8 @@ void LLBumpImageList::init()
LLStandardBumpmap::init();
LLStandardBumpmap::restoreGL();
+ sMainQueue = LL::WorkQueue::getInstance("mainloop");
+ sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
}
void LLBumpImageList::clear()
@@ -952,6 +783,8 @@ void LLBumpImageList::clear()
mBrightnessEntries.clear();
mDarknessEntries.clear();
+ sRenderTarget.release();
+
LLStandardBumpmap::clear();
}
@@ -1061,6 +894,7 @@ void LLBumpImageList::updateImages()
// Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives.
LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code )
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
LLViewerTexture* bump = NULL;
@@ -1090,10 +924,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
}
else
{
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
- raw->clear(0x77, 0x77, 0xFF, 0xFF);
-
- (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+ (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE );
bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
}
@@ -1113,11 +944,10 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
}
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_STANDARD_LOADED("Bump Standard Callback");
-
// static
void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLUUID* source_asset_id = (LLUUID*)userdata;
LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS );
if( final )
@@ -1137,22 +967,17 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTextu
}
}
-static LLTrace::BlockTimerStatHandle FTM_BUMP_GEN_NORMAL("Generate Normal Map");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_CREATE_TEXTURE("Create GL Normal Map");
-
void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
if (success && LLPipeline::sRenderDeferred)
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_STANDARD_LOADED);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_GEN_NORMAL);
generateNormalMapFromAlpha(src, nrm_image);
}
src_vi->setExplicitFormat(GL_RGBA, GL_RGBA);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_CREATE_TEXTURE);
src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
}
}
@@ -1213,43 +1038,32 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr
}
}
-
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_LOADED("Bump Source Loaded");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_ENTRIES_UPDATE("Entries Update");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_MIN_MAX("Min/Max");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_RESCALE("Rescale");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal");
-static LLTrace::BlockTimerStatHandle FTM_BUMP_SOURCE_CREATE("Bump Source Create");
-
// static
void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
{
+ LL_PROFILE_ZONE_SCOPED;
+
if( success )
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_LOADED);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_ENTRIES_UPDATE);
if (iter == entries_list.end() ||
iter->second.isNull() ||
iter->second->getWidth() != src->getWidth() ||
iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
{ //make sure an entry exists for this image
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
- raw->clear(0x77, 0x77, 0xFF, 0xFF);
-
- entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+ entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE);
iter = entries_list.find(src_vi->getID());
}
}
- //if (iter->second->getWidth() != src->getWidth() ||
- // iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
+ if (iter->second->getWidth() != src->getWidth() ||
+ iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
{
LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1);
U8* dst_data = dst_image->getData();
@@ -1277,7 +1091,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
case 1:
case 2:
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_MIN_MAX);
if( src_data_size == dst_data_size * src_components )
{
for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
@@ -1303,7 +1116,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
case 3:
case 4:
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_RGB2LUM);
if( src_data_size == dst_data_size * src_components )
{
for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
@@ -1336,7 +1148,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
if( maximum > minimum )
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_RESCALE);
U8 bias_and_scale_lut[256];
F32 twice_one_over_range = 2.f / (maximum - minimum);
S32 i;
@@ -1366,113 +1177,146 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
}
//---------------------------------------------------
- // immediately assign bump to a global smart pointer in case some local smart pointer
+ // immediately assign bump to a smart pointer in case some local smart pointer
// accidentally releases it.
- LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
+ LLPointer<LLViewerTexture> bump = iter->second;
if (!LLPipeline::sRenderDeferred)
{
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_CREATE);
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
- bump->createGLTexture(0, dst_image);
+
+#if LL_BUMPLIST_MULTITHREADED
+ auto tex_queue = LLImageGLThread::sEnabled ? sTexUpdateQueue.lock() : nullptr;
+
+ if (tex_queue)
+ { //dispatch creation to background thread
+ LLImageRaw* dst_ptr = dst_image;
+ LLViewerTexture* bump_ptr = bump;
+ dst_ptr->ref();
+ bump_ptr->ref();
+ tex_queue->post(
+ [=]()
+ {
+ LL_PROFILE_ZONE_NAMED("bil - create texture");
+ bump_ptr->createGLTexture(0, dst_ptr);
+ bump_ptr->unref();
+ dst_ptr->unref();
+ });
+
+ }
+ else
+#endif
+ {
+ bump->createGLTexture(0, dst_image);
+ }
}
else
{ //convert to normal map
-
- //disable compression on normal maps to prevent errors below
- bump->getGLTexture()->setAllowCompression(false);
-
- {
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_CREATE);
- bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
- bump->createGLTexture(0, dst_image);
- }
-
- {
- LL_RECORD_BLOCK_TIME(FTM_BUMP_SOURCE_GEN_NORMAL);
- gPipeline.mScreen.bindTarget();
-
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable cull(GL_CULL_FACE);
- LLGLDisable blend(GL_BLEND);
- gGL.setColorMask(TRUE, TRUE);
- gNormalMapGenProgram.bind();
-
- static LLStaticHashedString sNormScale("norm_scale");
- static LLStaticHashedString sStepX("stepX");
- static LLStaticHashedString sStepY("stepY");
-
- gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
- gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
- gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
-
- LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
- (F32) bump->getHeight()/gPipeline.mScreen.getHeight());
-
- gGL.getTexUnit(0)->bind(bump);
-
- S32 width = bump->getWidth();
- S32 height = bump->getHeight();
-
- S32 screen_width = gPipeline.mScreen.getWidth();
- S32 screen_height = gPipeline.mScreen.getHeight();
-
- glViewport(0, 0, screen_width, screen_height);
-
- for (S32 left = 0; left < width; left += screen_width)
- {
- S32 right = left + screen_width;
- right = llmin(right, width);
-
- F32 left_tc = (F32) left/ width;
- F32 right_tc = (F32) right/width;
-
- for (S32 bottom = 0; bottom < height; bottom += screen_height)
- {
- S32 top = bottom+screen_height;
- top = llmin(top, height);
-
- F32 bottom_tc = (F32) bottom/height;
- F32 top_tc = (F32)(bottom+screen_height)/height;
- top_tc = llmin(top_tc, 1.f);
-
- F32 screen_right = (F32) (right-left)/screen_width;
- F32 screen_top = (F32) (top-bottom)/screen_height;
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(left_tc, bottom_tc);
- gGL.vertex2f(0, 0);
-
- gGL.texCoord2f(left_tc, top_tc);
- gGL.vertex2f(0, screen_top);
-
- gGL.texCoord2f(right_tc, bottom_tc);
- gGL.vertex2f(screen_right, 0);
-
- gGL.texCoord2f(right_tc, top_tc);
- gGL.vertex2f(screen_right, screen_top);
-
- gGL.end();
-
- gGL.flush();
-
- S32 w = right-left;
- S32 h = top-bottom;
-
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, 0, 0, w, h);
- }
- }
-
- glGenerateMipmap(GL_TEXTURE_2D);
+ LL_PROFILE_ZONE_NAMED("bil - create normal map");
+ LLImageGL* img = bump->getGLTexture();
+ LLImageRaw* dst_ptr = dst_image.get();
+ LLGLTexture* bump_ptr = bump.get();
+
+ dst_ptr->ref();
+ img->ref();
+ bump_ptr->ref();
+ auto create_func = [=]()
+ {
+ img->setUseMipMaps(TRUE);
+ // upload dst_image to GPU (greyscale in red channel)
+ img->setExplicitFormat(GL_RED, GL_RED);
+
+ bump_ptr->createGLTexture(0, dst_ptr);
+ dst_ptr->unref();
+ };
+
+ auto generate_func = [=]()
+ {
+ // Allocate an empty RGBA texture at "tex_name" the same size as bump
+ // Note: bump will still point at GPU copy of dst_image
+ bump_ptr->setExplicitFormat(GL_RGBA, GL_RGBA);
+ LLGLuint tex_name;
+ img->createGLTexture(0, nullptr, 0, 0, true, &tex_name);
+
+ // point render target at empty buffer
+ sRenderTarget.setColorAttachment(img, tex_name);
+
+ // generate normal map in empty texture
+ {
+ sRenderTarget.bindTarget();
+
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+ gGL.setColorMask(TRUE, TRUE);
+
+ gNormalMapGenProgram.bind();
+
+ static LLStaticHashedString sNormScale("norm_scale");
+ static LLStaticHashedString sStepX("stepX");
+ static LLStaticHashedString sStepY("stepY");
+
+ gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
+ gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth());
+ gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight());
+
+ gGL.getTexUnit(0)->bind(bump_ptr);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(0, 0);
+ gGL.vertex2f(0, 0);
+
+ gGL.texCoord2f(0, 1);
+ gGL.vertex2f(0, 1);
+
+ gGL.texCoord2f(1, 0);
+ gGL.vertex2f(1, 0);
+
+ gGL.texCoord2f(1, 1);
+ gGL.vertex2f(1, 1);
+
+ gGL.end();
+
+ gGL.flush();
+
+ gNormalMapGenProgram.unbind();
+
+ sRenderTarget.flush();
+ sRenderTarget.releaseColorAttachment();
+ }
+
+ // point bump at normal map and free gpu copy of dst_image
+ img->syncTexName(tex_name);
+
+ // generate mipmap
+ gGL.getTexUnit(0)->bind(img);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ gGL.getTexUnit(0)->disable();
+
+ bump_ptr->unref();
+ img->unref();
+ };
+
+#if LL_BUMPLIST_MULTITHREADED
+ auto main_queue = LLImageGLThread::sEnabled ? sMainQueue.lock() : nullptr;
+
+ if (main_queue)
+ { //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread
+ main_queue->postTo(
+ sTexUpdateQueue,
+ create_func,
+ generate_func);
+ }
+ else
+#endif
+ { // immediate upload texture and generate normal map
+ create_func();
+ generate_func();
+ }
- gPipeline.mScreen.flush();
- gNormalMapGenProgram.unbind();
-
- //generateNormalMapFromAlpha(dst_image, nrm_image);
- }
}
-
+
iter->second = bump; // derefs (and deletes) old image
//---------------------------------------------------
}
@@ -1481,8 +1325,17 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
void LLDrawPoolBump::renderBump(U32 type, U32 mask)
{
- LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+ LLVOAvatar* avatar = nullptr;
+ U64 skin = 0;
+
+ if (mRigged)
+ { // nudge type enum and include skinweights for rigged pass
+ type += 1;
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
@@ -1490,6 +1343,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
if (LLDrawPoolBump::bindBumpMap(params))
{
+ if (mRigged)
+ {
+ if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
+ {
+ if (uploadMatrixPalette(params))
+ {
+ avatar = params.mAvatar;
+ skin = params.mSkinInfo->mHash;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
pushBatch(params, mask, FALSE);
}
}
@@ -1497,6 +1365,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
applyModelMatrix(params);
bool tex_setup = false;
@@ -1507,7 +1376,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{
if (params.mTextureList[i].notNull())
{
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+ gGL.getTexUnit(i)->bindFast(params.mTextureList[i]);
}
}
}
@@ -1522,13 +1391,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
}
else
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.getTexUnit(1)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- }
-
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
@@ -1545,8 +1407,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{
if (params.mTexture.notNull())
{
- gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
- params.mTexture->addTextureStats(params.mVSize);
+ gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);
}
else
{
@@ -1559,10 +1420,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{
params.mGroup->rebuildMesh();
}
- params.mVertexBuffer->setBuffer(mask);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
- if (tex_setup)
+ params.mVertexBuffer->setBufferFast(mask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+
+ if (tex_setup)
{
if (mShiny)
{
@@ -1570,12 +1431,6 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
}
else
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.getTexUnit(1)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- }
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
}
@@ -1586,9 +1441,9 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
void LLDrawPoolInvisible::render(S32 pass)
{ //render invisiprims
- LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
- if (gPipeline.canUseVertexShaders())
+ if (gPipeline.shadersLoaded())
{
gOcclusionProgram.bind();
}
@@ -1600,48 +1455,8 @@ void LLDrawPoolInvisible::render(S32 pass)
gGL.setColorMask(true, false);
glStencilMask(0xFFFFFFFF);
- if (gPipeline.canUseVertexShaders())
+ if (gPipeline.shadersLoaded())
{
gOcclusionProgram.unbind();
}
-
- if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
- {
- beginShiny(true);
- renderShiny(true);
- endShiny(true);
- }
-}
-
-void LLDrawPoolInvisible::beginDeferredPass(S32 pass)
-{
- beginRenderPass(pass);
-}
-
-void LLDrawPoolInvisible::endDeferredPass( S32 pass )
-{
- endRenderPass(pass);
-}
-
-void LLDrawPoolInvisible::renderDeferred( S32 pass )
-{ //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff
-#if 0
- LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
-
- U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
- glStencilMask(0);
- glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE);
- gGL.setColorMask(false, false);
- pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
- gGL.setColorMask(true, true);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- glStencilMask(0xFFFFFFFF);
-
- if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
- {
- beginShiny(true);
- renderShiny(true);
- endShiny(true);
- }
-#endif
}