Commit 253daa56 by Jamie Madill Committed by Commit Bot

D3D: Split applyTextures into each back-end.

This paves the way for a dirty bits implementation for Textures, and also will allow more precise ordering of the state update in D3D11. The latter becomes important when moving the shader application. Because the texture update can affect the built-in driver uniforms, we neeed to update textures before we update the uniforms. BUG=angleproject:1156 BUG=angleproject:1387 Change-Id: I995e095517c598d8672c6400d08a430da0e8339b Reviewed-on: https://chromium-review.googlesource.com/580361Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 590f6235
...@@ -59,88 +59,6 @@ void RendererD3D::cleanup() ...@@ -59,88 +59,6 @@ void RendererD3D::cleanup()
mIncompleteTextures.clear(); mIncompleteTextures.clear();
} }
// 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(const gl::Context *context,
gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures,
size_t framebufferTextureCount)
{
const auto &glState = context->getGLState();
const auto &caps = context->getCaps();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
ASSERT(!programD3D->isSamplerMappingDirty());
// TODO(jmadill): Use the Program's sampler bindings.
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, caps);
if (textureUnit != -1)
{
gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
ASSERT(texture);
gl::Sampler *samplerObject = glState.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,
context->getContextState()) &&
!std::binary_search(framebufferTextures.begin(),
framebufferTextures.begin() + framebufferTextureCount, texture))
{
ANGLE_TRY(
setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
ANGLE_TRY(setTexture(context, 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(context, textureType);
ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
incompleteTexture->getSamplerState()));
ANGLE_TRY(setTexture(context, 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(context, shaderType, samplerIndex, nullptr));
}
}
// Set all the remaining textures to NULL
size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits
: caps.maxVertexTextureImageUnits;
clearTextures(context, shaderType, samplerRange, samplerCount);
return gl::NoError();
}
gl::Error RendererD3D::applyTextures(const gl::Context *context)
{
FramebufferTextureArray framebufferTextures;
size_t framebufferSerialCount =
getBoundFramebufferTextures(context->getContextState(), &framebufferTextures);
ANGLE_TRY(
applyTextures(context, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount));
ANGLE_TRY(
applyTextures(context, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount));
return gl::NoError();
}
bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode) bool RendererD3D::skipDraw(const gl::ContextState &data, GLenum drawMode)
{ {
const gl::State &state = data.getState(); const gl::State &state = data.getState();
......
...@@ -104,6 +104,8 @@ class BufferFactoryD3D : angle::NonCopyable ...@@ -104,6 +104,8 @@ class BufferFactoryD3D : angle::NonCopyable
}; };
using AttribIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>; using AttribIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>;
using FramebufferTextureArray =
std::array<gl::Texture *, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
class RendererD3D : public BufferFactoryD3D class RendererD3D : public BufferFactoryD3D
{ {
...@@ -147,16 +149,6 @@ class RendererD3D : public BufferFactoryD3D ...@@ -147,16 +149,6 @@ class RendererD3D : public BufferFactoryD3D
HANDLE shareHandle, HANDLE shareHandle,
const egl::AttributeMap &attribs) const = 0; const egl::AttributeMap &attribs) const = 0;
virtual gl::Error setSamplerState(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture,
const gl::SamplerState &sampler) = 0;
virtual gl::Error setTexture(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture) = 0;
virtual gl::Error setUniformBuffers(const gl::ContextState &data, virtual gl::Error setUniformBuffers(const gl::ContextState &data,
const std::vector<GLint> &vertexUniformBuffers, const std::vector<GLint> &vertexUniformBuffers,
const std::vector<GLint> &fragmentUniformBuffers) = 0; const std::vector<GLint> &fragmentUniformBuffers) = 0;
...@@ -301,12 +293,6 @@ class RendererD3D : public BufferFactoryD3D ...@@ -301,12 +293,6 @@ class RendererD3D : public BufferFactoryD3D
GLint getGPUDisjoint(); GLint getGPUDisjoint();
GLint64 getTimestamp(); GLint64 getTimestamp();
// In D3D11, faster than calling setTexture a jillion times
virtual gl::Error clearTextures(const gl::Context *context,
gl::SamplerType samplerType,
size_t rangeStart,
size_t rangeEnd) = 0;
virtual gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, virtual gl::Error clearRenderTarget(RenderTargetD3D *renderTarget,
const gl::ColorF &clearValues) = 0; const gl::ColorF &clearValues) = 0;
...@@ -336,6 +322,11 @@ class RendererD3D : public BufferFactoryD3D ...@@ -336,6 +322,11 @@ class RendererD3D : public BufferFactoryD3D
bool isRobustResourceInitEnabled() const; bool isRobustResourceInitEnabled() const;
size_t getBoundFramebufferTextures(const gl::ContextState &data,
FramebufferTextureArray *outTextureArray);
gl::Texture *getIncompleteTexture(const gl::Context *context, GLenum type);
protected: protected:
virtual bool getLUID(LUID *adapterLuid) const = 0; virtual bool getLUID(LUID *adapterLuid) const = 0;
virtual void generateCaps(gl::Caps *outCaps, virtual void generateCaps(gl::Caps *outCaps,
...@@ -347,7 +338,6 @@ class RendererD3D : public BufferFactoryD3D ...@@ -347,7 +338,6 @@ class RendererD3D : public BufferFactoryD3D
// dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state. // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
gl::Error applyTextures(const gl::Context *context);
bool skipDraw(const gl::ContextState &data, GLenum drawMode); bool skipDraw(const gl::ContextState &data, GLenum drawMode);
gl::Error markTransformFeedbackUsage(const gl::ContextState &data); gl::Error markTransformFeedbackUsage(const gl::ContextState &data);
...@@ -358,17 +348,6 @@ class RendererD3D : public BufferFactoryD3D ...@@ -358,17 +348,6 @@ class RendererD3D : public BufferFactoryD3D
private: private:
void ensureCapsInitialized() const; void ensureCapsInitialized() const;
typedef std::array<gl::Texture*, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureArray;
gl::Error applyTextures(const gl::Context *context,
gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures,
size_t framebufferTextureCount);
size_t getBoundFramebufferTextures(const gl::ContextState &data,
FramebufferTextureArray *outTextureArray);
gl::Texture *getIncompleteTexture(const gl::Context *context, GLenum type);
virtual angle::WorkaroundsD3D generateWorkarounds() const = 0; virtual angle::WorkaroundsD3D generateWorkarounds() const = 0;
mutable bool mCapsInitialized; mutable bool mCapsInitialized;
......
...@@ -360,22 +360,6 @@ void GetTriFanIndices(const void *indices, ...@@ -360,22 +360,6 @@ void GetTriFanIndices(const void *indices,
} }
} }
int GetWrapBits(GLenum wrap)
{
switch (wrap)
{
case GL_CLAMP_TO_EDGE:
return 0x1;
case GL_REPEAT:
return 0x2;
case GL_MIRRORED_REPEAT:
return 0x3;
default:
UNREACHABLE();
return 0;
}
}
const uint32_t ScratchMemoryBufferLifetime = 1000; const uint32_t ScratchMemoryBufferLifetime = 1000;
} // anonymous namespace } // anonymous namespace
...@@ -817,20 +801,6 @@ void Renderer11::initializeDevice() ...@@ -817,20 +801,6 @@ void Renderer11::initializeDevice()
mStateManager.initialize(rendererCaps); mStateManager.initialize(rendererCaps);
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mSamplerMetadataVS.initData(rendererCaps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
mSamplerMetadataPS.initData(rendererCaps.maxTextureImageUnits);
mForceSetComputeSamplerStates.resize(rendererCaps.maxComputeTextureImageUnits);
mCurComputeSamplerStates.resize(rendererCaps.maxComputeTextureImageUnits);
mSamplerMetadataCS.initData(rendererCaps.maxComputeTextureImageUnits);
mStateManager.initialize(rendererCaps);
// No context is available here, use the proxy context in the display. // No context is available here, use the proxy context in the display.
markAllStateDirty(mDisplay->getProxyContext()); markAllStateDirty(mDisplay->getProxyContext());
...@@ -1404,134 +1374,6 @@ gl::Error Renderer11::generateSwizzles(const gl::Context *context) ...@@ -1404,134 +1374,6 @@ gl::Error Renderer11::generateSwizzles(const gl::Context *context)
ANGLE_TRY(generateSwizzles(context, gl::SAMPLER_PIXEL)); ANGLE_TRY(generateSwizzles(context, gl::SAMPLER_PIXEL));
return gl::NoError(); return gl::NoError();
} }
gl::Error Renderer11::setSamplerState(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture,
const gl::SamplerState &samplerState)
{
#if !defined(NDEBUG)
// Make sure to add the level offset for our tiny compressed texture workaround
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
TextureStorage *storage = nullptr;
ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
// Storage should exist, texture should be complete
ASSERT(storage);
#endif // !defined(NDEBUG)
// Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
// sampler state since having it in contiguous memory makes it possible to memcpy to a constant
// buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers.
SamplerMetadataD3D11 *metadata = nullptr;
if (type == gl::SAMPLER_PIXEL)
{
ASSERT(static_cast<unsigned int>(index) < getNativeCaps().maxTextureImageUnits);
if (mForceSetPixelSamplerStates[index] ||
memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = nullptr;
ANGLE_TRY(mStateCache.getSamplerState(this, samplerState, &dxSamplerState));
ASSERT(dxSamplerState != nullptr);
mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
mCurPixelSamplerStates[index] = samplerState;
}
mForceSetPixelSamplerStates[index] = false;
metadata = &mSamplerMetadataPS;
}
else if (type == gl::SAMPLER_VERTEX)
{
ASSERT(static_cast<unsigned int>(index) < getNativeCaps().maxVertexTextureImageUnits);
if (mForceSetVertexSamplerStates[index] ||
memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = nullptr;
ANGLE_TRY(mStateCache.getSamplerState(this, samplerState, &dxSamplerState));
ASSERT(dxSamplerState != nullptr);
mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
mCurVertexSamplerStates[index] = samplerState;
}
mForceSetVertexSamplerStates[index] = false;
metadata = &mSamplerMetadataVS;
}
else if (type == gl::SAMPLER_COMPUTE)
{
ASSERT(static_cast<unsigned int>(index) < getNativeCaps().maxComputeTextureImageUnits);
if (mForceSetComputeSamplerStates[index] ||
memcmp(&samplerState, &mCurComputeSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = nullptr;
ANGLE_TRY(mStateCache.getSamplerState(this, samplerState, &dxSamplerState));
ASSERT(dxSamplerState != nullptr);
mDeviceContext->CSSetSamplers(index, 1, &dxSamplerState);
mCurComputeSamplerStates[index] = samplerState;
}
mForceSetComputeSamplerStates[index] = false;
metadata = &mSamplerMetadataCS;
}
else
UNREACHABLE();
ASSERT(metadata != nullptr);
metadata->update(index, *texture);
return gl::NoError();
}
gl::Error Renderer11::setTexture(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture)
{
const d3d11::SharedSRV *textureSRV = nullptr;
if (texture)
{
TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
TextureStorage *texStorage = nullptr;
ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
// Texture should be complete and have a storage
ASSERT(texStorage);
TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
ANGLE_TRY(storage11->getSRV(context, texture->getTextureState(), &textureSRV));
// If we get an invalid SRV here, something went wrong in the texture class and we're
// unexpectedly missing the shader resource view.
ASSERT(textureSRV->valid());
textureImpl->resetDirty();
}
ASSERT((type == gl::SAMPLER_PIXEL &&
static_cast<unsigned int>(index) < getNativeCaps().maxTextureImageUnits) ||
(type == gl::SAMPLER_VERTEX &&
static_cast<unsigned int>(index) < getNativeCaps().maxVertexTextureImageUnits));
mStateManager.setShaderResource(type, index, textureSRV->get());
return gl::NoError();
}
gl::Error Renderer11::setUniformBuffers(const gl::ContextState &data, gl::Error Renderer11::setUniformBuffers(const gl::ContextState &data,
const std::vector<GLint> &vertexUniformBuffers, const std::vector<GLint> &vertexUniformBuffers,
...@@ -2398,6 +2240,7 @@ gl::Error Renderer11::applyShaders(const gl::Context *context, GLenum drawMode) ...@@ -2398,6 +2240,7 @@ gl::Error Renderer11::applyShaders(const gl::Context *context, GLenum drawMode)
return programD3D->applyUniforms(drawMode); return programD3D->applyUniforms(drawMode);
} }
// TODO(jmadill): Move to StateManager11.
gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
GLenum drawMode, GLenum drawMode,
const std::vector<D3DUniform *> &uniformArray) const std::vector<D3DUniform *> &uniformArray)
...@@ -2505,12 +2348,15 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2505,12 +2348,15 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
mCurrentPixelConstantBuffer = reinterpret_cast<uintptr_t>(appliedPixelConstants); mCurrentPixelConstantBuffer = reinterpret_cast<uintptr_t>(appliedPixelConstants);
} }
auto *samplerMetadataVS = mStateManager.getVertexSamplerMetadata();
auto *samplerMetadataPS = mStateManager.getPixelSamplerMetadata();
if (!mDriverConstantBufferVS.valid()) if (!mDriverConstantBufferVS.valid())
{ {
D3D11_BUFFER_DESC constantBufferDescription = {0}; D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc( d3d11::InitConstantBufferDesc(
&constantBufferDescription, &constantBufferDescription,
sizeof(dx_VertexConstants11) + mSamplerMetadataVS.sizeBytes()); sizeof(dx_VertexConstants11) + samplerMetadataVS->sizeBytes());
ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferVS)); ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferVS));
ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get(); ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get();
...@@ -2522,7 +2368,7 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2522,7 +2368,7 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
{ {
D3D11_BUFFER_DESC constantBufferDescription = {0}; D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(&constantBufferDescription, d3d11::InitConstantBufferDesc(&constantBufferDescription,
sizeof(dx_PixelConstants11) + mSamplerMetadataPS.sizeBytes()); sizeof(dx_PixelConstants11) + samplerMetadataPS->sizeBytes());
ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferPS)); ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferPS));
ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get(); ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get();
...@@ -2533,15 +2379,15 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2533,15 +2379,15 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
// Sampler metadata and driver constants need to coexist in the same constant buffer to conserve // Sampler metadata and driver constants need to coexist in the same constant buffer to conserve
// constant buffer slots. We update both in the constant buffer if needed. // constant buffer slots. We update both in the constant buffer if needed.
const dx_VertexConstants11 &vertexConstants = mStateManager.getVertexConstants(); const dx_VertexConstants11 &vertexConstants = mStateManager.getVertexConstants();
size_t samplerMetadataReferencedBytesVS = sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * size_t samplerMetadataReferencedBytesVS = sizeof(SamplerMetadata11::dx_SamplerMetadata) *
programD3D.getUsedSamplerRange(gl::SAMPLER_VERTEX); programD3D.getUsedSamplerRange(gl::SAMPLER_VERTEX);
applyDriverConstantsIfNeeded(&mAppliedVertexConstants, vertexConstants, &mSamplerMetadataVS, applyDriverConstantsIfNeeded(&mAppliedVertexConstants, vertexConstants, samplerMetadataVS,
samplerMetadataReferencedBytesVS, mDriverConstantBufferVS); samplerMetadataReferencedBytesVS, mDriverConstantBufferVS);
const dx_PixelConstants11 &pixelConstants = mStateManager.getPixelConstants(); const dx_PixelConstants11 &pixelConstants = mStateManager.getPixelConstants();
size_t samplerMetadataReferencedBytesPS = sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * size_t samplerMetadataReferencedBytesPS = sizeof(SamplerMetadata11::dx_SamplerMetadata) *
programD3D.getUsedSamplerRange(gl::SAMPLER_PIXEL); programD3D.getUsedSamplerRange(gl::SAMPLER_PIXEL);
applyDriverConstantsIfNeeded(&mAppliedPixelConstants, pixelConstants, &mSamplerMetadataPS, applyDriverConstantsIfNeeded(&mAppliedPixelConstants, pixelConstants, samplerMetadataPS,
samplerMetadataReferencedBytesPS, mDriverConstantBufferPS); samplerMetadataReferencedBytesPS, mDriverConstantBufferPS);
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
...@@ -2560,115 +2406,10 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, ...@@ -2560,115 +2406,10 @@ gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
return gl::NoError(); return gl::NoError();
} }
// SamplerMetadataD3D11 implementation
Renderer11::SamplerMetadataD3D11::SamplerMetadataD3D11() : mDirty(true)
{
}
Renderer11::SamplerMetadataD3D11::~SamplerMetadataD3D11()
{
}
void Renderer11::SamplerMetadataD3D11::initData(unsigned int samplerCount)
{
mSamplerMetadata.resize(samplerCount);
}
void Renderer11::SamplerMetadataD3D11::update(unsigned int samplerIndex, const gl::Texture &texture)
{
unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
GLenum sizedFormat =
texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat;
if (mSamplerMetadata[samplerIndex].baseLevel != static_cast<int>(baseLevel))
{
mSamplerMetadata[samplerIndex].baseLevel = static_cast<int>(baseLevel);
mDirty = true;
}
// Some metadata is needed only for integer textures. We avoid updating the constant buffer
// unnecessarily by changing the data only in case the texture is an integer texture and
// the values have changed.
bool needIntegerTextureMetadata = false;
// internalFormatBits == 0 means a 32-bit texture in the case of integer textures.
int internalFormatBits = 0;
switch (sizedFormat)
{
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGB32I:
case GL_RGB32UI:
case GL_RG32I:
case GL_RG32UI:
case GL_R32I:
case GL_R32UI:
needIntegerTextureMetadata = true;
break;
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RG16I:
case GL_RG16UI:
case GL_R16I:
case GL_R16UI:
needIntegerTextureMetadata = true;
internalFormatBits = 16;
break;
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_RGB8I:
case GL_RGB8UI:
case GL_RG8I:
case GL_RG8UI:
case GL_R8I:
case GL_R8UI:
needIntegerTextureMetadata = true;
internalFormatBits = 8;
break;
case GL_RGB10_A2UI:
needIntegerTextureMetadata = true;
internalFormatBits = 10;
break;
default:
break;
}
if (needIntegerTextureMetadata)
{
if (mSamplerMetadata[samplerIndex].internalFormatBits != internalFormatBits)
{
mSamplerMetadata[samplerIndex].internalFormatBits = internalFormatBits;
mDirty = true;
}
// Pack the wrap values into one integer so we can fit all the metadata in one 4-integer
// vector.
GLenum wrapS = texture.getWrapS();
GLenum wrapT = texture.getWrapT();
GLenum wrapR = texture.getWrapR();
int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4);
if (mSamplerMetadata[samplerIndex].wrapModes != wrapModes)
{
mSamplerMetadata[samplerIndex].wrapModes = wrapModes;
mDirty = true;
}
}
}
const Renderer11::SamplerMetadataD3D11::dx_SamplerMetadata *
Renderer11::SamplerMetadataD3D11::getData() const
{
return mSamplerMetadata.data();
}
size_t Renderer11::SamplerMetadataD3D11::sizeBytes() const
{
return sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * mSamplerMetadata.size();
}
template <class TShaderConstants> template <class TShaderConstants>
void Renderer11::applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants, void Renderer11::applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants,
const TShaderConstants &constants, const TShaderConstants &constants,
SamplerMetadataD3D11 *samplerMetadata, SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes, size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer) const d3d11::Buffer &driverConstantBuffer)
{ {
...@@ -2696,19 +2437,19 @@ void Renderer11::applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants ...@@ -2696,19 +2437,19 @@ void Renderer11::applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants
template void Renderer11::applyDriverConstantsIfNeeded<dx_VertexConstants11>( template void Renderer11::applyDriverConstantsIfNeeded<dx_VertexConstants11>(
dx_VertexConstants11 *appliedConstants, dx_VertexConstants11 *appliedConstants,
const dx_VertexConstants11 &constants, const dx_VertexConstants11 &constants,
SamplerMetadataD3D11 *samplerMetadata, SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes, size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer); const d3d11::Buffer &driverConstantBuffer);
template void Renderer11::applyDriverConstantsIfNeeded<dx_PixelConstants11>( template void Renderer11::applyDriverConstantsIfNeeded<dx_PixelConstants11>(
dx_PixelConstants11 *appliedConstants, dx_PixelConstants11 *appliedConstants,
const dx_PixelConstants11 &constants, const dx_PixelConstants11 &constants,
SamplerMetadataD3D11 *samplerMetadata, SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes, size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer); const d3d11::Buffer &driverConstantBuffer);
template void Renderer11::applyDriverConstantsIfNeeded<dx_ComputeConstants11>( template void Renderer11::applyDriverConstantsIfNeeded<dx_ComputeConstants11>(
dx_ComputeConstants11 *appliedConstants, dx_ComputeConstants11 *appliedConstants,
const dx_ComputeConstants11 &constants, const dx_ComputeConstants11 &constants,
SamplerMetadataD3D11 *samplerMetadata, SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes, size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer); const d3d11::Buffer &driverConstantBuffer);
...@@ -2716,21 +2457,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context) ...@@ -2716,21 +2457,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context)
{ {
TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{
mForceSetVertexSamplerStates[vsamplerId] = true;
}
for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
{
mForceSetPixelSamplerStates[fsamplerId] = true;
}
for (size_t csamplerId = 0; csamplerId < mForceSetComputeSamplerStates.size(); ++csamplerId)
{
mForceSetComputeSamplerStates[csamplerId] = true;
}
mStateManager.invalidateEverything(context); mStateManager.invalidateEverything(context);
mAppliedIB = nullptr; mAppliedIB = nullptr;
...@@ -4523,14 +4249,6 @@ angle::WorkaroundsD3D Renderer11::generateWorkarounds() const ...@@ -4523,14 +4249,6 @@ angle::WorkaroundsD3D Renderer11::generateWorkarounds() const
return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription); return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription);
} }
gl::Error Renderer11::clearTextures(const gl::Context *context,
gl::SamplerType samplerType,
size_t rangeStart,
size_t rangeEnd)
{
return mStateManager.clearTextures(samplerType, rangeStart, rangeEnd);
}
egl::Error Renderer11::getEGLDevice(DeviceImpl **device) egl::Error Renderer11::getEGLDevice(DeviceImpl **device)
{ {
if (mEGLDevice == nullptr) if (mEGLDevice == nullptr)
...@@ -4595,7 +4313,6 @@ gl::Error Renderer11::genericDrawElements(const gl::Context *context, ...@@ -4595,7 +4313,6 @@ gl::Error Renderer11::genericDrawElements(const gl::Context *context,
size_t vertexCount = indexInfo.indexRange.vertexCount(); size_t vertexCount = indexInfo.indexRange.vertexCount();
ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexInfo.indexRange.start), ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
static_cast<GLsizei>(vertexCount), instances, &indexInfo)); static_cast<GLsizei>(vertexCount), instances, &indexInfo));
ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode)); ANGLE_TRY(applyShaders(context, mode));
ANGLE_TRY(programD3D->applyUniformBuffers(data)); ANGLE_TRY(programD3D->applyUniformBuffers(data));
...@@ -4631,7 +4348,6 @@ gl::Error Renderer11::genericDrawArrays(const gl::Context *context, ...@@ -4631,7 +4348,6 @@ gl::Error Renderer11::genericDrawArrays(const gl::Context *context,
ANGLE_TRY(mStateManager.updateState(context, mode)); ANGLE_TRY(mStateManager.updateState(context, mode));
ANGLE_TRY(applyTransformFeedbackBuffers(data)); ANGLE_TRY(applyTransformFeedbackBuffers(data));
ANGLE_TRY(applyVertexBuffer(context, mode, first, count, instances, nullptr)); ANGLE_TRY(applyVertexBuffer(context, mode, first, count, instances, nullptr));
ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode)); ANGLE_TRY(applyShaders(context, mode));
ANGLE_TRY(programD3D->applyUniformBuffers(data)); ANGLE_TRY(programD3D->applyUniformBuffers(data));
...@@ -4666,7 +4382,6 @@ gl::Error Renderer11::genericDrawIndirect(const gl::Context *context, ...@@ -4666,7 +4382,6 @@ gl::Error Renderer11::genericDrawIndirect(const gl::Context *context,
ANGLE_TRY(mStateManager.updateState(context, mode)); ANGLE_TRY(mStateManager.updateState(context, mode));
ANGLE_TRY(applyTransformFeedbackBuffers(contextState)); ANGLE_TRY(applyTransformFeedbackBuffers(contextState));
ASSERT(!glState.isTransformFeedbackActiveUnpaused()); ASSERT(!glState.isTransformFeedbackActiveUnpaused());
ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyShaders(context, mode)); ANGLE_TRY(applyShaders(context, mode));
ANGLE_TRY(programD3D->applyUniformBuffers(contextState)); ANGLE_TRY(programD3D->applyUniformBuffers(contextState));
...@@ -4706,11 +4421,11 @@ gl::DebugAnnotator *Renderer11::getAnnotator() ...@@ -4706,11 +4421,11 @@ gl::DebugAnnotator *Renderer11::getAnnotator()
return mAnnotator; return mAnnotator;
} }
gl::Error Renderer11::applyComputeShader(const gl::ContextState &data) gl::Error Renderer11::applyComputeShader(const gl::Context *context)
{ {
ANGLE_TRY(ensureHLSLCompilerInitialized()); ANGLE_TRY(ensureHLSLCompilerInitialized());
const auto &glState = data.getState(); const auto &glState = context->getGLState();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram()); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
ShaderExecutableD3D *computeExe = nullptr; ShaderExecutableD3D *computeExe = nullptr;
...@@ -4727,18 +4442,16 @@ gl::Error Renderer11::dispatchCompute(const gl::Context *context, ...@@ -4727,18 +4442,16 @@ gl::Error Renderer11::dispatchCompute(const gl::Context *context,
GLuint numGroupsY, GLuint numGroupsY,
GLuint numGroupsZ) GLuint numGroupsZ)
{ {
const auto &data = context->getContextState(); gl::Program *program = context->getGLState().getProgram();
gl::Program *program = data.getState().getProgram();
ASSERT(program != nullptr); ASSERT(program != nullptr);
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
mStateManager.setComputeConstants(numGroupsX, numGroupsY, numGroupsZ);
programD3D->updateSamplerMapping(); programD3D->updateSamplerMapping();
ANGLE_TRY(generateSwizzles(context, gl::SAMPLER_COMPUTE)); ANGLE_TRY(generateSwizzles(context, gl::SAMPLER_COMPUTE));
ANGLE_TRY(applyTextures(context));
ANGLE_TRY(applyComputeShader(data)); ANGLE_TRY(mStateManager.updateStateForCompute(context, numGroupsX, numGroupsY, numGroupsZ));
ANGLE_TRY(applyComputeShader(context));
// TODO(Xinghua): applyUniformBuffers for compute shader. // TODO(Xinghua): applyUniformBuffers for compute shader.
mDeviceContext->Dispatch(numGroupsX, numGroupsY, numGroupsZ); mDeviceContext->Dispatch(numGroupsX, numGroupsY, numGroupsZ);
...@@ -4805,12 +4518,14 @@ gl::Error Renderer11::applyComputeUniforms(const ProgramD3D &programD3D, ...@@ -4805,12 +4518,14 @@ gl::Error Renderer11::applyComputeUniforms(const ProgramD3D &programD3D,
mCurrentComputeConstantBuffer = reinterpret_cast<uintptr_t>(computeConstantBuffer); mCurrentComputeConstantBuffer = reinterpret_cast<uintptr_t>(computeConstantBuffer);
} }
auto *samplerMetadataCS = mStateManager.getComputeSamplerMetadata();
if (!mDriverConstantBufferCS.valid()) if (!mDriverConstantBufferCS.valid())
{ {
D3D11_BUFFER_DESC constantBufferDescription = {0}; D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc( d3d11::InitConstantBufferDesc(
&constantBufferDescription, &constantBufferDescription,
sizeof(dx_ComputeConstants11) + mSamplerMetadataCS.sizeBytes()); sizeof(dx_ComputeConstants11) + samplerMetadataCS->sizeBytes());
ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferCS)); ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferCS));
ID3D11Buffer *buffer = mDriverConstantBufferCS.get(); ID3D11Buffer *buffer = mDriverConstantBufferCS.get();
mDeviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, mDeviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
...@@ -4818,9 +4533,9 @@ gl::Error Renderer11::applyComputeUniforms(const ProgramD3D &programD3D, ...@@ -4818,9 +4533,9 @@ gl::Error Renderer11::applyComputeUniforms(const ProgramD3D &programD3D,
} }
const dx_ComputeConstants11 &computeConstants = mStateManager.getComputeConstants(); const dx_ComputeConstants11 &computeConstants = mStateManager.getComputeConstants();
size_t samplerMetadataReferencedBytesCS = sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * size_t samplerMetadataReferencedBytesCS = sizeof(SamplerMetadata11::dx_SamplerMetadata) *
programD3D.getUsedSamplerRange(gl::SAMPLER_COMPUTE); programD3D.getUsedSamplerRange(gl::SAMPLER_COMPUTE);
applyDriverConstantsIfNeeded(&mAppliedComputeConstants, computeConstants, &mSamplerMetadataCS, applyDriverConstantsIfNeeded(&mAppliedComputeConstants, computeConstants, samplerMetadataCS,
samplerMetadataReferencedBytesCS, mDriverConstantBufferCS); samplerMetadataReferencedBytesCS, mDriverConstantBufferCS);
return gl::NoError(); return gl::NoError();
......
...@@ -138,16 +138,6 @@ class Renderer11 : public RendererD3D ...@@ -138,16 +138,6 @@ class Renderer11 : public RendererD3D
HANDLE shareHandle, HANDLE shareHandle,
const egl::AttributeMap &attribs) const override; const egl::AttributeMap &attribs) const override;
gl::Error setSamplerState(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture,
const gl::SamplerState &sampler) override;
gl::Error setTexture(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture) override;
gl::Error setUniformBuffers(const gl::ContextState &data, gl::Error setUniformBuffers(const gl::ContextState &data,
const std::vector<GLint> &vertexUniformBuffers, const std::vector<GLint> &vertexUniformBuffers,
const std::vector<GLint> &fragmentUniformBuffers) override; const std::vector<GLint> &fragmentUniformBuffers) override;
...@@ -435,7 +425,7 @@ class Renderer11 : public RendererD3D ...@@ -435,7 +425,7 @@ class Renderer11 : public RendererD3D
GLuint numGroupsZ); GLuint numGroupsZ);
gl::Error applyComputeUniforms(const ProgramD3D &programD3D, gl::Error applyComputeUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) override; const std::vector<D3DUniform *> &uniformArray) override;
gl::Error applyComputeShader(const gl::ContextState &data); gl::Error applyComputeShader(const gl::Context *context);
gl::ErrorOrResult<TextureHelper11> createStagingTexture(ResourceType textureType, gl::ErrorOrResult<TextureHelper11> createStagingTexture(ResourceType textureType,
const d3d11::Format &formatSet, const d3d11::Format &formatSet,
...@@ -481,12 +471,6 @@ class Renderer11 : public RendererD3D ...@@ -481,12 +471,6 @@ class Renderer11 : public RendererD3D
gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, gl::Error clearRenderTarget(RenderTargetD3D *renderTarget,
const gl::ColorF &clearValues) override; const gl::ColorF &clearValues) override;
protected:
gl::Error clearTextures(const gl::Context *context,
gl::SamplerType samplerType,
size_t rangeStart,
size_t rangeEnd) override;
private: private:
gl::Error drawArraysImpl(const gl::Context *context, gl::Error drawArraysImpl(const gl::Context *context,
GLenum mode, GLenum mode,
...@@ -543,39 +527,10 @@ class Renderer11 : public RendererD3D ...@@ -543,39 +527,10 @@ class Renderer11 : public RendererD3D
void updateHistograms(); void updateHistograms();
class SamplerMetadataD3D11 final : angle::NonCopyable
{
public:
SamplerMetadataD3D11();
~SamplerMetadataD3D11();
struct dx_SamplerMetadata
{
int baseLevel;
int internalFormatBits;
int wrapModes;
int padding; // This just pads the struct to 16 bytes
};
static_assert(sizeof(dx_SamplerMetadata) == 16u,
"Sampler metadata struct must be one 4-vec / 16 bytes.");
void initData(unsigned int samplerCount);
void update(unsigned int samplerIndex, const gl::Texture &texture);
const dx_SamplerMetadata *getData() const;
size_t sizeBytes() const;
bool isDirty() const { return mDirty; }
void markClean() { mDirty = false; }
private:
std::vector<dx_SamplerMetadata> mSamplerMetadata;
bool mDirty;
};
template <class TShaderConstants> template <class TShaderConstants>
void applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants, void applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants,
const TShaderConstants &constants, const TShaderConstants &constants,
SamplerMetadataD3D11 *samplerMetadata, SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes, size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer); const d3d11::Buffer &driverConstantBuffer);
...@@ -610,16 +565,6 @@ class Renderer11 : public RendererD3D ...@@ -610,16 +565,6 @@ class Renderer11 : public RendererD3D
RenderStateCache mStateCache; RenderStateCache mStateCache;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> mCurVertexSamplerStates;
std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates;
std::vector<bool> mForceSetComputeSamplerStates;
std::vector<gl::SamplerState> mCurComputeSamplerStates;
StateManager11 mStateManager; StateManager11 mStateManager;
// Currently applied index buffer // Currently applied index buffer
...@@ -633,7 +578,6 @@ class Renderer11 : public RendererD3D ...@@ -633,7 +578,6 @@ class Renderer11 : public RendererD3D
dx_VertexConstants11 mAppliedVertexConstants; dx_VertexConstants11 mAppliedVertexConstants;
d3d11::Buffer mDriverConstantBufferVS; d3d11::Buffer mDriverConstantBufferVS;
SamplerMetadataD3D11 mSamplerMetadataVS;
uintptr_t mCurrentVertexConstantBuffer; uintptr_t mCurrentVertexConstantBuffer;
unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
...@@ -641,7 +585,6 @@ class Renderer11 : public RendererD3D ...@@ -641,7 +585,6 @@ class Renderer11 : public RendererD3D
dx_PixelConstants11 mAppliedPixelConstants; dx_PixelConstants11 mAppliedPixelConstants;
d3d11::Buffer mDriverConstantBufferPS; d3d11::Buffer mDriverConstantBufferPS;
SamplerMetadataD3D11 mSamplerMetadataPS;
uintptr_t mCurrentPixelConstantBuffer; uintptr_t mCurrentPixelConstantBuffer;
unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
...@@ -649,7 +592,6 @@ class Renderer11 : public RendererD3D ...@@ -649,7 +592,6 @@ class Renderer11 : public RendererD3D
dx_ComputeConstants11 mAppliedComputeConstants; dx_ComputeConstants11 mAppliedComputeConstants;
d3d11::Buffer mDriverConstantBufferCS; d3d11::Buffer mDriverConstantBufferCS;
SamplerMetadataD3D11 mSamplerMetadataCS;
uintptr_t mCurrentComputeConstantBuffer; uintptr_t mCurrentComputeConstantBuffer;
uintptr_t mCurrentGeometryConstantBuffer; uintptr_t mCurrentGeometryConstantBuffer;
......
...@@ -13,9 +13,11 @@ ...@@ -13,9 +13,11 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Query.h" #include "libANGLE/Query.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
namespace rx namespace rx
{ {
...@@ -97,8 +99,26 @@ ID3D11Resource *GetViewResource(ID3D11View *view) ...@@ -97,8 +99,26 @@ ID3D11Resource *GetViewResource(ID3D11View *view)
return resource; return resource;
} }
int GetWrapBits(GLenum wrap)
{
switch (wrap)
{
case GL_CLAMP_TO_EDGE:
return 0x1;
case GL_REPEAT:
return 0x2;
case GL_MIRRORED_REPEAT:
return 0x3;
default:
UNREACHABLE();
return 0;
}
}
} // anonymous namespace } // anonymous namespace
// StateManager11::SRVCache Implementation.
void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv) void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv)
{ {
ASSERT(resourceIndex < mCurrentSRVs.size()); ASSERT(resourceIndex < mCurrentSRVs.size());
...@@ -136,6 +156,110 @@ void StateManager11::SRVCache::clear() ...@@ -136,6 +156,110 @@ void StateManager11::SRVCache::clear()
mHighestUsedSRV = 0; mHighestUsedSRV = 0;
} }
// SamplerMetadataD3D11 implementation
SamplerMetadata11::SamplerMetadata11() : mDirty(true)
{
}
SamplerMetadata11::~SamplerMetadata11()
{
}
void SamplerMetadata11::initData(unsigned int samplerCount)
{
mSamplerMetadata.resize(samplerCount);
}
void SamplerMetadata11::update(unsigned int samplerIndex, const gl::Texture &texture)
{
unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
GLenum sizedFormat =
texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat;
if (mSamplerMetadata[samplerIndex].baseLevel != static_cast<int>(baseLevel))
{
mSamplerMetadata[samplerIndex].baseLevel = static_cast<int>(baseLevel);
mDirty = true;
}
// Some metadata is needed only for integer textures. We avoid updating the constant buffer
// unnecessarily by changing the data only in case the texture is an integer texture and
// the values have changed.
bool needIntegerTextureMetadata = false;
// internalFormatBits == 0 means a 32-bit texture in the case of integer textures.
int internalFormatBits = 0;
switch (sizedFormat)
{
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGB32I:
case GL_RGB32UI:
case GL_RG32I:
case GL_RG32UI:
case GL_R32I:
case GL_R32UI:
needIntegerTextureMetadata = true;
break;
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RG16I:
case GL_RG16UI:
case GL_R16I:
case GL_R16UI:
needIntegerTextureMetadata = true;
internalFormatBits = 16;
break;
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_RGB8I:
case GL_RGB8UI:
case GL_RG8I:
case GL_RG8UI:
case GL_R8I:
case GL_R8UI:
needIntegerTextureMetadata = true;
internalFormatBits = 8;
break;
case GL_RGB10_A2UI:
needIntegerTextureMetadata = true;
internalFormatBits = 10;
break;
default:
break;
}
if (needIntegerTextureMetadata)
{
if (mSamplerMetadata[samplerIndex].internalFormatBits != internalFormatBits)
{
mSamplerMetadata[samplerIndex].internalFormatBits = internalFormatBits;
mDirty = true;
}
// Pack the wrap values into one integer so we can fit all the metadata in one 4-integer
// vector.
GLenum wrapS = texture.getWrapS();
GLenum wrapT = texture.getWrapT();
GLenum wrapR = texture.getWrapR();
int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4);
if (mSamplerMetadata[samplerIndex].wrapModes != wrapModes)
{
mSamplerMetadata[samplerIndex].wrapModes = wrapModes;
mDirty = true;
}
}
}
const SamplerMetadata11::dx_SamplerMetadata *SamplerMetadata11::getData() const
{
return mSamplerMetadata.data();
}
size_t SamplerMetadata11::sizeBytes() const
{
return sizeof(dx_SamplerMetadata) * mSamplerMetadata.size();
}
static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT,
GL_COMMANDS_COMPLETED_CHROMIUM}; GL_COMMANDS_COMPLETED_CHROMIUM};
...@@ -252,11 +376,19 @@ void StateManager11::checkPresentPath(const gl::Context *context) ...@@ -252,11 +376,19 @@ void StateManager11::checkPresentPath(const gl::Context *context)
} }
} }
void StateManager11::setComputeConstants(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) gl::Error StateManager11::updateStateForCompute(const gl::Context *context,
GLuint numGroupsX,
GLuint numGroupsY,
GLuint numGroupsZ)
{ {
mComputeConstants.numWorkGroups[0] = numGroupsX; mComputeConstants.numWorkGroups[0] = numGroupsX;
mComputeConstants.numWorkGroups[1] = numGroupsY; mComputeConstants.numWorkGroups[1] = numGroupsY;
mComputeConstants.numWorkGroups[2] = numGroupsZ; mComputeConstants.numWorkGroups[2] = numGroupsZ;
// TODO(jmadill): More complete implementation.
ANGLE_TRY(syncTextures(context));
return gl::NoError();
} }
void StateManager11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) void StateManager11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits)
...@@ -853,6 +985,10 @@ void StateManager11::invalidateEverything(const gl::Context *context) ...@@ -853,6 +985,10 @@ void StateManager11::invalidateEverything(const gl::Context *context)
mAppliedGeometryShader.dirty(); mAppliedGeometryShader.dirty();
mAppliedPixelShader.dirty(); mAppliedPixelShader.dirty();
mAppliedComputeShader.dirty(); mAppliedComputeShader.dirty();
std::fill(mForceSetVertexSamplerStates.begin(), mForceSetVertexSamplerStates.end(), true);
std::fill(mForceSetPixelSamplerStates.begin(), mForceSetPixelSamplerStates.end(), true);
std::fill(mForceSetComputeSamplerStates.begin(), mForceSetComputeSamplerStates.end(), true);
} }
void StateManager11::invalidateVertexBuffer() void StateManager11::invalidateVertexBuffer()
...@@ -1020,6 +1156,18 @@ void StateManager11::initialize(const gl::Caps &caps) ...@@ -1020,6 +1156,18 @@ void StateManager11::initialize(const gl::Caps &caps)
mNullSRVs.resize(caps.maxTextureImageUnits, nullptr); mNullSRVs.resize(caps.maxTextureImageUnits, nullptr);
mCurrentValueAttribs.resize(caps.maxVertexAttributes); mCurrentValueAttribs.resize(caps.maxVertexAttributes);
mForceSetVertexSamplerStates.resize(caps.maxVertexTextureImageUnits);
mForceSetPixelSamplerStates.resize(caps.maxTextureImageUnits);
mForceSetComputeSamplerStates.resize(caps.maxComputeTextureImageUnits);
mCurVertexSamplerStates.resize(caps.maxVertexTextureImageUnits);
mCurPixelSamplerStates.resize(caps.maxTextureImageUnits);
mCurComputeSamplerStates.resize(caps.maxComputeTextureImageUnits);
mSamplerMetadataVS.initData(caps.maxVertexTextureImageUnits);
mSamplerMetadataPS.initData(caps.maxTextureImageUnits);
mSamplerMetadataCS.initData(caps.maxComputeTextureImageUnits);
} }
void StateManager11::deinitialize() void StateManager11::deinitialize()
...@@ -1284,6 +1432,9 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod ...@@ -1284,6 +1432,9 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
} }
} }
// TODO(jmadill): Use dirty bits.
ANGLE_TRY(syncTextures(context));
// Check that we haven't set any dirty bits in the flushing of the dirty bits loop. // Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
ASSERT(mInternalDirtyBits.none()); ASSERT(mInternalDirtyBits.none());
...@@ -1356,4 +1507,218 @@ void StateManager11::setComputeShader(const d3d11::ComputeShader *shader) ...@@ -1356,4 +1507,218 @@ void StateManager11::setComputeShader(const d3d11::ComputeShader *shader)
} }
} }
// 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 StateManager11::applyTextures(const gl::Context *context,
gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures,
size_t framebufferTextureCount)
{
const auto &glState = context->getGLState();
const auto &caps = context->getCaps();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
ASSERT(!programD3D->isSamplerMappingDirty());
// TODO(jmadill): Use the Program's sampler bindings.
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, caps);
if (textureUnit != -1)
{
gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
ASSERT(texture);
gl::Sampler *samplerObject = glState.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,
context->getContextState()) &&
!std::binary_search(framebufferTextures.begin(),
framebufferTextures.begin() + framebufferTextureCount, texture))
{
ANGLE_TRY(
setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture));
}
else
{
// Texture is not sampler complete or it is in use by the framebuffer. Bind the
// incomplete texture.
gl::Texture *incompleteTexture =
mRenderer->getIncompleteTexture(context, textureType);
ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
incompleteTexture->getSamplerState()));
ANGLE_TRY(setTexture(context, 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(context, shaderType, samplerIndex, nullptr));
}
}
// Set all the remaining textures to NULL
size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits
: caps.maxVertexTextureImageUnits;
clearTextures(shaderType, samplerRange, samplerCount);
return gl::NoError();
}
gl::Error StateManager11::syncTextures(const gl::Context *context)
{
FramebufferTextureArray framebufferTextures;
size_t framebufferSerialCount =
mRenderer->getBoundFramebufferTextures(context->getContextState(), &framebufferTextures);
ANGLE_TRY(
applyTextures(context, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount));
ANGLE_TRY(
applyTextures(context, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount));
return gl::NoError();
}
gl::Error StateManager11::setSamplerState(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture,
const gl::SamplerState &samplerState)
{
#if !defined(NDEBUG)
// Storage should exist, texture should be complete. Only verified in Debug.
TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
TextureStorage *storage = nullptr;
ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
ASSERT(storage);
#endif // !defined(NDEBUG)
// Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
// sampler state since having it in contiguous memory makes it possible to memcpy to a constant
// buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers.
SamplerMetadata11 *metadata = nullptr;
auto *deviceContext = mRenderer->getDeviceContext();
if (type == gl::SAMPLER_PIXEL)
{
ASSERT(static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits);
if (mForceSetPixelSamplerStates[index] ||
memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = nullptr;
ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
ASSERT(dxSamplerState != nullptr);
deviceContext->PSSetSamplers(index, 1, &dxSamplerState);
mCurPixelSamplerStates[index] = samplerState;
}
mForceSetPixelSamplerStates[index] = false;
metadata = &mSamplerMetadataPS;
}
else if (type == gl::SAMPLER_VERTEX)
{
ASSERT(static_cast<unsigned int>(index) <
mRenderer->getNativeCaps().maxVertexTextureImageUnits);
if (mForceSetVertexSamplerStates[index] ||
memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = nullptr;
ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
ASSERT(dxSamplerState != nullptr);
deviceContext->VSSetSamplers(index, 1, &dxSamplerState);
mCurVertexSamplerStates[index] = samplerState;
}
mForceSetVertexSamplerStates[index] = false;
metadata = &mSamplerMetadataVS;
}
else if (type == gl::SAMPLER_COMPUTE)
{
ASSERT(static_cast<unsigned int>(index) <
mRenderer->getNativeCaps().maxComputeTextureImageUnits);
if (mForceSetComputeSamplerStates[index] ||
memcmp(&samplerState, &mCurComputeSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = nullptr;
ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState));
ASSERT(dxSamplerState != nullptr);
deviceContext->CSSetSamplers(index, 1, &dxSamplerState);
mCurComputeSamplerStates[index] = samplerState;
}
mForceSetComputeSamplerStates[index] = false;
metadata = &mSamplerMetadataCS;
}
else
UNREACHABLE();
ASSERT(metadata != nullptr);
metadata->update(index, *texture);
return gl::NoError();
}
gl::Error StateManager11::setTexture(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture)
{
const d3d11::SharedSRV *textureSRV = nullptr;
if (texture)
{
TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
TextureStorage *texStorage = nullptr;
ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
// Texture should be complete and have a storage
ASSERT(texStorage);
TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
ANGLE_TRY(storage11->getSRV(context, texture->getTextureState(), &textureSRV));
// If we get an invalid SRV here, something went wrong in the texture class and we're
// unexpectedly missing the shader resource view.
ASSERT(textureSRV->valid());
textureImpl->resetDirty();
}
ASSERT(
(type == gl::SAMPLER_PIXEL &&
static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxTextureImageUnits) ||
(type == gl::SAMPLER_VERTEX &&
static_cast<unsigned int>(index) < mRenderer->getNativeCaps().maxVertexTextureImageUnits));
setShaderResource(type, index, textureSRV->get());
return gl::NoError();
}
} // namespace rx } // namespace rx
...@@ -47,6 +47,35 @@ struct dx_ComputeConstants11 ...@@ -47,6 +47,35 @@ struct dx_ComputeConstants11
unsigned int padding; // This just pads the struct to 16 bytes unsigned int padding; // This just pads the struct to 16 bytes
}; };
class SamplerMetadata11 final : angle::NonCopyable
{
public:
SamplerMetadata11();
~SamplerMetadata11();
struct dx_SamplerMetadata
{
int baseLevel;
int internalFormatBits;
int wrapModes;
int padding; // This just pads the struct to 16 bytes
};
static_assert(sizeof(dx_SamplerMetadata) == 16u,
"Sampler metadata struct must be one 4-vec / 16 bytes.");
void initData(unsigned int samplerCount);
void update(unsigned int samplerIndex, const gl::Texture &texture);
const dx_SamplerMetadata *getData() const;
size_t sizeBytes() const;
bool isDirty() const { return mDirty; }
void markClean() { mDirty = false; }
private:
std::vector<dx_SamplerMetadata> mSamplerMetadata;
bool mDirty;
};
class StateManager11 final : angle::NonCopyable class StateManager11 final : angle::NonCopyable
{ {
public: public:
...@@ -58,18 +87,25 @@ class StateManager11 final : angle::NonCopyable ...@@ -58,18 +87,25 @@ class StateManager11 final : angle::NonCopyable
void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits); void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits);
// TODO(jmadill): Don't expose these.
const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; } const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; }
const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; } const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; }
const dx_ComputeConstants11 &getComputeConstants() const { return mComputeConstants; } const dx_ComputeConstants11 &getComputeConstants() const { return mComputeConstants; }
void setComputeConstants(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); SamplerMetadata11 *getVertexSamplerMetadata() { return &mSamplerMetadataVS; }
SamplerMetadata11 *getPixelSamplerMetadata() { return &mSamplerMetadataPS; }
SamplerMetadata11 *getComputeSamplerMetadata() { return &mSamplerMetadataCS; }
gl::Error updateStateForCompute(const gl::Context *context,
GLuint numGroupsX,
GLuint numGroupsY,
GLuint numGroupsZ);
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void setShaderResource(gl::SamplerType shaderType, void setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot, UINT resourceSlot,
ID3D11ShaderResourceView *srv); ID3D11ShaderResourceView *srv);
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
// Checks are done on a framebuffer state change to trigger other state changes. // Checks are done on a framebuffer state change to trigger other state changes.
// The Context is allowed to be nullptr for these methods, when called in EGL init code. // The Context is allowed to be nullptr for these methods, when called in EGL init code.
...@@ -144,6 +180,25 @@ class StateManager11 final : angle::NonCopyable ...@@ -144,6 +180,25 @@ class StateManager11 final : angle::NonCopyable
gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer); gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer);
gl::Error syncTextures(const gl::Context *context);
gl::Error applyTextures(const gl::Context *context,
gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures,
size_t framebufferTextureCount);
gl::Error setSamplerState(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture,
const gl::SamplerState &sampler);
gl::Error setTexture(const gl::Context *context,
gl::SamplerType type,
int index,
gl::Texture *texture);
// Faster than calling setTexture a jillion times
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
enum DirtyBitType enum DirtyBitType
{ {
DIRTY_BIT_RENDER_TARGET, DIRTY_BIT_RENDER_TARGET,
...@@ -263,6 +318,20 @@ class StateManager11 final : angle::NonCopyable ...@@ -263,6 +318,20 @@ class StateManager11 final : angle::NonCopyable
ResourceSerial mAppliedGeometryShader; ResourceSerial mAppliedGeometryShader;
ResourceSerial mAppliedPixelShader; ResourceSerial mAppliedPixelShader;
ResourceSerial mAppliedComputeShader; ResourceSerial mAppliedComputeShader;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> mCurVertexSamplerStates;
std::vector<bool> mForceSetPixelSamplerStates;
std::vector<gl::SamplerState> mCurPixelSamplerStates;
std::vector<bool> mForceSetComputeSamplerStates;
std::vector<gl::SamplerState> mCurComputeSamplerStates;
SamplerMetadata11 mSamplerMetadataVS;
SamplerMetadata11 mSamplerMetadataPS;
SamplerMetadata11 mSamplerMetadataCS;
}; };
} // namespace rx } // namespace rx
......
...@@ -3082,20 +3082,6 @@ angle::WorkaroundsD3D Renderer9::generateWorkarounds() const ...@@ -3082,20 +3082,6 @@ angle::WorkaroundsD3D Renderer9::generateWorkarounds() const
return d3d9::GenerateWorkarounds(); return d3d9::GenerateWorkarounds();
} }
gl::Error Renderer9::clearTextures(const gl::Context *context,
gl::SamplerType samplerType,
size_t rangeStart,
size_t rangeEnd)
{
// TODO(jmadill): faster way?
for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; samplerIndex++)
{
ANGLE_TRY(setTexture(context, samplerType, static_cast<int>(samplerIndex), nullptr));
}
return gl::NoError();
}
egl::Error Renderer9::getEGLDevice(DeviceImpl **device) egl::Error Renderer9::getEGLDevice(DeviceImpl **device)
{ {
if (mEGLDevice == nullptr) if (mEGLDevice == nullptr)
...@@ -3233,4 +3219,91 @@ gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget, const gl:: ...@@ -3233,4 +3219,91 @@ gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget, const gl::
return gl::InternalError() << "clearRenderTarget is not implemented on D3D9"; return gl::InternalError() << "clearRenderTarget is not implemented on D3D9";
} }
// 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 Renderer9::applyTextures(const gl::Context *context,
gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures,
size_t framebufferTextureCount)
{
const auto &glState = context->getGLState();
const auto &caps = context->getCaps();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
ASSERT(!programD3D->isSamplerMappingDirty());
// TODO(jmadill): Use the Program's sampler bindings.
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, caps);
if (textureUnit != -1)
{
gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
ASSERT(texture);
gl::Sampler *samplerObject = glState.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,
context->getContextState()) &&
!std::binary_search(framebufferTextures.begin(),
framebufferTextures.begin() + framebufferTextureCount, texture))
{
ANGLE_TRY(
setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
ANGLE_TRY(setTexture(context, 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(context, textureType);
ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
incompleteTexture->getSamplerState()));
ANGLE_TRY(setTexture(context, 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(context, shaderType, samplerIndex, nullptr));
}
}
// Set all the remaining textures to NULL
size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits
: caps.maxVertexTextureImageUnits;
// TODO(jmadill): faster way?
for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
{
ANGLE_TRY(setTexture(context, shaderType, static_cast<int>(samplerIndex), nullptr));
}
return gl::NoError();
}
gl::Error Renderer9::applyTextures(const gl::Context *context)
{
FramebufferTextureArray framebufferTextures;
size_t framebufferSerialCount =
getBoundFramebufferTextures(context->getContextState(), &framebufferTextures);
ANGLE_TRY(
applyTextures(context, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount));
ANGLE_TRY(
applyTextures(context, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount));
return gl::NoError();
}
} // namespace rx } // namespace rx
...@@ -123,11 +123,11 @@ class Renderer9 : public RendererD3D ...@@ -123,11 +123,11 @@ class Renderer9 : public RendererD3D
gl::SamplerType type, gl::SamplerType type,
int index, int index,
gl::Texture *texture, gl::Texture *texture,
const gl::SamplerState &sampler) override; const gl::SamplerState &sampler);
gl::Error setTexture(const gl::Context *context, gl::Error setTexture(const gl::Context *context,
gl::SamplerType type, gl::SamplerType type,
int index, int index,
gl::Texture *texture) override; gl::Texture *texture);
gl::Error setUniformBuffers(const gl::ContextState &data, gl::Error setUniformBuffers(const gl::ContextState &data,
const std::vector<GLint> &vertexUniformBuffers, const std::vector<GLint> &vertexUniformBuffers,
...@@ -398,12 +398,6 @@ class Renderer9 : public RendererD3D ...@@ -398,12 +398,6 @@ class Renderer9 : public RendererD3D
gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, gl::Error clearRenderTarget(RenderTargetD3D *renderTarget,
const gl::ColorF &clearValues) override; const gl::ColorF &clearValues) override;
protected:
gl::Error clearTextures(const gl::Context *context,
gl::SamplerType samplerType,
size_t rangeStart,
size_t rangeEnd) override;
private: private:
gl::Error drawArraysImpl(const gl::ContextState &data, gl::Error drawArraysImpl(const gl::ContextState &data,
GLenum mode, GLenum mode,
...@@ -420,6 +414,12 @@ class Renderer9 : public RendererD3D ...@@ -420,6 +414,12 @@ class Renderer9 : public RendererD3D
gl::Error applyShaders(const gl::Context *context, GLenum drawMode); gl::Error applyShaders(const gl::Context *context, GLenum drawMode);
gl::Error applyTextures(const gl::Context *context);
gl::Error applyTextures(const gl::Context *context,
gl::SamplerType shaderType,
const FramebufferTextureArray &framebufferTextures,
size_t framebufferTextureCount);
void generateCaps(gl::Caps *outCaps, void generateCaps(gl::Caps *outCaps,
gl::TextureCapsMap *outTextureCaps, gl::TextureCapsMap *outTextureCaps,
gl::Extensions *outExtensions, gl::Extensions *outExtensions,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment