D3D11: Add support to compile and link compute shaders
This is a reland of 2cd9d7e032fb412b539a907c58342060340387a1.
BUG=angleproject:1442
TEST=angle_end2end_tests
Change-Id: I5be0032b97617c31cdd4c66a823e8eb3b518867a
Reviewed-on: https://chromium-review.googlesource.com/430199
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 0bdf125..2deda67 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -246,6 +246,7 @@
dirty(true),
vsRegisterIndex(GL_INVALID_INDEX),
psRegisterIndex(GL_INVALID_INDEX),
+ csRegisterIndex(GL_INVALID_INDEX),
registerCount(0),
registerElement(0)
{
@@ -283,6 +284,11 @@
return psRegisterIndex != GL_INVALID_INDEX;
}
+bool D3DUniform::isReferencedByComputeShader() const
+{
+ return csRegisterIndex != GL_INVALID_INDEX;
+}
+
// D3DVarying Implementation
D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0)
@@ -487,14 +493,17 @@
ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
: ProgramImpl(state),
mRenderer(renderer),
- mDynamicHLSL(NULL),
- mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX, nullptr),
+ mDynamicHLSL(nullptr),
+ mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX),
+ mComputeExecutable(nullptr),
mUsesPointSize(false),
mUsesFlatInterpolation(false),
- mVertexUniformStorage(NULL),
- mFragmentUniformStorage(NULL),
+ mVertexUniformStorage(nullptr),
+ mFragmentUniformStorage(nullptr),
+ mComputeUniformStorage(nullptr),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
+ mUsedComputeSamplerRange(0),
mDirtySamplerMapping(true),
mSerial(issueSerial())
{
@@ -549,6 +558,13 @@
logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
}
break;
+ case gl::SAMPLER_COMPUTE:
+ ASSERT(samplerIndex < caps.maxComputeTextureImageUnits);
+ if (samplerIndex < mSamplersCS.size() && mSamplersCS[samplerIndex].active)
+ {
+ logicalTextureUnit = mSamplersCS[samplerIndex].logicalTextureUnit;
+ }
+ break;
default:
UNREACHABLE();
}
@@ -576,6 +592,10 @@
ASSERT(samplerIndex < mSamplersVS.size());
ASSERT(mSamplersVS[samplerIndex].active);
return mSamplersVS[samplerIndex].textureType;
+ case gl::SAMPLER_COMPUTE:
+ ASSERT(samplerIndex < mSamplersCS.size());
+ ASSERT(mSamplersCS[samplerIndex].active);
+ return mSamplersCS[samplerIndex].textureType;
default:
UNREACHABLE();
}
@@ -591,6 +611,8 @@
return mUsedPixelSamplerRange;
case gl::SAMPLER_VERTEX:
return mUsedVertexSamplerRange;
+ case gl::SAMPLER_COMPUTE:
+ return mUsedComputeSamplerRange;
default:
UNREACHABLE();
return 0u;
@@ -649,6 +671,22 @@
}
}
}
+
+ if (d3dUniform->isReferencedByComputeShader())
+ {
+ unsigned int firstIndex = d3dUniform->csRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersCS.size())
+ {
+ ASSERT(mSamplersCS[samplerIndex].active);
+ mSamplersCS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
}
}
@@ -702,8 +740,19 @@
mSamplersVS.push_back(sampler);
}
+ const unsigned int csSamplerCount = stream->readInt<unsigned int>();
+ for (unsigned int i = 0; i < csSamplerCount; ++i)
+ {
+ Sampler sampler;
+ stream->readBool(&sampler.active);
+ stream->readInt(&sampler.logicalTextureUnit);
+ stream->readInt(&sampler.textureType);
+ mSamplersCS.push_back(sampler);
+ }
+
stream->readInt(&mUsedVertexSamplerRange);
stream->readInt(&mUsedPixelSamplerRange);
+ stream->readInt(&mUsedComputeSamplerRange);
const unsigned int uniformCount = stream->readInt<unsigned int>();
if (stream->error())
@@ -723,6 +772,7 @@
linkedUniform.isInDefaultBlock());
stream->readInt(&d3dUniform->psRegisterIndex);
stream->readInt(&d3dUniform->vsRegisterIndex);
+ stream->readInt(&d3dUniform->csRegisterIndex);
stream->readInt(&d3dUniform->registerCount);
stream->readInt(&d3dUniform->registerElement);
@@ -742,6 +792,7 @@
D3DUniformBlock uniformBlock;
stream->readInt(&uniformBlock.psRegisterIndex);
stream->readInt(&uniformBlock.vsRegisterIndex);
+ stream->readInt(&uniformBlock.csRegisterIndex);
mD3DUniformBlocks.push_back(uniformBlock);
}
@@ -816,8 +867,8 @@
VertexExecutable::getSignature(mRenderer, inputLayout, &signature);
// add new binary
- mVertexExecutables.push_back(
- new VertexExecutable(inputLayout, signature, shaderExecutable));
+ mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
+ new VertexExecutable(inputLayout, signature, shaderExecutable)));
stream->skip(vertexShaderSize);
}
@@ -847,7 +898,8 @@
}
// add new binary
- mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
+ mPixelExecutables.push_back(
+ std::unique_ptr<PixelExecutable>(new PixelExecutable(outputs, shaderExecutable)));
stream->skip(pixelShaderSize);
}
@@ -858,24 +910,46 @@
unsigned int geometryShaderSize = stream->readInt<unsigned int>();
if (geometryShaderSize == 0)
{
- mGeometryExecutables[geometryExeIndex] = nullptr;
continue;
}
const unsigned char *geometryShaderFunction = binary + stream->offset();
+ ShaderExecutableD3D *geometryExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
SHADER_GEOMETRY, mStreamOutVaryings, separateAttribs,
- &mGeometryExecutables[geometryExeIndex]));
+ &geometryExecutable));
- if (!mGeometryExecutables[geometryExeIndex])
+ if (!geometryExecutable)
{
infoLog << "Could not create geometry shader.";
return false;
}
+
+ mGeometryExecutables[geometryExeIndex].reset(geometryExecutable);
+
stream->skip(geometryShaderSize);
}
+ unsigned int computeShaderSize = stream->readInt<unsigned int>();
+ if (computeShaderSize > 0)
+ {
+ const unsigned char *computeShaderFunction = binary + stream->offset();
+
+ ShaderExecutableD3D *computeExecutable = nullptr;
+ ANGLE_TRY(mRenderer->loadExecutable(computeShaderFunction, computeShaderSize,
+ SHADER_COMPUTE, std::vector<D3DVarying>(), false,
+ &computeExecutable));
+
+ if (!computeExecutable)
+ {
+ infoLog << "Could not create compute shader.";
+ return false;
+ }
+
+ mComputeExecutable.reset(computeExecutable);
+ }
+
initializeUniformStorage();
return true;
@@ -913,8 +987,17 @@
stream->writeInt(mSamplersVS[i].textureType);
}
+ stream->writeInt(mSamplersCS.size());
+ for (unsigned int i = 0; i < mSamplersCS.size(); ++i)
+ {
+ stream->writeInt(mSamplersCS[i].active);
+ stream->writeInt(mSamplersCS[i].logicalTextureUnit);
+ stream->writeInt(mSamplersCS[i].textureType);
+ }
+
stream->writeInt(mUsedVertexSamplerRange);
stream->writeInt(mUsedPixelSamplerRange);
+ stream->writeInt(mUsedComputeSamplerRange);
stream->writeInt(mD3DUniforms.size());
for (const D3DUniform *uniform : mD3DUniforms)
@@ -922,6 +1005,7 @@
// Type, name and arraySize are redundant, so aren't stored in the binary.
stream->writeIntOrNegOne(uniform->psRegisterIndex);
stream->writeIntOrNegOne(uniform->vsRegisterIndex);
+ stream->writeIntOrNegOne(uniform->csRegisterIndex);
stream->writeInt(uniform->registerCount);
stream->writeInt(uniform->registerElement);
}
@@ -935,6 +1019,7 @@
{
stream->writeIntOrNegOne(uniformBlock.psRegisterIndex);
stream->writeIntOrNegOne(uniformBlock.vsRegisterIndex);
+ stream->writeIntOrNegOne(uniformBlock.csRegisterIndex);
}
stream->writeInt(mStreamOutVaryings.size());
@@ -974,7 +1059,7 @@
for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size();
vertexExecutableIndex++)
{
- VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
+ VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get();
const auto &inputLayout = vertexExecutable->inputs();
stream->writeInt(inputLayout.size());
@@ -995,7 +1080,7 @@
for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size();
pixelExecutableIndex++)
{
- PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
+ PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get();
const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
stream->writeInt(outputs.size());
@@ -1011,17 +1096,28 @@
stream->writeBytes(pixelBlob, pixelShaderSize);
}
- for (const ShaderExecutableD3D *geometryExe : mGeometryExecutables)
+ for (auto const &geometryExecutable : mGeometryExecutables)
{
- if (geometryExe == nullptr)
+ if (!geometryExecutable)
{
stream->writeInt(0);
continue;
}
- size_t geometryShaderSize = geometryExe->getLength();
+ size_t geometryShaderSize = geometryExecutable->getLength();
stream->writeInt(geometryShaderSize);
- stream->writeBytes(geometryExe->getFunction(), geometryShaderSize);
+ stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize);
+ }
+
+ if (mComputeExecutable)
+ {
+ size_t computeShaderSize = mComputeExecutable->getLength();
+ stream->writeInt(computeShaderSize);
+ stream->writeBytes(mComputeExecutable->getFunction(), computeShaderSize);
+ }
+ else
+ {
+ stream->writeInt(0);
}
return gl::NoError();
@@ -1087,7 +1183,8 @@
if (pixelExecutable)
{
- mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
+ mPixelExecutables.push_back(std::unique_ptr<PixelExecutable>(
+ new PixelExecutable(outputSignature, pixelExecutable)));
}
else if (!infoLog)
{
@@ -1132,8 +1229,8 @@
if (vertexExecutable)
{
- mVertexExecutables.push_back(
- new VertexExecutable(inputLayout, mCachedVertexSignature, vertexExecutable));
+ mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
+ new VertexExecutable(inputLayout, mCachedVertexSignature, vertexExecutable)));
}
else if (!infoLog)
{
@@ -1164,11 +1261,11 @@
gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
- if (mGeometryExecutables[geometryShaderType] != nullptr)
+ if (mGeometryExecutables[geometryShaderType])
{
if (outExecutable)
{
- *outExecutable = mGeometryExecutables[geometryShaderType];
+ *outExecutable = mGeometryExecutables[geometryShaderType].get();
}
return gl::NoError();
}
@@ -1180,10 +1277,11 @@
gl::InfoLog tempInfoLog;
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
- gl::Error error = mRenderer->compileToExecutable(
+ ShaderExecutableD3D *geometryExecutable = nullptr;
+ gl::Error error = mRenderer->compileToExecutable(
*currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
- angle::CompilerWorkaroundsD3D(), &mGeometryExecutables[geometryShaderType]);
+ angle::CompilerWorkaroundsD3D(), &geometryExecutable);
if (!infoLog && error.isError())
{
@@ -1192,9 +1290,14 @@
ERR("Error compiling dynamic geometry executable:\n%s\n", &tempCharBuffer[0]);
}
+ if (geometryExecutable != nullptr)
+ {
+ mGeometryExecutables[geometryShaderType].reset(geometryExecutable);
+ }
+
if (outExecutable)
{
- *outExecutable = mGeometryExecutables[geometryShaderType];
+ *outExecutable = mGeometryExecutables[geometryShaderType].get();
}
return error;
}
@@ -1337,82 +1440,134 @@
(!usesGeometryShader(GL_POINTS) || pointGS));
}
+LinkResult ProgramD3D::compileComputeExecutable(gl::InfoLog &infoLog)
+{
+ // Ensure the compiler is initialized to avoid race conditions.
+ ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized());
+
+ std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(mState);
+
+ ShaderExecutableD3D *computeExecutable = nullptr;
+ ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, SHADER_COMPUTE,
+ std::vector<D3DVarying>(), false,
+ angle::CompilerWorkaroundsD3D(), &computeExecutable));
+
+ if (computeExecutable == nullptr)
+ {
+ ERR("Error compiling dynamic compute executable:\n%s\n", infoLog.str().c_str());
+ }
+ else
+ {
+ const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+ computeShaderD3D->appendDebugInfo(computeExecutable->getDebugInfo());
+ mComputeExecutable.reset(computeExecutable);
+ }
+
+ return mComputeExecutable.get() != nullptr;
+}
+
LinkResult ProgramD3D::link(const gl::ContextState &data,
const gl::VaryingPacking &packing,
gl::InfoLog &infoLog)
{
reset();
- const gl::Shader *vertexShader = mState.getAttachedVertexShader();
- const gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
-
- const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
- const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
-
- mSamplersVS.resize(data.getCaps().maxVertexTextureImageUnits);
- mSamplersPS.resize(data.getCaps().maxTextureImageUnits);
-
- vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds);
- fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds);
-
- if (mRenderer->getNativeLimitations().noFrontFacingSupport)
+ const gl::Shader *computeShader = mState.getAttachedComputeShader();
+ if (computeShader)
{
- if (fragmentShaderD3D->usesFrontFacing())
+ mSamplersCS.resize(data.getCaps().maxComputeTextureImageUnits);
+
+ defineUniformsAndAssignRegisters();
+
+ LinkResult result = compileComputeExecutable(infoLog);
+ if (result.isError())
{
- infoLog << "The current renderer doesn't support gl_FrontFacing";
+ infoLog << result.getError().getMessage();
+ return result;
+ }
+ else if (!result.getResult())
+ {
+ infoLog << "Failed to create D3D compute shader.";
+ return result;
+ }
+
+ initUniformBlockInfo(computeShader);
+ }
+ else
+ {
+ const gl::Shader *vertexShader = mState.getAttachedVertexShader();
+ const gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
+
+ const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
+ const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
+
+ mSamplersVS.resize(data.getCaps().maxVertexTextureImageUnits);
+ mSamplersPS.resize(data.getCaps().maxTextureImageUnits);
+
+ vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds);
+ fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds);
+
+ if (mRenderer->getNativeLimitations().noFrontFacingSupport)
+ {
+ if (fragmentShaderD3D->usesFrontFacing())
+ {
+ infoLog << "The current renderer doesn't support gl_FrontFacing";
+ return false;
+ }
+ }
+
+ // TODO(jmadill): Implement more sophisticated component packing in D3D9.
+ // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings
+ // intelligently, but D3D9 assumes one semantic per register.
+ if (mRenderer->getRendererClass() == RENDERER_D3D9 &&
+ packing.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors)
+ {
+ infoLog << "Cannot pack these varyings on D3D9.";
return false;
}
+
+ ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D);
+ BuiltinVaryingsD3D builtins(metadata, packing);
+
+ mDynamicHLSL->generateShaderLinkHLSL(data, mState, metadata, packing, builtins, &mPixelHLSL,
+ &mVertexHLSL);
+
+ mUsesPointSize = vertexShaderD3D->usesPointSize();
+ mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
+ mUsesFragDepth = metadata.usesFragDepth();
+
+ // Cache if we use flat shading
+ mUsesFlatInterpolation = (FindFlatInterpolationVarying(fragmentShader->getVaryings()) ||
+ FindFlatInterpolationVarying(vertexShader->getVaryings()));
+
+ if (mRenderer->getMajorShaderModel() >= 4)
+ {
+ mGeometryShaderPreamble =
+ mDynamicHLSL->generateGeometryShaderPreamble(packing, builtins);
+ }
+
+ initAttribLocationsToD3DSemantic();
+
+ defineUniformsAndAssignRegisters();
+
+ gatherTransformFeedbackVaryings(packing, builtins[SHADER_VERTEX]);
+
+ LinkResult result = compileProgramExecutables(data, infoLog);
+ if (result.isError())
+ {
+ infoLog << result.getError().getMessage();
+ return result;
+ }
+ else if (!result.getResult())
+ {
+ infoLog << "Failed to create D3D shaders.";
+ return result;
+ }
+
+ initUniformBlockInfo(vertexShader);
+ initUniformBlockInfo(fragmentShader);
}
- // TODO(jmadill): Implement more sophisticated component packing in D3D9.
- // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings
- // intelligently, but D3D9 assumes one semantic per register.
- if (mRenderer->getRendererClass() == RENDERER_D3D9 &&
- packing.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors)
- {
- infoLog << "Cannot pack these varyings on D3D9.";
- return false;
- }
-
- ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D);
- BuiltinVaryingsD3D builtins(metadata, packing);
-
- mDynamicHLSL->generateShaderLinkHLSL(data, mState, metadata, packing, builtins, &mPixelHLSL,
- &mVertexHLSL);
-
- mUsesPointSize = vertexShaderD3D->usesPointSize();
- mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
- mUsesFragDepth = metadata.usesFragDepth();
-
- // Cache if we use flat shading
- mUsesFlatInterpolation = (FindFlatInterpolationVarying(fragmentShader->getVaryings()) ||
- FindFlatInterpolationVarying(vertexShader->getVaryings()));
-
- if (mRenderer->getMajorShaderModel() >= 4)
- {
- mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(packing, builtins);
- }
-
- initAttribLocationsToD3DSemantic();
-
- defineUniformsAndAssignRegisters();
-
- gatherTransformFeedbackVaryings(packing, builtins[SHADER_VERTEX]);
-
- LinkResult result = compileProgramExecutables(data, infoLog);
- if (result.isError())
- {
- infoLog << result.getError().getMessage();
- return result;
- }
- else if (!result.getResult())
- {
- infoLog << "Failed to create D3D shaders.";
- return result;
- }
-
- initUniformBlockInfo();
-
return true;
}
@@ -1422,34 +1577,18 @@
return GL_TRUE;
}
-void ProgramD3D::initUniformBlockInfo()
+void ProgramD3D::initUniformBlockInfo(const gl::Shader *shader)
{
- const gl::Shader *vertexShader = mState.getAttachedVertexShader();
-
- for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks())
+ for (const sh::InterfaceBlock &interfaceBlock : shader->getInterfaceBlocks())
{
- if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED)
+ if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
continue;
- if (mBlockDataSizes.count(vertexBlock.name) > 0)
+ if (mBlockDataSizes.count(interfaceBlock.name) > 0)
continue;
- size_t dataSize = getUniformBlockInfo(vertexBlock);
- mBlockDataSizes[vertexBlock.name] = dataSize;
- }
-
- const gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
-
- for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks())
- {
- if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED)
- continue;
-
- if (mBlockDataSizes.count(fragmentBlock.name) > 0)
- continue;
-
- size_t dataSize = getUniformBlockInfo(fragmentBlock);
- mBlockDataSizes[fragmentBlock.name] = dataSize;
+ size_t dataSize = getUniformBlockInfo(interfaceBlock);
+ mBlockDataSizes[interfaceBlock.name] = dataSize;
}
}
@@ -1462,8 +1601,10 @@
}
// Assign registers and update sizes.
- const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
- const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
+ const ShaderD3D *vertexShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
+ const ShaderD3D *fragmentShaderD3D =
+ SafeGetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
+ const ShaderD3D *computeShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
for (const gl::UniformBlock &uniformBlock : mState.getUniformBlocks())
{
@@ -1473,6 +1614,7 @@
if (uniformBlock.vertexStaticUse)
{
+ ASSERT(vertexShaderD3D != nullptr);
unsigned int baseRegister =
vertexShaderD3D->getInterfaceBlockRegister(uniformBlock.name);
d3dUniformBlock.vsRegisterIndex = baseRegister + uniformBlockElement;
@@ -1480,11 +1622,20 @@
if (uniformBlock.fragmentStaticUse)
{
+ ASSERT(fragmentShaderD3D != nullptr);
unsigned int baseRegister =
fragmentShaderD3D->getInterfaceBlockRegister(uniformBlock.name);
d3dUniformBlock.psRegisterIndex = baseRegister + uniformBlockElement;
}
+ if (uniformBlock.computeStaticUse)
+ {
+ ASSERT(computeShaderD3D != nullptr);
+ unsigned int baseRegister =
+ computeShaderD3D->getInterfaceBlockRegister(uniformBlock.name);
+ d3dUniformBlock.csRegisterIndex = baseRegister + uniformBlockElement;
+ }
+
mD3DUniformBlocks.push_back(d3dUniformBlock);
}
}
@@ -1494,6 +1645,7 @@
// Compute total default block size
unsigned int vertexRegisters = 0;
unsigned int fragmentRegisters = 0;
+ unsigned int computeRegisters = 0;
for (const D3DUniform *d3dUniform : mD3DUniforms)
{
if (!d3dUniform->isSampler())
@@ -1508,11 +1660,20 @@
fragmentRegisters = std::max(
fragmentRegisters, d3dUniform->psRegisterIndex + d3dUniform->registerCount);
}
+ if (d3dUniform->isReferencedByComputeShader())
+ {
+ computeRegisters = std::max(
+ computeRegisters, d3dUniform->csRegisterIndex + d3dUniform->registerCount);
+ }
}
}
- mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
- mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
+ mVertexUniformStorage =
+ std::unique_ptr<UniformStorageD3D>(mRenderer->createUniformStorage(vertexRegisters * 16u));
+ mFragmentUniformStorage = std::unique_ptr<UniformStorageD3D>(
+ mRenderer->createUniformStorage(fragmentRegisters * 16u));
+ mComputeUniformStorage =
+ std::unique_ptr<UniformStorageD3D>(mRenderer->createUniformStorage(computeRegisters * 16u));
}
gl::Error ProgramD3D::applyUniforms(GLenum drawMode)
@@ -1736,22 +1897,37 @@
void ProgramD3D::defineUniformsAndAssignRegisters()
{
D3DUniformMap uniformMap;
- const gl::Shader *vertexShader = mState.getAttachedVertexShader();
- for (const sh::Uniform &vertexUniform : vertexShader->getUniforms())
-
+ const gl::Shader *computeShader = mState.getAttachedComputeShader();
+ if (computeShader)
{
- if (vertexUniform.staticUse)
+ for (const sh::Uniform &computeUniform : computeShader->getUniforms())
+
{
- defineUniformBase(vertexShader, vertexUniform, &uniformMap);
+ if (computeUniform.staticUse)
+ {
+ defineUniformBase(computeShader, computeUniform, &uniformMap);
+ }
}
}
-
- const gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
- for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms())
+ else
{
- if (fragmentUniform.staticUse)
+ const gl::Shader *vertexShader = mState.getAttachedVertexShader();
+ for (const sh::Uniform &vertexUniform : vertexShader->getUniforms())
+
{
- defineUniformBase(fragmentShader, fragmentUniform, &uniformMap);
+ if (vertexUniform.staticUse)
+ {
+ defineUniformBase(vertexShader, vertexUniform, &uniformMap);
+ }
+ }
+
+ const gl::Shader *fragmentShader = mState.getAttachedFragmentShader();
+ for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms())
+ {
+ if (fragmentUniform.staticUse)
+ {
+ defineUniformBase(fragmentShader, fragmentUniform, &uniformMap);
+ }
}
}
@@ -1877,10 +2053,14 @@
{
d3dUniform->psRegisterIndex = reg;
}
+ else if (shaderType == GL_VERTEX_SHADER)
+ {
+ d3dUniform->vsRegisterIndex = reg;
+ }
else
{
- ASSERT(shaderType == GL_VERTEX_SHADER);
- d3dUniform->vsRegisterIndex = reg;
+ ASSERT(shaderType == GL_COMPUTE_SHADER);
+ d3dUniform->csRegisterIndex = reg;
}
// Arrays are treated as aggregate types
@@ -2043,22 +2223,37 @@
void ProgramD3D::assignSamplerRegisters(D3DUniform *d3dUniform)
{
ASSERT(d3dUniform->isSampler());
- const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
- const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
- ASSERT(vertexShaderD3D->hasUniform(d3dUniform) || fragmentShaderD3D->hasUniform(d3dUniform));
- if (vertexShaderD3D->hasUniform(d3dUniform))
+ const gl::Shader *computeShader = mState.getAttachedComputeShader();
+ if (computeShader)
{
- d3dUniform->vsRegisterIndex = vertexShaderD3D->getUniformRegister(d3dUniform->name);
- ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX);
- AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
- mSamplersVS, &mUsedVertexSamplerRange);
+ const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedComputeShader());
+ ASSERT(computeShaderD3D->hasUniform(d3dUniform));
+ d3dUniform->csRegisterIndex = computeShaderD3D->getUniformRegister(d3dUniform->name);
+ ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX);
+ AssignSamplers(d3dUniform->csRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
+ mSamplersCS, &mUsedComputeSamplerRange);
}
- if (fragmentShaderD3D->hasUniform(d3dUniform))
+ else
{
- d3dUniform->psRegisterIndex = fragmentShaderD3D->getUniformRegister(d3dUniform->name);
- ASSERT(d3dUniform->psRegisterIndex != GL_INVALID_INDEX);
- AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
- mSamplersPS, &mUsedPixelSamplerRange);
+ const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
+ const ShaderD3D *fragmentShaderD3D =
+ GetImplAs<ShaderD3D>(mState.getAttachedFragmentShader());
+ ASSERT(vertexShaderD3D->hasUniform(d3dUniform) ||
+ fragmentShaderD3D->hasUniform(d3dUniform));
+ if (vertexShaderD3D->hasUniform(d3dUniform))
+ {
+ d3dUniform->vsRegisterIndex = vertexShaderD3D->getUniformRegister(d3dUniform->name);
+ ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX);
+ AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
+ mSamplersVS, &mUsedVertexSamplerRange);
+ }
+ if (fragmentShaderD3D->hasUniform(d3dUniform))
+ {
+ d3dUniform->psRegisterIndex = fragmentShaderD3D->getUniformRegister(d3dUniform->name);
+ ASSERT(d3dUniform->psRegisterIndex != GL_INVALID_INDEX);
+ AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
+ mSamplersPS, &mUsedPixelSamplerRange);
+ }
}
}
@@ -2085,14 +2280,16 @@
void ProgramD3D::reset()
{
- SafeDeleteContainer(mVertexExecutables);
- SafeDeleteContainer(mPixelExecutables);
+ mVertexExecutables.clear();
+ mPixelExecutables.clear();
- for (auto &element : mGeometryExecutables)
+ for (auto &geometryExecutable : mGeometryExecutables)
{
- SafeDelete(element);
+ geometryExecutable.reset(nullptr);
}
+ mComputeExecutable.reset(nullptr);
+
mVertexHLSL.clear();
mVertexWorkarounds = angle::CompilerWorkaroundsD3D();
@@ -2106,14 +2303,17 @@
SafeDeleteContainer(mD3DUniforms);
mD3DUniformBlocks.clear();
- SafeDelete(mVertexUniformStorage);
- SafeDelete(mFragmentUniformStorage);
+ mVertexUniformStorage.reset(nullptr);
+ mFragmentUniformStorage.reset(nullptr);
+ mComputeUniformStorage.reset(nullptr);
mSamplersPS.clear();
mSamplersVS.clear();
+ mSamplersCS.clear();
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
+ mUsedComputeSamplerRange = 0;
mDirtySamplerMapping = true;
mAttribLocationToD3DSemantic.fill(-1);