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,
unsigned int atomicCounterRangeHigh = stream.readInt<unsigned int>();
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);
}
......@@ -569,6 +572,8 @@ void MemoryProgramCache::Serialize(const Context *context,
stream.writeInt(state.getAtomicCounterUniformRange().low());
stream.writeInt(state.getAtomicCounterUniformRange().high());
stream.writeInt(state.getLinkedShaderStages().to_ulong());
program->getImplementation()->save(context, &stream);
ASSERT(binaryOut);
......
......@@ -948,6 +948,9 @@ Error Program::link(const gl::Context *context)
setUniformValuesFromBindingQualifiers();
ASSERT(mLinked);
updateLinkedShaderStages();
// Mark implementation-specific unreferenced uniforms as ignored.
mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings);
......@@ -965,6 +968,24 @@ Error Program::link(const gl::Context *context)
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
void Program::unlink()
{
......@@ -985,6 +1006,7 @@ void Program::unlink()
mState.mSamplerBindings.clear();
mState.mImageBindings.clear();
mState.mNumViews = -1;
mState.mLinkedShaderStages.reset();
mValidated = false;
......
......@@ -229,6 +229,8 @@ struct ImageBinding
std::vector<GLuint> boundImageUnits;
};
using ShaderStagesMask = angle::BitSet<SHADER_TYPE_MAX>;
class ProgramState final : angle::NonCopyable
{
public:
......@@ -305,6 +307,8 @@ class ProgramState final : angle::NonCopyable
int getNumViews() const { return mNumViews; }
bool usesMultiview() const { return mNumViews != -1; }
const ShaderStagesMask &getLinkedShaderStages() const { return mLinkedShaderStages; }
private:
friend class MemoryProgramCache;
friend class Program;
......@@ -368,6 +372,7 @@ class ProgramState final : angle::NonCopyable
bool mBinaryRetrieveableHint;
bool mSeparable;
ShaderStagesMask mLinkedShaderStages;
// ANGLE_multiview.
int mNumViews;
......@@ -410,6 +415,10 @@ class Program final : angle::NonCopyable, public LabeledObject
Error link(const gl::Context *context);
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,
GLenum binaryFormat,
const void *binary,
......@@ -636,6 +645,8 @@ class Program final : angle::NonCopyable, public LabeledObject
void linkSamplerAndImageBindings();
bool linkAtomicCounterBuffers();
void updateLinkedShaderStages();
bool areMatchingInterfaceBlocks(InfoLog &infoLog,
const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock,
......
......@@ -47,6 +47,15 @@ enum SamplerType
SAMPLER_COMPUTE
};
enum ShaderType
{
SHADER_VERTEX,
SHADER_FRAGMENT,
SHADER_GEOMETRY,
SHADER_COMPUTE,
SHADER_TYPE_MAX
};
struct Rectangle
{
Rectangle() : x(0), y(0), width(0), height(0) {}
......
......@@ -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
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
vertexStream << "struct VS_OUTPUT\n";
......@@ -657,7 +657,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
<< " return output;\n"
<< "}\n";
const auto &pixelBuiltins = builtinsD3D[SHADER_PIXEL];
const auto &pixelBuiltins = builtinsD3D[gl::SHADER_FRAGMENT];
std::ostringstream pixelStream;
pixelStream << fragmentShaderGL->getTranslatedSource(context);
......@@ -931,14 +931,14 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
std::ostringstream preambleStream;
const auto &vertexBuiltins = builtinsD3D[SHADER_VERTEX];
const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX];
preambleStream << "struct GS_INPUT\n";
generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
preambleStream);
preambleStream << "\n"
<< "struct GS_OUTPUT\n";
generateVaryingLinkHLSL(varyingPacking, builtinsD3D[SHADER_GEOMETRY],
generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::SHADER_GEOMETRY],
builtinsD3D.usesPointSize(), preambleStream);
preambleStream
<< "\n"
......@@ -956,8 +956,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n";
if (selectViewInVS)
{
ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[SHADER_GEOMETRY].glLayer.enabled);
ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled);
// If the view is already selected in the VS, then we just pass the gl_ViewportIndex and
// gl_Layer to the output.
......@@ -989,8 +989,8 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va
if (hasANGLEMultiviewEnabled && !selectViewInVS)
{
ASSERT(builtinsD3D[SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[SHADER_GEOMETRY].glLayer.enabled);
ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled &&
builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled);
// 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
......@@ -1329,17 +1329,17 @@ void BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVa
BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata,
const VaryingPacking &packing)
{
updateBuiltins(SHADER_VERTEX, metadata, packing);
updateBuiltins(SHADER_PIXEL, metadata, packing);
updateBuiltins(gl::SHADER_VERTEX, metadata, packing);
updateBuiltins(gl::SHADER_FRAGMENT, metadata, packing);
if (metadata.getRendererMajorShaderModel() >= 4)
{
updateBuiltins(SHADER_GEOMETRY, metadata, packing);
updateBuiltins(gl::SHADER_GEOMETRY, metadata, packing);
}
}
BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default;
void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
void BuiltinVaryingsD3D::updateBuiltins(gl::ShaderType shaderType,
const ProgramD3DMetadata &metadata,
const VaryingPacking &packing)
{
......@@ -1354,7 +1354,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
{
builtins->dxPosition.enableSystem("SV_Position");
}
else if (shaderType == SHADER_PIXEL)
else if (shaderType == gl::SHADER_FRAGMENT)
{
builtins->dxPosition.enableSystem("VPOS");
}
......@@ -1373,8 +1373,8 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++);
}
if (shaderType == SHADER_VERTEX ? metadata.addsPointCoordToVertexShader()
: metadata.usesPointCoord())
if (shaderType == gl::SHADER_VERTEX ? metadata.addsPointCoordToVertexShader()
: metadata.usesPointCoord())
{
// SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
// In D3D11 we manually compute gl_PointCoord in the GS.
......@@ -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++);
if (metadata.canSelectViewInVertexShader())
......@@ -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++);
}
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
// SV_ViewportArrayIndex or SV_RenderTargetArrayIndex based on the multi-view state in the
......@@ -1418,7 +1418,7 @@ void BuiltinVaryingsD3D::updateBuiltins(ShaderType shaderType,
// Special case: do not include PSIZE semantic in HLSL 3 pixel shaders
if (metadata.usesSystemValuePointSize() &&
(shaderType != SHADER_PIXEL || metadata.getRendererMajorShaderModel() >= 4))
(shaderType != gl::SHADER_FRAGMENT || metadata.getRendererMajorShaderModel() >= 4))
{
builtins->glPointSize.enableSystem("PSIZE");
}
......
......@@ -16,6 +16,7 @@
#include "common/angleutils.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Program.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
......@@ -97,17 +98,20 @@ class BuiltinVaryingsD3D
BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
~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]; }
BuiltinInfo &operator[](ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
const BuiltinInfo &operator[](gl::ShaderType shaderType) const
{
return mBuiltinInfo[shaderType];
}
BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
private:
void updateBuiltins(ShaderType shaderType,
void updateBuiltins(gl::ShaderType shaderType,
const ProgramD3DMetadata &metadata,
const gl::VaryingPacking &packing);
std::array<BuiltinInfo, SHADER_TYPE_MAX> mBuiltinInfo;
std::array<BuiltinInfo, gl::SHADER_TYPE_MAX> mBuiltinInfo;
};
class DynamicHLSL : angle::NonCopyable
......
......@@ -967,8 +967,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ShaderExecutableD3D *shaderExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, SHADER_VERTEX,
mStreamOutVaryings, separateAttribs,
ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
gl::SHADER_VERTEX, mStreamOutVaryings, separateAttribs,
&shaderExecutable));
if (!shaderExecutable)
......@@ -1002,9 +1002,9 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
const unsigned char *pixelShaderFunction = binary + stream->offset();
ShaderExecutableD3D *shaderExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL,
mStreamOutVaryings, separateAttribs,
&shaderExecutable));
ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
gl::SHADER_FRAGMENT, mStreamOutVaryings,
separateAttribs, &shaderExecutable));
if (!shaderExecutable)
{
......@@ -1032,8 +1032,8 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ShaderExecutableD3D *geometryExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize,
SHADER_GEOMETRY, mStreamOutVaryings, separateAttribs,
&geometryExecutable));
gl::SHADER_GEOMETRY, mStreamOutVaryings,
separateAttribs, &geometryExecutable));
if (!geometryExecutable)
{
......@@ -1053,7 +1053,7 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
ShaderExecutableD3D *computeExecutable = nullptr;
ANGLE_TRY(mRenderer->loadExecutable(computeShaderFunction, computeShaderSize,
SHADER_COMPUTE, std::vector<D3DVarying>(), false,
gl::SHADER_COMPUTE, std::vector<D3DVarying>(), false,
&computeExecutable));
if (!computeExecutable)
......@@ -1261,7 +1261,7 @@ gl::Error ProgramD3D::getPixelExecutableForCachedOutputLayout(ShaderExecutableD3
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
ANGLE_TRY(mRenderer->compileToExecutable(
*currentInfoLog, finalPixelHLSL, SHADER_PIXEL, mStreamOutVaryings,
*currentInfoLog, finalPixelHLSL, gl::SHADER_FRAGMENT, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds,
&pixelExecutable));
......@@ -1302,7 +1302,7 @@ gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3
gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
ANGLE_TRY(mRenderer->compileToExecutable(
*currentInfoLog, finalVertexHLSL, SHADER_VERTEX, mStreamOutVaryings,
*currentInfoLog, finalVertexHLSL, gl::SHADER_VERTEX, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds,
&vertexExecutable));
......@@ -1359,7 +1359,7 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Context *c
ShaderExecutableD3D *geometryExecutable = nullptr;
gl::Error error = mRenderer->compileToExecutable(
*currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mStreamOutVaryings,
*currentInfoLog, geometryHLSL, gl::SHADER_GEOMETRY, mStreamOutVaryings,
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
angle::CompilerWorkaroundsD3D(), &geometryExecutable);
......@@ -1553,7 +1553,7 @@ gl::LinkResult ProgramD3D::compileComputeExecutable(const gl::Context *context,
std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(context, mState);
ShaderExecutableD3D *computeExecutable = nullptr;
ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, SHADER_COMPUTE,
ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, gl::SHADER_COMPUTE,
std::vector<D3DVarying>(), false,
angle::CompilerWorkaroundsD3D(), &computeExecutable));
......@@ -1660,7 +1660,7 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
defineUniformsAndAssignRegisters(context);
gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[SHADER_VERTEX]);
gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::SHADER_VERTEX]);
gl::LinkResult result = compileProgramExecutables(context, infoLog);
if (result.isError())
......
......@@ -18,6 +18,7 @@
#include "libANGLE/Device.h"
#include "libANGLE/Version.h"
#include "libANGLE/WorkerThread.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/formatutilsD3D.h"
......@@ -72,15 +73,6 @@ enum RendererClass
RENDERER_D3D9
};
enum ShaderType
{
SHADER_VERTEX,
SHADER_PIXEL,
SHADER_GEOMETRY,
SHADER_COMPUTE,
SHADER_TYPE_MAX
};
// Useful for unit testing
class BufferFactoryD3D : angle::NonCopyable
{
......@@ -208,13 +200,13 @@ class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitialize
// Shader operations
virtual gl::Error loadExecutable(const uint8_t *function,
size_t length,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) = 0;
ShaderExecutableD3D **outExecutable) = 0;
virtual gl::Error compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds,
......
......@@ -2808,7 +2808,7 @@ gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTarg
gl::Error Renderer11::loadExecutable(const uint8_t *function,
size_t length,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable)
......@@ -2817,7 +2817,7 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function,
switch (type)
{
case SHADER_VERTEX:
case gl::SHADER_VERTEX:
{
d3d11::VertexShader vertexShader;
d3d11::GeometryShader streamOutShader;
......@@ -2848,21 +2848,21 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function,
std::move(streamOutShader));
}
break;
case SHADER_PIXEL:
case gl::SHADER_FRAGMENT:
{
d3d11::PixelShader pixelShader;
ANGLE_TRY(allocateResource(shaderData, &pixelShader));
*outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader));
}
break;
case SHADER_GEOMETRY:
case gl::SHADER_GEOMETRY:
{
d3d11::GeometryShader geometryShader;
ANGLE_TRY(allocateResource(shaderData, &geometryShader));
*outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader));
}
break;
case SHADER_COMPUTE:
case gl::SHADER_COMPUTE:
{
d3d11::ComputeShader computeShader;
ANGLE_TRY(allocateResource(shaderData, &computeShader));
......@@ -2879,7 +2879,7 @@ gl::Error Renderer11::loadExecutable(const uint8_t *function,
gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds,
......@@ -2889,16 +2889,16 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
switch (type)
{
case SHADER_VERTEX:
case gl::SHADER_VERTEX:
profileStream << "vs";
break;
case SHADER_PIXEL:
case gl::SHADER_FRAGMENT:
profileStream << "ps";
break;
case SHADER_GEOMETRY:
case gl::SHADER_GEOMETRY:
profileStream << "gs";
break;
case SHADER_COMPUTE:
case gl::SHADER_COMPUTE:
profileStream << "cs";
break;
default:
......
......@@ -230,13 +230,13 @@ class Renderer11 : public RendererD3D
// Shader operations
gl::Error loadExecutable(const uint8_t *function,
size_t length,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) override;
gl::Error compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds,
......
......@@ -2685,7 +2685,7 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge
gl::Error Renderer9::loadExecutable(const uint8_t *function,
size_t length,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable)
......@@ -2695,7 +2695,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function,
switch (type)
{
case SHADER_VERTEX:
case gl::SHADER_VERTEX:
{
IDirect3DVertexShader9 *vshader = nullptr;
gl::Error error = createVertexShader((DWORD *)function, length, &vshader);
......@@ -2706,7 +2706,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function,
*outExecutable = new ShaderExecutable9(function, length, vshader);
}
break;
case SHADER_PIXEL:
case gl::SHADER_FRAGMENT:
{
IDirect3DPixelShader9 *pshader = nullptr;
gl::Error error = createPixelShader((DWORD *)function, length, &pshader);
......@@ -2727,7 +2727,7 @@ gl::Error Renderer9::loadExecutable(const uint8_t *function,
gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds,
......@@ -2740,10 +2740,10 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
switch (type)
{
case SHADER_VERTEX:
case gl::SHADER_VERTEX:
profileStream << "vs";
break;
case SHADER_PIXEL:
case gl::SHADER_FRAGMENT:
profileStream << "ps";
break;
default:
......
......@@ -247,13 +247,13 @@ class Renderer9 : public RendererD3D
// Shader operations
gl::Error loadExecutable(const uint8_t *function,
size_t length,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
ShaderExecutableD3D **outExecutable) override;
gl::Error compileToExecutable(gl::InfoLog &infoLog,
const std::string &shaderHLSL,
ShaderType type,
gl::ShaderType type,
const std::vector<D3DVarying> &streamOutVaryings,
bool separatedOutputBuffers,
const angle::CompilerWorkaroundsD3D &workarounds,
......
......@@ -1008,7 +1008,7 @@ bool ValidateDispatchCompute(Context *context,
return false;
}
if (program->isLinked() == false || program->getAttachedComputeShader() == nullptr)
if (!program->isLinked() || !program->hasLinkedComputeShader())
{
context->handleError(
InvalidOperation()
......
......@@ -42,6 +42,38 @@ TEST_P(ComputeShaderTest, LinkComputeProgram)
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.
TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError)
{
......
......@@ -423,9 +423,11 @@ TEST_P(ProgramBinaryES31Test, ProgramBinaryWithComputeShader)
// Load a new program with the binary.
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();
}
......
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