Commit 0af8b596 by Xinghua Cao Committed by Commit Bot

D3D11: Translate uniform blocks to StructuredBuffer when necessary

fxc exhibits slow compile performance with dynamic cbuffer indexing. So when a uniform block contains only one large array member, which is an array of structures, translate this uniform block to a StructuredBuffer instead. Bug: angleproject:3682 TEST=angle_end2end_tests.UniformBufferTest.* Change-Id: Ife80dba8aae65b761737e095895e00a570230f88 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1782046 Commit-Queue: Xinghua Cao <xinghua.cao@intel.com> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 291be9ac
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,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 220 #define ANGLE_SH_VERSION 221
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -314,6 +314,10 @@ const ShCompileOptions SH_ADD_BASE_VERTEX_TO_VERTEX_ID = UINT64_C(1) << 48; ...@@ -314,6 +314,10 @@ const ShCompileOptions SH_ADD_BASE_VERTEX_TO_VERTEX_ID = UINT64_C(1) << 48;
// This works around the dynamic lvalue indexing of swizzled vectors on various platforms. // This works around the dynamic lvalue indexing of swizzled vectors on various platforms.
const ShCompileOptions SH_REMOVE_DYNAMIC_INDEXING_OF_SWIZZLED_VECTOR = UINT64_C(1) << 49; const ShCompileOptions SH_REMOVE_DYNAMIC_INDEXING_OF_SWIZZLED_VECTOR = UINT64_C(1) << 49;
// This flag works a driver bug that fails to allocate ShaderResourceView for StructuredBuffer
// on old Windows system with AMD driver.
const ShCompileOptions SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER = UINT64_C(1) << 50;
// Defines alternate strategies for implementing array index clamping. // Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy enum ShArrayIndexClampingStrategy
{ {
...@@ -674,6 +678,9 @@ bool GetUniformBlockRegister(const ShHandle handle, ...@@ -674,6 +678,9 @@ bool GetUniformBlockRegister(const ShHandle handle,
const std::string &uniformBlockName, const std::string &uniformBlockName,
unsigned int *indexOut); unsigned int *indexOut);
bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
const std::string &uniformBlockName);
// Gives a map from uniform names to compiler-assigned registers in the default uniform block. // Gives a map from uniform names to compiler-assigned registers in the default uniform block.
// Note that the map contains also registers of samplers that have been extracted from structs. // Note that the map contains also registers of samplers that have been extracted from structs.
const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle); const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle);
......
...@@ -206,6 +206,13 @@ struct FeaturesD3D : FeatureSetBase ...@@ -206,6 +206,13 @@ struct FeaturesD3D : FeatureSetBase
"allow_clear_for_robust_resource_init", FeatureCategory::D3DWorkarounds, "allow_clear_for_robust_resource_init", FeatureCategory::D3DWorkarounds,
"Some drivers corrupt texture data when clearing for robust resource initialization.", "Some drivers corrupt texture data when clearing for robust resource initialization.",
&members, "http://crbug.com/941620"}; &members, "http://crbug.com/941620"};
// Don't translate uniform block to StructuredBuffer on old Windows system with AMD driver.
// This is targeted to work around a bug in AMD D3D driver that fails to allocate
// ShaderResourceView for StructuredBuffer.
Feature dontTranslateUniformBlockToStructuredBuffer = {
"dont_translate_uniform_block_to_structured_buffer", FeatureCategory::D3DWorkarounds,
"Fails to allocate ShaderResourceView for StructuredBuffer on some drivers", &members};
}; };
inline FeaturesD3D::FeaturesD3D() = default; inline FeaturesD3D::FeaturesD3D() = default;
......
...@@ -344,7 +344,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -344,7 +344,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
unsigned int firstUniformRegister = unsigned int firstUniformRegister =
((compileOptions & SH_SKIP_D3D_CONSTANT_REGISTER_ZERO) != 0) ? 1u : 0u; ((compileOptions & SH_SKIP_D3D_CONSTANT_REGISTER_ZERO) != 0) ? 1u : 0u;
mResourcesHLSL = new ResourcesHLSL(mStructureHLSL, outputType, uniforms, firstUniformRegister); mResourcesHLSL = new ResourcesHLSL(mStructureHLSL, outputType, compileOptions, uniforms,
firstUniformRegister);
if (mOutputType == SH_HLSL_3_0_OUTPUT) if (mOutputType == SH_HLSL_3_0_OUTPUT)
{ {
...@@ -431,6 +432,11 @@ const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMa ...@@ -431,6 +432,11 @@ const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMa
return mResourcesHLSL->getUniformBlockRegisterMap(); return mResourcesHLSL->getUniformBlockRegisterMap();
} }
const std::map<std::string, bool> &OutputHLSL::getUniformBlockUseStructuredBufferMap() const
{
return mResourcesHLSL->getUniformBlockUseStructuredBufferMap();
}
const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() const const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() const
{ {
return mResourcesHLSL->getUniformRegisterMap(); return mResourcesHLSL->getUniformRegisterMap();
......
...@@ -58,6 +58,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -58,6 +58,7 @@ class OutputHLSL : public TIntermTraverser
const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const; 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, bool> &getUniformBlockUseStructuredBufferMap() const;
const std::map<std::string, unsigned int> &getUniformRegisterMap() const; const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
unsigned int getReadonlyImage2DRegisterIndex() const; unsigned int getReadonlyImage2DRegisterIndex() const;
unsigned int getImage2DRegisterIndex() const; unsigned int getImage2DRegisterIndex() const;
......
...@@ -24,6 +24,11 @@ namespace ...@@ -24,6 +24,11 @@ namespace
{ {
constexpr const ImmutableString kAngleDecorString("angle_"); constexpr const ImmutableString kAngleDecorString("angle_");
// D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT = 128;
const unsigned int kMaxInputResourceSlotCount = 128u;
// If uniform block member's array size is larger than kMinArraySizeUseStructuredBuffer,
// then we translate uniform block to StructuredBuffer for compiling performance.
const unsigned int kMinArraySizeUseStructuredBuffer = 50u;
static const char *UniformRegisterPrefix(const TType &type) static const char *UniformRegisterPrefix(const TType &type)
{ {
...@@ -37,7 +42,9 @@ static const char *UniformRegisterPrefix(const TType &type) ...@@ -37,7 +42,9 @@ static const char *UniformRegisterPrefix(const TType &type)
} }
} }
static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage) static TString InterfaceBlockFieldTypeString(const TField &field,
TLayoutBlockStorage blockStorage,
bool usedStructuredbuffer)
{ {
const TType &fieldType = *field.type(); const TType &fieldType = *field.type();
const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking; const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
...@@ -53,9 +60,12 @@ static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockSt ...@@ -53,9 +60,12 @@ static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockSt
} }
else if (structure) else if (structure)
{ {
// If uniform block's layout is std140 and translating it to StructuredBuffer,
// should pack structure in the end, in order to fit API buffer.
bool forcePackingEnd = usedStructuredbuffer && (blockStorage == EbsStd140);
// Use HLSL row-major packing for GLSL column-major matrices // Use HLSL row-major packing for GLSL column-major matrices
return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor, return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor,
blockStorage == EbsStd140); blockStorage == EbsStd140, forcePackingEnd);
} }
else else
{ {
...@@ -98,15 +108,17 @@ void OutputUniformIndexArrayInitializer(TInfoSinkBase &out, ...@@ -98,15 +108,17 @@ void OutputUniformIndexArrayInitializer(TInfoSinkBase &out,
ResourcesHLSL::ResourcesHLSL(StructureHLSL *structureHLSL, ResourcesHLSL::ResourcesHLSL(StructureHLSL *structureHLSL,
ShShaderOutput outputType, ShShaderOutput outputType,
ShCompileOptions compileOptions,
const std::vector<ShaderVariable> &uniforms, const std::vector<ShaderVariable> &uniforms,
unsigned int firstUniformRegister) unsigned int firstUniformRegister)
: mUniformRegister(firstUniformRegister), : mUniformRegister(firstUniformRegister),
mUniformBlockRegister(0), mUniformBlockRegister(0),
mTextureRegister(0), mSRVRegister(0),
mUAVRegister(0), mUAVRegister(0),
mSamplerCount(0), mSamplerCount(0),
mStructureHLSL(structureHLSL), mStructureHLSL(structureHLSL),
mOutputType(outputType), mOutputType(outputType),
mCompileOptions(compileOptions),
mUniforms(uniforms) mUniforms(uniforms)
{} {}
...@@ -144,7 +156,7 @@ unsigned int ResourcesHLSL::assignUniformRegister(const TType &type, ...@@ -144,7 +156,7 @@ unsigned int ResourcesHLSL::assignUniformRegister(const TType &type,
if (IsSampler(type.getBasicType()) || if (IsSampler(type.getBasicType()) ||
(IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly)) (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
{ {
registerIndex = mTextureRegister; registerIndex = mSRVRegister;
} }
else if (IsImage(type.getBasicType())) else if (IsImage(type.getBasicType()))
{ {
...@@ -187,7 +199,7 @@ unsigned int ResourcesHLSL::assignUniformRegister(const TType &type, ...@@ -187,7 +199,7 @@ unsigned int ResourcesHLSL::assignUniformRegister(const TType &type,
if (IsSampler(type.getBasicType()) || if (IsSampler(type.getBasicType()) ||
(IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly)) (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
{ {
mTextureRegister += registerCount; mSRVRegister += registerCount;
} }
else if (IsImage(type.getBasicType())) else if (IsImage(type.getBasicType()))
{ {
...@@ -210,10 +222,10 @@ unsigned int ResourcesHLSL::assignSamplerInStructUniformRegister(const TType &ty ...@@ -210,10 +222,10 @@ unsigned int ResourcesHLSL::assignSamplerInStructUniformRegister(const TType &ty
{ {
// Sampler that is a field of a uniform structure. // Sampler that is a field of a uniform structure.
ASSERT(IsSampler(type.getBasicType())); ASSERT(IsSampler(type.getBasicType()));
unsigned int registerIndex = mTextureRegister; unsigned int registerIndex = mSRVRegister;
mUniformRegisterMap[std::string(name.c_str())] = registerIndex; mUniformRegisterMap[std::string(name.c_str())] = registerIndex;
unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u; unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u;
mTextureRegister += registerCount; mSRVRegister += registerCount;
if (outRegisterCount) if (outRegisterCount)
{ {
*outRegisterCount = registerCount; *outRegisterCount = registerCount;
...@@ -240,7 +252,7 @@ void ResourcesHLSL::outputHLSLSamplerUniformGroup( ...@@ -240,7 +252,7 @@ void ResourcesHLSL::outputHLSLSamplerUniformGroup(
unsigned int registerCount; unsigned int registerCount;
// The uniform might be just a regular sampler or one extracted from a struct. // The uniform might be just a regular sampler or one extracted from a struct.
unsigned int samplerArrayIndex = 0u; unsigned int samplerArrayIndex = 0u;
const ShaderVariable *uniformByName = findUniformByName(name); const ShaderVariable *uniformByName = findUniformByName(name);
if (uniformByName) if (uniformByName)
{ {
...@@ -386,7 +398,7 @@ void ResourcesHLSL::outputUniform(TInfoSinkBase &out, ...@@ -386,7 +398,7 @@ void ResourcesHLSL::outputUniform(TInfoSinkBase &out,
// nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers
// are permitted. // are permitted.
const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty) const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty)
? QualifiedStructNameString(*structure, false, false) ? QualifiedStructNameString(*structure, false, false, false)
: TypeString(type)); : TypeString(type));
const TString &registerString = const TString &registerString =
...@@ -549,9 +561,9 @@ void ResourcesHLSL::uniformsHeader(TInfoSinkBase &out, ...@@ -549,9 +561,9 @@ void ResourcesHLSL::uniformsHeader(TInfoSinkBase &out,
mSamplerCount = groupTextureRegisterIndex; mSamplerCount = groupTextureRegisterIndex;
// Reserve t type register for readonly image2D variables. // Reserve t type register for readonly image2D variables.
mReadonlyImage2DRegisterIndex = mTextureRegister; mReadonlyImage2DRegisterIndex = mSRVRegister;
groupTextureRegisterIndex += reservedReadonlyImageRegisterCount; groupTextureRegisterIndex += reservedReadonlyImageRegisterCount;
mTextureRegister += reservedReadonlyImageRegisterCount; mSRVRegister += reservedReadonlyImageRegisterCount;
for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId) for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
{ {
...@@ -642,6 +654,21 @@ TString ResourcesHLSL::uniformBlocksHeader( ...@@ -642,6 +654,21 @@ TString ResourcesHLSL::uniformBlocksHeader(
interfaceBlocks += uniformBlockStructString(interfaceBlock); interfaceBlocks += uniformBlockStructString(interfaceBlock);
} }
// In order to avoid compile performance issue, translate uniform block to structured
// buffer. anglebug.com/3682.
// TODO(anglebug.com/4205): Support uniform block with an instance name.
if (instanceVariable == nullptr &&
shouldTranslateUniformBlockToStructuredBuffer(interfaceBlock))
{
unsigned int structuredBufferRegister = mSRVRegister;
interfaceBlocks +=
uniformBlockWithOneLargeArrayMemberString(interfaceBlock, structuredBufferRegister);
mUniformBlockRegisterMap[interfaceBlock.name().data()] = structuredBufferRegister;
mUniformBlockUseStructuredBufferMap[interfaceBlock.name().data()] = true;
mSRVRegister += 1u;
continue;
}
unsigned int activeRegister = mUniformBlockRegister; unsigned int activeRegister = mUniformBlockRegister;
mUniformBlockRegisterMap[interfaceBlock.name().data()] = activeRegister; mUniformBlockRegisterMap[interfaceBlock.name().data()] = activeRegister;
...@@ -729,6 +756,22 @@ TString ResourcesHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock, ...@@ -729,6 +756,22 @@ TString ResourcesHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
return hlsl; return hlsl;
} }
TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString(
const TInterfaceBlock &interfaceBlock,
unsigned int registerIndex)
{
TString hlsl, typeString;
const TField &field = *interfaceBlock.fields()[0];
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
typeString = InterfaceBlockFieldTypeString(field, blockStorage, true);
hlsl += "StructuredBuffer <" + typeString + "> " + Decorate(field.name()) + " : register(t" +
str(registerIndex) + ");\n";
return hlsl;
}
TString ResourcesHLSL::shaderStorageBlockString(const TInterfaceBlock &interfaceBlock, TString ResourcesHLSL::shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
const TVariable *instanceVariable, const TVariable *instanceVariable,
unsigned int registerIndex, unsigned int registerIndex,
...@@ -780,7 +823,7 @@ TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfac ...@@ -780,7 +823,7 @@ TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfac
hlsl += padHelper.prePaddingString(fieldType); hlsl += padHelper.prePaddingString(fieldType);
} }
hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage) + " " + hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage, false) + " " +
Decorate(field.name()) + ArrayString(fieldType).data() + ";\n"; Decorate(field.name()) + ArrayString(fieldType).data() + ";\n";
// must pad out after matrices and arrays, where HLSL usually allows itself room to pack // must pad out after matrices and arrays, where HLSL usually allows itself room to pack
...@@ -789,7 +832,7 @@ TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfac ...@@ -789,7 +832,7 @@ TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfac
{ {
const bool useHLSLRowMajorPacking = const bool useHLSLRowMajorPacking =
(fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor); (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking); hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking, false);
} }
} }
...@@ -805,4 +848,17 @@ TString ResourcesHLSL::uniformBlockStructString(const TInterfaceBlock &interface ...@@ -805,4 +848,17 @@ TString ResourcesHLSL::uniformBlockStructString(const TInterfaceBlock &interface
"{\n" + "{\n" +
uniformBlockMembersString(interfaceBlock, blockStorage) + "};\n\n"; uniformBlockMembersString(interfaceBlock, blockStorage) + "};\n\n";
} }
bool ResourcesHLSL::shouldTranslateUniformBlockToStructuredBuffer(
const TInterfaceBlock &interfaceBlock)
{
const TType &fieldType = *interfaceBlock.fields()[0]->type();
// TODO(anglebug.com/4206): Support uniform block contains only a matrix array member,
// and fix row-major/column-major conversion issue.
return (mCompileOptions & SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER) == 0 &&
mSRVRegister < kMaxInputResourceSlotCount && interfaceBlock.fields().size() == 1u &&
fieldType.getStruct() != nullptr && fieldType.getNumArraySizes() == 1u &&
fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer;
}
} // namespace sh } // namespace sh
...@@ -24,6 +24,7 @@ class ResourcesHLSL : angle::NonCopyable ...@@ -24,6 +24,7 @@ class ResourcesHLSL : angle::NonCopyable
public: public:
ResourcesHLSL(StructureHLSL *structureHLSL, ResourcesHLSL(StructureHLSL *structureHLSL,
ShShaderOutput outputType, ShShaderOutput outputType,
ShCompileOptions compileOptions,
const std::vector<ShaderVariable> &uniforms, const std::vector<ShaderVariable> &uniforms,
unsigned int firstUniformRegister); unsigned int firstUniformRegister);
...@@ -54,6 +55,12 @@ class ResourcesHLSL : angle::NonCopyable ...@@ -54,6 +55,12 @@ class ResourcesHLSL : angle::NonCopyable
{ {
return mUniformBlockRegisterMap; return mUniformBlockRegisterMap;
} }
const std::map<std::string, bool> &getUniformBlockUseStructuredBufferMap() const
{
return mUniformBlockUseStructuredBufferMap;
}
const std::map<std::string, unsigned int> &getUniformRegisterMap() const const std::map<std::string, unsigned int> &getUniformRegisterMap() const
{ {
return mUniformRegisterMap; return mUniformRegisterMap;
...@@ -67,6 +74,8 @@ class ResourcesHLSL : angle::NonCopyable ...@@ -67,6 +74,8 @@ class ResourcesHLSL : angle::NonCopyable
const TVariable *instanceVariable, const TVariable *instanceVariable,
unsigned int registerIndex, unsigned int registerIndex,
unsigned int arrayIndex); unsigned int arrayIndex);
TString uniformBlockWithOneLargeArrayMemberString(const TInterfaceBlock &interfaceBlock,
unsigned int registerIndex);
TString shaderStorageBlockString(const TInterfaceBlock &interfaceBlock, TString shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
const TVariable *instanceVariable, const TVariable *instanceVariable,
...@@ -116,21 +125,24 @@ class ResourcesHLSL : angle::NonCopyable ...@@ -116,21 +125,24 @@ class ResourcesHLSL : angle::NonCopyable
const HLSLRWTextureGroup textureGroup, const HLSLRWTextureGroup textureGroup,
const TVector<const TVariable *> &group, const TVector<const TVariable *> &group,
unsigned int *groupTextureRegisterIndex); unsigned int *groupTextureRegisterIndex);
bool shouldTranslateUniformBlockToStructuredBuffer(const TInterfaceBlock &interfaceBlock);
unsigned int mUniformRegister; unsigned int mUniformRegister;
unsigned int mUniformBlockRegister; unsigned int mUniformBlockRegister;
unsigned int mTextureRegister; unsigned int mSRVRegister;
unsigned int mUAVRegister; unsigned int mUAVRegister;
unsigned int mSamplerCount; unsigned int mSamplerCount;
unsigned int mReadonlyImageCount; unsigned int mReadonlyImageCount;
unsigned int mImageCount; unsigned int mImageCount;
StructureHLSL *mStructureHLSL; StructureHLSL *mStructureHLSL;
ShShaderOutput mOutputType; ShShaderOutput mOutputType;
ShCompileOptions mCompileOptions;
const std::vector<ShaderVariable> &mUniforms; const std::vector<ShaderVariable> &mUniforms;
std::map<std::string, unsigned int> mUniformBlockRegisterMap; std::map<std::string, unsigned int> mUniformBlockRegisterMap;
std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap; std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap; std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
unsigned int mReadonlyImage2DRegisterIndex; unsigned int mReadonlyImage2DRegisterIndex;
unsigned int mImage2DRegisterIndex; unsigned int mImage2DRegisterIndex;
}; };
......
...@@ -546,6 +546,19 @@ bool GetUniformBlockRegister(const ShHandle handle, ...@@ -546,6 +546,19 @@ bool GetUniformBlockRegister(const ShHandle handle,
#endif // ANGLE_ENABLE_HLSL #endif // ANGLE_ENABLE_HLSL
} }
bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
const std::string &uniformBlockName)
{
#ifdef ANGLE_ENABLE_HLSL
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
ASSERT(translator);
return translator->shouldUniformBlockUseStructuredBuffer(uniformBlockName);
#else
return false;
#endif // ANGLE_ENABLE_HLSL
}
const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle) const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
{ {
#ifdef ANGLE_ENABLE_HLSL #ifdef ANGLE_ENABLE_HLSL
......
...@@ -23,12 +23,13 @@ namespace ...@@ -23,12 +23,13 @@ namespace
TString Define(const TStructure &structure, TString Define(const TStructure &structure,
bool useHLSLRowMajorPacking, bool useHLSLRowMajorPacking,
bool useStd140Packing, bool useStd140Packing,
bool forcePackingEnd,
Std140PaddingHelper *padHelper) Std140PaddingHelper *padHelper)
{ {
const TFieldList &fields = structure.fields(); const TFieldList &fields = structure.fields();
const bool isNameless = (structure.symbolType() == SymbolType::Empty); const bool isNameless = (structure.symbolType() == SymbolType::Empty);
const TString &structName = const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking,
QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing); useStd140Packing, forcePackingEnd);
const TString declareString = (isNameless ? "struct" : "struct " + structName); const TString declareString = (isNameless ? "struct" : "struct " + structName);
TString string; TString string;
...@@ -36,15 +37,17 @@ TString Define(const TStructure &structure, ...@@ -36,15 +37,17 @@ TString Define(const TStructure &structure,
"\n" "\n"
"{\n"; "{\n";
size_t memberSize = fields.size();
for (const TField *field : fields) for (const TField *field : fields)
{ {
memberSize--;
const TType &fieldType = *field->type(); const TType &fieldType = *field->type();
if (!IsSampler(fieldType.getBasicType())) if (!IsSampler(fieldType.getBasicType()))
{ {
const TStructure *fieldStruct = fieldType.getStruct(); const TStructure *fieldStruct = fieldType.getStruct();
const TString &fieldTypeString = const TString &fieldTypeString =
fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking, fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
useStd140Packing) useStd140Packing, false)
: TypeString(fieldType); : TypeString(fieldType);
if (padHelper) if (padHelper)
...@@ -57,7 +60,8 @@ TString Define(const TStructure &structure, ...@@ -57,7 +60,8 @@ TString Define(const TStructure &structure,
if (padHelper) if (padHelper)
{ {
string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking); string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking,
memberSize == 0 && forcePackingEnd);
} }
} }
} }
...@@ -165,9 +169,11 @@ TString Std140PaddingHelper::prePaddingString(const TType &type) ...@@ -165,9 +169,11 @@ TString Std140PaddingHelper::prePaddingString(const TType &type)
return padding; return padding;
} }
TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRowMajorPacking) TString Std140PaddingHelper::postPaddingString(const TType &type,
bool useHLSLRowMajorPacking,
bool forcePadding)
{ {
if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct) if (!forcePadding && !type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
{ {
return ""; return "";
} }
...@@ -191,7 +197,7 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo ...@@ -191,7 +197,7 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo
else if (structure) else if (structure)
{ {
const TString &structName = const TString &structName =
QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true); QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true, false);
numComponents = mStructElementIndexes->find(structName)->second; numComponents = mStructElementIndexes->find(structName)->second;
if (numComponents == 0) if (numComponents == 0)
...@@ -222,22 +228,24 @@ Std140PaddingHelper StructureHLSL::getPaddingHelper() ...@@ -222,22 +228,24 @@ Std140PaddingHelper StructureHLSL::getPaddingHelper()
TString StructureHLSL::defineQualified(const TStructure &structure, TString StructureHLSL::defineQualified(const TStructure &structure,
bool useHLSLRowMajorPacking, bool useHLSLRowMajorPacking,
bool useStd140Packing) bool useStd140Packing,
bool forcePackingEnd)
{ {
if (useStd140Packing) if (useStd140Packing)
{ {
Std140PaddingHelper padHelper = getPaddingHelper(); Std140PaddingHelper padHelper = getPaddingHelper();
return Define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper); return Define(structure, useHLSLRowMajorPacking, useStd140Packing, forcePackingEnd,
&padHelper);
} }
else else
{ {
return Define(structure, useHLSLRowMajorPacking, useStd140Packing, nullptr); return Define(structure, useHLSLRowMajorPacking, useStd140Packing, false, nullptr);
} }
} }
TString StructureHLSL::defineNameless(const TStructure &structure) TString StructureHLSL::defineNameless(const TStructure &structure)
{ {
return Define(structure, false, false, nullptr); return Define(structure, false, false, false, nullptr);
} }
StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure, StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure,
...@@ -260,24 +268,33 @@ StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStr ...@@ -260,24 +268,33 @@ StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStr
storeStd140ElementIndex(structure, false); storeStd140ElementIndex(structure, false);
storeStd140ElementIndex(structure, true); storeStd140ElementIndex(structure, true);
const TString &structString = defineQualified(structure, false, false); const TString &structString = defineQualified(structure, false, false, false);
ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
mStructDeclarations.end()); mStructDeclarations.end());
// Add row-major packed struct for interface blocks // Add row-major packed struct for interface blocks
TString rowMajorString = "#pragma pack_matrix(row_major)\n" + TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
defineQualified(structure, true, false) + defineQualified(structure, true, false, false) +
"#pragma pack_matrix(column_major)\n"; "#pragma pack_matrix(column_major)\n";
TString std140String = defineQualified(structure, false, true); TString std140String = defineQualified(structure, false, true, false);
TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
defineQualified(structure, true, true) + defineQualified(structure, true, true, false) +
"#pragma pack_matrix(column_major)\n"; "#pragma pack_matrix(column_major)\n";
// Must use packed structure for StructuredBuffer element type, if qualifier of structure is
// std140.
TString std140PackingEndString = defineQualified(structure, false, true, true);
TString std140RowMajorPackEndingString = "#pragma pack_matrix(row_major)\n" +
defineQualified(structure, true, true, true) +
"#pragma pack_matrix(column_major)\n";
mStructDeclarations.push_back(structString); mStructDeclarations.push_back(structString);
mStructDeclarations.push_back(rowMajorString); mStructDeclarations.push_back(rowMajorString);
mStructDeclarations.push_back(std140String); mStructDeclarations.push_back(std140String);
mStructDeclarations.push_back(std140RowMajorString); mStructDeclarations.push_back(std140RowMajorString);
mStructDeclarations.push_back(std140PackingEndString);
mStructDeclarations.push_back(std140RowMajorPackEndingString);
return addedStruct; return addedStruct;
} }
...@@ -584,7 +601,8 @@ void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, ...@@ -584,7 +601,8 @@ void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
// Add remaining element index to the global map, for use with nested structs in standard // Add remaining element index to the global map, for use with nested structs in standard
// layouts // layouts
const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true); const TString &structName =
QualifiedStructNameString(structure, useHLSLRowMajorPacking, true, false);
mStd140StructElementIndexes[structName] = padHelper.elementIndex(); mStd140StructElementIndexes[structName] = padHelper.elementIndex();
} }
......
...@@ -34,7 +34,7 @@ class Std140PaddingHelper ...@@ -34,7 +34,7 @@ class Std140PaddingHelper
int elementIndex() const { return mElementIndex; } int elementIndex() const { return mElementIndex; }
int prePadding(const TType &type); int prePadding(const TType &type);
TString prePaddingString(const TType &type); TString prePaddingString(const TType &type);
TString postPaddingString(const TType &type, bool useHLSLRowMajorPacking); TString postPaddingString(const TType &type, bool useHLSLRowMajorPacking, bool forcePadding);
private: private:
TString next(); TString next();
...@@ -90,7 +90,8 @@ class StructureHLSL : angle::NonCopyable ...@@ -90,7 +90,8 @@ class StructureHLSL : angle::NonCopyable
void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking); void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking);
TString defineQualified(const TStructure &structure, TString defineQualified(const TStructure &structure,
bool useHLSLRowMajorPacking, bool useHLSLRowMajorPacking,
bool useStd140Packing); bool useStd140Packing,
bool forcePackingEnd);
DefinedStructs::iterator defineVariants(const TStructure &structure, const TString &name); DefinedStructs::iterator defineVariants(const TStructure &structure, const TString &name);
}; };
} // namespace sh } // namespace sh
......
...@@ -203,12 +203,13 @@ bool TranslatorHLSL::translate(TIntermBlock *root, ...@@ -203,12 +203,13 @@ bool TranslatorHLSL::translate(TIntermBlock *root,
outputHLSL.output(root, getInfoSink().obj); outputHLSL.output(root, getInfoSink().obj);
mShaderStorageBlockRegisterMap = outputHLSL.getShaderStorageBlockRegisterMap(); mShaderStorageBlockRegisterMap = outputHLSL.getShaderStorageBlockRegisterMap();
mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap(); mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap();
mUniformRegisterMap = outputHLSL.getUniformRegisterMap(); mUniformBlockUseStructuredBufferMap = outputHLSL.getUniformBlockUseStructuredBufferMap();
mReadonlyImage2DRegisterIndex = outputHLSL.getReadonlyImage2DRegisterIndex(); mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
mImage2DRegisterIndex = outputHLSL.getImage2DRegisterIndex(); mReadonlyImage2DRegisterIndex = outputHLSL.getReadonlyImage2DRegisterIndex();
mUsedImage2DFunctionNames = outputHLSL.getUsedImage2DFunctionNames(); mImage2DRegisterIndex = outputHLSL.getImage2DRegisterIndex();
mUsedImage2DFunctionNames = outputHLSL.getUsedImage2DFunctionNames();
return true; return true;
} }
...@@ -262,4 +263,12 @@ const std::set<std::string> *TranslatorHLSL::getUsedImage2DFunctionNames() const ...@@ -262,4 +263,12 @@ const std::set<std::string> *TranslatorHLSL::getUsedImage2DFunctionNames() const
return &mUsedImage2DFunctionNames; return &mUsedImage2DFunctionNames;
} }
bool TranslatorHLSL::shouldUniformBlockUseStructuredBuffer(
const std::string &uniformBlockName) const
{
auto uniformBlockIter = mUniformBlockUseStructuredBufferMap.find(uniformBlockName);
return uniformBlockIter != mUniformBlockUseStructuredBufferMap.end() &&
uniformBlockIter->second;
}
} // namespace sh } // namespace sh
...@@ -23,6 +23,7 @@ class TranslatorHLSL : public TCompiler ...@@ -23,6 +23,7 @@ class TranslatorHLSL : public TCompiler
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;
bool shouldUniformBlockUseStructuredBuffer(const std::string &uniformBlockName) const;
const std::map<std::string, unsigned int> *getUniformRegisterMap() const; const std::map<std::string, unsigned int> *getUniformRegisterMap() const;
unsigned int getReadonlyImage2DRegisterIndex() const; unsigned int getReadonlyImage2DRegisterIndex() const;
...@@ -40,6 +41,7 @@ class TranslatorHLSL : public TCompiler ...@@ -40,6 +41,7 @@ class TranslatorHLSL : public TCompiler
std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap; 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, bool> mUniformBlockUseStructuredBufferMap;
std::map<std::string, unsigned int> mUniformRegisterMap; std::map<std::string, unsigned int> mUniformRegisterMap;
unsigned int mReadonlyImage2DRegisterIndex; unsigned int mReadonlyImage2DRegisterIndex;
unsigned int mImage2DRegisterIndex; unsigned int mImage2DRegisterIndex;
......
...@@ -1008,7 +1008,8 @@ TString StructNameString(const TStructure &structure) ...@@ -1008,7 +1008,8 @@ TString StructNameString(const TStructure &structure)
TString QualifiedStructNameString(const TStructure &structure, TString QualifiedStructNameString(const TStructure &structure,
bool useHLSLRowMajorPacking, bool useHLSLRowMajorPacking,
bool useStd140Packing) bool useStd140Packing,
bool forcePackingEnd)
{ {
if (structure.symbolType() == SymbolType::Empty) if (structure.symbolType() == SymbolType::Empty)
{ {
...@@ -1030,6 +1031,11 @@ TString QualifiedStructNameString(const TStructure &structure, ...@@ -1030,6 +1031,11 @@ TString QualifiedStructNameString(const TStructure &structure,
prefix += "rm_"; prefix += "rm_";
} }
if (forcePackingEnd)
{
prefix += "pe_";
}
return prefix + StructNameString(structure); return prefix + StructNameString(structure);
} }
......
...@@ -123,7 +123,8 @@ TString TypeString(const TType &type); ...@@ -123,7 +123,8 @@ TString TypeString(const TType &type);
TString StructNameString(const TStructure &structure); TString StructNameString(const TStructure &structure);
TString QualifiedStructNameString(const TStructure &structure, TString QualifiedStructNameString(const TStructure &structure,
bool useHLSLRowMajorPacking, bool useHLSLRowMajorPacking,
bool useStd140Packing); bool useStd140Packing,
bool forcePackingEnd);
const char *InterpolationString(TQualifier qualifier); const char *InterpolationString(TQualifier qualifier);
const char *QualifierString(TQualifier qualifier); const char *QualifierString(TQualifier qualifier);
// Parameters may need to be included in function names to disambiguate between overloaded // Parameters may need to be included in function names to disambiguate between overloaded
......
...@@ -1138,6 +1138,8 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSizeFunc &getBlock ...@@ -1138,6 +1138,8 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSizeFunc &getBlock
blockIndexes.push_back(static_cast<unsigned int>(blockMemberIndex)); blockIndexes.push_back(static_cast<unsigned int>(blockMemberIndex));
} }
unsigned int firstFieldArraySize = interfaceBlock.fields[0].getArraySizeProduct();
for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount(); for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount();
++arrayElement) ++arrayElement)
{ {
...@@ -1161,7 +1163,8 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSizeFunc &getBlock ...@@ -1161,7 +1163,8 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSizeFunc &getBlock
int blockBinding = int blockBinding =
(interfaceBlock.binding == -1 ? 0 : interfaceBlock.binding + arrayElement); (interfaceBlock.binding == -1 ? 0 : interfaceBlock.binding + arrayElement);
InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName,
interfaceBlock.isArray(), arrayElement, blockBinding); interfaceBlock.isArray(), arrayElement, firstFieldArraySize,
blockBinding);
block.memberIndexes = blockIndexes; block.memberIndexes = blockIndexes;
block.setActive(shaderType, interfaceBlock.active); block.setActive(shaderType, interfaceBlock.active);
......
...@@ -87,11 +87,11 @@ LinkedUniform::LinkedUniform(const LinkedUniform &uniform) ...@@ -87,11 +87,11 @@ LinkedUniform::LinkedUniform(const LinkedUniform &uniform)
LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform) LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
{ {
sh::ShaderVariable::operator=(uniform); sh::ShaderVariable::operator=(uniform);
ActiveVariable::operator=(uniform); ActiveVariable::operator =(uniform);
typeInfo = uniform.typeInfo; typeInfo = uniform.typeInfo;
bufferIndex = uniform.bufferIndex; bufferIndex = uniform.bufferIndex;
blockInfo = uniform.blockInfo; blockInfo = uniform.blockInfo;
outerArraySizes = uniform.outerArraySizes; outerArraySizes = uniform.outerArraySizes;
return *this; return *this;
} }
...@@ -134,8 +134,13 @@ InterfaceBlock::InterfaceBlock(const std::string &nameIn, ...@@ -134,8 +134,13 @@ InterfaceBlock::InterfaceBlock(const std::string &nameIn,
const std::string &mappedNameIn, const std::string &mappedNameIn,
bool isArrayIn, bool isArrayIn,
unsigned int arrayElementIn, unsigned int arrayElementIn,
unsigned int firstFieldArraySizeIn,
int bindingIn) int bindingIn)
: name(nameIn), mappedName(mappedNameIn), isArray(isArrayIn), arrayElement(arrayElementIn) : name(nameIn),
mappedName(mappedNameIn),
isArray(isArrayIn),
arrayElement(arrayElementIn),
firstFieldArraySize(firstFieldArraySizeIn)
{ {
binding = bindingIn; binding = bindingIn;
} }
......
...@@ -119,6 +119,7 @@ struct InterfaceBlock : public ShaderVariableBuffer ...@@ -119,6 +119,7 @@ struct InterfaceBlock : public ShaderVariableBuffer
const std::string &mappedNameIn, const std::string &mappedNameIn,
bool isArrayIn, bool isArrayIn,
unsigned int arrayElementIn, unsigned int arrayElementIn,
unsigned int firstFieldArraySizeIn,
int bindingIn); int bindingIn);
std::string nameWithArrayIndex() const; std::string nameWithArrayIndex() const;
...@@ -128,6 +129,7 @@ struct InterfaceBlock : public ShaderVariableBuffer ...@@ -128,6 +129,7 @@ struct InterfaceBlock : public ShaderVariableBuffer
std::string mappedName; std::string mappedName;
bool isArray; bool isArray;
unsigned int arrayElement; unsigned int arrayElement;
unsigned int firstFieldArraySize;
}; };
} // namespace gl } // namespace gl
......
...@@ -372,6 +372,15 @@ D3DInterfaceBlock::D3DInterfaceBlock() ...@@ -372,6 +372,15 @@ D3DInterfaceBlock::D3DInterfaceBlock()
D3DInterfaceBlock::D3DInterfaceBlock(const D3DInterfaceBlock &other) = default; D3DInterfaceBlock::D3DInterfaceBlock(const D3DInterfaceBlock &other) = default;
D3DUniformBlock::D3DUniformBlock()
{
mUseStructuredBuffers.fill(false);
mByteWidths.fill(0u);
mStructureByteStrides.fill(0u);
}
D3DUniformBlock::D3DUniformBlock(const D3DUniformBlock &other) = default;
// D3DVarying Implementation // D3DVarying Implementation
D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {} D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {}
...@@ -1081,10 +1090,13 @@ std::unique_ptr<rx::LinkEvent> ProgramD3D::load(const gl::Context *context, ...@@ -1081,10 +1090,13 @@ std::unique_ptr<rx::LinkEvent> 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)
{ {
D3DInterfaceBlock uniformBlock; D3DUniformBlock uniformBlock;
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]); stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
stream->readBool(&uniformBlock.mUseStructuredBuffers[shaderType]);
stream->readInt(&uniformBlock.mByteWidths[shaderType]);
stream->readInt(&uniformBlock.mStructureByteStrides[shaderType]);
} }
mD3DUniformBlocks.push_back(uniformBlock); mD3DUniformBlocks.push_back(uniformBlock);
} }
...@@ -1365,11 +1377,14 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1365,11 +1377,14 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
} }
stream->writeInt(mD3DUniformBlocks.size()); stream->writeInt(mD3DUniformBlocks.size());
for (const D3DInterfaceBlock &uniformBlock : mD3DUniformBlocks) for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
{ {
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]); stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]);
stream->writeInt(uniformBlock.mUseStructuredBuffers[shaderType]);
stream->writeInt(uniformBlock.mByteWidths[shaderType]);
stream->writeInt(uniformBlock.mStructureByteStrides[shaderType]);
} }
} }
...@@ -2143,7 +2158,7 @@ void ProgramD3D::initializeUniformBlocks() ...@@ -2143,7 +2158,7 @@ void ProgramD3D::initializeUniformBlocks()
{ {
unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0; unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
D3DInterfaceBlock d3dUniformBlock; D3DUniformBlock d3dUniformBlock;
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
...@@ -2154,6 +2169,18 @@ void ProgramD3D::initializeUniformBlocks() ...@@ -2154,6 +2169,18 @@ void ProgramD3D::initializeUniformBlocks()
shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name); shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name);
d3dUniformBlock.mShaderRegisterIndexes[shaderType] = d3dUniformBlock.mShaderRegisterIndexes[shaderType] =
baseRegister + uniformBlockElement; baseRegister + uniformBlockElement;
bool useStructuredBuffer =
shadersD3D[shaderType]->shouldUniformBlockUseStructuredBuffer(
uniformBlock.name);
if (useStructuredBuffer)
{
d3dUniformBlock.mUseStructuredBuffers[shaderType] = true;
d3dUniformBlock.mByteWidths[shaderType] = uniformBlock.dataSize;
d3dUniformBlock.mStructureByteStrides[shaderType] =
uniformBlock.firstFieldArraySize == 0u
? uniformBlock.dataSize
: uniformBlock.dataSize / uniformBlock.firstFieldArraySize;
}
} }
} }
...@@ -2213,9 +2240,7 @@ void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShade ...@@ -2213,9 +2240,7 @@ void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShade
} }
} }
void ProgramD3D::updateUniformBufferCache( void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps)
const gl::Caps &caps,
const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes)
{ {
if (mState.getUniformBlocks().empty()) if (mState.getUniformBlocks().empty())
{ {
...@@ -2225,13 +2250,14 @@ void ProgramD3D::updateUniformBufferCache( ...@@ -2225,13 +2250,14 @@ void ProgramD3D::updateUniformBufferCache(
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
mShaderUBOCaches[shaderType].clear(); mShaderUBOCaches[shaderType].clear();
mShaderUBOCachesUseSB[shaderType].clear();
} }
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size(); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
uniformBlockIndex++) uniformBlockIndex++)
{ {
const D3DInterfaceBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex]; const D3DUniformBlock &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
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
...@@ -2241,21 +2267,36 @@ void ProgramD3D::updateUniformBufferCache( ...@@ -2241,21 +2267,36 @@ void ProgramD3D::updateUniformBufferCache(
continue; continue;
} }
unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType] - bool useStructuredBuffer = uniformBlock.mUseStructuredBuffers[shaderType];
reservedShaderRegisterIndexes[shaderType]; unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType];
ASSERT(registerIndex < if (useStructuredBuffer)
static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
std::vector<int> &shaderUBOcache = mShaderUBOCaches[shaderType];
if (shaderUBOcache.size() <= registerIndex)
{ {
shaderUBOcache.resize(registerIndex + 1, -1); D3DUBOCacheUseSB cacheUseSB;
cacheUseSB.registerIndex = registerIndex;
cacheUseSB.binding = blockBinding;
cacheUseSB.byteWidth = uniformBlock.mByteWidths[shaderType];
cacheUseSB.structureByteStride = uniformBlock.mStructureByteStrides[shaderType];
mShaderUBOCachesUseSB[shaderType].push_back(cacheUseSB);
}
else
{
ASSERT(registerIndex <
static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
D3DUBOCache cache;
cache.registerIndex = registerIndex;
cache.binding = blockBinding;
mShaderUBOCaches[shaderType].push_back(cache);
} }
ASSERT(shaderUBOcache[registerIndex] == -1);
shaderUBOcache[registerIndex] = blockBinding;
} }
} }
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
GLuint uniformBlockCount = static_cast<GLuint>(mShaderUBOCaches[shaderType].size() +
mShaderUBOCachesUseSB[shaderType].size());
ASSERT(uniformBlockCount <=
static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
}
} }
unsigned int ProgramD3D::getAtomicCounterBufferRegisterIndex(GLuint binding, unsigned int ProgramD3D::getAtomicCounterBufferRegisterIndex(GLuint binding,
...@@ -2276,11 +2317,18 @@ unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex, ...@@ -2276,11 +2317,18 @@ unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex,
return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType]; return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType];
} }
const std::vector<GLint> &ProgramD3D::getShaderUniformBufferCache(gl::ShaderType shaderType) const const std::vector<D3DUBOCache> &ProgramD3D::getShaderUniformBufferCache(
gl::ShaderType shaderType) const
{ {
return mShaderUBOCaches[shaderType]; return mShaderUBOCaches[shaderType];
} }
const std::vector<D3DUBOCacheUseSB> &ProgramD3D::getShaderUniformBufferCacheUseSB(
gl::ShaderType shaderType) const
{
return mShaderUBOCachesUseSB[shaderType];
}
void ProgramD3D::dirtyAllUniforms() void ProgramD3D::dirtyAllUniforms()
{ {
mShaderUniformsDirty = mState.getLinkedShaderStages(); mShaderUniformsDirty = mState.getLinkedShaderStages();
......
...@@ -96,6 +96,28 @@ struct D3DInterfaceBlock ...@@ -96,6 +96,28 @@ struct D3DInterfaceBlock
gl::ShaderMap<unsigned int> mShaderRegisterIndexes; gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
}; };
struct D3DUniformBlock : D3DInterfaceBlock
{
D3DUniformBlock();
D3DUniformBlock(const D3DUniformBlock &other);
gl::ShaderMap<bool> mUseStructuredBuffers;
gl::ShaderMap<unsigned int> mByteWidths;
gl::ShaderMap<unsigned int> mStructureByteStrides;
};
struct D3DUBOCache
{
unsigned int registerIndex;
int binding;
};
struct D3DUBOCacheUseSB : D3DUBOCache
{
unsigned int byteWidth;
unsigned int structureByteStride;
};
struct D3DVarying final struct D3DVarying final
{ {
D3DVarying(); D3DVarying();
...@@ -219,15 +241,16 @@ class ProgramD3D : public ProgramImpl ...@@ -219,15 +241,16 @@ class ProgramD3D : public ProgramImpl
GLint components, GLint components,
const GLfloat *coeffs) override; const GLfloat *coeffs) override;
void updateUniformBufferCache(const gl::Caps &caps, void updateUniformBufferCache(const gl::Caps &caps);
const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes);
unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding, unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding,
gl::ShaderType shaderType) const; gl::ShaderType shaderType) const;
unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex, unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
gl::ShaderType shaderType) const; gl::ShaderType shaderType) const;
const std::vector<GLint> &getShaderUniformBufferCache(gl::ShaderType shaderType) const; const std::vector<D3DUBOCache> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
const std::vector<D3DUBOCacheUseSB> &getShaderUniformBufferCacheUseSB(
gl::ShaderType shaderType) const;
void dirtyAllUniforms(); void dirtyAllUniforms();
...@@ -552,7 +575,8 @@ class ProgramD3D : public ProgramImpl ...@@ -552,7 +575,8 @@ class ProgramD3D : public ProgramImpl
unsigned int mSerial; unsigned int mSerial;
gl::ShaderMap<std::vector<int>> mShaderUBOCaches; gl::ShaderMap<std::vector<D3DUBOCache>> mShaderUBOCaches;
gl::ShaderMap<std::vector<D3DUBOCacheUseSB>> mShaderUBOCachesUseSB;
VertexExecutable::Signature mCachedVertexSignature; VertexExecutable::Signature mCachedVertexSignature;
gl::InputLayout mCachedInputLayout; gl::InputLayout mCachedInputLayout;
Optional<size_t> mCachedVertexExecutableIndex; Optional<size_t> mCachedVertexExecutableIndex;
...@@ -561,7 +585,7 @@ class ProgramD3D : public ProgramImpl ...@@ -561,7 +585,7 @@ class ProgramD3D : public ProgramImpl
std::vector<D3DUniform *> mD3DUniforms; std::vector<D3DUniform *> mD3DUniforms;
std::map<std::string, int> mImageBindingMap; std::map<std::string, int> mImageBindingMap;
std::map<std::string, int> mAtomicBindingMap; std::map<std::string, int> mAtomicBindingMap;
std::vector<D3DInterfaceBlock> mD3DUniformBlocks; std::vector<D3DUniformBlock> mD3DUniformBlocks;
std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks; std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS> std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS>
mComputeAtomicCounterBufferRegisterIndices; mComputeAtomicCounterBufferRegisterIndices;
......
...@@ -123,6 +123,10 @@ ShaderD3D::ShaderD3D(const gl::ShaderState &data, ...@@ -123,6 +123,10 @@ ShaderD3D::ShaderD3D(const gl::ShaderState &data,
{ {
mAdditionalOptions |= SH_FORCE_ATOMIC_VALUE_RESOLUTION; mAdditionalOptions |= SH_FORCE_ATOMIC_VALUE_RESOLUTION;
} }
if (features.dontTranslateUniformBlockToStructuredBuffer.enabled)
{
mAdditionalOptions |= SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER;
}
if (extensions.multiview || extensions.multiview2) if (extensions.multiview || extensions.multiview2)
{ {
mAdditionalOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW; mAdditionalOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
...@@ -207,6 +211,12 @@ unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) co ...@@ -207,6 +211,12 @@ unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) co
return mUniformBlockRegisterMap.find(blockName)->second; return mUniformBlockRegisterMap.find(blockName)->second;
} }
bool ShaderD3D::shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const
{
ASSERT(mUniformBlockUseStructuredBufferMap.count(blockName) > 0);
return mUniformBlockUseStructuredBufferMap.find(blockName)->second;
}
unsigned int ShaderD3D::getShaderStorageBlockRegister(const std::string &blockName) const unsigned int ShaderD3D::getShaderStorageBlockRegister(const std::string &blockName) const
{ {
ASSERT(mShaderStorageBlockRegisterMap.count(blockName) > 0); ASSERT(mShaderStorageBlockRegisterMap.count(blockName) > 0);
...@@ -310,8 +320,11 @@ std::shared_ptr<WaitableCompileEvent> ShaderD3D::compile(const gl::Context *cont ...@@ -310,8 +320,11 @@ std::shared_ptr<WaitableCompileEvent> ShaderD3D::compile(const gl::Context *cont
bool blockRegisterResult = bool blockRegisterResult =
sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index); sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index);
ASSERT(blockRegisterResult); ASSERT(blockRegisterResult);
bool useStructuredBuffer =
sh::ShouldUniformBlockUseStructuredBuffer(compilerHandle, interfaceBlock.name);
mUniformBlockRegisterMap[interfaceBlock.name] = index; mUniformBlockRegisterMap[interfaceBlock.name] = index;
mUniformBlockUseStructuredBufferMap[interfaceBlock.name] = useStructuredBuffer;
} }
} }
......
...@@ -54,6 +54,7 @@ class ShaderD3D : public ShaderImpl ...@@ -54,6 +54,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;
bool shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const;
unsigned int getShaderStorageBlockRegister(const std::string &blockName) const; unsigned int getShaderStorageBlockRegister(const std::string &blockName) const;
unsigned int getReadonlyImage2DRegisterIndex() const { return mReadonlyImage2DRegisterIndex; } unsigned int getReadonlyImage2DRegisterIndex() const { return mReadonlyImage2DRegisterIndex; }
unsigned int getImage2DRegisterIndex() const { return mImage2DRegisterIndex; } unsigned int getImage2DRegisterIndex() const { return mImage2DRegisterIndex; }
...@@ -102,6 +103,7 @@ class ShaderD3D : public ShaderImpl ...@@ -102,6 +103,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, bool> mUniformBlockUseStructuredBufferMap;
std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap; std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
unsigned int mReadonlyImage2DRegisterIndex; unsigned int mReadonlyImage2DRegisterIndex;
unsigned int mImage2DRegisterIndex; unsigned int mImage2DRegisterIndex;
......
...@@ -39,6 +39,7 @@ enum BufferUsage ...@@ -39,6 +39,7 @@ enum BufferUsage
BUFFER_USAGE_PIXEL_UNPACK, BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_PIXEL_PACK, BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM, BUFFER_USAGE_UNIFORM,
BUFFER_USAGE_STRUCTURED,
BUFFER_USAGE_EMULATED_INDEXED_VERTEX, BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
BUFFER_USAGE_RAW_UAV, BUFFER_USAGE_RAW_UAV,
...@@ -67,6 +68,11 @@ class Buffer11 : public BufferD3D ...@@ -67,6 +68,11 @@ class Buffer11 : public BufferD3D
const d3d11::Buffer **bufferOut, const d3d11::Buffer **bufferOut,
UINT *firstConstantOut, UINT *firstConstantOut,
UINT *numConstantsOut); UINT *numConstantsOut);
angle::Result getStructuredBufferRangeSRV(const gl::Context *context,
unsigned int offset,
unsigned int size,
unsigned int structureByteStride,
const d3d11::ShaderResourceView **srvOut);
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);
...@@ -120,15 +126,30 @@ class Buffer11 : public BufferD3D ...@@ -120,15 +126,30 @@ class Buffer11 : public BufferD3D
class NativeStorage; class NativeStorage;
class PackStorage; class PackStorage;
class SystemMemoryStorage; class SystemMemoryStorage;
class StructuredBufferStorage;
struct ConstantBufferCacheEntry struct BufferCacheEntry
{ {
ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) {} BufferCacheEntry() : storage(nullptr), lruCount(0) {}
BufferStorage *storage; BufferStorage *storage;
unsigned int lruCount; unsigned int lruCount;
}; };
struct StructuredBufferKey
{
StructuredBufferKey(unsigned int offsetIn, unsigned int structureByteStrideIn)
: offset(offsetIn), structureByteStride(structureByteStrideIn)
{}
bool operator<(const StructuredBufferKey &rhs) const
{
return std::tie(offset, structureByteStride) <
std::tie(rhs.offset, rhs.structureByteStride);
}
unsigned int offset;
unsigned int structureByteStride;
};
void markBufferUsage(BufferUsage usage); void markBufferUsage(BufferUsage usage);
angle::Result markBufferUsage(const gl::Context *context, BufferUsage usage); angle::Result markBufferUsage(const gl::Context *context, BufferUsage usage);
angle::Result garbageCollection(const gl::Context *context, BufferUsage currentUsage); angle::Result garbageCollection(const gl::Context *context, BufferUsage currentUsage);
...@@ -189,10 +210,15 @@ class Buffer11 : public BufferD3D ...@@ -189,10 +210,15 @@ class Buffer11 : public BufferD3D
// Cache of D3D11 constant buffer for specific ranges of buffer data. // Cache of D3D11 constant buffer for specific ranges of buffer data.
// This is used to emulate UBO ranges on 11.0 devices. // This is used to emulate UBO ranges on 11.0 devices.
// Constant buffers are indexed by there start offset. // Constant buffers are indexed by there start offset.
typedef std::map<GLintptr /*offset*/, ConstantBufferCacheEntry> ConstantBufferCache; typedef std::map<GLintptr /*offset*/, BufferCacheEntry> BufferCache;
ConstantBufferCache mConstantBufferRangeStoragesCache; BufferCache mConstantBufferRangeStoragesCache;
size_t mConstantBufferStorageAdditionalSize; size_t mConstantBufferStorageAdditionalSize;
unsigned int mMaxConstantBufferLruCount; unsigned int mMaxConstantBufferLruCount;
typedef std::map<StructuredBufferKey, BufferCacheEntry> StructuredBufferCache;
StructuredBufferCache mStructuredBufferRangeStoragesCache;
size_t mStructuredBufferStorageAdditionalSize;
unsigned int mMaxStructuredBufferLruCount;
}; };
} // namespace rx } // namespace rx
......
...@@ -3481,24 +3481,21 @@ angle::Result StateManager11::applyComputeUniforms(const gl::Context *context, ...@@ -3481,24 +3481,21 @@ angle::Result StateManager11::applyComputeUniforms(const gl::Context *context,
angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *context, angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *context,
gl::ShaderType shaderType) gl::ShaderType shaderType)
{ {
gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers();
const auto &glState = context->getState(); const auto &glState = context->getState();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
const auto &shaderUniformBuffers = mProgramD3D->getShaderUniformBufferCache(shaderType); const auto &shaderUniformBuffers = mProgramD3D->getShaderUniformBufferCache(shaderType);
const unsigned int reservedUBOs = shaderReservedUBOs[shaderType];
for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffers.size(); ++bufferIndex) for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffers.size(); ++bufferIndex)
{ {
const GLint binding = shaderUniformBuffers[bufferIndex]; const D3DUBOCache cache = shaderUniformBuffers[bufferIndex];
if (binding == -1) if (cache.binding == -1)
{ {
continue; continue;
} }
const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding); const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding);
const GLintptr uniformBufferOffset = uniformBuffer.getOffset(); const GLintptr uniformBufferOffset = uniformBuffer.getOffset();
const GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); const GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
...@@ -3517,7 +3514,6 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3517,7 +3514,6 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
&firstConstant, &numConstants)); &firstConstant, &numConstants));
ASSERT(constantBuffer); ASSERT(constantBuffer);
const unsigned int appliedIndex = reservedUBOs + static_cast<unsigned int>(bufferIndex);
switch (shaderType) switch (shaderType)
{ {
case gl::ShaderType::Vertex: case gl::ShaderType::Vertex:
...@@ -3532,19 +3528,19 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3532,19 +3528,19 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
if (firstConstant != 0 && uniformBufferSize != 0) if (firstConstant != 0 && uniformBufferSize != 0)
{ {
ASSERT(numConstants != 0); ASSERT(numConstants != 0);
deviceContext1->VSSetConstantBuffers1(appliedIndex, 1, deviceContext1->VSSetConstantBuffers1(cache.registerIndex, 1,
constantBuffer->getPointer(), constantBuffer->getPointer(),
&firstConstant, &numConstants); &firstConstant, &numConstants);
} }
else else
{ {
deviceContext->VSSetConstantBuffers(appliedIndex, 1, deviceContext->VSSetConstantBuffers(cache.registerIndex, 1,
constantBuffer->getPointer()); constantBuffer->getPointer());
} }
mCurrentConstantBufferVS[appliedIndex] = constantBuffer->getSerial(); mCurrentConstantBufferVS[cache.registerIndex] = constantBuffer->getSerial();
mCurrentConstantBufferVSOffset[appliedIndex] = uniformBufferOffset; mCurrentConstantBufferVSOffset[cache.registerIndex] = uniformBufferOffset;
mCurrentConstantBufferVSSize[appliedIndex] = uniformBufferSize; mCurrentConstantBufferVSSize[cache.registerIndex] = uniformBufferSize;
break; break;
} }
...@@ -3559,19 +3555,19 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3559,19 +3555,19 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
if (firstConstant != 0 && uniformBufferSize != 0) if (firstConstant != 0 && uniformBufferSize != 0)
{ {
deviceContext1->PSSetConstantBuffers1(appliedIndex, 1, deviceContext1->PSSetConstantBuffers1(cache.registerIndex, 1,
constantBuffer->getPointer(), constantBuffer->getPointer(),
&firstConstant, &numConstants); &firstConstant, &numConstants);
} }
else else
{ {
deviceContext->PSSetConstantBuffers(appliedIndex, 1, deviceContext->PSSetConstantBuffers(cache.registerIndex, 1,
constantBuffer->getPointer()); constantBuffer->getPointer());
} }
mCurrentConstantBufferPS[appliedIndex] = constantBuffer->getSerial(); mCurrentConstantBufferPS[cache.registerIndex] = constantBuffer->getSerial();
mCurrentConstantBufferPSOffset[appliedIndex] = uniformBufferOffset; mCurrentConstantBufferPSOffset[cache.registerIndex] = uniformBufferOffset;
mCurrentConstantBufferPSSize[appliedIndex] = uniformBufferSize; mCurrentConstantBufferPSSize[cache.registerIndex] = uniformBufferSize;
break; break;
} }
...@@ -3586,19 +3582,19 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3586,19 +3582,19 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
if (firstConstant != 0 && uniformBufferSize != 0) if (firstConstant != 0 && uniformBufferSize != 0)
{ {
deviceContext1->CSSetConstantBuffers1(appliedIndex, 1, deviceContext1->CSSetConstantBuffers1(cache.registerIndex, 1,
constantBuffer->getPointer(), constantBuffer->getPointer(),
&firstConstant, &numConstants); &firstConstant, &numConstants);
} }
else else
{ {
deviceContext->CSSetConstantBuffers(appliedIndex, 1, deviceContext->CSSetConstantBuffers(cache.registerIndex, 1,
constantBuffer->getPointer()); constantBuffer->getPointer());
} }
mCurrentConstantBufferCS[appliedIndex] = constantBuffer->getSerial(); mCurrentConstantBufferCS[cache.registerIndex] = constantBuffer->getSerial();
mCurrentConstantBufferCSOffset[appliedIndex] = uniformBufferOffset; mCurrentConstantBufferCSOffset[cache.registerIndex] = uniformBufferOffset;
mCurrentConstantBufferCSSize[appliedIndex] = uniformBufferSize; mCurrentConstantBufferCSSize[cache.registerIndex] = uniformBufferSize;
break; break;
} }
...@@ -3612,6 +3608,33 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3612,6 +3608,33 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
} }
} }
const auto &shaderUniformBuffersUseSB =
mProgramD3D->getShaderUniformBufferCacheUseSB(shaderType);
for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffersUseSB.size(); ++bufferIndex)
{
const D3DUBOCacheUseSB cache = shaderUniformBuffersUseSB[bufferIndex];
if (cache.binding == -1)
{
continue;
}
const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding);
if (uniformBuffer.get() == nullptr)
{
continue;
}
const GLintptr uniformBufferOffset = uniformBuffer.getOffset();
Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get());
const d3d11::ShaderResourceView *bufferSRV = nullptr;
ANGLE_TRY(bufferStorage->getStructuredBufferRangeSRV(
context, static_cast<unsigned int>(uniformBufferOffset), cache.byteWidth,
cache.structureByteStride, &bufferSRV));
ASSERT(bufferSRV->valid());
setShaderResourceInternal(shaderType, cache.registerIndex, bufferSRV);
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -3693,8 +3716,7 @@ angle::Result StateManager11::syncShaderStorageBuffersForShader(const gl::Contex ...@@ -3693,8 +3716,7 @@ angle::Result StateManager11::syncShaderStorageBuffersForShader(const gl::Contex
angle::Result StateManager11::syncUniformBuffers(const gl::Context *context) angle::Result StateManager11::syncUniformBuffers(const gl::Context *context)
{ {
gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers(); mProgramD3D->updateUniformBufferCache(context->getCaps());
mProgramD3D->updateUniformBufferCache(context->getCaps(), shaderReservedUBOs);
if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute)) if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute))
{ {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include <versionhelpers.h>
#include <algorithm> #include <algorithm>
#include "common/debug.h" #include "common/debug.h"
...@@ -2444,6 +2445,12 @@ void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps, ...@@ -2444,6 +2445,12 @@ void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
// Never clear for robust resource init. This matches Chrome's texture clearning behaviour. // Never clear for robust resource init. This matches Chrome's texture clearning behaviour.
ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, false); ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, false);
// Don't translate uniform block to StructuredBuffer on old Windows system with AMD driver.
// This is targeted to work around a bug in AMD D3D driver that fails to allocate
// ShaderResourceView for StructuredBuffer.
ANGLE_FEATURE_CONDITION(features, dontTranslateUniformBlockToStructuredBuffer,
isAMD && !IsWindows10OrGreater());
// Call platform hooks for testing overrides. // Call platform hooks for testing overrides.
auto *platform = ANGLEPlatformCurrent(); auto *platform = ANGLEPlatformCurrent();
platform->overrideWorkaroundsD3D(platform, features); platform->overrideWorkaroundsD3D(platform, features);
......
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