Merge branch 'master' of git://github.com/Shyotl/SingularityViewer

This commit is contained in:
Latif Khalifa
2014-02-20 10:31:47 +01:00
6 changed files with 645 additions and 124 deletions

View File

@@ -240,5 +240,16 @@
<key>Value</key> <key>Value</key>
<real>.5</real> <real>.5</real>
</map> </map>
<key>SHAltBatching</key>
<map>
<key>Comment</key>
<string>Experimental retooling of face batching.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<real>1</real>
</map>
</map> </map>
</llsd> </llsd>

View File

@@ -295,14 +295,7 @@ void LLDrawPoolAlpha::render(S32 pass)
} }
} }
if (mVertexShaderLevel > 0) renderAlpha(getVertexDataMask(), pass); //getVertexDataMask base mask if fixed-function.
{
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
}
else
{
renderAlpha(getVertexDataMask(), pass);
}
gGL.setColorMask(true, false); gGL.setColorMask(true, false);
@@ -408,11 +401,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{ {
LLDrawInfo& params = **k; LLDrawInfo& params = **k;
if ((params.mVertexBuffer->getTypeMask() & mask) != mask) /*if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
{ //FIXME! { //FIXME!
llwarns << "Missing required components, skipping render batch." << llendl; llwarns << "Missing required components, skipping render batch." << llendl;
continue; continue;
} }*/
// Fix for bug - NORSPEC-271 // Fix for bug - NORSPEC-271
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
@@ -512,7 +505,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
} }
} }
else if(deferred_render && current_shader == simple_shader) /*else if(deferred_render && current_shader == simple_shader)
{ {
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
@@ -520,7 +513,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
} }*/
if (params.mTextureList.size() > 1) if (params.mTextureList.size() > 1)
{ {
@@ -567,12 +560,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
{ {
LLFastTimer t(FTM_RENDER_ALPHA_PUSH); LLFastTimer t(FTM_RENDER_ALPHA_PUSH);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
// Singu Note: Only remove tan/texcoord1/texcoord2 if actually using the fullbright shader. Material faces ignore fullbright bit.
params.mVertexBuffer->setBuffer(mask & ~((current_shader == fullbright_shader) ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); // Singu Note: If using shaders, pull the attribute mask from it, else used passed base mask.
params.mVertexBuffer->setBuffer(current_shader ? current_shader->mAttributeMask : mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
} }
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
@@ -588,7 +582,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
emissive_shader->bind(); emissive_shader->bind();
// glow doesn't use vertex colors from the mesh data // glow doesn't use vertex colors from the mesh data
params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); // Singu Note: Pull attribs from shader, since we always have one here.
params.mVertexBuffer->setBuffer(emissive_shader->mAttributeMask);
// do the actual drawing, again // do the actual drawing, again
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);

View File

@@ -1297,15 +1297,33 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_color) // FALSE if tep == NULL if (rebuild_color) // FALSE if tep == NULL
{ //decide if shiny goes in alpha channel of color { //decide if shiny goes in alpha channel of color
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
if (tep && if (tep &&
getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny ((!alt_batching && getPoolType() != LLDrawPool::POOL_ALPHA) ||
(alt_batching && getPoolType() != LLDrawPool::POOL_ALPHA &&
getPoolType() != LLDrawPool::POOL_ALPHA_MASK &&
getPoolType() != LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK && // <--- alpha channel MUST contain transparency, not shiny
(getPoolType() != LLDrawPool::POOL_SIMPLE || LLPipeline::sRenderDeferred)))) // Impostor pass for simple uses alpha masking. Need to be opaque.
{ {
LLMaterial* mat = tep->getMaterialParams().get(); LLMaterial* mat = tep->getMaterialParams().get();
bool shiny_in_alpha = false; bool shiny_in_alpha = alt_batching ? true : false;
if(alt_batching)
{
if (LLPipeline::sRenderDeferred) if (LLPipeline::sRenderDeferred)
{ //store shiny in alpha if we don't have a specular map { //store shiny in alpha if we don't have a specular map
if (getPoolType() == LLDrawPool::POOL_MATERIALS && mat->getSpecularID().notNull())
{
shiny_in_alpha = false;
}
}
}
else
{
if (LLPipeline::sRenderDeferred)
{
if (!mat || mat->getSpecularID().isNull()) if (!mat || mat->getSpecularID().isNull())
{ {
shiny_in_alpha = true; shiny_in_alpha = true;
@@ -1318,6 +1336,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
shiny_in_alpha = true; shiny_in_alpha = true;
} }
} }
}
if (shiny_in_alpha) if (shiny_in_alpha)
{ {

View File

@@ -711,7 +711,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group);
void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE); void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
}; };

View File

@@ -4063,8 +4063,12 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)
mSlopRatio = 0.25f; mSlopRatio = 0.25f;
} }
bool can_batch_texture(LLFace* facep) bool can_batch_texture(const LLFace* facep)
{ {
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
if(!alt_batching)
{
if (facep->getTextureEntry()->getBumpmap()) if (facep->getTextureEntry()->getBumpmap())
{ //bump maps aren't worked into texture batching yet { //bump maps aren't worked into texture batching yet
return false; return false;
@@ -4084,6 +4088,30 @@ bool can_batch_texture(LLFace* facep)
{ //texture animation breaks batches { //texture animation breaks batches
return false; return false;
} }
}
else
{
if (facep->getPoolType() == LLDrawPool::POOL_BUMP && (facep->getTextureEntry()->getBumpmap() > 0 && facep->getTextureEntry()->getBumpmap() < 18))
{ //bump maps aren't worked into texture batching yet
return false;
}
if (LLPipeline::sRenderDeferred && (facep->getPoolType() == LLDrawPool::POOL_ALPHA || facep->getPoolType() == LLDrawPool::POOL_MATERIALS) && facep->getTextureEntry()->getMaterialParams().notNull())
{ //materials don't work with texture batching yet
return false;
}
if (facep->getPoolType() != LLDrawPool::POOL_ALPHA && facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)
{ //can't batch invisiprims
return false;
}
if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
{ //texture animation breaks batches
return false;
}
}
return true; return true;
} }
@@ -4093,10 +4121,10 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{ {
LLFastTimer t(FTM_REGISTER_FACE); LLFastTimer t(FTM_REGISTER_FACE);
if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) //if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))
{ //{
LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; // LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
} //}
// if (facep->getViewerObject()->isSelected() && gHideSelectedObjects) // if (facep->getViewerObject()->isSelected() && gHideSelectedObjects)
// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
@@ -4115,11 +4143,21 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
S32 idx = draw_vec.size()-1; S32 idx = draw_vec.size()-1;
BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
BOOL fullbright;
if(!alt_batching)
{
fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
(type == LLRenderPass::PASS_INVISIBLE) || (type == LLRenderPass::PASS_INVISIBLE) ||
(type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) ||
(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
(facep->getTextureEntry()->getFullbright()); (facep->getTextureEntry()->getFullbright());
}
else
{
fullbright = facep->isState(LLFace::FULLBRIGHT);
}
if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
{ {
@@ -4152,15 +4190,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
bool cmp_bump = (type == LLRenderPass::PASS_BUMP) || (type == LLRenderPass::PASS_POST_BUMP);
bool cmp_shiny = !alt_batching ? !!mat : ((type == LLRenderPass::PASS_SHINY) || (type == LLRenderPass::PASS_FULLBRIGHT_SHINY) || (type == LLRenderPass::PASS_INVISI_SHINY));
bool cmp_mat = !alt_batching || LLPipeline::sRenderDeferred && ((facep->getPoolType() == LLDrawPool::POOL_MATERIALS) || (facep->getPoolType() == LLDrawPool::POOL_ALPHA));
U8 bump = facep->getTextureEntry()->getBumpmap();
U8 shiny = facep->getTextureEntry()->getShiny(); U8 shiny = facep->getTextureEntry()->getShiny();
LLViewerTexture* tex = facep->getTexture(); LLViewerTexture* tex = facep->getTexture();
U8 index = facep->getTextureIndex(); U8 index = facep->getTextureIndex();
LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); //LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
bool batchable = false; bool batchable = false;
@@ -4178,10 +4221,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
} }
} }
if (index < 255 && idx >= 0) if (index < 255 && idx >= 0)
{ {
if (mat || draw_vec[idx]->mMaterial) if (cmp_mat && (mat || draw_vec[idx]->mMaterial))
{ //can't batch textures when materials are present (yet) { //can't batch textures when materials are present (yet)
batchable = false; batchable = false;
} }
@@ -4211,14 +4253,15 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif #endif
draw_vec[idx]->mMaterial == mat && (!cmp_mat || draw_vec[idx]->mMaterial == mat) &&
draw_vec[idx]->mMaterialID == mat_id && //draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mFullbright == fullbright &&
draw_vec[idx]->mBump == bump && (!cmp_bump || draw_vec[idx]->mBump == bump) &&
(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different (!cmp_shiny || !!draw_vec[idx]->mShiny == !!shiny) &&
//(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat && draw_vec[idx]->mTextureMatrix == tex_mat &&
draw_vec[idx]->mModelMatrix == model_mat && draw_vec[idx]->mModelMatrix == model_mat &&
draw_vec[idx]->mShaderMask == shader_mask) (!cmp_mat || draw_vec[idx]->mShaderMask == shader_mask))
{ {
draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mEnd += facep->getGeomCount();
@@ -4265,9 +4308,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mMaterial = mat; draw_info->mMaterial = mat;
draw_info->mShaderMask = shader_mask; draw_info->mShaderMask = shader_mask;
if (mat) if (cmp_mat && mat)
{ {
draw_info->mMaterialID = mat_id; //draw_info->mMaterialID = mat_id;
// We have a material. Update our draw info accordingly. // We have a material. Update our draw info accordingly.
@@ -4312,6 +4355,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mTextureList.resize(index+1); draw_info->mTextureList.resize(index+1);
draw_info->mTextureList[index] = tex; draw_info->mTextureList[index] = tex;
} }
draw_info->validate(); draw_info->validate();
} }
} }
@@ -4491,7 +4535,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
vobj->isMesh() && vobj->isMesh() &&
gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); //bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
bool is_rigged = false; bool is_rigged = false;
@@ -4760,18 +4804,66 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
} }
} }
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
bool force_fullbright = group->isHUDGroup();
BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
U32 type = gPipeline.getPoolTypeFromTE(te, tex); U32 type = gPipeline.getPoolTypeFromTE(te, tex);
if(!alt_batching)
{
if (type != LLDrawPool::POOL_ALPHA && force_simple) if (type != LLDrawPool::POOL_ALPHA && force_simple)
{ {
type = LLDrawPool::POOL_SIMPLE; type = LLDrawPool::POOL_SIMPLE;
} }
}
else
{
if (force_fullbright || te->getFullbright())
facep->setState(LLFace::FULLBRIGHT);
if ( type == LLDrawPool::POOL_ALPHA )
{
if(facep->canRenderAsMask())
{
if (facep->isState(LLFace::FULLBRIGHT))
{
type = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK;
}
else
{
type = LLDrawPool::POOL_ALPHA_MASK;
}
}
}
else if (force_fullbright)
{
if(type == LLDrawPool::POOL_ALPHA_MASK)
type = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK;
else
type = LLDrawPool::POOL_FULLBRIGHT;
}
else if(force_simple && type != LLDrawPool::POOL_FULLBRIGHT && type != LLDrawPool::POOL_ALPHA_MASK && type != LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
type = LLDrawPool::POOL_SIMPLE;
}
}
facep->setPoolType(type); facep->setPoolType(type);
if(!alt_batching)
{
if (vobj->isHUDAttachment()) if (vobj->isHUDAttachment())
{ {
facep->setState(LLFace::FULLBRIGHT); facep->setState(LLFace::FULLBRIGHT);
} }
}
/*LLColor4 clr = facep->getFaceColor();
LLColor4U clru = LLColor4U(llround(clr.mV[0] * 255.f), llround(clr.mV[0] * 255.f), llround(clr.mV[0] * 255.f), llround(clr.mV[0] * 255.f));
if(clru.mV[0] == 164 && clru.mV[1] == 106 && clr.mV[2] == 65)
{
llinfos << "Facepool = " << type << " alpha = " << clr.mV[3] << llendl;
}*/
if (vobj->mTextureAnimp && vobj->mTexAnimMode) if (vobj->mTextureAnimp && vobj->mTexAnimMode)
{ {
@@ -4797,8 +4889,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
} }
} }
if (type == LLDrawPool::POOL_ALPHA) if(!alt_batching)
{ {
if (type == LLDrawPool::POOL_ALPHA)
{
if (facep->canRenderAsMask()) if (facep->canRenderAsMask())
{ //can be treated as alpha mask { //can be treated as alpha mask
if (simple_count < MAX_FACE_COUNT) if (simple_count < MAX_FACE_COUNT)
@@ -4824,7 +4918,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ {
facep->mLastUpdateTime = gFrameTimeSeconds; facep->mLastUpdateTime = gFrameTimeSeconds;
} }
if (gPipeline.canUseWindLightShadersOnObjects() if (gPipeline.canUseWindLightShadersOnObjects()
&& LLPipeline::sRenderBump) && LLPipeline::sRenderBump)
{ {
@@ -4832,7 +4925,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
// If we did check, then genDrawInfo would be more lenient than rebuildGeom on deciding if a face verts should have material-related attributes, // If we did check, then genDrawInfo would be more lenient than rebuildGeom on deciding if a face verts should have material-related attributes,
// which would result in a face with a vertex buffer that fails to meet shader attribute requirements. // which would result in a face with a vertex buffer that fails to meet shader attribute requirements.
if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() /* && !te->getMaterialID().isNull()*/) if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() /* && !te->getMaterialID().isNull()*/)
{ {
LLMaterial* mat = te->getMaterialParams().get(); LLMaterial* mat = te->getMaterialParams().get();
if (mat->getNormalID().notNull()) if (mat->getNormalID().notNull())
{ {
@@ -4899,7 +4992,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
} }
} }
else if ((te->getShiny() && LLPipeline::sRenderBump) || else if ((te->getShiny() && LLPipeline::sRenderBump) ||
!(te->getFullbright() || bake_sunlight)) !(te->getFullbright()))
{ //needs normal { //needs normal
if (simple_count < MAX_FACE_COUNT) if (simple_count < MAX_FACE_COUNT)
{ {
@@ -4916,6 +5009,132 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
} }
} }
} }
}
else
{
LLFace*** cur_type = NULL;
U32* cur_count = NULL;
if (type == LLDrawPool::POOL_ALPHA)
{
cur_type = &alpha_faces;
cur_count = &alpha_count;
if (te->getColor().mV[3] > 0.f)
{ //only treat as alpha in the pipeline if < 100% transparent
drawablep->setState(LLDrawable::HAS_ALPHA);
}
LLMaterial* mat = te->getMaterialParams().get();
if(mat && LLPipeline::sRenderDeferred)
{
if (mat->getNormalID().notNull())
{
if (mat->getSpecularID().notNull())
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
cur_type = &normspec_faces;
cur_count = &normspec_count;
}
else
{ //has normal map (needs texcoord1 and tangent)
cur_type = &norm_faces;
cur_count = &norm_count;
}
}
else if (mat->getSpecularID().notNull())
{ //has specular map but no normal map, needs texcoord2
cur_type = &spec_faces;
cur_count = &spec_count;
}
}
}
else if(type == LLDrawPool::POOL_ALPHA_MASK)
{
cur_type = &simple_faces;
cur_count = &simple_count;
}
else if(type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
cur_type = &fullbright_faces;
cur_count = &fullbright_count;
}
else
{
if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
{
facep->mLastUpdateTime = gFrameTimeSeconds;
}
if (type == LLDrawPool::POOL_BUMP)
{ //needs normal + tangent
if(te->getBumpmap() > 0 && te->getBumpmap() < 18)
{
cur_type = &bump_faces;
cur_count = &bump_count;
}
else if(te->getShiny())
{
cur_type = &simple_faces;
cur_count = &simple_count;
}
}
else if (type == LLDrawPool::POOL_SIMPLE)
{ //needs normal + tangent
cur_type = &simple_faces;
cur_count = &simple_count;
}
else if (type == LLDrawPool::POOL_FULLBRIGHT)
{ //doesn't need normal...
if(LLPipeline::sRenderBump && te->getShiny()) //unless it's shiny..
{
cur_type = &simple_faces;
cur_count = &simple_count;
}
else
{
cur_type = &fullbright_faces;
cur_count = &fullbright_count;
}
}
/*Singu Note: Don't check the materials ID, as doing such causes a mismatch between rebuildGeom and genDrawInfo.
If we did check, then genDrawInfo would be more lenient than rebuildGeom on deciding if a face verts should have material-related attributes,
which would result in a face with a vertex buffer that fails to meet shader attribute requirements.*/
else if(type == LLDrawPool::POOL_MATERIALS)
{
LLMaterial* mat = te->getMaterialParams().get();
if (mat->getNormalID().notNull())
{
if (mat->getSpecularID().notNull())
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
cur_type = &normspec_faces;
cur_count = &normspec_count;
}
else
{ //has normal map (needs texcoord1 and tangent)
cur_type = &norm_faces;
cur_count = &norm_count;
}
}
else if (mat->getSpecularID().notNull())
{ //has specular map but no normal map, needs texcoord2
cur_type = &spec_faces;
cur_count = &spec_count;
}
else
{ //has neither specular map nor normal map, only needs texcoord0
cur_type = &simple_faces;
cur_count = &simple_count;
}
}
else
{
llerrs << "Unknown pool type: " << type << llendl;
}
}
llassert_always(cur_type);
if(*cur_count < MAX_FACE_COUNT)
(*cur_type)[(*cur_count)++] = facep;
}
} }
else else
{ //face has no renderable geometry { //face has no renderable geometry
@@ -4946,7 +5165,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//PROCESS NON-ALPHA FACES //PROCESS NON-ALPHA FACES
U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
U32 bump_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1; U32 bump_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;
U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;
@@ -4964,23 +5183,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
} }
BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; BOOL batch_textures = gPipeline.getUseVertexShaders();
if (batch_textures) U32 additional_flags = 0x0;
{ if(batch_textures)
bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; additional_flags |= LLVertexBuffer::MAP_TEXTURE_INDEX;
simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; if(emissive)
alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; additional_flags |= LLVertexBuffer::MAP_EMISSIVE;
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, batch_textures, FALSE); genDrawInfo(group, simple_mask | additional_flags, simple_faces, simple_count, FALSE, batch_textures);
genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, batch_textures); genDrawInfo(group, fullbright_mask | additional_flags, fullbright_faces, fullbright_count, FALSE, batch_textures);
genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, batch_textures); genDrawInfo(group, alpha_mask | additional_flags, alpha_faces, alpha_count, TRUE, batch_textures);
genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE); genDrawInfo(group, bump_mask | additional_flags, bump_faces, bump_count, FALSE);
genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, norm_count, FALSE, FALSE); genDrawInfo(group, norm_mask | additional_flags, norm_faces, norm_count, FALSE);
genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, spec_count, FALSE, FALSE); genDrawInfo(group, spec_mask | additional_flags, spec_faces, spec_count, FALSE);
genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, normspec_count, FALSE, FALSE); genDrawInfo(group, normspec_mask | additional_flags, normspec_faces, normspec_count, FALSE);
if (!LLPipeline::sDelayVBUpdate) if (!LLPipeline::sDelayVBUpdate)
{ {
@@ -5132,29 +5349,76 @@ struct CompareBatchBreakerModified
{ {
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{ {
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
if(!alt_batching)
{
const LLTextureEntry* lte = lhs->getTextureEntry();
const LLTextureEntry* rte = rhs->getTextureEntry();
if (lte->getBumpmap() != rte->getBumpmap())
{
return lte->getBumpmap() < rte->getBumpmap();
}
else if (lte->getFullbright() != rte->getFullbright())
{
return lte->getFullbright() < rte->getFullbright();
}
else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams())
{
return lte->getMaterialParams() < rte->getMaterialParams();
}
else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny()))
{
return lte->getShiny() < rte->getShiny();
}
else
{
return lhs->getTexture() < rhs->getTexture();
}
}
else
{
const LLTextureEntry* lte = lhs->getTextureEntry(); const LLTextureEntry* lte = lhs->getTextureEntry();
const LLTextureEntry* rte = rhs->getTextureEntry(); const LLTextureEntry* rte = rhs->getTextureEntry();
if (lte->getBumpmap() != rte->getBumpmap()) bool batch_left = can_batch_texture(lhs);
bool batch_right = can_batch_texture(rhs);
if (lhs->getPoolType() != rhs->getPoolType())
{ {
return lte->getBumpmap() < rte->getBumpmap(); return lhs->getPoolType() < rhs->getPoolType();
} }
else if (lte->getFullbright() != rte->getFullbright()) else if(batch_left != batch_right) //Move non-batchable faces together.
{ {
return lte->getFullbright() < rte->getFullbright(); return !(batch_left < batch_right);
} }
else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams())
bool batch_shiny = (!LLPipeline::sRenderDeferred || lhs->isState(LLFace::FULLBRIGHT)) && lhs->getPoolType() == LLDrawPool::POOL_BUMP;
if (lhs->isState(LLFace::FULLBRIGHT) != rhs->isState(LLFace::FULLBRIGHT))
{ {
return lte->getMaterialParams() < rte->getMaterialParams(); return lhs->isState(LLFace::FULLBRIGHT) < rhs->isState(LLFace::FULLBRIGHT);
} }
else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) else if(batch_shiny && lte->getShiny() != rte->getShiny())
{ {
return lte->getShiny() < rte->getShiny(); return lte->getShiny() < rte->getShiny();
} }
else if(lhs->getPoolType() == LLDrawPool::POOL_MATERIALS)
{
return lte->getMaterialParams().get() < rte->getMaterialParams().get();
}
else if(lhs->getPoolType() == LLDrawPool::POOL_BUMP)
{
return lte->getBumpmap() < rte->getBumpmap();
}
else else
{ {
return lhs->getTexture() < rhs->getTexture(); return lhs->getTexture() < rhs->getTexture();
} }
}
} }
}; };
@@ -5168,7 +5432,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials) void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures)
{ {
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
@@ -5210,34 +5474,13 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
LLSpatialGroup::buffer_map_t buffer_map; LLSpatialGroup::buffer_map_t buffer_map;
LLViewerTexture* last_tex = NULL; S32 texture_index_channels = llmax(LLGLSLShader::sIndexedTextureChannels-1,1); //always reserve one for shiny for now just for simplicity
S32 buffer_index = 0;
if (distance_sort)
{
buffer_index = -1;
}
S32 texture_index_channels = 1;
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{
static const LLCachedControl<bool> no_texture_indexing("ShyotlUseLegacyTextureBatching",false);
if(!no_texture_indexing)
texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity;
}
if (LLPipeline::sRenderDeferred && distance_sort) if (LLPipeline::sRenderDeferred && distance_sort)
{ {
texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
} }
static const LLCachedControl<U32> max_texture_index("RenderMaxTextureIndex",1);
texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index.get());
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
texture_index_channels = llmin(texture_index_channels, 16);
bool flexi = false; bool flexi = false;
while (face_iter != end_faces) while (face_iter != end_faces)
@@ -5247,23 +5490,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
LLViewerTexture* tex = facep->getTexture(); LLViewerTexture* tex = facep->getTexture();
LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams(); LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams();
if (distance_sort) //bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic();
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
if (!alt_batching && distance_sort)
{ {
tex = NULL; tex = NULL;
} }
if (last_tex == tex)
{
buffer_index++;
}
else
{
last_tex = tex;
buffer_index = 0;
}
bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic();
U32 index_count = facep->getIndicesCount(); U32 index_count = facep->getIndicesCount();
U32 geom_count = facep->getGeomCount(); U32 geom_count = facep->getGeomCount();
@@ -5273,6 +5507,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
LLFace** i = face_iter; LLFace** i = face_iter;
++i; ++i;
if(!alt_batching)
{
const U32 MAX_TEXTURE_COUNT = 32; const U32 MAX_TEXTURE_COUNT = 32;
static LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; static LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
@@ -5389,6 +5625,95 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
} }
} }
}
else
{
LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
if (batch_textures)
{
facep->setTextureIndex(0);
if(can_batch_texture(facep) && texture_index_channels > 1)
{
static const U8 MAX_TEXTURE_COUNT = 32;
static LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
U8 texture_count = 1;
U8 cur_tex = 0;
texture_list[0] = tex;
U8 pool = facep->getPoolType();
while (i != end_faces)
{
facep = *i;
if ( !can_batch_texture(facep) || !(facep) || (geom_count + facep->getGeomCount() > max_vertices) || pool != facep->getPoolType() )
{ //cut batches on geom count too big
break;
}
else
{
if(facep->getTexture() != tex)
{
bool reused = false;
if(distance_sort) //Alpha faces aren't sorted by batch criteria, but rather distance WRT camera.
{
for(U8 j = 0; j < texture_count; ++j)
{
if(texture_list[j] == facep->getTexture())
{
tex = facep->getTexture();
cur_tex = j;
reused = true;
break;
}
}
}
if(!reused)
{
if(++texture_count > llmin((U8)texture_index_channels,MAX_TEXTURE_COUNT))
break;
cur_tex = texture_count - 1;
tex = facep->getTexture();
texture_list[cur_tex] = tex;
}
}
facep->setTextureIndex(cur_tex);
flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
}
++i;
}
}
}
else
{
//face has no texture index
facep->mDrawInfo = NULL;
facep->setTextureIndex(255);
while (i != end_faces &&
(LLPipeline::sTextureBindTest ||
(distance_sort ||
((*i)->getTexture() == tex &&
((*i)->getTextureEntry()->getMaterialParams() == mat)))))
{
facep = *i;
if (geom_count + facep->getGeomCount() > max_vertices)
{ //cut batches on geom count too big
break;
}
//face has no texture index
facep->mDrawInfo = NULL;
facep->setTextureIndex(255);
flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
++i;
}
}
}
if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB) if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
{ {
@@ -5398,14 +5723,19 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
// Singu Note: Catch insufficient vbos right when they are created. Easier to debug. // Singu Note: Catch insufficient vbos right when they are created. Easier to debug.
if(gDebugGL) if(gDebugGL)
{ {
const LLTextureEntry* te = facep->getTextureEntry(); if (LLPipeline::sRenderDeferred &&
if (mat && LLPipeline::sRenderDeferred && !hud_group && (*face_iter)->getTextureEntry()->getMaterialParams().get() &&
!no_materials && ((*face_iter)->getPoolType() == LLDrawPool::POOL_ALPHA ||
!te->getFullbright() && (*face_iter)->getPoolType() == LLDrawPool::POOL_MATERIALS ))
!(te->getColor().mV[3] < 0.999f) &&
!(te->getBumpmap() && (te->getBumpmap() < 18) && (mat->getNormalID().isNull())))
{ {
U32 shader_mask = mat->getShaderMask(); LLMaterial* mat = (*face_iter)->getTextureEntry()->getMaterialParams().get();
U32 shader_mask;
if((*face_iter)->getPoolType() == LLDrawPool::POOL_ALPHA)
shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND);
else
shader_mask = mat->getShaderMask();
if(shader_mask != 1 && shader_mask != 5 && shader_mask != 9 && shader_mask != 13) if(shader_mask != 1 && shader_mask != 5 && shader_mask != 9 && shader_mask != 13)
{ {
LLGLSLShader* shader = &(gDeferredMaterialProgram[shader_mask]); LLGLSLShader* shader = &(gDeferredMaterialProgram[shader_mask]);
@@ -5493,8 +5823,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
index_offset += facep->getGeomCount(); index_offset += facep->getGeomCount();
indices_index += facep->getIndicesCount(); indices_index += facep->getIndicesCount();
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
//append face to appropriate render batch //append face to appropriate render batch
if(!alt_batching)
{
BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA;
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) if ((mask & LLVertexBuffer::MAP_NORMAL) == 0)
@@ -5563,10 +5897,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
} }
} }
} }
else if (no_materials) /*else if (no_materials)
{ {
registerFace(group, facep, LLRenderPass::PASS_SIMPLE); registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
} }*/
else if (!opaque) //Just use opaque instead of te->getColorblahblah else if (!opaque) //Just use opaque instead of te->getColorblahblah
{ {
registerFace(group, facep, LLRenderPass::PASS_ALPHA); registerFace(group, facep, LLRenderPass::PASS_ALPHA);
@@ -5708,7 +6042,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
{ //invisiprim { //invisiprim
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
} }
else if (fullbright || bake_sunlight) else if (fullbright)
{ //fullbright { //fullbright
if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{ {
@@ -5764,11 +6098,126 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
registerFace(group, facep, LLRenderPass::PASS_BUMP); registerFace(group, facep, LLRenderPass::PASS_BUMP);
} }
} }
if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
{ {
registerFace(group, facep, LLRenderPass::PASS_GLOW); registerFace(group, facep, LLRenderPass::PASS_GLOW);
} }
}
else
{
const LLTextureEntry* te = facep->getTextureEntry();
tex = facep->getTexture();
bool is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA;
bool is_shiny_shader = facep->getPoolType() == LLDrawPool::POOL_BUMP && gPipeline.canUseVertexShaders() && te->getShiny();
bool is_shiny_fixed = facep->getPoolType() == LLDrawPool::POOL_BUMP && !gPipeline.canUseVertexShaders() && te->getShiny();
bool is_fullbright = facep->isState(LLFace::FULLBRIGHT);
if (facep->getPoolType() == LLDrawPool::POOL_MATERIALS)
{
U32 pass[] =
{
LLRenderPass::PASS_MATERIAL,
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
LLRenderPass::PASS_SPECMAP,
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND,
LLRenderPass::PASS_SPECMAP_MASK,
LLRenderPass::PASS_SPECMAP_EMISSIVE,
LLRenderPass::PASS_NORMMAP,
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND,
LLRenderPass::PASS_NORMMAP_MASK,
LLRenderPass::PASS_NORMMAP_EMISSIVE,
LLRenderPass::PASS_NORMSPEC,
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND,
LLRenderPass::PASS_NORMSPEC_MASK,
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
U32 mask = mat->getShaderMask();
llassert(mask < sizeof(pass)/sizeof(U32));
mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
registerFace(group, facep, pass[mask]);
}
else if (facep->getPoolType() == LLDrawPool::POOL_ALPHA)
{
// can we safely treat this as an alpha mask?
if (facep->getFaceColor().mV[3] <= 0.f)
{ //100% transparent, don't render unless we're highlighting transparent
registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
}
else
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
}
else if (facep->getPoolType() == LLDrawPool::POOL_ALPHA_MASK)
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
}
else if (facep->getPoolType() == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK)
{
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
}
else
{
if (tex->getPrimaryFormat() == GL_ALPHA)
{
if(is_shiny_shader && facep->getPoolType() == LLDrawPool::POOL_BUMP)
{
registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
}
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
}
else if (facep->getPoolType() == LLDrawPool::POOL_SIMPLE)
{
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
}
else if (facep->getPoolType() == LLDrawPool::POOL_FULLBRIGHT)
{
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
else if (facep->getPoolType() == LLDrawPool::POOL_BUMP)
{
llassert_always(mask & LLVertexBuffer::MAP_NORMAL);
bool is_bump = te->getBumpmap() > 0 && te->getBumpmap() < 18;
if(is_bump)
{
llassert_always(mask & LLVertexBuffer::MAP_TANGENT);
}
if(is_shiny_shader || is_shiny_fixed)
{
llassert_always(mask & LLVertexBuffer::MAP_NORMAL);
}
if (is_fullbright)
{
registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT);
if(is_bump)
registerFace(group, facep, LLPipeline::sRenderDeferred ? LLRenderPass::PASS_POST_BUMP : LLRenderPass::PASS_BUMP);
}
else
{
registerFace(group, facep, (LLPipeline::sRenderDeferred || !is_shiny_shader) ? LLRenderPass::PASS_SIMPLE : LLRenderPass::PASS_SHINY);
if(is_bump)
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
if(is_shiny_fixed)
registerFace(group, facep, LLRenderPass::PASS_SHINY);
}
}
if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
{
registerFace(group, facep, LLRenderPass::PASS_GLOW);
}
}
++face_iter; ++face_iter;
} }

View File

@@ -1531,19 +1531,23 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{ {
switch (mat->getDiffuseAlphaMode()) switch (mat->getDiffuseAlphaMode())
{ {
case 1: case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
break; break;
case 0: //alpha mode set to none, never go to alpha pool case LLMaterial::DIFFUSE_ALPHA_MODE_NONE: //alpha mode set to none, never go to alpha pool
case 3: //alpha mode set to emissive, never go to alpha pool case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: //alpha mode set to emissive, never go to alpha pool
alpha = color_alpha; alpha = color_alpha;
break; break;
default: //alpha mode set to "mask", go to alpha pool if fullbright default: //alpha mode set to "mask", go to alpha pool if fullbright
alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. alpha = color_alpha; // Material's alpha mode is set to mask, or default. Toss it into the opaque material draw pool.
break; break;
} }
} }
static const LLCachedControl<bool> alt_batching("SHAltBatching",true);
if(!alt_batching)
{
if (alpha) if (alpha)
{ {
return LLDrawPool::POOL_ALPHA; return LLDrawPool::POOL_ALPHA;
@@ -1560,6 +1564,49 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{ {
return LLDrawPool::POOL_SIMPLE; return LLDrawPool::POOL_SIMPLE;
} }
}
else
{
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
else if ((!LLPipeline::sRenderDeferred || !mat || mat->getNormalID().isNull()) && LLPipeline::sRenderBump && te->getBumpmap() && te->getBumpmap() < 18)
{
return LLDrawPool::POOL_BUMP; //Bump goes into bump pool unless using deferred and there's a normal map that takes precedence.
}
else if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
if(te->getFullbright())
{
return LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK;
}
else
{
return LLPipeline::sRenderDeferred ? LLDrawPool::POOL_MATERIALS : LLDrawPool::POOL_ALPHA_MASK;
}
}
else if(LLPipeline::sRenderDeferred && mat)
{
if(te->getFullbright() && mat->getEnvironmentIntensity())
{
return LLDrawPool::POOL_FULLBRIGHT;
}
return LLDrawPool::POOL_MATERIALS;
}
else if(te->getFullbright())
{
return (LLPipeline::sRenderBump && te->getShiny()) ? LLDrawPool::POOL_BUMP : LLDrawPool::POOL_FULLBRIGHT;
}
else if (!LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getShiny())
{
return LLDrawPool::POOL_BUMP; //Shiny goes into bump pool when not using deferred rendering.
}
else
{
return LLDrawPool::POOL_SIMPLE;
}
}
} }