Commit 85072e8f by Yunchao He Committed by Commit Bot

ES31: Fix detaching/deleting compute shader after LinkProgram.

This change also moves the ShaderType enum from D3D renderer to angletype.h. And it uses a bit mask to track the linked shader stages. BUG=angleproject:2247 Change-Id: I5c7ee1445d353a02e24549ffcf6b0ac694dd1069 Reviewed-on: https://chromium-review.googlesource.com/768629 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8e4bb4b1
...@@ -407,6 +407,9 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context, ...@@ -407,6 +407,9 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
unsigned int atomicCounterRangeHigh = stream.readInt<unsigned int>(); unsigned int atomicCounterRangeHigh = stream.readInt<unsigned int>();
state->mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh); state->mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
static_assert(SHADER_TYPE_MAX <= sizeof(unsigned long) * 8, "Too many shader types");
state->mLinkedShaderStages = stream.readInt<unsigned long>();
return program->getImplementation()->load(context, infoLog, &stream); return program->getImplementation()->load(context, infoLog, &stream);
} }
...@@ -569,6 +572,8 @@ void MemoryProgramCache::Serialize(const Context *context, ...@@ -569,6 +572,8 @@ void MemoryProgramCache::Serialize(const Context *context,
stream.writeInt(state.getAtomicCounterUniformRange().low()); stream.writeInt(state.getAtomicCounterUniformRange().low());
stream.writeInt(state.getAtomicCounterUniformRange().high()); stream.writeInt(state.getAtomicCounterUniformRange().high());
stream.writeInt(state.getLinkedShaderStages().to_ulong());
program->getImplementation()->save(context, &stream); program->getImplementation()->save(context, &stream);
ASSERT(binaryOut); ASSERT(binaryOut);
......
...@@ -948,6 +948,9 @@ Error Program::link(const gl::Context *context) ...@@ -948,6 +948,9 @@ Error Program::link(const gl::Context *context)
setUniformValuesFromBindingQualifiers(); setUniformValuesFromBindingQualifiers();
ASSERT(mLinked);
updateLinkedShaderStages();
// Mark implementation-specific unreferenced uniforms as ignored. // Mark implementation-specific unreferenced uniforms as ignored.
mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings); mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings);
...@@ -965,6 +968,24 @@ Error Program::link(const gl::Context *context) ...@@ -965,6 +968,24 @@ Error Program::link(const gl::Context *context)
return NoError(); return NoError();
} }
void Program::updateLinkedShaderStages()
{
if (mState.mAttachedVertexShader)
{
mState.mLinkedShaderStages.set(SHADER_VERTEX);
}
if (mState.mAttachedFragmentShader)
{
mState.mLinkedShaderStages.set(SHADER_FRAGMENT);
}
if (mState.mAttachedComputeShader)
{
mState.mLinkedShaderStages.set(SHADER_COMPUTE);
}
}
// Returns the program object to an unlinked state, before re-linking, or at destruction // Returns the program object to an unlinked state, before re-linking, or at destruction
void Program::unlink() void Program::unlink()
{ {
...@@ -985,6 +1006,7 @@ void Program::unlink() ...@@ -985,6 +1006,7 @@ void Program::unlink()
mState.mSamplerBindings.clear(); mState.mSamplerBindings.clear();
mState.mImageBindings.clear(); mState.mImageBindings.clear();
mState.mNumViews = -1; mState.mNumViews = -1;
mState.mLinkedShaderStages.reset();
mValidated = false; mValidated = false;
......
...@@ -229,6 +229,8 @@ struct ImageBinding ...@@ -229,6 +229,8 @@ struct ImageBinding
std::vector<GLuint> boundImageUnits; std::vector<GLuint> boundImageUnits;
}; };
using ShaderStagesMask = angle::BitSet<SHADER_TYPE_MAX>;
class ProgramState final : angle::NonCopyable class ProgramState final : angle::NonCopyable
{ {
public: public:
...@@ -305,6 +307,8 @@ class ProgramState final : angle::NonCopyable ...@@ -305,6 +307,8 @@ class ProgramState final : angle::NonCopyable
int getNumViews() const { return mNumViews; } int getNumViews() const { return mNumViews; }
bool usesMultiview() const { return mNumViews != -1; } bool usesMultiview() const { return mNumViews != -1; }
const ShaderStagesMask &getLinkedShaderStages() const { return mLinkedShaderStages; }
private: private:
friend class MemoryProgramCache; friend class MemoryProgramCache;
friend class Program; friend class Program;
...@@ -368,6 +372,7 @@ class ProgramState final : angle::NonCopyable ...@@ -368,6 +372,7 @@ class ProgramState final : angle::NonCopyable
bool mBinaryRetrieveableHint; bool mBinaryRetrieveableHint;
bool mSeparable; bool mSeparable;
ShaderStagesMask mLinkedShaderStages;
// ANGLE_multiview. // ANGLE_multiview.
int mNumViews; int mNumViews;
...@@ -410,6 +415,10 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -410,6 +415,10 @@ class Program final : angle::NonCopyable, public LabeledObject
Error link(const gl::Context *context); Error link(const gl::Context *context);
bool isLinked() const; bool isLinked() const;
bool hasLinkedVertexShader() const { return mState.mLinkedShaderStages[SHADER_VERTEX]; }
bool hasLinkedFragmentShader() const { return mState.mLinkedShaderStages[SHADER_FRAGMENT]; }
bool hasLinkedComputeShader() const { return mState.mLinkedShaderStages[SHADER_COMPUTE]; }
Error loadBinary(const Context *context, Error loadBinary(const Context *context,
GLenum binaryFormat, GLenum binaryFormat,
const void *binary, const void *binary,
...@@ -636,6 +645,8 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -636,6 +645,8 @@ class Program final : angle::NonCopyable, public LabeledObject
void linkSamplerAndImageBindings(); void linkSamplerAndImageBindings();
bool linkAtomicCounterBuffers(); bool linkAtomicCounterBuffers();
void updateLinkedShaderStages();
bool areMatchingInterfaceBlocks(InfoLog &infoLog, bool areMatchingInterfaceBlocks(InfoLog &infoLog,
const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock,
......
...@@ -47,6 +47,15 @@ enum SamplerType ...@@ -47,6 +47,15 @@ enum SamplerType
SAMPLER_COMPUTE SAMPLER_COMPUTE
}; };
enum ShaderType
{
SHADER_VERTEX,
SHADER_FRAGMENT,
SHADER_GEOMETRY,
SHADER_COMPUTE,
SHADER_TYPE_MAX
};
struct Rectangle struct Rectangle
{ {
Rectangle() : x(0), y(0), width(0), height(0) {} Rectangle() : x(0), y(0), width(0), height(0) {}
......
...@@ -491,7 +491,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, ...@@ -491,7 +491,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
// Add stub string to be replaced when shader is dynamically defined by its layout // Add stub string to be replaced when shader is dynamically defined by its layout
vertexStream << "\n" << std::string(VERTEX_ATTRIBUTE_STUB_STRING) << "\n"; vertexStream << "\n" << std::string(VERTEX_ATTRIBUTE_STUB_STRING) << "\n";
const auto &vertexBuiltins = builtinsD3D[SHADER_VERTEX]; const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX];
// Write the HLSL input/output declarations // Write the HLSL input/output declarations
vertexStream << "struct VS_OUTPUT\n"; vertexStream << "struct VS_OUTPUT\n";
...@@ -657,7 +657,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, ...@@ -657,7 +657,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
<< " return output;\n" << " return output;\n"
<< "}\n"; << "}\n";
const auto &pixelBuiltins = builtinsD3D[SHADER_PIXEL]; const auto &pixelBuiltins = builtinsD3D[gl::SHADER_FRAGMENT];
std::ostringstream pixelStream; std::ostringstream pixelStream;
pixelStream << fragmentShaderGL->getTranslatedSource(context); pixelStream << fragmentShaderGL->getTranslatedSource(context);
...@@ -931,14 +931,14 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -931,14 +931,14 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
std::ostringstream preambleStream; std::ostringstream preambleStream;
const auto &vertexBuiltins = builtinsD3D[SHADER_VERTEX]; const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX];
preambleStream << "struct GS_INPUT\n"; preambleStream << "struct GS_INPUT\n";
generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(), generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
preambleStream); preambleStream);
preambleStream << "\n" preambleStream << "\n"
<< "struct GS_OUTPUT\n"; << "struct GS_OUTPUT\n";
generateVaryingLinkHLSL(varyingPacking, builtinsD3D[SHADER_GEOMETRY], generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::SHADER_GEOMETRY],
builtinsD3D.usesPointSize(), preambleStream); builtinsD3D.usesPointSize(), preambleStream);
preambleStream preambleStream
<< "\n" << "\n"
...@@ -956,8 +956,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -956,8 +956,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n"; preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n";
if (selectViewInVS) if (selectViewInVS)
{ {
ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled && ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[SHADER_GEOMETRY].glLayer.enabled); builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled);
// If the view is already selected in the VS, then we just pass the gl_ViewportIndex and // If the view is already selected in the VS, then we just pass the gl_ViewportIndex and
// gl_Layer to the output. // gl_Layer to the output.
...@@ -989,8 +989,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va ...@@ -989,8 +989,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
if (hasANGLEMultiviewEnabled && !selectViewInVS) if (hasANGLEMultiviewEnabled && !selectViewInVS)
{ {
ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled && ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[SHADER_GEOMETRY].glLayer.enabled); builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled);
// According to the HLSL reference, using SV_RenderTargetArrayIndex is only valid if the // According to the HLSL reference, using SV_RenderTargetArrayIndex is only valid if the
// render target is an array resource. Because of this we do not write to gl_Layer if we are // render target is an array resource. Because of this we do not write to gl_Layer if we are
...@@ -1329,17 +1329,17 @@ void BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVa ...@@ -1329,17 +1329,17 @@ void BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVa
BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata,
const VaryingPacking &packing) const VaryingPacking &packing)
{ {
updateBuiltins(SHADER_VERTEX, metadata, packing); updateBuiltins(gl::SHADER_VERTEX, metadata, packing);
updateBuiltins(SHADER_PIXEL, metadata, packing); updateBuiltins(gl::SHADER_FRAGMENT, metadata, packing);
if (metadata.getRendererMajorShaderModel() >= 4) if (metadata.getRendererMajorShaderModel() >= 4)
{ {
updateBuiltins(SHADER_GEOMETRY, metadata, packing); updateBuiltins(gl::SHADER_GEOMETRY, metadata, packing);
} }
} }
BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default; BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default;
void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, void BuiltinVaryingsD3D::updateBuiltins(gl::ShaderType shaderType,
const ProgramD3DMetadata &metadata, const ProgramD3DMetadata &metadata,
const VaryingPacking &packing) const VaryingPacking &packing)
{ {
...@@ -1354,7 +1354,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1354,7 +1354,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
{ {
builtins->dxPosition.enableSystem("SV_Position"); builtins->dxPosition.enableSystem("SV_Position");
} }
else if (shaderType == SHADER_PIXEL) else if (shaderType == gl::SHADER_FRAGMENT)
{ {
builtins->dxPosition.enableSystem("VPOS"); builtins->dxPosition.enableSystem("VPOS");
} }
...@@ -1373,8 +1373,8 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1373,8 +1373,8 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++); builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++);
} }
if (shaderType == SHADER_VERTEX ? metadata.addsPointCoordToVertexShader() if (shaderType == gl::SHADER_VERTEX ? metadata.addsPointCoordToVertexShader()
: metadata.usesPointCoord()) : metadata.usesPointCoord())
{ {
// SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
// In D3D11 we manually compute gl_PointCoord in the GS. // In D3D11 we manually compute gl_PointCoord in the GS.
...@@ -1388,7 +1388,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1388,7 +1388,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
} }
} }
if (shaderType == SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled()) if (shaderType == gl::SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled())
{ {
builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
if (metadata.canSelectViewInVertexShader()) if (metadata.canSelectViewInVertexShader())
...@@ -1398,12 +1398,12 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1398,12 +1398,12 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
} }
} }
if (shaderType == SHADER_PIXEL && metadata.hasANGLEMultiviewEnabled()) if (shaderType == gl::SHADER_FRAGMENT && metadata.hasANGLEMultiviewEnabled())
{ {
builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
} }
if (shaderType == SHADER_GEOMETRY && metadata.hasANGLEMultiviewEnabled()) if (shaderType == gl::SHADER_GEOMETRY && metadata.hasANGLEMultiviewEnabled())
{ {
// Although it is possible to retrieve gl_ViewID_OVR from the value of // Although it is possible to retrieve gl_ViewID_OVR from the value of
// SV_ViewportArrayIndex or SV_RenderTargetArrayIndex based on the multi-view state in the // SV_ViewportArrayIndex or SV_RenderTargetArrayIndex based on the multi-view state in the
...@@ -1418,7 +1418,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType, ...@@ -1418,7 +1418,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
// Special case: do not include PSIZE semantic in HLSL 3 pixel shaders // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders
if (metadata.usesSystemValuePointSize() && if (metadata.usesSystemValuePointSize() &&
(shaderType != SHADER_PIXEL || metadata.getRendererMajorShaderModel() >= 4)) (shaderType != gl::SHADER_FRAGMENT || metadata.getRendererMajorShaderModel() >= 4))
{ {
builtins->glPointSize.enableSystem("PSIZE"); builtins->glPointSize.enableSystem("PSIZE");
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/Constants.h" #include "libANGLE/Constants.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
...@@ -97,17 +98,20 @@ class BuiltinVaryingsD3D ...@@ -97,17 +98,20 @@ class BuiltinVaryingsD3D
BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing); BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
~BuiltinVaryingsD3D(); ~BuiltinVaryingsD3D();
bool usesPointSize() const { return mBuiltinInfo[SHADER_VERTEX].glPointSize.enabled; } bool usesPointSize() const { return mBuiltinInfo[gl::SHADER_VERTEX].glPointSize.enabled; }
const BuiltinInfo &operator[](ShaderType shaderType) const { return mBuiltinInfo[shaderType]; } const BuiltinInfo &operator[](gl::ShaderType shaderType) const
BuiltinInfo &operator[](ShaderType shaderType) { return mBuiltinInfo[shaderType]; } {
return mBuiltinInfo[shaderType];
}
BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
private: private:
void updateBuiltins(ShaderType shaderType, void updateBuiltins(gl::ShaderType shaderType,
const ProgramD3DMetadata &metadata, const ProgramD3DMetadata &metadata,
const gl::VaryingPacking &packing); const gl::VaryingPacking &packing);
std::array<BuiltinInfo, SHADER_TYPE_MAX> mBuiltinInfo; std::array<BuiltinInfo, gl::SHADER_TYPE_MAX> mBuiltinInfo;
}; };
class DynamicHLSL : angle::NonCopyable class DynamicHLSL : angle::NonCopyable
......
...@@ -967,8 +967,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -967,8 +967,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ShaderExecutableD3D *shaderExecutable = nullptr; ShaderExecutableD3D *shaderExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, SHADER_VERTEX, ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
mStreamOutVaryings, separateAttribs, gl::SHADER_VERTEX, mStreamOutVaryings, separateAttribs,
&shaderExecutable)); &shaderExecutable));
if (!shaderExecutable) if (!shaderExecutable)
...@@ -1002,9 +1002,9 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -1002,9 +1002,9 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
const unsigned char *pixelShaderFunction = binary + stream->offset(); const unsigned char *pixelShaderFunction = binary + stream->offset();
ShaderExecutableD3D *shaderExecutable = nullptr; ShaderExecutableD3D *shaderExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL, ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
mStreamOutVaryings, separateAttribs, gl::SHADER_FRAGMENT, mStreamOutVaryings,
&shaderExecutable)); separateAttribs, &shaderExecutable));
if (!shaderExecutable) if (!shaderExecutable)
{ {
...@@ -1032,8 +1032,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -1032,8 +1032,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ShaderExecutableD3D *geometryExecutable = nullptr; ShaderExecutableD3D *geometryExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
SHADER_GEOMETRY, mStreamOutVaryings, separateAttribs, gl::SHADER_GEOMETRY, mStreamOutVaryings,
&geometryExecutable)); separateAttribs, &geometryExecutable));
if (!geometryExecutable) if (!geometryExecutable)
{ {
...@@ -1053,7 +1053,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -1053,7 +1053,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ShaderExecutableD3D *computeExecutable = nullptr; ShaderExecutableD3D *computeExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(computeShaderFunction, computeShaderSize, ANGLE_TRY(mRenderer->loadExecutable(computeShaderFunction, computeShaderSize,
SHADER_COMPUTE, std::vector<D3DVarying>(), false, gl::SHADER_COMPUTE, std::vector<D3DVarying>(), false,
&computeExecutable)); &computeExecutable));
if (!computeExecutable) if (!computeExecutable)
...@@ -1261,7 +1261,7 @@ gl::Error ProgramD3D::getPixelExecutableForCachedOutputLayout(ShaderExecutableD3 ...@@ -1261,7 +1261,7 @@ gl::Error ProgramD3D::getPixelExecutableForCachedOutputLayout(ShaderExecutableD3
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
ANGLE_TRY(mRenderer->compileToExecutable( ANGLE_TRY(mRenderer->compileToExecutable(
*currentInfoLog, finalPixelHLSL, SHADER_PIXEL, mStreamOutVaryings, *currentInfoLog, finalPixelHLSL, gl::SHADER_FRAGMENT, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds, (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds,
&pixelExecutable)); &pixelExecutable));
...@@ -1302,7 +1302,7 @@ gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3 ...@@ -1302,7 +1302,7 @@ gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
ANGLE_TRY(mRenderer->compileToExecutable( ANGLE_TRY(mRenderer->compileToExecutable(
*currentInfoLog, finalVertexHLSL, SHADER_VERTEX, mStreamOutVaryings, *currentInfoLog, finalVertexHLSL, gl::SHADER_VERTEX, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds, (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds,
&vertexExecutable)); &vertexExecutable));
...@@ -1359,7 +1359,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Context *c ...@@ -1359,7 +1359,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Context *c
ShaderExecutableD3D *geometryExecutable = nullptr; ShaderExecutableD3D *geometryExecutable = nullptr;
gl::Error error = mRenderer->compileToExecutable( gl::Error error = mRenderer->compileToExecutable(
*currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mStreamOutVaryings, *currentInfoLog, geometryHLSL, gl::SHADER_GEOMETRY, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
angle::CompilerWorkaroundsD3D(), &geometryExecutable); angle::CompilerWorkaroundsD3D(), &geometryExecutable);
...@@ -1553,7 +1553,7 @@ gl::LinkResult ProgramD3D::compileComputeExecutable(const gl::Context *context, ...@@ -1553,7 +1553,7 @@ gl::LinkResult ProgramD3D::compileComputeExecutable(const gl::Context *context,
std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(context, mState); std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(context, mState);
ShaderExecutableD3D *computeExecutable = nullptr; ShaderExecutableD3D *computeExecutable = nullptr;
ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, SHADER_COMPUTE, ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, gl::SHADER_COMPUTE,
std::vector<D3DVarying>(), false, std::vector<D3DVarying>(), false,
angle::CompilerWorkaroundsD3D(), &computeExecutable)); angle::CompilerWorkaroundsD3D(), &computeExecutable));
...@@ -1660,7 +1660,7 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1660,7 +1660,7 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
defineUniformsAndAssignRegisters(context); defineUniformsAndAssignRegisters(context);
gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[SHADER_VERTEX]); gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::SHADER_VERTEX]);
gl::LinkResult result = compileProgramExecutables(context, infoLog); gl::LinkResult result = compileProgramExecutables(context, infoLog);
if (result.isError()) if (result.isError())
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libANGLE/Device.h" #include "libANGLE/Device.h"
#include "libANGLE/Version.h" #include "libANGLE/Version.h"
#include "libANGLE/WorkerThread.h" #include "libANGLE/WorkerThread.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/formatutilsD3D.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h"
...@@ -72,15 +73,6 @@ enum RendererClass ...@@ -72,15 +73,6 @@ enum RendererClass
RENDERER_D3D9 RENDERER_D3D9
}; };
enum ShaderType
{
SHADER_VERTEX,
SHADER_PIXEL,
SHADER_GEOMETRY,
SHADER_COMPUTE,
SHADER_TYPE_MAX
};
// Useful for unit testing // Useful for unit testing
class BufferFactoryD3D : angle::NonCopyable class BufferFactoryD3D : angle::NonCopyable
{ {
...@@ -208,13 +200,13 @@ class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitialize ...@@ -208,13 +200,13 @@ class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitialize
// Shader operations // Shader operations
virtual gl::Error loadExecutable(const uint8_t *function, virtual gl::Error loadExecutable(const uint8_t *function,
size_t length, size_t length,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) = 0; ShaderExecutableD3D **outExecutable) = 0;
virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, virtual gl::Error compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL, const std::string &shaderHLSL,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds, const angle::CompilerWorkaroundsD3D &workarounds,
......
...@@ -2808,7 +2808,7 @@ gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTarg ...@@ -2808,7 +2808,7 @@ gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTarg
gl::Error Renderer11::loadExecutable(const uint8_t *function, gl::Error Renderer11::loadExecutable(const uint8_t *function,
size_t length, size_t length,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) ShaderExecutableD3D **outExecutable)
...@@ -2817,7 +2817,7 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function, ...@@ -2817,7 +2817,7 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function,
switch (type) switch (type)
{ {
case SHADER_VERTEX: case gl::SHADER_VERTEX:
{ {
d3d11::VertexShader vertexShader; d3d11::VertexShader vertexShader;
d3d11::GeometryShader streamOutShader; d3d11::GeometryShader streamOutShader;
...@@ -2848,21 +2848,21 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function, ...@@ -2848,21 +2848,21 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function,
std::move(streamOutShader)); std::move(streamOutShader));
} }
break; break;
case SHADER_PIXEL: case gl::SHADER_FRAGMENT:
{ {
d3d11::PixelShader pixelShader; d3d11::PixelShader pixelShader;
ANGLE_TRY(allocateResource(shaderData, &pixelShader)); ANGLE_TRY(allocateResource(shaderData, &pixelShader));
*outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader)); *outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader));
} }
break; break;
case SHADER_GEOMETRY: case gl::SHADER_GEOMETRY:
{ {
d3d11::GeometryShader geometryShader; d3d11::GeometryShader geometryShader;
ANGLE_TRY(allocateResource(shaderData, &geometryShader)); ANGLE_TRY(allocateResource(shaderData, &geometryShader));
*outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader)); *outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader));
} }
break; break;
case SHADER_COMPUTE: case gl::SHADER_COMPUTE:
{ {
d3d11::ComputeShader computeShader; d3d11::ComputeShader computeShader;
ANGLE_TRY(allocateResource(shaderData, &computeShader)); ANGLE_TRY(allocateResource(shaderData, &computeShader));
...@@ -2879,7 +2879,7 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function, ...@@ -2879,7 +2879,7 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function,
gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL, const std::string &shaderHLSL,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds, const angle::CompilerWorkaroundsD3D &workarounds,
...@@ -2889,16 +2889,16 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, ...@@ -2889,16 +2889,16 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
switch (type) switch (type)
{ {
case SHADER_VERTEX: case gl::SHADER_VERTEX:
profileStream << "vs"; profileStream << "vs";
break; break;
case SHADER_PIXEL: case gl::SHADER_FRAGMENT:
profileStream << "ps"; profileStream << "ps";
break; break;
case SHADER_GEOMETRY: case gl::SHADER_GEOMETRY:
profileStream << "gs"; profileStream << "gs";
break; break;
case SHADER_COMPUTE: case gl::SHADER_COMPUTE:
profileStream << "cs"; profileStream << "cs";
break; break;
default: default:
......
...@@ -230,13 +230,13 @@ class Renderer11 : public RendererD3D ...@@ -230,13 +230,13 @@ class Renderer11 : public RendererD3D
// Shader operations // Shader operations
gl::Error loadExecutable(const uint8_t *function, gl::Error loadExecutable(const uint8_t *function,
size_t length, size_t length,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) override; ShaderExecutableD3D **outExecutable) override;
gl::Error compileToExecutable(gl::InfoLog &infoLog, gl::Error compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL, const std::string &shaderHLSL,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds, const angle::CompilerWorkaroundsD3D &workarounds,
......
...@@ -2685,7 +2685,7 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge ...@@ -2685,7 +2685,7 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge
gl::Error Renderer9::loadExecutable(const uint8_t *function, gl::Error Renderer9::loadExecutable(const uint8_t *function,
size_t length, size_t length,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) ShaderExecutableD3D **outExecutable)
...@@ -2695,7 +2695,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function, ...@@ -2695,7 +2695,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function,
switch (type) switch (type)
{ {
case SHADER_VERTEX: case gl::SHADER_VERTEX:
{ {
IDirect3DVertexShader9 *vshader = nullptr; IDirect3DVertexShader9 *vshader = nullptr;
gl::Error error = createVertexShader((DWORD *)function, length, &vshader); gl::Error error = createVertexShader((DWORD *)function, length, &vshader);
...@@ -2706,7 +2706,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function, ...@@ -2706,7 +2706,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function,
*outExecutable = new ShaderExecutable9(function, length, vshader); *outExecutable = new ShaderExecutable9(function, length, vshader);
} }
break; break;
case SHADER_PIXEL: case gl::SHADER_FRAGMENT:
{ {
IDirect3DPixelShader9 *pshader = nullptr; IDirect3DPixelShader9 *pshader = nullptr;
gl::Error error = createPixelShader((DWORD *)function, length, &pshader); gl::Error error = createPixelShader((DWORD *)function, length, &pshader);
...@@ -2727,7 +2727,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function, ...@@ -2727,7 +2727,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function,
gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL, const std::string &shaderHLSL,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds, const angle::CompilerWorkaroundsD3D &workarounds,
...@@ -2740,10 +2740,10 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, ...@@ -2740,10 +2740,10 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
switch (type) switch (type)
{ {
case SHADER_VERTEX: case gl::SHADER_VERTEX:
profileStream << "vs"; profileStream << "vs";
break; break;
case SHADER_PIXEL: case gl::SHADER_FRAGMENT:
profileStream << "ps"; profileStream << "ps";
break; break;
default: default:
......
...@@ -247,13 +247,13 @@ class Renderer9 : public RendererD3D ...@@ -247,13 +247,13 @@ class Renderer9 : public RendererD3D
// Shader operations // Shader operations
gl::Error loadExecutable(const uint8_t *function, gl::Error loadExecutable(const uint8_t *function,
size_t length, size_t length,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) override; ShaderExecutableD3D **outExecutable) override;
gl::Error compileToExecutable(gl::InfoLog &infoLog, gl::Error compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL, const std::string &shaderHLSL,
ShaderType type, gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings, const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers, bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds, const angle::CompilerWorkaroundsD3D &workarounds,
......
...@@ -1008,7 +1008,7 @@ bool ValidateDispatchCompute(Context *context, ...@@ -1008,7 +1008,7 @@ bool ValidateDispatchCompute(Context *context,
return false; return false;
} }
if (program->isLinked() == false || program->getAttachedComputeShader() == nullptr) if (!program->isLinked() || !program->hasLinkedComputeShader())
{ {
context->handleError( context->handleError(
InvalidOperation() InvalidOperation()
......
...@@ -42,6 +42,38 @@ TEST_P(ComputeShaderTest, LinkComputeProgram) ...@@ -42,6 +42,38 @@ TEST_P(ComputeShaderTest, LinkComputeProgram)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Link a simple compute program. Then detach the shader and dispatch compute.
// It should be successful.
TEST_P(ComputeShaderTest, DetachShaderAfterLinkSuccess)
{
const std::string csSource =
R"(#version 310 es
layout(local_size_x=1) in;
void main()
{
})";
GLuint program = glCreateProgram();
GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource);
EXPECT_NE(0u, cs);
glAttachShader(program, cs);
glDeleteShader(cs);
glLinkProgram(program);
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
EXPECT_EQ(GL_TRUE, linkStatus);
glDetachShader(program, cs);
EXPECT_GL_NO_ERROR();
glUseProgram(program);
glDispatchCompute(8, 4, 2);
EXPECT_GL_NO_ERROR();
}
// link a simple compute program. There is no local size and linking should fail. // link a simple compute program. There is no local size and linking should fail.
TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError) TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError)
{ {
......
...@@ -423,9 +423,11 @@ TEST_P(ProgramBinaryES31Test, ProgramBinaryWithComputeShader) ...@@ -423,9 +423,11 @@ TEST_P(ProgramBinaryES31Test, ProgramBinaryWithComputeShader)
// Load a new program with the binary. // Load a new program with the binary.
ANGLE_GL_BINARY_ES3_PROGRAM(binaryProgram, binary, binaryFormat); ANGLE_GL_BINARY_ES3_PROGRAM(binaryProgram, binary, binaryFormat);
ASSERT_GL_NO_ERROR();
// TODO(Xinghua): add dispatch support when available. // Dispatch compute with the loaded binary program
glUseProgram(binaryProgram.get());
glDispatchCompute(8, 4, 2);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
......
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