Fix binding texture error with AZDO

See specification of bindless textures for details
This commit is contained in:
Benau 2016-12-02 20:09:08 +08:00
parent bfc006b979
commit c7d025d81d
10 changed files with 98 additions and 19 deletions

View File

@ -179,23 +179,15 @@ AbstractGeometryPasses::AbstractGeometryPasses()
}
// ----------------------------------------------------------------------------
void AbstractGeometryPasses::setFirstPassRenderTargets(const std::vector<GLuint>& prefilled_textures)
void AbstractGeometryPasses::setFirstPassRenderTargets(const std::vector<GLuint>& prefilled_textures,
const std::vector<uint64_t>& prefilled_handles)
{
m_prefilled_textures = prefilled_textures;
#if !defined(USE_GLES2)
if (CVS->isAZDOEnabled())
{
m_textures_handles.clear();
for(size_t i=0;i<m_prefilled_textures.size();i++)
{
uint64_t handle = 0;
handle = glGetTextureSamplerHandleARB(m_prefilled_textures[i],
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[i]);
if (!glIsTextureHandleResidentARB(handle))
glMakeTextureHandleResidentARB(handle);
m_textures_handles.push_back(handle);
}
m_textures_handles = prefilled_handles;
}
#endif // !defined(USE_GLES2)
}

View File

@ -11,7 +11,7 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy éof the GNU General Public License
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@ -45,7 +45,8 @@ public:
AbstractGeometryPasses();
virtual ~AbstractGeometryPasses(){}
void setFirstPassRenderTargets(const std::vector<GLuint>& prefilled_textures);
void setFirstPassRenderTargets(const std::vector<GLuint>& prefilled_textures,
const std::vector<uint64_t>& prefilled_handles);
virtual void renderSolidFirstPass(const DrawCalls& draw_calls) const = 0;

View File

@ -20,6 +20,7 @@
#include "config/user_config.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/shaders.hpp"
#include "utils/log.hpp"
static GLuint generateRTT3D(GLenum target, size_t w, size_t h, size_t d, GLint internalFormat, GLint format, GLint type, unsigned mipmaplevel = 1)
@ -291,11 +292,39 @@ RTT::RTT(size_t width, size_t height)
glClearColor(.5, .5, .5, .5);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (CVS->isAZDOEnabled())
{
uint64_t handle =
glGetTextureSamplerHandleARB(getRenderTarget(RTT_DIFFUSE),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[0]);
glMakeTextureHandleResidentARB(handle);
m_prefilled_handles.push_back(handle);
handle =
glGetTextureSamplerHandleARB(getRenderTarget(RTT_SPECULAR),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[1]);
glMakeTextureHandleResidentARB(handle);
m_prefilled_handles.push_back(handle);
handle =
glGetTextureSamplerHandleARB(getRenderTarget(RTT_HALF1_R),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[2]);
glMakeTextureHandleResidentARB(handle);
m_prefilled_handles.push_back(handle);
handle =
glGetTextureSamplerHandleARB(getDepthStencilTexture(),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[3]);
glMakeTextureHandleResidentARB(handle);
m_prefilled_handles.push_back(handle);
}
}
RTT::~RTT()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (CVS->isAZDOEnabled())
{
for (uint64_t& handle : m_prefilled_handles)
glMakeTextureHandleNonResidentARB(handle);
}
glDeleteTextures(RTT_COUNT, RenderTargetTextures);
glDeleteTextures(1, &DepthStencilTexture);
if (CVS->isShadowEnabled())

View File

@ -156,10 +156,12 @@ public:
unsigned getDepthStencilTexture() const { return DepthStencilTexture; }
unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; }
FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
const std::vector<uint64_t>& getPrefilledHandles() { return m_prefilled_handles; }
private:
unsigned RenderTargetTextures[RTT_COUNT];
PtrVector<FrameBuffer> FrameBuffers;
std::vector<uint64_t> m_prefilled_handles;
unsigned DepthStencilTexture;
size_t m_width;

View File

