Commit a602f906 by Qin Jiajia Committed by Commit Bot

ES31: Support shader storage buffer in D3D-API side.

Bug: angleproject:1951 Test: angle_end2end_tests Change-Id: I0d8a4f8cf00fc7fd2d85315138e2b7457fd0b90c Reviewed-on: https://chromium-review.googlesource.com/1242846 Commit-Queue: Jiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 547edfe2
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 198 #define ANGLE_SH_VERSION 199
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -592,6 +592,17 @@ int GetVertexShaderNumViews(const ShHandle handle); ...@@ -592,6 +592,17 @@ int GetVertexShaderNumViews(const ShHandle handle);
bool CheckVariablesWithinPackingLimits(int maxVectors, bool CheckVariablesWithinPackingLimits(int maxVectors,
const std::vector<sh::ShaderVariable> &variables); const std::vector<sh::ShaderVariable> &variables);
// Gives the compiler-assigned register for a shader storage block.
// The method writes the value to the output variable "indexOut".
// Returns true if it found a valid shader storage block, false otherwise.
// Parameters:
// handle: Specifies the compiler
// shaderStorageBlockName: Specifies the shader storage block
// indexOut: output variable that stores the assigned register
bool GetShaderStorageBlockRegister(const ShHandle handle,
const std::string &shaderStorageBlockName,
unsigned int *indexOut);
// Gives the compiler-assigned register for a uniform block. // Gives the compiler-assigned register for a uniform block.
// The method writes the value to the output variable "indexOut". // The method writes the value to the output variable "indexOut".
// Returns true if it found a valid uniform block, false otherwise. // Returns true if it found a valid uniform block, false otherwise.
......
...@@ -314,6 +314,11 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink) ...@@ -314,6 +314,11 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
builtInFunctionEmulator.cleanup(); builtInFunctionEmulator.cleanup();
} }
const std::map<std::string, unsigned int> &OutputHLSL::getShaderStorageBlockRegisterMap() const
{
return mResourcesHLSL->getShaderStorageBlockRegisterMap();
}
const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMap() const const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMap() const
{ {
return mResourcesHLSL->getUniformBlockRegisterMap(); return mResourcesHLSL->getUniformBlockRegisterMap();
......
...@@ -52,6 +52,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -52,6 +52,7 @@ class OutputHLSL : public TIntermTraverser
void output(TIntermNode *treeRoot, TInfoSinkBase &objSink); void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const;
const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const; const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const;
const std::map<std::string, unsigned int> &getUniformRegisterMap() const; const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
......
...@@ -44,6 +44,11 @@ class ResourcesHLSL : angle::NonCopyable ...@@ -44,6 +44,11 @@ class ResourcesHLSL : angle::NonCopyable
static TString InterfaceBlockInstanceString(const ImmutableString &instanceName, static TString InterfaceBlockInstanceString(const ImmutableString &instanceName,
unsigned int arrayIndex); unsigned int arrayIndex);
const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const
{
return mShaderStorageBlockRegisterMap;
}
const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const
{ {
return mUniformBlockRegisterMap; return mUniformBlockRegisterMap;
......
...@@ -496,6 +496,28 @@ bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderV ...@@ -496,6 +496,28 @@ bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderV
return CheckVariablesInPackingLimits(maxVectors, variables); return CheckVariablesInPackingLimits(maxVectors, variables);
} }
bool GetShaderStorageBlockRegister(const ShHandle handle,
const std::string &shaderStorageBlockName,
unsigned int *indexOut)
{
#ifdef ANGLE_ENABLE_HLSL
ASSERT(indexOut);
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
ASSERT(translator);
if (!translator->hasShaderStorageBlock(shaderStorageBlockName))
{
return false;
}
*indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName);
return true;
#else
return false;
#endif // ANGLE_ENABLE_HLSL
}
bool GetUniformBlockRegister(const ShHandle handle, bool GetUniformBlockRegister(const ShHandle handle,
const std::string &uniformBlockName, const std::string &uniformBlockName,
unsigned int *indexOut) unsigned int *indexOut)
......
...@@ -139,6 +139,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ...@@ -139,6 +139,7 @@ void TranslatorHLSL::translate(TIntermBlock *root,
outputHLSL.output(root, getInfoSink().obj); outputHLSL.output(root, getInfoSink().obj);
mShaderStorageBlockRegisterMap = outputHLSL.getShaderStorageBlockRegisterMap();
mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap(); mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap();
mUniformRegisterMap = outputHLSL.getUniformRegisterMap(); mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
} }
...@@ -149,6 +150,18 @@ bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll() ...@@ -149,6 +150,18 @@ bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll()
return false; return false;
} }
bool TranslatorHLSL::hasShaderStorageBlock(const std::string &uniformBlockName) const
{
return (mShaderStorageBlockRegisterMap.count(uniformBlockName) > 0);
}
unsigned int TranslatorHLSL::getShaderStorageBlockRegister(
const std::string &shaderStorageBlockName) const
{
ASSERT(hasShaderStorageBlock(shaderStorageBlockName));
return mShaderStorageBlockRegisterMap.find(shaderStorageBlockName)->second;
}
bool TranslatorHLSL::hasUniformBlock(const std::string &uniformBlockName) const bool TranslatorHLSL::hasUniformBlock(const std::string &uniformBlockName) const
{ {
return (mUniformBlockRegisterMap.count(uniformBlockName) > 0); return (mUniformBlockRegisterMap.count(uniformBlockName) > 0);
......
...@@ -18,6 +18,9 @@ class TranslatorHLSL : public TCompiler ...@@ -18,6 +18,9 @@ class TranslatorHLSL : public TCompiler
TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
TranslatorHLSL *getAsTranslatorHLSL() override { return this; } TranslatorHLSL *getAsTranslatorHLSL() override { return this; }
bool hasShaderStorageBlock(const std::string &interfaceBlockName) const;
unsigned int getShaderStorageBlockRegister(const std::string &interfaceBlockName) const;
bool hasUniformBlock(const std::string &interfaceBlockName) const; bool hasUniformBlock(const std::string &interfaceBlockName) const;
unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const; unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const;
...@@ -32,6 +35,7 @@ class TranslatorHLSL : public TCompiler ...@@ -32,6 +35,7 @@ class TranslatorHLSL : public TCompiler
// collectVariables needs to be run always so registers can be assigned. // collectVariables needs to be run always so registers can be assigned.
bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; } bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; }
std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
std::map<std::string, unsigned int> mUniformBlockRegisterMap; std::map<std::string, unsigned int> mUniformBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap; std::map<std::string, unsigned int> mUniformRegisterMap;
}; };
......
...@@ -815,6 +815,24 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -815,6 +815,24 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
mUsedComputeReadonlyImageRange = mUsedComputeReadonlyImageRange =
gl::RangeUI(computeReadonlyImageRangeLow, computeReadonlyImageRangeHigh); gl::RangeUI(computeReadonlyImageRangeLow, computeReadonlyImageRangeHigh);
const unsigned int shaderStorageBlockCount = stream->readInt<unsigned int>();
if (stream->error())
{
infoLog << "Invalid program binary.";
return false;
}
ASSERT(mD3DShaderStorageBlocks.empty());
for (unsigned int blockIndex = 0; blockIndex < shaderStorageBlockCount; ++blockIndex)
{
D3DInterfaceBlock shaderStorageBlock;
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
stream->readInt(&shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
}
mD3DShaderStorageBlocks.push_back(shaderStorageBlock);
}
const unsigned int uniformCount = stream->readInt<unsigned int>(); const unsigned int uniformCount = stream->readInt<unsigned int>();
if (stream->error()) if (stream->error())
{ {
...@@ -852,7 +870,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -852,7 +870,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ASSERT(mD3DUniformBlocks.empty()); ASSERT(mD3DUniformBlocks.empty());
for (unsigned int blockIndex = 0; blockIndex < blockCount; ++blockIndex) for (unsigned int blockIndex = 0; blockIndex < blockCount; ++blockIndex)
{ {
D3DUniformBlock uniformBlock; D3DInterfaceBlock uniformBlock;
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]); stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
...@@ -1072,6 +1090,15 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1072,6 +1090,15 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeInt(mUsedComputeReadonlyImageRange.low()); stream->writeInt(mUsedComputeReadonlyImageRange.low());
stream->writeInt(mUsedComputeReadonlyImageRange.high()); stream->writeInt(mUsedComputeReadonlyImageRange.high());
stream->writeInt(mD3DShaderStorageBlocks.size());
for (const D3DInterfaceBlock &shaderStorageBlock : mD3DShaderStorageBlocks)
{
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
stream->writeIntOrNegOne(shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
}
}
stream->writeInt(mD3DUniforms.size()); stream->writeInt(mD3DUniforms.size());
for (const D3DUniform *uniform : mD3DUniforms) for (const D3DUniform *uniform : mD3DUniforms)
{ {
...@@ -1086,7 +1113,7 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1086,7 +1113,7 @@ 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 D3DInterfaceBlock &uniformBlock : mD3DUniformBlocks)
{ {
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
...@@ -1719,6 +1746,45 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo ...@@ -1719,6 +1746,45 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo
return GL_TRUE; return GL_TRUE;
} }
void ProgramD3D::initializeShaderStorageBlocks()
{
if (mState.getShaderStorageBlocks().empty())
{
return;
}
ASSERT(mD3DShaderStorageBlocks.empty());
// Assign registers and update sizes.
gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
}
for (const gl::InterfaceBlock &shaderStorageBlock : mState.getShaderStorageBlocks())
{
unsigned int shaderStorageBlockElement =
shaderStorageBlock.isArray ? shaderStorageBlock.arrayElement : 0;
D3DInterfaceBlock d3dShaderStorageBlock;
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
if (shaderStorageBlock.isActive(shaderType))
{
ASSERT(shadersD3D[shaderType]);
unsigned int baseRegister =
shadersD3D[shaderType]->getShaderStorageBlockRegister(shaderStorageBlock.name);
d3dShaderStorageBlock.mShaderRegisterIndexes[shaderType] =
baseRegister + shaderStorageBlockElement;
}
}
mD3DShaderStorageBlocks.push_back(d3dShaderStorageBlock);
}
}
void ProgramD3D::initializeUniformBlocks() void ProgramD3D::initializeUniformBlocks()
{ {
if (mState.getUniformBlocks().empty()) if (mState.getUniformBlocks().empty())
...@@ -1739,7 +1805,7 @@ void ProgramD3D::initializeUniformBlocks() ...@@ -1739,7 +1805,7 @@ void ProgramD3D::initializeUniformBlocks()
{ {
unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0; unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
D3DUniformBlock d3dUniformBlock; D3DInterfaceBlock d3dUniformBlock;
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
...@@ -1826,7 +1892,7 @@ void ProgramD3D::updateUniformBufferCache( ...@@ -1826,7 +1892,7 @@ void ProgramD3D::updateUniformBufferCache(
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size(); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
uniformBlockIndex++) uniformBlockIndex++)
{ {
const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex]; const D3DInterfaceBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
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
...@@ -1853,6 +1919,12 @@ void ProgramD3D::updateUniformBufferCache( ...@@ -1853,6 +1919,12 @@ void ProgramD3D::updateUniformBufferCache(
} }
} }
unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex,
gl::ShaderType shaderType) const
{
return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType];
}
const std::vector<GLint> &ProgramD3D::getShaderUniformBufferCache(gl::ShaderType shaderType) const const std::vector<GLint> &ProgramD3D::getShaderUniformBufferCache(gl::ShaderType shaderType) const
{ {
return mShaderUBOCaches[shaderType]; return mShaderUBOCaches[shaderType];
...@@ -2561,6 +2633,7 @@ void ProgramD3D::reset() ...@@ -2561,6 +2633,7 @@ void ProgramD3D::reset()
SafeDeleteContainer(mD3DUniforms); SafeDeleteContainer(mD3DUniforms);
mD3DUniformBlocks.clear(); mD3DUniformBlocks.clear();
mD3DShaderStorageBlocks.clear();
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
...@@ -2880,6 +2953,7 @@ void ProgramD3D::linkResources(const gl::ProgramLinkedResources &resources) ...@@ -2880,6 +2953,7 @@ void ProgramD3D::linkResources(const gl::ProgramLinkedResources &resources)
resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize, resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
getShaderStorageBlockMemberInfo); getShaderStorageBlockMemberInfo);
initializeShaderStorageBlocks();
} }
} // namespace rx } // namespace rx
...@@ -82,9 +82,9 @@ struct D3DUniform : private angle::NonCopyable ...@@ -82,9 +82,9 @@ struct D3DUniform : private angle::NonCopyable
std::vector<GLint> mSamplerData; std::vector<GLint> mSamplerData;
}; };
struct D3DUniformBlock struct D3DInterfaceBlock
{ {
D3DUniformBlock() { mShaderRegisterIndexes.fill(GL_INVALID_INDEX); } D3DInterfaceBlock() { mShaderRegisterIndexes.fill(GL_INVALID_INDEX); }
bool activeInShader(gl::ShaderType shaderType) const bool activeInShader(gl::ShaderType shaderType) const
{ {
...@@ -208,6 +208,9 @@ class ProgramD3D : public ProgramImpl ...@@ -208,6 +208,9 @@ class ProgramD3D : public ProgramImpl
void updateUniformBufferCache(const gl::Caps &caps, void updateUniformBufferCache(const gl::Caps &caps,
const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes); const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes);
unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
gl::ShaderType shaderType) const;
const std::vector<GLint> &getShaderUniformBufferCache(gl::ShaderType shaderType) const; const std::vector<GLint> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
void dirtyAllUniforms(); void dirtyAllUniforms();
...@@ -464,6 +467,7 @@ class ProgramD3D : public ProgramImpl ...@@ -464,6 +467,7 @@ class ProgramD3D : public ProgramImpl
void reset(); void reset();
void initializeUniformBlocks(); void initializeUniformBlocks();
void initializeShaderStorageBlocks();
void updateCachedInputLayoutFromShader(); void updateCachedInputLayoutFromShader();
void updateCachedOutputLayoutFromShader(); void updateCachedOutputLayoutFromShader();
...@@ -524,7 +528,8 @@ class ProgramD3D : public ProgramImpl ...@@ -524,7 +528,8 @@ class ProgramD3D : public ProgramImpl
std::vector<D3DVarying> mStreamOutVaryings; std::vector<D3DVarying> mStreamOutVaryings;
std::vector<D3DUniform *> mD3DUniforms; std::vector<D3DUniform *> mD3DUniforms;
std::map<std::string, int> mImageBindingMap; std::map<std::string, int> mImageBindingMap;
std::vector<D3DUniformBlock> mD3DUniformBlocks; std::vector<D3DInterfaceBlock> mD3DUniformBlocks;
std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
gl::ShaderBitSet mShaderUniformsDirty; gl::ShaderBitSet mShaderUniformsDirty;
......
...@@ -132,6 +132,12 @@ unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) co ...@@ -132,6 +132,12 @@ unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) co
return mUniformBlockRegisterMap.find(blockName)->second; return mUniformBlockRegisterMap.find(blockName)->second;
} }
unsigned int ShaderD3D::getShaderStorageBlockRegister(const std::string &blockName) const
{
ASSERT(mShaderStorageBlockRegisterMap.count(blockName) > 0);
return mShaderStorageBlockRegisterMap.find(blockName)->second;
}
ShShaderOutput ShaderD3D::getCompilerOutputType() const ShShaderOutput ShaderD3D::getCompilerOutputType() const
{ {
return mCompilerOutputType; return mCompilerOutputType;
...@@ -216,6 +222,19 @@ bool ShaderD3D::postTranslateCompile(gl::ShCompilerInstance *compiler, std::stri ...@@ -216,6 +222,19 @@ bool ShaderD3D::postTranslateCompile(gl::ShCompilerInstance *compiler, std::stri
} }
} }
for (const sh::InterfaceBlock &interfaceBlock : mData.getShaderStorageBlocks())
{
if (interfaceBlock.active)
{
unsigned int index = static_cast<unsigned int>(-1);
bool blockRegisterResult =
sh::GetShaderStorageBlockRegister(compilerHandle, interfaceBlock.name, &index);
ASSERT(blockRegisterResult);
mShaderStorageBlockRegisterMap[interfaceBlock.name] = index;
}
}
mDebugInfo += mDebugInfo +=
std::string("// ") + gl::GetShaderTypeString(mData.getShaderType()) + " SHADER BEGIN\n"; std::string("// ") + gl::GetShaderTypeString(mData.getShaderType()) + " SHADER BEGIN\n";
mDebugInfo += "\n// GLSL BEGIN\n\n" + mData.getSource() + "\n\n// GLSL END\n\n\n"; mDebugInfo += "\n// GLSL BEGIN\n\n" + mData.getSource() + "\n\n// GLSL END\n\n\n";
......
...@@ -55,6 +55,7 @@ class ShaderD3D : public ShaderImpl ...@@ -55,6 +55,7 @@ class ShaderD3D : public ShaderImpl
unsigned int getUniformRegister(const std::string &uniformName) const; unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getUniformBlockRegister(const std::string &blockName) const; unsigned int getUniformBlockRegister(const std::string &blockName) const;
unsigned int getShaderStorageBlockRegister(const std::string &blockName) const;
void appendDebugInfo(const std::string &info) const { mDebugInfo += info; } void appendDebugInfo(const std::string &info) const { mDebugInfo += info; }
void generateWorkarounds(angle::CompilerWorkaroundsD3D *workarounds) const; void generateWorkarounds(angle::CompilerWorkaroundsD3D *workarounds) const;
...@@ -93,6 +94,7 @@ class ShaderD3D : public ShaderImpl ...@@ -93,6 +94,7 @@ class ShaderD3D : public ShaderImpl
mutable std::string mDebugInfo; mutable std::string mDebugInfo;
std::map<std::string, unsigned int> mUniformRegisterMap; std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mUniformBlockRegisterMap; std::map<std::string, unsigned int> mUniformBlockRegisterMap;
std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
ShCompileOptions mAdditionalOptions; ShCompileOptions mAdditionalOptions;
}; };
} // namespace rx } // namespace rx
......
...@@ -177,6 +177,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage ...@@ -177,6 +177,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
angle::Result getSRVForFormat(const gl::Context *context, angle::Result getSRVForFormat(const gl::Context *context,
DXGI_FORMAT srvFormat, DXGI_FORMAT srvFormat,
const d3d11::ShaderResourceView **srvOut); const d3d11::ShaderResourceView **srvOut);
angle::Result getRawUAV(const gl::Context *context, d3d11::UnorderedAccessView **uavOut);
private: private:
static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
...@@ -188,6 +189,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage ...@@ -188,6 +189,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
d3d11::Buffer mBuffer; d3d11::Buffer mBuffer;
const angle::Subject *mOnStorageChanged; const angle::Subject *mOnStorageChanged;
std::map<DXGI_FORMAT, d3d11::ShaderResourceView> mBufferResourceViews; std::map<DXGI_FORMAT, d3d11::ShaderResourceView> mBufferResourceViews;
d3d11::UnorderedAccessView mBufferRawUAV;
}; };
// A emulated indexed buffer storage represents an underlying D3D11 buffer for data // A emulated indexed buffer storage represents an underlying D3D11 buffer for data
...@@ -691,6 +693,13 @@ angle::Result Buffer11::getConstantBufferRange(const gl::Context *context, ...@@ -691,6 +693,13 @@ angle::Result Buffer11::getConstantBufferRange(const gl::Context *context,
return angle::Result::Continue(); return angle::Result::Continue();
} }
angle::Result Buffer11::getRawUAV(const gl::Context *context, d3d11::UnorderedAccessView **uavOut)
{
NativeStorage *nativeStorage = nullptr;
ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_RAW_UAV, &nativeStorage));
return nativeStorage->getRawUAV(context, uavOut);
}
angle::Result Buffer11::getSRV(const gl::Context *context, angle::Result Buffer11::getSRV(const gl::Context *context,
DXGI_FORMAT srvFormat, DXGI_FORMAT srvFormat,
const d3d11::ShaderResourceView **srvOut) const d3d11::ShaderResourceView **srvOut)
...@@ -1180,6 +1189,13 @@ void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, ...@@ -1180,6 +1189,13 @@ void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
static_cast<UINT>(renderer->getNativeCaps().maxUniformBlockSize)); static_cast<UINT>(renderer->getNativeCaps().maxUniformBlockSize));
break; break;
case BUFFER_USAGE_RAW_UAV:
bufferDesc->MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
bufferDesc->BindFlags = D3D11_BIND_UNORDERED_ACCESS;
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->CPUAccessFlags = 0;
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -1238,6 +1254,30 @@ angle::Result Buffer11::NativeStorage::getSRVForFormat(const gl::Context *contex ...@@ -1238,6 +1254,30 @@ angle::Result Buffer11::NativeStorage::getSRVForFormat(const gl::Context *contex
return angle::Result::Continue(); return angle::Result::Continue();
} }
angle::Result Buffer11::NativeStorage::getRawUAV(const gl::Context *context,
d3d11::UnorderedAccessView **uavOut)
{
if (mBufferRawUAV.get())
{
*uavOut = &mBufferRawUAV;
return angle::Result::Continue();
}
D3D11_UNORDERED_ACCESS_VIEW_DESC bufferUAVDesc;
bufferUAVDesc.Buffer.FirstElement = 0;
bufferUAVDesc.Buffer.NumElements = mBufferSize / 4;
bufferUAVDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
bufferUAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; // Format must be DXGI_FORMAT_R32_TYPELESS,
// when creating Raw Unordered Access View
bufferUAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferUAVDesc,
mBuffer.get(), &mBufferRawUAV));
*uavOut = &mBufferRawUAV;
return angle::Result::Continue();
}
void Buffer11::NativeStorage::clearSRVs() void Buffer11::NativeStorage::clearSRVs()
{ {
mBufferResourceViews.clear(); mBufferResourceViews.clear();
......
...@@ -35,12 +35,12 @@ enum BufferUsage ...@@ -35,12 +35,12 @@ enum BufferUsage
BUFFER_USAGE_STAGING, BUFFER_USAGE_STAGING,
BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
BUFFER_USAGE_INDEX, BUFFER_USAGE_INDEX,
// TODO: possibly share this buffer type with shader storage buffers.
BUFFER_USAGE_INDIRECT, BUFFER_USAGE_INDIRECT,
BUFFER_USAGE_PIXEL_UNPACK, BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_PIXEL_PACK, BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM, BUFFER_USAGE_UNIFORM,
BUFFER_USAGE_EMULATED_INDEXED_VERTEX, BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
BUFFER_USAGE_RAW_UAV,
BUFFER_USAGE_COUNT, BUFFER_USAGE_COUNT,
}; };
...@@ -70,6 +70,7 @@ class Buffer11 : public BufferD3D ...@@ -70,6 +70,7 @@ class Buffer11 : public BufferD3D
angle::Result getSRV(const gl::Context *context, angle::Result getSRV(const gl::Context *context,
DXGI_FORMAT srvFormat, DXGI_FORMAT srvFormat,
const d3d11::ShaderResourceView **srvOut); const d3d11::ShaderResourceView **srvOut);
angle::Result getRawUAV(const gl::Context *context, d3d11::UnorderedAccessView **uavOut);
bool isMapped() const { return mMappedStorage != nullptr; } bool isMapped() const { return mMappedStorage != nullptr; }
angle::Result packPixels(const gl::Context *context, angle::Result packPixels(const gl::Context *context,
const gl::FramebufferAttachment &readAttachment, const gl::FramebufferAttachment &readAttachment,
......
...@@ -3093,7 +3093,7 @@ angle::Result StateManager11::generateSwizzle(const gl::Context *context, gl::Te ...@@ -3093,7 +3093,7 @@ angle::Result StateManager11::generateSwizzle(const gl::Context *context, gl::Te
angle::Result StateManager11::generateSwizzlesForShader(const gl::Context *context, angle::Result StateManager11::generateSwizzlesForShader(const gl::Context *context,
gl::ShaderType type) gl::ShaderType type)
{ {
const gl::State &glState = context->getGLState(); const gl::State &glState = context->getGLState();
const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(type); const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(type);
for (unsigned int i = samplerRange.low(); i < samplerRange.high(); i++) for (unsigned int i = samplerRange.low(); i < samplerRange.high(); i++)
...@@ -3449,6 +3449,59 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3449,6 +3449,59 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
return angle::Result::Continue(); return angle::Result::Continue();
} }
angle::Result StateManager11::syncShaderStorageBuffersForShader(const gl::Context *context,
gl::ShaderType shaderType)
{
const gl::State &glState = context->getGLState();
const gl::Program *program = glState.getProgram();
for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
blockIndex++)
{
GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
if (shaderStorageBuffer.get() == nullptr)
{
continue;
}
Buffer11 *bufferStorage = GetImplAs<Buffer11>(shaderStorageBuffer.get());
d3d11::UnorderedAccessView *uavPtr = nullptr;
// TODO(jiajia.qin@intel.com): add buffer offset support. http://anglebug.com/1951
ANGLE_TRY(bufferStorage->getRawUAV(context, &uavPtr));
// We need to make sure that resource being set to UnorderedAccessView slot |registerIndex|
// is not bound on SRV.
if (uavPtr && unsetConflictingView(uavPtr->get()))
{
mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
}
const unsigned int registerIndex = mProgramD3D->getShaderStorageBufferRegisterIndex(
static_cast<GLuint>(blockIndex), shaderType);
switch (shaderType)
{
case gl::ShaderType::Compute:
{
ID3D11UnorderedAccessView *uav = uavPtr->get();
auto deviceContext = mRenderer->getDeviceContext();
deviceContext->CSSetUnorderedAccessViews(registerIndex, 1, &uav, nullptr);
break;
}
case gl::ShaderType::Vertex:
case gl::ShaderType::Fragment:
case gl::ShaderType::Geometry:
UNIMPLEMENTED();
break;
default:
UNREACHABLE();
}
}
return angle::Result::Continue();
}
angle::Result StateManager11::syncUniformBuffers(const gl::Context *context) angle::Result StateManager11::syncUniformBuffers(const gl::Context *context)
{ {
gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers(); gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers();
...@@ -3479,7 +3532,11 @@ angle::Result StateManager11::syncAtomicCounterBuffers(const gl::Context *contex ...@@ -3479,7 +3532,11 @@ angle::Result StateManager11::syncAtomicCounterBuffers(const gl::Context *contex
angle::Result StateManager11::syncShaderStorageBuffers(const gl::Context *context) angle::Result StateManager11::syncShaderStorageBuffers(const gl::Context *context)
{ {
// TODO(jie.a.chen@intel.com): http://anglebug.com/1951 if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute))
{
ANGLE_TRY(syncShaderStorageBuffersForShader(context, gl::ShaderType::Compute));
}
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -3556,13 +3613,13 @@ void StateManager11::syncPrimitiveTopology(const gl::State &glState, ...@@ -3556,13 +3613,13 @@ void StateManager11::syncPrimitiveTopology(const gl::State &glState,
break; break;
} }
case gl::PrimitiveMode::Lines: case gl::PrimitiveMode::Lines:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
break; break;
case gl::PrimitiveMode::LineLoop: case gl::PrimitiveMode::LineLoop:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
break; break;
case gl::PrimitiveMode::LineStrip: case gl::PrimitiveMode::LineStrip:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
break; break;
case gl::PrimitiveMode::Triangles: case gl::PrimitiveMode::Triangles:
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
......
...@@ -329,6 +329,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -329,6 +329,9 @@ class StateManager11 final : angle::NonCopyable
angle::Result applyUniforms(const gl::Context *context); angle::Result applyUniforms(const gl::Context *context);
angle::Result applyUniformsForShader(const gl::Context *context, gl::ShaderType shaderType); angle::Result applyUniformsForShader(const gl::Context *context, gl::ShaderType shaderType);
angle::Result syncShaderStorageBuffersForShader(const gl::Context *context,
gl::ShaderType shaderType);
angle::Result syncUniformBuffers(const gl::Context *context); angle::Result syncUniformBuffers(const gl::Context *context);
angle::Result syncUniformBuffersForShader(const gl::Context *context, angle::Result syncUniformBuffersForShader(const gl::Context *context,
gl::ShaderType shaderType); gl::ShaderType shaderType);
......
...@@ -150,10 +150,7 @@ TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite) ...@@ -150,10 +150,7 @@ TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite)
"void main()\n" "void main()\n"
"{\n" "{\n"
" instanceName.data[0] = 3u;\n" " instanceName.data[0] = 3u;\n"
" if (instanceName.data[0] == 3u)\n" " instanceName.data[1] = 4u;\n"
" instanceName.data[1] = 4u;\n"
" else\n"
" instanceName.data[1] = 5u;\n"
"}\n"; "}\n";
ANGLE_GL_COMPUTE_PROGRAM(program, csSource); ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
...@@ -196,6 +193,10 @@ TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite) ...@@ -196,6 +193,10 @@ TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite)
// Test atomic memory functions. // Test atomic memory functions.
TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions) TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions)
{ {
// TODO(jiajia.qin@intel.com): Don't skip this test once atomic memory functions for SSBO is
// supported on d3d backend. http://anglebug.com/1951
ANGLE_SKIP_TEST_IF(IsD3D11());
const std::string &csSource = const std::string &csSource =
R"(#version 310 es R"(#version 310 es
...@@ -255,6 +256,10 @@ TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions) ...@@ -255,6 +256,10 @@ TEST_P(ShaderStorageBufferTest31, AtomicMemoryFunctions)
// bindings again. // bindings again.
TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms) TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms)
{ {
// TODO(jiajia.qin@intel.com): Don't skip this test once glGetProgramResourceiv is supported on
// d3d backend. http://anglebug.com/1920
ANGLE_SKIP_TEST_IF(IsD3D11());
const std::string &csSource1 = const std::string &csSource1 =
R"(#version 310 es R"(#version 310 es
layout(local_size_x=3, local_size_y=1, local_size_z=1) in; layout(local_size_x=3, local_size_y=1, local_size_z=1) in;
...@@ -338,6 +343,6 @@ TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms) ...@@ -338,6 +343,6 @@ TEST_P(ShaderStorageBufferTest31, MultiStorageBuffersForMultiPrograms)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31, ES31_OPENGL(), ES31_OPENGLES()); ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31, ES31_OPENGL(), ES31_OPENGLES(), ES31_D3D11());
} // namespace } // namespace
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