// For each Direct3D sampler of either the pixel or vertex stage, // looks up the corresponding OpenGL texture image unit and texture type, // and sets the texture and its addressing/filtering state (or NULL when inactive). // Sampler mapping needs to be up-to-date on the program object before this is called. gl::Error RendererD3D::applyTextures(GLImplFactory *implFactory, const gl::ContextState &data, gl::SamplerType shaderType, const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount) { ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram()); ASSERT(!programD3D->isSamplerMappingDirty()); unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) { GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, *data.caps); if (textureUnit != -1) { gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); ASSERT(texture); gl::Sampler *samplerObject = data.state->getSampler(textureUnit); const gl::SamplerState &samplerState = samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); // TODO: std::binary_search may become unavailable using older versions of GCC if (texture->getTextureState().isSamplerComplete(samplerState, data) && !std::binary_search(framebufferTextures.begin(), framebufferTextures.begin() + framebufferTextureCount, texture)) { ANGLE_TRY(setSamplerState(shaderType, samplerIndex, texture, samplerState)); ANGLE_TRY(setTexture(shaderType, samplerIndex, texture)); } else { // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. gl::Texture *incompleteTexture = getIncompleteTexture(implFactory, textureType); ANGLE_TRY(setSamplerState(shaderType, samplerIndex, incompleteTexture, incompleteTexture->getSamplerState())); ANGLE_TRY(setTexture(shaderType, samplerIndex, incompleteTexture)); } } else { // No texture bound to this slot even though it is used by the shader, bind a NULL texture ANGLE_TRY(setTexture(shaderType, samplerIndex, nullptr)); } } // Set all the remaining textures to NULL size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits : data.caps->maxVertexTextureImageUnits; clearTextures(shaderType, samplerRange, samplerCount); return gl::NoError(); }
// For each Direct3D sampler of either the pixel or vertex stage, // looks up the corresponding OpenGL texture image unit and texture type, // and sets the texture and its addressing/filtering state (or NULL when inactive). gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType, const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount) { gl::Program *program = data.state->getProgram(); unsigned int samplerRange = program->getUsedSamplerRange(shaderType); for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) { GLenum textureType = program->getSamplerTextureType(shaderType, samplerIndex); GLint textureUnit = program->getSamplerMapping(shaderType, samplerIndex, *data.caps); if (textureUnit != -1) { gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); ASSERT(texture); gl::SamplerState sampler = texture->getSamplerState(); gl::Sampler *samplerObject = data.state->getSampler(textureUnit); if (samplerObject) { samplerObject->getState(&sampler); } // TODO: std::binary_search may become unavailable using older versions of GCC if (texture->isSamplerComplete(sampler, data) && !std::binary_search(framebufferTextures.begin(), framebufferTextures.begin() + framebufferTextureCount, texture)) { gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler); if (error.isError()) { return error; } error = setTexture(shaderType, samplerIndex, texture); if (error.isError()) { return error; } } else { // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. gl::Texture *incompleteTexture = getIncompleteTexture(textureType); gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture); if (error.isError()) { return error; } } } else { // No texture bound to this slot even though it is used by the shader, bind a NULL texture gl::Error error = setTexture(shaderType, samplerIndex, NULL); if (error.isError()) { return error; } } } // Set all the remaining textures to NULL size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits : data.caps->maxVertexTextureImageUnits; clearTextures(shaderType, samplerRange, samplerCount); return gl::Error(GL_NO_ERROR); }