Commit af2b33be by Jiawei Shao Committed by Commit Bot

Use ShaderMap in ProgramD3D - Part I

This patch is the first part of using ShaderMap to contain shader information in ProgramD3D, including the refactoring on struct D3DUniform, D3DUniformBlock and ProgramD3DMetadata. In the next patch all shader information in class ProgramD3D will be organized in the form of ShaderMap. BUG=angleproject:2169 Change-Id: I27008169dbf6cd8017a67f36f474667feddbd1f6 Reviewed-on: https://chromium-review.googlesource.com/1018728 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 37b3e596
...@@ -301,16 +301,13 @@ D3DUniform::D3DUniform(GLenum type, ...@@ -301,16 +301,13 @@ D3DUniform::D3DUniform(GLenum type,
: typeInfo(gl::GetUniformTypeInfo(type)), : typeInfo(gl::GetUniformTypeInfo(type)),
name(nameIn), name(nameIn),
arraySizes(arraySizesIn), arraySizes(arraySizesIn),
vsData(nullptr), mShaderData({}),
psData(nullptr),
csData(nullptr),
regType(reg), regType(reg),
vsRegisterIndex(GL_INVALID_INDEX),
psRegisterIndex(GL_INVALID_INDEX),
csRegisterIndex(GL_INVALID_INDEX),
registerCount(0), registerCount(0),
registerElement(0) registerElement(0)
{ {
mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
// We use data storage for default block uniforms to cache values that are sent to D3D during // We use data storage for default block uniforms to cache values that are sent to D3D during
// rendering // rendering
// Uniform blocks/buffers are treated separately by the Renderer (ES3 path only) // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
...@@ -353,31 +350,28 @@ bool D3DUniform::isImage() const ...@@ -353,31 +350,28 @@ bool D3DUniform::isImage() const
return typeInfo.isImageType; return typeInfo.isImageType;
} }
bool D3DUniform::isReferencedByVertexShader() const bool D3DUniform::isReferencedByShader(gl::ShaderType shaderType) const
{
return vsRegisterIndex != GL_INVALID_INDEX;
}
bool D3DUniform::isReferencedByFragmentShader() const
{
return psRegisterIndex != GL_INVALID_INDEX;
}
bool D3DUniform::isReferencedByComputeShader() const
{ {
return csRegisterIndex != GL_INVALID_INDEX; return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
} }
const uint8_t *D3DUniform::firstNonNullData() const const uint8_t *D3DUniform::firstNonNullData() const
{ {
ASSERT(vsData || psData || csData || !mSamplerData.empty());
if (!mSamplerData.empty()) if (!mSamplerData.empty())
{ {
return reinterpret_cast<const uint8_t *>(mSamplerData.data()); return reinterpret_cast<const uint8_t *>(mSamplerData.data());
} }
return vsData ? vsData : (psData ? psData : csData); for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
if (mShaderData[shaderType])
{
return mShaderData[shaderType];
}
}
UNREACHABLE();
return nullptr;
} }
// D3DVarying Implementation // D3DVarying Implementation
...@@ -400,18 +394,14 @@ D3DVarying::D3DVarying(const std::string &semanticNameIn, ...@@ -400,18 +394,14 @@ D3DVarying::D3DVarying(const std::string &semanticNameIn,
// ProgramD3DMetadata Implementation // ProgramD3DMetadata Implementation
ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer, ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
const ShaderD3D *vertexShader, const gl::ShaderMap<const ShaderD3D *> &attachedShaders)
const ShaderD3D *fragmentShader)
: mRendererMajorShaderModel(renderer->getMajorShaderModel()), : mRendererMajorShaderModel(renderer->getMajorShaderModel()),
mShaderModelSuffix(renderer->getShaderModelSuffix()), mShaderModelSuffix(renderer->getShaderModelSuffix()),
mUsesInstancedPointSpriteEmulation( mUsesInstancedPointSpriteEmulation(
renderer->getWorkarounds().useInstancedPointSpriteEmulation), renderer->getWorkarounds().useInstancedPointSpriteEmulation),
mUsesViewScale(renderer->presentPathFastEnabled()), mUsesViewScale(renderer->presentPathFastEnabled()),
mHasANGLEMultiviewEnabled(vertexShader->hasANGLEMultiviewEnabled()),
mUsesViewID(fragmentShader->usesViewID()),
mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()), mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
mVertexShader(vertexShader), mAttachedShaders(attachedShaders)
mFragmentShader(fragmentShader)
{ {
} }
...@@ -422,28 +412,29 @@ int ProgramD3DMetadata::getRendererMajorShaderModel() const ...@@ -422,28 +412,29 @@ int ProgramD3DMetadata::getRendererMajorShaderModel() const
bool ProgramD3DMetadata::usesBroadcast(const gl::ContextState &data) const bool ProgramD3DMetadata::usesBroadcast(const gl::ContextState &data) const
{ {
return (mFragmentShader->usesFragColor() && mFragmentShader->usesMultipleRenderTargets() && return (mAttachedShaders[gl::ShaderType::Fragment]->usesFragColor() &&
mAttachedShaders[gl::ShaderType::Fragment]->usesMultipleRenderTargets() &&
data.getClientMajorVersion() < 3); data.getClientMajorVersion() < 3);
} }
bool ProgramD3DMetadata::usesFragDepth() const bool ProgramD3DMetadata::usesFragDepth() const
{ {
return mFragmentShader->usesFragDepth(); return mAttachedShaders[gl::ShaderType::Fragment]->usesFragDepth();
} }
bool ProgramD3DMetadata::usesPointCoord() const bool ProgramD3DMetadata::usesPointCoord() const
{ {
return mFragmentShader->usesPointCoord(); return mAttachedShaders[gl::ShaderType::Fragment]->usesPointCoord();
} }
bool ProgramD3DMetadata::usesFragCoord() const bool ProgramD3DMetadata::usesFragCoord() const
{ {
return mFragmentShader->usesFragCoord(); return mAttachedShaders[gl::ShaderType::Fragment]->usesFragCoord();
} }
bool ProgramD3DMetadata::usesPointSize() const bool ProgramD3DMetadata::usesPointSize() const
{ {
return mVertexShader->usesPointSize(); return mAttachedShaders[gl::ShaderType::Vertex]->usesPointSize();
} }
bool ProgramD3DMetadata::usesInsertedPointCoordValue() const bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
...@@ -459,12 +450,12 @@ bool ProgramD3DMetadata::usesViewScale() const ...@@ -459,12 +450,12 @@ bool ProgramD3DMetadata::usesViewScale() const
bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const
{ {
return mHasANGLEMultiviewEnabled; return mAttachedShaders[gl::ShaderType::Vertex]->hasANGLEMultiviewEnabled();
} }
bool ProgramD3DMetadata::usesViewID() const bool ProgramD3DMetadata::usesViewID() const
{ {
return mUsesViewID; return mAttachedShaders[gl::ShaderType::Fragment]->usesViewID();
} }
bool ProgramD3DMetadata::canSelectViewInVertexShader() const bool ProgramD3DMetadata::canSelectViewInVertexShader() const
...@@ -499,17 +490,17 @@ bool ProgramD3DMetadata::usesSystemValuePointSize() const ...@@ -499,17 +490,17 @@ bool ProgramD3DMetadata::usesSystemValuePointSize() const
bool ProgramD3DMetadata::usesMultipleFragmentOuts() const bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
{ {
return mFragmentShader->usesMultipleRenderTargets(); return mAttachedShaders[gl::ShaderType::Fragment]->usesMultipleRenderTargets();
} }
GLint ProgramD3DMetadata::getMajorShaderVersion() const GLint ProgramD3DMetadata::getMajorShaderVersion() const
{ {
return mVertexShader->getData().getShaderVersion(); return mAttachedShaders[gl::ShaderType::Vertex]->getData().getShaderVersion();
} }
const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const
{ {
return mFragmentShader; return mAttachedShaders[gl::ShaderType::Fragment];
} }
// ProgramD3D Implementation // ProgramD3D Implementation
...@@ -613,9 +604,6 @@ ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer) ...@@ -613,9 +604,6 @@ ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
mComputeExecutable(nullptr), mComputeExecutable(nullptr),
mUsesPointSize(false), mUsesPointSize(false),
mUsesFlatInterpolation(false), mUsesFlatInterpolation(false),
mVertexUniformStorage(nullptr),
mFragmentUniformStorage(nullptr),
mComputeUniformStorage(nullptr),
mUsedVertexSamplerRange(0), mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0), mUsedPixelSamplerRange(0),
mUsedComputeSamplerRange(0), mUsedComputeSamplerRange(0),
...@@ -762,9 +750,9 @@ ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping() ...@@ -762,9 +750,9 @@ ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
int count = d3dUniform->getArraySizeProduct(); int count = d3dUniform->getArraySizeProduct();
if (d3dUniform->isReferencedByFragmentShader()) if (d3dUniform->isReferencedByShader(gl::ShaderType::Fragment))
{ {
unsigned int firstIndex = d3dUniform->psRegisterIndex; unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment];
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
...@@ -778,9 +766,9 @@ ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping() ...@@ -778,9 +766,9 @@ ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
} }
} }
if (d3dUniform->isReferencedByVertexShader()) if (d3dUniform->isReferencedByShader(gl::ShaderType::Vertex))
{ {
unsigned int firstIndex = d3dUniform->vsRegisterIndex; unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex];
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
...@@ -794,9 +782,9 @@ ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping() ...@@ -794,9 +782,9 @@ ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
} }
} }
if (d3dUniform->isReferencedByComputeShader()) if (d3dUniform->isReferencedByShader(gl::ShaderType::Compute))
{ {
unsigned int firstIndex = d3dUniform->csRegisterIndex; unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute];
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
...@@ -961,9 +949,10 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -961,9 +949,10 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name, new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name,
linkedUniform.arraySizes, linkedUniform.isInDefaultBlock()); linkedUniform.arraySizes, linkedUniform.isInDefaultBlock());
stream->readInt<HLSLRegisterType>(&d3dUniform->regType); stream->readInt<HLSLRegisterType>(&d3dUniform->regType);
stream->readInt(&d3dUniform->psRegisterIndex); for (gl::ShaderType shaderType : gl::AllShaderTypes())
stream->readInt(&d3dUniform->vsRegisterIndex); {
stream->readInt(&d3dUniform->csRegisterIndex); stream->readInt(&d3dUniform->mShaderRegisterIndexes[shaderType]);
}
stream->readInt(&d3dUniform->registerCount); stream->readInt(&d3dUniform->registerCount);
stream->readInt(&d3dUniform->registerElement); stream->readInt(&d3dUniform->registerElement);
...@@ -981,9 +970,10 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -981,9 +970,10 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
for (unsigned int blockIndex = 0; blockIndex < blockCount; ++blockIndex) for (unsigned int blockIndex = 0; blockIndex < blockCount; ++blockIndex)
{ {
D3DUniformBlock uniformBlock; D3DUniformBlock uniformBlock;
stream->readInt(&uniformBlock.psRegisterIndex); for (gl::ShaderType shaderType : gl::AllShaderTypes())
stream->readInt(&uniformBlock.vsRegisterIndex); {
stream->readInt(&uniformBlock.csRegisterIndex); stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
}
mD3DUniformBlocks.push_back(uniformBlock); mD3DUniformBlocks.push_back(uniformBlock);
} }
...@@ -1143,7 +1133,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -1143,7 +1133,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
mComputeExecutable.reset(computeExecutable); mComputeExecutable.reset(computeExecutable);
} }
initializeUniformStorage(); initializeUniformStorage(mState.getLinkedShaderStages());
dirtyAllUniforms(); dirtyAllUniforms();
...@@ -1215,9 +1205,10 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1215,9 +1205,10 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
{ {
// Type, name and arraySize are redundant, so aren't stored in the binary. // Type, name and arraySize are redundant, so aren't stored in the binary.
stream->writeInt(static_cast<unsigned int>(uniform->regType)); stream->writeInt(static_cast<unsigned int>(uniform->regType));
stream->writeIntOrNegOne(uniform->psRegisterIndex); for (gl::ShaderType shaderType : gl::AllShaderTypes())
stream->writeIntOrNegOne(uniform->vsRegisterIndex); {
stream->writeIntOrNegOne(uniform->csRegisterIndex); stream->writeIntOrNegOne(uniform->mShaderRegisterIndexes[shaderType]);
}
stream->writeInt(uniform->registerCount); stream->writeInt(uniform->registerCount);
stream->writeInt(uniform->registerElement); stream->writeInt(uniform->registerElement);
} }
...@@ -1225,9 +1216,10 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1225,9 +1216,10 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeInt(mD3DUniformBlocks.size()); stream->writeInt(mD3DUniformBlocks.size());
for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks) for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
{ {
stream->writeIntOrNegOne(uniformBlock.psRegisterIndex); for (gl::ShaderType shaderType : gl::AllShaderTypes())
stream->writeIntOrNegOne(uniformBlock.vsRegisterIndex); {
stream->writeIntOrNegOne(uniformBlock.csRegisterIndex); stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]);
}
} }
stream->writeInt(mStreamOutVaryings.size()); stream->writeInt(mStreamOutVaryings.size());
...@@ -1716,31 +1708,32 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1716,31 +1708,32 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex); gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment); gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment);
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader); gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader); shadersD3D[gl::ShaderType::Vertex] = GetImplAs<ShaderD3D>(vertexShader);
shadersD3D[gl::ShaderType::Fragment] = GetImplAs<ShaderD3D>(fragmentShader);
mSamplersVS.resize(data.getCaps().maxVertexTextureImageUnits); mSamplersVS.resize(data.getCaps().maxVertexTextureImageUnits);
mSamplersPS.resize(data.getCaps().maxTextureImageUnits); mSamplersPS.resize(data.getCaps().maxTextureImageUnits);
vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds); shadersD3D[gl::ShaderType::Vertex]->generateWorkarounds(&mVertexWorkarounds);
fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds); shadersD3D[gl::ShaderType::Fragment]->generateWorkarounds(&mPixelWorkarounds);
if (mRenderer->getNativeLimitations().noFrontFacingSupport) if (mRenderer->getNativeLimitations().noFrontFacingSupport)
{ {
if (fragmentShaderD3D->usesFrontFacing()) if (shadersD3D[gl::ShaderType::Fragment]->usesFrontFacing())
{ {
infoLog << "The current renderer doesn't support gl_FrontFacing"; infoLog << "The current renderer doesn't support gl_FrontFacing";
return false; return false;
} }
} }
ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D); ProgramD3DMetadata metadata(mRenderer, shadersD3D);
BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking); BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking);
mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, resources.varyingPacking, mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, resources.varyingPacking,
builtins, &mPixelHLSL, &mVertexHLSL); builtins, &mPixelHLSL, &mVertexHLSL);
mUsesPointSize = vertexShaderD3D->usesPointSize(); mUsesPointSize = shadersD3D[gl::ShaderType::Vertex]->usesPointSize();
mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
mUsesFragDepth = metadata.usesFragDepth(); mUsesFragDepth = metadata.usesFragDepth();
mUsesViewID = metadata.usesViewID(); mUsesViewID = metadata.usesViewID();
...@@ -1802,12 +1795,11 @@ void ProgramD3D::initializeUniformBlocks() ...@@ -1802,12 +1795,11 @@ void ProgramD3D::initializeUniformBlocks()
ASSERT(mD3DUniformBlocks.empty()); ASSERT(mD3DUniformBlocks.empty());
// Assign registers and update sizes. // Assign registers and update sizes.
const ShaderD3D *vertexShaderD3D = gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Vertex)); for (gl::ShaderType shaderType : gl::AllShaderTypes())
const ShaderD3D *fragmentShaderD3D = {
SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Fragment)); shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
const ShaderD3D *computeShaderD3D = }
SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks()) for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks())
{ {
...@@ -1815,67 +1807,55 @@ void ProgramD3D::initializeUniformBlocks() ...@@ -1815,67 +1807,55 @@ void ProgramD3D::initializeUniformBlocks()
D3DUniformBlock d3dUniformBlock; D3DUniformBlock d3dUniformBlock;
if (uniformBlock.isActive(gl::ShaderType::Vertex)) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
ASSERT(vertexShaderD3D != nullptr); if (uniformBlock.isActive(shaderType))
unsigned int baseRegister = vertexShaderD3D->getUniformBlockRegister(uniformBlock.name);
d3dUniformBlock.vsRegisterIndex = baseRegister + uniformBlockElement;
}
if (uniformBlock.isActive(gl::ShaderType::Fragment))
{ {
ASSERT(fragmentShaderD3D != nullptr); ASSERT(shadersD3D[shaderType]);
unsigned int baseRegister = unsigned int baseRegister =
fragmentShaderD3D->getUniformBlockRegister(uniformBlock.name); shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name);
d3dUniformBlock.psRegisterIndex = baseRegister + uniformBlockElement; d3dUniformBlock.mShaderRegisterIndexes[shaderType] =
baseRegister + uniformBlockElement;
} }
if (uniformBlock.isActive(gl::ShaderType::Compute))
{
ASSERT(computeShaderD3D != nullptr);
unsigned int baseRegister =
computeShaderD3D->getUniformBlockRegister(uniformBlock.name);
d3dUniformBlock.csRegisterIndex = baseRegister + uniformBlockElement;
} }
mD3DUniformBlocks.push_back(d3dUniformBlock); mD3DUniformBlocks.push_back(d3dUniformBlock);
} }
} }
void ProgramD3D::initializeUniformStorage() void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages)
{ {
// Compute total default block size // Compute total default block size
unsigned int vertexRegisters = 0; gl::ShaderMap<unsigned int> shaderRegisters = {};
unsigned int fragmentRegisters = 0;
unsigned int computeRegisters = 0;
for (const D3DUniform *d3dUniform : mD3DUniforms) for (const D3DUniform *d3dUniform : mD3DUniforms)
{ {
if (!d3dUniform->isSampler()) if (d3dUniform->isSampler())
{
if (d3dUniform->isReferencedByVertexShader())
{ {
vertexRegisters = std::max(vertexRegisters, continue;
d3dUniform->vsRegisterIndex + d3dUniform->registerCount);
} }
if (d3dUniform->isReferencedByFragmentShader())
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
fragmentRegisters = std::max( if (d3dUniform->isReferencedByShader(shaderType))
fragmentRegisters, d3dUniform->psRegisterIndex + d3dUniform->registerCount);
}
if (d3dUniform->isReferencedByComputeShader())
{ {
computeRegisters = std::max( ASSERT(availableShaderStages[shaderType]);
computeRegisters, d3dUniform->csRegisterIndex + d3dUniform->registerCount); shaderRegisters[shaderType] = std::max(
shaderRegisters[shaderType],
d3dUniform->mShaderRegisterIndexes[shaderType] + d3dUniform->registerCount);
} }
} }
} }
mVertexUniformStorage = // We only reset uniform storages for the shader stages available in the program (attached
std::unique_ptr<UniformStorageD3D>(mRenderer->createUniformStorage(vertexRegisters * 16u)); // shaders in ProgramD3D::link() and linkedShaderStages in ProgramD3D::load()).
mFragmentUniformStorage = std::unique_ptr<UniformStorageD3D>( for (gl::ShaderType shaderType : gl::AllShaderTypes())
mRenderer->createUniformStorage(fragmentRegisters * 16u)); {
mComputeUniformStorage = if (availableShaderStages[shaderType])
std::unique_ptr<UniformStorageD3D>(mRenderer->createUniformStorage(computeRegisters * 16u)); {
mShaderUniformStorages[shaderType].reset(
mRenderer->createUniformStorage(shaderRegisters[shaderType] * 16u));
}
}
// Iterate the uniforms again to assign data pointers to default block uniforms. // Iterate the uniforms again to assign data pointers to default block uniforms.
for (D3DUniform *d3dUniform : mD3DUniforms) for (D3DUniform *d3dUniform : mD3DUniforms)
...@@ -1886,37 +1866,32 @@ void ProgramD3D::initializeUniformStorage() ...@@ -1886,37 +1866,32 @@ void ProgramD3D::initializeUniformStorage()
continue; continue;
} }
if (d3dUniform->isReferencedByVertexShader()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
d3dUniform->vsData = mVertexUniformStorage->getDataPointer(d3dUniform->vsRegisterIndex, if (d3dUniform->isReferencedByShader(shaderType))
d3dUniform->registerElement);
}
if (d3dUniform->isReferencedByFragmentShader())
{ {
d3dUniform->psData = mFragmentUniformStorage->getDataPointer( d3dUniform->mShaderData[shaderType] =
d3dUniform->psRegisterIndex, d3dUniform->registerElement); mShaderUniformStorages[shaderType]->getDataPointer(
d3dUniform->mShaderRegisterIndexes[shaderType],
d3dUniform->registerElement);
} }
if (d3dUniform->isReferencedByComputeShader())
{
d3dUniform->csData = mComputeUniformStorage->getDataPointer(
d3dUniform->csRegisterIndex, d3dUniform->registerElement);
} }
} }
} }
void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps, void ProgramD3D::updateUniformBufferCache(
unsigned int reservedVertex, const gl::Caps &caps,
unsigned int reservedFragment) const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes)
{ {
if (mState.getUniformBlocks().empty()) if (mState.getUniformBlocks().empty())
{ {
return; return;
} }
mVertexUBOCache.clear(); for (gl::ShaderType shaderType : gl::AllShaderTypes())
mFragmentUBOCache.clear(); {
mShaderUBOCaches[shaderType].clear();
}
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size(); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
uniformBlockIndex++) uniformBlockIndex++)
...@@ -1925,49 +1900,32 @@ void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps, ...@@ -1925,49 +1900,32 @@ void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps,
GLuint blockBinding = mState.getUniformBlockBinding(uniformBlockIndex); GLuint blockBinding = mState.getUniformBlockBinding(uniformBlockIndex);
// Unnecessary to apply an unreferenced standard or shared UBO // Unnecessary to apply an unreferenced standard or shared UBO
if (!uniformBlock.vertexActive() && !uniformBlock.fragmentActive()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
if (!uniformBlock.activeInShader(shaderType))
{ {
continue; continue;
} }
if (uniformBlock.vertexActive()) unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType] -
{ reservedShaderRegisterIndexes[shaderType];
unsigned int registerIndex = uniformBlock.vsRegisterIndex - reservedVertex;
ASSERT(registerIndex < caps.maxVertexUniformBlocks); ASSERT(registerIndex < caps.maxVertexUniformBlocks);
if (mVertexUBOCache.size() <= registerIndex) std::vector<int> &shaderUBOcache = mShaderUBOCaches[shaderType];
{ if (shaderUBOcache.size() <= registerIndex)
mVertexUBOCache.resize(registerIndex + 1, -1);
}
ASSERT(mVertexUBOCache[registerIndex] == -1);
mVertexUBOCache[registerIndex] = blockBinding;
}
if (uniformBlock.fragmentActive())
{ {
unsigned int registerIndex = uniformBlock.psRegisterIndex - reservedFragment; shaderUBOcache.resize(registerIndex + 1, -1);
ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
if (mFragmentUBOCache.size() <= registerIndex)
{
mFragmentUBOCache.resize(registerIndex + 1, -1);
} }
ASSERT(mFragmentUBOCache[registerIndex] == -1); ASSERT(shaderUBOcache[registerIndex] == -1);
mFragmentUBOCache[registerIndex] = blockBinding; shaderUBOcache[registerIndex] = blockBinding;
} }
} }
} }
const std::vector<GLint> &ProgramD3D::getVertexUniformBufferCache() const const std::vector<GLint> &ProgramD3D::getShaderUniformBufferCache(gl::ShaderType shaderType) const
{ {
return mVertexUBOCache; return mShaderUBOCaches[shaderType];
}
const std::vector<GLint> &ProgramD3D::getFragmentUniformBufferCache() const
{
return mFragmentUBOCache;
} }
void ProgramD3D::dirtyAllUniforms() void ProgramD3D::dirtyAllUniforms()
...@@ -2120,6 +2078,8 @@ void ProgramD3D::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint /*unifo ...@@ -2120,6 +2078,8 @@ void ProgramD3D::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint /*unifo
void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context) void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
{ {
D3DUniformMap uniformMap; D3DUniformMap uniformMap;
gl::ShaderBitSet attachedShaders;
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
gl::Shader *shader = mState.getAttachedShader(shaderType); gl::Shader *shader = mState.getAttachedShader(shaderType);
...@@ -2132,6 +2092,8 @@ void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context) ...@@ -2132,6 +2092,8 @@ void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
defineUniformBase(shader, uniform, &uniformMap); defineUniformBase(shader, uniform, &uniformMap);
} }
} }
attachedShaders.set(shader->getType());
} }
} }
...@@ -2158,7 +2120,7 @@ void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context) ...@@ -2158,7 +2120,7 @@ void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
assignAllSamplerRegisters(); assignAllSamplerRegisters();
assignAllImageRegisters(); assignAllImageRegisters();
initializeUniformStorage(); initializeUniformStorage(attachedShaders);
} }
void ProgramD3D::defineUniformBase(const gl::Shader *shader, void ProgramD3D::defineUniformBase(const gl::Shader *shader,
...@@ -2357,20 +2319,8 @@ void ProgramD3D::defineUniform(gl::ShaderType shaderType, ...@@ -2357,20 +2319,8 @@ void ProgramD3D::defineUniform(gl::ShaderType shaderType,
unsigned int reg = unsigned int reg =
static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo)); static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo));
switch (shaderType) ASSERT(shaderType != gl::ShaderType::InvalidEnum);
{ d3dUniform->mShaderRegisterIndexes[shaderType] = reg;
case gl::ShaderType::Fragment:
d3dUniform->psRegisterIndex = reg;
break;
case gl::ShaderType::Vertex:
d3dUniform->vsRegisterIndex = reg;
break;
case gl::ShaderType::Compute:
d3dUniform->csRegisterIndex = reg;
break;
default:
UNREACHABLE();
}
// Arrays are treated as aggregate types // Arrays are treated as aggregate types
if (uniform.isArray()) if (uniform.isArray())
...@@ -2439,22 +2389,14 @@ void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, G ...@@ -2439,22 +2389,14 @@ void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, G
return; return;
} }
if (targetUniform->vsData) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
setUniformImpl(locationInfo, count, v, targetUniform->vsData, uniformType); if (targetUniform->mShaderData[shaderType])
mShaderUniformsDirty.set(gl::ShaderType::Vertex);
}
if (targetUniform->psData)
{ {
setUniformImpl(locationInfo, count, v, targetUniform->psData, uniformType); setUniformImpl(locationInfo, count, v, targetUniform->mShaderData[shaderType],
mShaderUniformsDirty.set(gl::ShaderType::Fragment); uniformType);
mShaderUniformsDirty.set(shaderType);
} }
if (targetUniform->csData)
{
setUniformImpl(locationInfo, count, v, targetUniform->csData, uniformType);
mShaderUniformsDirty.set(gl::ShaderType::Compute);
} }
} }
...@@ -2506,30 +2448,16 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location, ...@@ -2506,30 +2448,16 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location,
{ {
D3DUniform *targetUniform = getD3DUniformFromLocation(location); D3DUniform *targetUniform = getD3DUniformFromLocation(location);
if (targetUniform->vsData) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
targetUniform->vsData, targetUniformType))
{ {
mShaderUniformsDirty.set(gl::ShaderType::Vertex); if (targetUniform->mShaderData[shaderType])
}
}
if (targetUniform->psData)
{ {
if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value, if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
targetUniform->psData, targetUniformType)) targetUniform->mShaderData[shaderType],
targetUniformType))
{ {
mShaderUniformsDirty.set(gl::ShaderType::Fragment); mShaderUniformsDirty.set(shaderType);
}
} }
if (targetUniform->csData)
{
if (setUniformMatrixfvImpl<cols, rows>(location, countIn, transpose, value,
targetUniform->csData, targetUniformType))
{
mShaderUniformsDirty.set(gl::ShaderType::Compute);
} }
} }
} }
...@@ -2557,17 +2485,20 @@ void ProgramD3D::assignSamplerRegisters(size_t uniformIndex) ...@@ -2557,17 +2485,20 @@ void ProgramD3D::assignSamplerRegisters(size_t uniformIndex)
unsigned int registerOffset = mState.getUniforms()[uniformIndex].flattenedOffsetInParentArrays * unsigned int registerOffset = mState.getUniforms()[uniformIndex].flattenedOffsetInParentArrays *
d3dUniform->getArraySizeProduct(); d3dUniform->getArraySizeProduct();
// TODO(jiawei.shao@intel.com): refactor this code when using ShaderMap on mSamplers(VS|PS|CS)
// and mUsed(Vertex|Pixel|Compute)SamplerRange.
const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute); const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
if (computeShader) if (computeShader)
{ {
const ShaderD3D *computeShaderD3D = const ShaderD3D *computeShaderD3D =
GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute)); GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
ASSERT(computeShaderD3D->hasUniform(baseName)); ASSERT(computeShaderD3D->hasUniform(baseName));
d3dUniform->csRegisterIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] =
computeShaderD3D->getUniformRegister(baseName) + registerOffset; computeShaderD3D->getUniformRegister(baseName) + registerOffset;
ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX); ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX);
AssignSamplers(d3dUniform->csRegisterIndex, d3dUniform->typeInfo, AssignSamplers(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
d3dUniform->getArraySizeProduct(), mSamplersCS, &mUsedComputeSamplerRange); d3dUniform->typeInfo, d3dUniform->getArraySizeProduct(), mSamplersCS,
&mUsedComputeSamplerRange);
} }
else else
{ {
...@@ -2578,20 +2509,22 @@ void ProgramD3D::assignSamplerRegisters(size_t uniformIndex) ...@@ -2578,20 +2509,22 @@ void ProgramD3D::assignSamplerRegisters(size_t uniformIndex)
ASSERT(vertexShaderD3D->hasUniform(baseName) || fragmentShaderD3D->hasUniform(baseName)); ASSERT(vertexShaderD3D->hasUniform(baseName) || fragmentShaderD3D->hasUniform(baseName));
if (vertexShaderD3D->hasUniform(baseName)) if (vertexShaderD3D->hasUniform(baseName))
{ {
d3dUniform->vsRegisterIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex] =
vertexShaderD3D->getUniformRegister(baseName) + registerOffset; vertexShaderD3D->getUniformRegister(baseName) + registerOffset;
ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX); ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex] != GL_INVALID_INDEX);
AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->typeInfo, AssignSamplers(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex],
d3dUniform->getArraySizeProduct(), mSamplersVS, d3dUniform->typeInfo, d3dUniform->getArraySizeProduct(), mSamplersVS,
&mUsedVertexSamplerRange); &mUsedVertexSamplerRange);
} }
if (fragmentShaderD3D->hasUniform(baseName)) if (fragmentShaderD3D->hasUniform(baseName))
{ {
d3dUniform->psRegisterIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment] =
fragmentShaderD3D->getUniformRegister(baseName) + registerOffset; fragmentShaderD3D->getUniformRegister(baseName) + registerOffset;
ASSERT(d3dUniform->psRegisterIndex != GL_INVALID_INDEX); ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment] !=
AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->typeInfo, GL_INVALID_INDEX);
d3dUniform->getArraySizeProduct(), mSamplersPS, &mUsedPixelSamplerRange); AssignSamplers(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment],
d3dUniform->typeInfo, d3dUniform->getArraySizeProduct(), mSamplersPS,
&mUsedPixelSamplerRange);
} }
} }
} }
...@@ -2646,21 +2579,22 @@ void ProgramD3D::assignImageRegisters(size_t uniformIndex) ...@@ -2646,21 +2579,22 @@ void ProgramD3D::assignImageRegisters(size_t uniformIndex)
const ShaderD3D *computeShaderD3D = const ShaderD3D *computeShaderD3D =
GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute)); GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
ASSERT(computeShaderD3D->hasUniform(baseName)); ASSERT(computeShaderD3D->hasUniform(baseName));
d3dUniform->csRegisterIndex = d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] =
computeShaderD3D->getUniformRegister(baseName) + registerOffset; computeShaderD3D->getUniformRegister(baseName) + registerOffset;
ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX); ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX);
auto bindingIter = mImageBindingMap.find(baseName); auto bindingIter = mImageBindingMap.find(baseName);
ASSERT(bindingIter != mImageBindingMap.end()); ASSERT(bindingIter != mImageBindingMap.end());
if (d3dUniform->regType == HLSLRegisterType::Texture) if (d3dUniform->regType == HLSLRegisterType::Texture)
{ {
AssignImages(d3dUniform->csRegisterIndex, bindingIter->second, AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
d3dUniform->getArraySizeProduct(), mReadonlyImagesCS, bindingIter->second, d3dUniform->getArraySizeProduct(), mReadonlyImagesCS,
&mUsedComputeReadonlyImageRange); &mUsedComputeReadonlyImageRange);
} }
else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView) else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView)
{ {
AssignImages(d3dUniform->csRegisterIndex, bindingIter->second, AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
d3dUniform->getArraySizeProduct(), mImagesCS, &mUsedComputeImageRange); bindingIter->second, d3dUniform->getArraySizeProduct(), mImagesCS,
&mUsedComputeImageRange);
} }
else else
{ {
...@@ -2734,9 +2668,10 @@ void ProgramD3D::reset() ...@@ -2734,9 +2668,10 @@ void ProgramD3D::reset()
SafeDeleteContainer(mD3DUniforms); SafeDeleteContainer(mD3DUniforms);
mD3DUniformBlocks.clear(); mD3DUniformBlocks.clear();
mVertexUniformStorage.reset(nullptr); for (gl::ShaderType shaderType : gl::AllShaderTypes())
mFragmentUniformStorage.reset(nullptr); {
mComputeUniformStorage.reset(nullptr); mShaderUniformStorages[shaderType].reset();
}
mSamplersPS.clear(); mSamplersPS.clear();
mSamplersVS.clear(); mSamplersVS.clear();
......
...@@ -55,9 +55,7 @@ struct D3DUniform : private angle::NonCopyable ...@@ -55,9 +55,7 @@ struct D3DUniform : private angle::NonCopyable
bool isImage() const; bool isImage() const;
bool isArray() const { return !arraySizes.empty(); } bool isArray() const { return !arraySizes.empty(); }
unsigned int getArraySizeProduct() const; unsigned int getArraySizeProduct() const;
bool isReferencedByVertexShader() const; bool isReferencedByShader(gl::ShaderType shaderType) const;
bool isReferencedByFragmentShader() const;
bool isReferencedByComputeShader() const;
const uint8_t *firstNonNullData() const; const uint8_t *firstNonNullData() const;
const uint8_t *getDataPtrToElement(size_t elementIndex) const; const uint8_t *getDataPtrToElement(size_t elementIndex) const;
...@@ -68,15 +66,11 @@ struct D3DUniform : private angle::NonCopyable ...@@ -68,15 +66,11 @@ struct D3DUniform : private angle::NonCopyable
std::vector<unsigned int> arraySizes; std::vector<unsigned int> arraySizes;
// Pointer to a system copies of the data. Separate pointers for each uniform storage type. // Pointer to a system copies of the data. Separate pointers for each uniform storage type.
uint8_t *vsData; gl::ShaderMap<uint8_t *> mShaderData;
uint8_t *psData;
uint8_t *csData;
// Register information. // Register information.
HLSLRegisterType regType; HLSLRegisterType regType;
unsigned int vsRegisterIndex; gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
unsigned int psRegisterIndex;
unsigned int csRegisterIndex;
unsigned int registerCount; unsigned int registerCount;
// Register "elements" are used for uniform structs in ES3, to appropriately identify single // Register "elements" are used for uniform structs in ES3, to appropriately identify single
...@@ -90,22 +84,14 @@ struct D3DUniform : private angle::NonCopyable ...@@ -90,22 +84,14 @@ struct D3DUniform : private angle::NonCopyable
struct D3DUniformBlock struct D3DUniformBlock
{ {
D3DUniformBlock() D3DUniformBlock() { mShaderRegisterIndexes.fill(GL_INVALID_INDEX); }
: vsRegisterIndex(GL_INVALID_INDEX),
psRegisterIndex(GL_INVALID_INDEX), bool activeInShader(gl::ShaderType shaderType) const
csRegisterIndex(GL_INVALID_INDEX)
{ {
return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
} }
bool vertexActive() const { return vsRegisterIndex != GL_INVALID_INDEX; } gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
bool fragmentActive() const { return psRegisterIndex != GL_INVALID_INDEX; }
bool computeActive() const { return csRegisterIndex != GL_INVALID_INDEX; }
unsigned int vsRegisterIndex;
unsigned int psRegisterIndex;
unsigned int csRegisterIndex;
}; };
struct D3DVarying final struct D3DVarying final
...@@ -129,8 +115,7 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -129,8 +115,7 @@ class ProgramD3DMetadata final : angle::NonCopyable
{ {
public: public:
ProgramD3DMetadata(RendererD3D *renderer, ProgramD3DMetadata(RendererD3D *renderer,
const ShaderD3D *vertexShader, const gl::ShaderMap<const ShaderD3D *> &attachedShaders);
const ShaderD3D *fragmentShader);
int getRendererMajorShaderModel() const; int getRendererMajorShaderModel() const;
bool usesBroadcast(const gl::ContextState &data) const; bool usesBroadcast(const gl::ContextState &data) const;
...@@ -155,11 +140,8 @@ class ProgramD3DMetadata final : angle::NonCopyable ...@@ -155,11 +140,8 @@ class ProgramD3DMetadata final : angle::NonCopyable
const std::string mShaderModelSuffix; const std::string mShaderModelSuffix;
const bool mUsesInstancedPointSpriteEmulation; const bool mUsesInstancedPointSpriteEmulation;
const bool mUsesViewScale; const bool mUsesViewScale;
const bool mHasANGLEMultiviewEnabled;
const bool mUsesViewID;
const bool mCanSelectViewInVertexShader; const bool mCanSelectViewInVertexShader;
const ShaderD3D *mVertexShader; const gl::ShaderMap<const ShaderD3D *> mAttachedShaders;
const ShaderD3D *mFragmentShader;
}; };
class ProgramD3D : public ProgramImpl class ProgramD3D : public ProgramImpl
...@@ -223,12 +205,9 @@ class ProgramD3D : public ProgramImpl ...@@ -223,12 +205,9 @@ class ProgramD3D : public ProgramImpl
GLint components, GLint components,
const GLfloat *coeffs) override; const GLfloat *coeffs) override;
void initializeUniformStorage();
void updateUniformBufferCache(const gl::Caps &caps, void updateUniformBufferCache(const gl::Caps &caps,
unsigned int reservedVertex, const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes);
unsigned int reservedFragment); const std::vector<GLint> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
const std::vector<GLint> &getVertexUniformBufferCache() const;
const std::vector<GLint> &getFragmentUniformBufferCache() const;
void dirtyAllUniforms(); void dirtyAllUniforms();
...@@ -287,9 +266,10 @@ class ProgramD3D : public ProgramImpl ...@@ -287,9 +266,10 @@ class ProgramD3D : public ProgramImpl
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage.get(); } UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const
UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage.get(); } {
UniformStorageD3D &getComputeUniformStorage() const { return *mComputeUniformStorage.get(); } return mShaderUniformStorages[shaderType].get();
}
unsigned int getSerial() const; unsigned int getSerial() const;
...@@ -395,6 +375,8 @@ class ProgramD3D : public ProgramImpl ...@@ -395,6 +375,8 @@ class ProgramD3D : public ProgramImpl
typedef std::map<std::string, D3DUniform *> D3DUniformMap; typedef std::map<std::string, D3DUniform *> D3DUniformMap;
void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);
void defineUniformsAndAssignRegisters(const gl::Context *context); void defineUniformsAndAssignRegisters(const gl::Context *context);
void defineUniformBase(const gl::Shader *shader, void defineUniformBase(const gl::Shader *shader,
const sh::Uniform &uniform, const sh::Uniform &uniform,
...@@ -516,9 +498,7 @@ class ProgramD3D : public ProgramImpl ...@@ -516,9 +498,7 @@ class ProgramD3D : public ProgramImpl
bool mUsesPointSize; bool mUsesPointSize;
bool mUsesFlatInterpolation; bool mUsesFlatInterpolation;
std::unique_ptr<UniformStorageD3D> mVertexUniformStorage; gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;
std::unique_ptr<UniformStorageD3D> mFragmentUniformStorage;
std::unique_ptr<UniformStorageD3D> mComputeUniformStorage;
std::vector<Sampler> mSamplersPS; std::vector<Sampler> mSamplersPS;
std::vector<Sampler> mSamplersVS; std::vector<Sampler> mSamplersVS;
...@@ -541,8 +521,7 @@ class ProgramD3D : public ProgramImpl ...@@ -541,8 +521,7 @@ class ProgramD3D : public ProgramImpl
unsigned int mSerial; unsigned int mSerial;
std::vector<GLint> mVertexUBOCache; gl::ShaderMap<std::vector<int>> mShaderUBOCaches;
std::vector<GLint> mFragmentUBOCache;
VertexExecutable::Signature mCachedVertexSignature; VertexExecutable::Signature mCachedVertexSignature;
gl::InputLayout mCachedInputLayout; gl::InputLayout mCachedInputLayout;
Optional<size_t> mCachedVertexExecutableIndex; Optional<size_t> mCachedVertexExecutableIndex;
......
...@@ -1996,16 +1996,15 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const ...@@ -1996,16 +1996,15 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const
return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel); return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel);
} }
unsigned int Renderer11::getReservedVertexUniformBuffers() const gl::ShaderMap<unsigned int> Renderer11::getReservedShaderUniformBuffers() const
{ {
// we reserve one buffer for the application uniforms, and one for driver uniforms gl::ShaderMap<unsigned int> shaderReservedUniformBuffers = {};
return 2;
}
unsigned int Renderer11::getReservedFragmentUniformBuffers() const
{
// we reserve one buffer for the application uniforms, and one for driver uniforms // we reserve one buffer for the application uniforms, and one for driver uniforms
return 2; shaderReservedUniformBuffers[gl::ShaderType::Vertex] = 2;
shaderReservedUniformBuffers[gl::ShaderType::Fragment] = 2;
return shaderReservedUniformBuffers;
} }
d3d11::ANGLED3D11DeviceType Renderer11::getDeviceType() const d3d11::ANGLED3D11DeviceType Renderer11::getDeviceType() const
......
...@@ -157,8 +157,7 @@ class Renderer11 : public RendererD3D ...@@ -157,8 +157,7 @@ class Renderer11 : public RendererD3D
unsigned int getReservedVertexUniformVectors() const; unsigned int getReservedVertexUniformVectors() const;
unsigned int getReservedFragmentUniformVectors() const; unsigned int getReservedFragmentUniformVectors() const;
unsigned int getReservedVertexUniformBuffers() const; gl::ShaderMap<unsigned int> getReservedShaderUniformBuffers() const;
unsigned int getReservedFragmentUniformBuffers() const;
bool getShareHandleSupport() const; bool getShareHandleSupport() const;
......
...@@ -3077,9 +3077,9 @@ gl::Error StateManager11::generateSwizzles(const gl::Context *context) ...@@ -3077,9 +3077,9 @@ gl::Error StateManager11::generateSwizzles(const gl::Context *context)
gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D) gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D)
{ {
UniformStorage11 *vertexUniformStorage = UniformStorage11 *vertexUniformStorage =
GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage()); GetAs<UniformStorage11>(programD3D->getShaderUniformStorage(gl::ShaderType::Vertex));
UniformStorage11 *fragmentUniformStorage = UniformStorage11 *fragmentUniformStorage =
GetAs<UniformStorage11>(&programD3D->getFragmentUniformStorage()); GetAs<UniformStorage11>(programD3D->getShaderUniformStorage(gl::ShaderType::Fragment));
ASSERT(vertexUniformStorage); ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage); ASSERT(fragmentUniformStorage);
...@@ -3180,7 +3180,7 @@ gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D) ...@@ -3180,7 +3180,7 @@ gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D)
gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D) gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D)
{ {
UniformStorage11 *computeUniformStorage = UniformStorage11 *computeUniformStorage =
GetAs<UniformStorage11>(&programD3D->getComputeUniformStorage()); GetAs<UniformStorage11>(programD3D->getShaderUniformStorage(gl::ShaderType::Compute));
ASSERT(computeUniformStorage); ASSERT(computeUniformStorage);
const d3d11::Buffer *constantBuffer = nullptr; const d3d11::Buffer *constantBuffer = nullptr;
...@@ -3223,19 +3223,22 @@ gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D) ...@@ -3223,19 +3223,22 @@ gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D)
gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D) gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D)
{ {
unsigned int reservedVertex = mRenderer->getReservedVertexUniformBuffers(); gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers();
unsigned int reservedFragment = mRenderer->getReservedFragmentUniformBuffers(); programD3D->updateUniformBufferCache(context->getCaps(), shaderReservedUBOs);
programD3D->updateUniformBufferCache(context->getCaps(), reservedVertex, reservedFragment); const auto &vertexUniformBuffers =
programD3D->getShaderUniformBufferCache(gl::ShaderType::Vertex);
const auto &vertexUniformBuffers = programD3D->getVertexUniformBufferCache(); const auto &fragmentUniformBuffers =
const auto &fragmentUniformBuffers = programD3D->getFragmentUniformBufferCache(); programD3D->getShaderUniformBufferCache(gl::ShaderType::Fragment);
const auto &glState = context->getGLState(); const auto &glState = context->getGLState();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
mConstantBufferObserver.reset(); mConstantBufferObserver.reset();
unsigned int reservedVertex = shaderReservedUBOs[gl::ShaderType::Vertex];
unsigned int reservedFragment = shaderReservedUBOs[gl::ShaderType::Fragment];
for (size_t bufferIndex = 0; bufferIndex < vertexUniformBuffers.size(); bufferIndex++) for (size_t bufferIndex = 0; bufferIndex < vertexUniformBuffers.size(); bufferIndex++)
{ {
GLint binding = vertexUniformBuffers[bufferIndex]; GLint binding = vertexUniformBuffers[bufferIndex];
......
...@@ -1817,8 +1817,8 @@ gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D) ...@@ -1817,8 +1817,8 @@ gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D)
for (const D3DUniform *targetUniform : uniformArray) for (const D3DUniform *targetUniform : uniformArray)
{ {
// Built-in uniforms must be skipped. // Built-in uniforms must be skipped.
if (!targetUniform->isReferencedByFragmentShader() && if (!targetUniform->isReferencedByShader(gl::ShaderType::Vertex) &&
!targetUniform->isReferencedByVertexShader()) !targetUniform->isReferencedByShader(gl::ShaderType::Fragment))
continue; continue;
const GLfloat *f = reinterpret_cast<const GLfloat *>(targetUniform->firstNonNullData()); const GLfloat *f = reinterpret_cast<const GLfloat *>(targetUniform->firstNonNullData());
...@@ -1862,15 +1862,17 @@ gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D) ...@@ -1862,15 +1862,17 @@ gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D)
void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v)
{ {
if (targetUniform->isReferencedByFragmentShader()) if (targetUniform->isReferencedByShader(gl::ShaderType::Fragment))
{ {
mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, mDevice->SetPixelShaderConstantF(
targetUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment], v,
targetUniform->registerCount); targetUniform->registerCount);
} }
if (targetUniform->isReferencedByVertexShader()) if (targetUniform->isReferencedByShader(gl::ShaderType::Vertex))
{ {
mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, mDevice->SetVertexShaderConstantF(
targetUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex], v,
targetUniform->registerCount); targetUniform->registerCount);
} }
} }
......
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