@ -53,7 +53,8 @@ void ShaderBasedRenderer::setRTT(RTT* rtts)
rtts->getRenderTarget(RTT_SPECULAR),
rtts->getRenderTarget(RTT_HALF1_R),
rtts->getDepthStencilTexture());
m_geometry_passes->setFirstPassRenderTargets(prefilled_textures);
m_geometry_passes->setFirstPassRenderTargets(prefilled_textures,
rtts->getPrefilledHandles());
m_rtts = rtts;
}
else if (rtts == NULL)

View File

@ -363,7 +363,10 @@ static void setTexture(GLMesh &mesh, unsigned i, bool is_srgb,
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
}
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
insertTextureHandle(mesh.TextureHandles[i]);
}
}
#endif
} // setTexture
@ -449,7 +452,10 @@ void initTexturesTransparent(GLMesh &mesh)
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
}
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
}
#endif
} // initTexturesTransparent

View File

@ -372,7 +372,10 @@ void STKMeshSceneNode::render()
::getInstance()->m_sampler_ids[0]);
}
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
Shaders::ObjectPass1Shader::getInstance()->setTextureHandles(mesh.TextureHandles[0]);
}
else
@ -425,23 +428,32 @@ void STKMeshSceneNode::render()
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] =
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[0]);
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
if (!mesh.TextureHandles[1])
mesh.TextureHandles[1] =
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[1]),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[0]);
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[1]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[1]);
insertTextureHandle(mesh.TextureHandles[1]);
}
if (!mesh.TextureHandles[2])
mesh.TextureHandles[2] =
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[2]),
Shaders::ObjectPass2Shader::getInstance()->m_sampler_ids[0]);
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[2]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[2]);
insertTextureHandle(mesh.TextureHandles[2]);
}
Shaders::ObjectPass2Shader::getInstance()
->setTextureHandles(DiffuseHandle, SpecularHandle, SSAOHandle,
@ -530,9 +542,12 @@ void STKMeshSceneNode::render()
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] =
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
Shaders::TransparentFogShader::getInstance()->m_sampler_ids[0]);
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
Shaders::TransparentFogShader::getInstance()
->setTextureHandles(mesh.TextureHandles[0]);
}
@ -570,9 +585,12 @@ void STKMeshSceneNode::render()
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] =
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
Shaders::TransparentShader::getInstance()->m_sampler_ids[0]);
Shaders::ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
Shaders::TransparentShader::getInstance()->setTextureHandles(mesh.TextureHandles[0]);
}
else

View File

@ -19,6 +19,7 @@
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/shaders.hpp"
#if defined(USE_GLES2)
#define _IRR_COMPILE_WITH_OGLES2_
@ -55,12 +56,28 @@ GLuint getDepthTexture(irr::video::ITexture *tex)
static std::set<irr::video::ITexture *> AlreadyTransformedTexture;
static std::map<int, video::ITexture*> unicolor_cache;
static std::vector<uint64_t> texture_handles;
void resetTextureTable()
{
if (CVS->isAZDOEnabled())
{
// Driver seems to crash if texture handles are not cleared...
for (uint64_t& handle : texture_handles)
{
glMakeTextureHandleNonResidentARB(handle);
}
Shaders::ObjectPass1Shader::getInstance()->recreateTrilinearSampler(0);
texture_handles.clear();
}
AlreadyTransformedTexture.clear();
}
void insertTextureHandle(uint64_t handle)
{
texture_handles.push_back(handle);
}
void cleanUnicolorTextures()
{
for (std::pair<const int, video::ITexture*>& uc : unicolor_cache)

View File

@ -33,5 +33,6 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);
irr::video::ITexture* getUnicolorTexture(const irr::video::SColor &c);
void insertTextureHandle(uint64_t handle);
#endif

View File

@ -243,6 +243,18 @@ public:
for (unsigned i = 0; i < m_sampler_ids.size(); i++)
glDeleteSamplers(1, &m_sampler_ids[i]);
} // ~TextureShader
// ------------------------------------------------------------------------
/** For AZDO to remove the old texture handles, according to specification,
* they can only be removed when the underlying texture or sampler objects
* are finally deleted. This deletion will happen only when no handle
* using the texture or sampler object is resident on any context.
*/
void recreateTrilinearSampler(int sampler_id)
{
glDeleteSamplers(1, &m_sampler_ids[sampler_id]);
m_sampler_ids[sampler_id] =
createSamplers(ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // recreateTrilinearSampler
}; // class TextureShader