Commit f92fc916 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Compute shader support

A DispatchHelper class is created as the equivalent of FramebufferHelper as a command graph resource. There's currently a single dispatcher and all dispatch calls are recorded on that. Context dirty bits are set up in such a way that graphics and compute workloads are independently handled, so that issuing a dispatch call wouldn't cause a framebuffer's render pass to rebind resources. Bug: angleproject:3562 Change-Id: Ib96db48297074d99b04324e44b067cfbfd43e333 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1688504 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 6e7dd1ef
...@@ -1429,6 +1429,16 @@ bool TCompiler::isVaryingDefined(const char *varyingName) ...@@ -1429,6 +1429,16 @@ bool TCompiler::isVaryingDefined(const char *varyingName)
return false; return false;
} }
void EmitWorkGroupSizeGLSL(const TCompiler &compiler, TInfoSinkBase &sink)
{
if (compiler.isComputeShaderLocalSizeDeclared())
{
const sh::WorkGroupSize &localSize = compiler.getComputeShaderLocalSize();
sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
<< ", local_size_z=" << localSize[2] << ") in;\n";
}
}
void EmitMultiviewGLSL(const TCompiler &compiler, void EmitMultiviewGLSL(const TCompiler &compiler,
const ShCompileOptions &compileOptions, const ShCompileOptions &compileOptions,
const TBehavior behavior, const TBehavior behavior,
......
...@@ -296,6 +296,7 @@ class TCompiler : public TShHandleBase ...@@ -296,6 +296,7 @@ class TCompiler : public TShHandleBase
TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
void DeleteCompiler(TCompiler *); void DeleteCompiler(TCompiler *);
void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink);
void EmitMultiviewGLSL(const TCompiler &, const ShCompileOptions &, TBehavior, TInfoSinkBase &sink); void EmitMultiviewGLSL(const TCompiler &, const ShCompileOptions &, TBehavior, TInfoSinkBase &sink);
} // namespace sh } // namespace sh
......
...@@ -84,11 +84,9 @@ void TranslatorESSL::translate(TIntermBlock *root, ...@@ -84,11 +84,9 @@ void TranslatorESSL::translate(TIntermBlock *root,
// Write array bounds clamping emulation if needed. // Write array bounds clamping emulation if needed.
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink); getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) if (getShaderType() == GL_COMPUTE_SHADER)
{ {
const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); EmitWorkGroupSizeGLSL(*this, sink);
sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
<< ", local_size_z=" << localSize[2] << ") in;\n";
} }
if (getShaderType() == GL_GEOMETRY_SHADER_EXT) if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
......
...@@ -194,11 +194,9 @@ void TranslatorGLSL::translate(TIntermBlock *root, ...@@ -194,11 +194,9 @@ void TranslatorGLSL::translate(TIntermBlock *root,
} }
} }
if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) if (getShaderType() == GL_COMPUTE_SHADER)
{ {
const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); EmitWorkGroupSizeGLSL(*this, sink);
sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
<< ", local_size_z=" << localSize[2] << ") in;\n";
} }
if (getShaderType() == GL_GEOMETRY_SHADER_EXT) if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
......
...@@ -692,9 +692,12 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -692,9 +692,12 @@ void TranslatorVulkan::translate(TIntermBlock *root,
sink << "};\n"; sink << "};\n";
} }
const TVariable *driverUniforms = AddDriverUniformsToShader(root, &getSymbolTable()); const TVariable *driverUniforms = nullptr;
if (getShaderType() != GL_COMPUTE_SHADER)
ReplaceGLDepthRangeWithDriverUniform(root, driverUniforms, &getSymbolTable()); {
driverUniforms = AddDriverUniformsToShader(root, &getSymbolTable());
ReplaceGLDepthRangeWithDriverUniform(root, driverUniforms, &getSymbolTable());
}
// Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
// if it's core profile shaders and they are used. // if it's core profile shaders and they are used.
...@@ -775,10 +778,8 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -775,10 +778,8 @@ void TranslatorVulkan::translate(TIntermBlock *root,
RewriteDfdy(root, getSymbolTable(), getShaderVersion(), viewportYScale); RewriteDfdy(root, getSymbolTable(), getShaderVersion(), viewportYScale);
} }
} }
else else if (getShaderType() == GL_VERTEX_SHADER)
{ {
ASSERT(getShaderType() == GL_VERTEX_SHADER);
AddANGLEPositionVarying(root, &getSymbolTable()); AddANGLEPositionVarying(root, &getSymbolTable());
// Add a macro to declare transform feedback buffers. // Add a macro to declare transform feedback buffers.
...@@ -790,6 +791,11 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -790,6 +791,11 @@ void TranslatorVulkan::translate(TIntermBlock *root,
// Append depth range translation to main. // Append depth range translation to main.
AppendVertexShaderDepthCorrectionToMain(root, &getSymbolTable()); AppendVertexShaderDepthCorrectionToMain(root, &getSymbolTable());
} }
else
{
ASSERT(getShaderType() == GL_COMPUTE_SHADER);
EmitWorkGroupSizeGLSL(*this, sink);
}
// Write translated shader. // Write translated shader.
root->traverse(&outputGLSL); root->traverse(&outputGLSL);
......
...@@ -3344,18 +3344,22 @@ void Context::initCaps() ...@@ -3344,18 +3344,22 @@ void Context::initCaps()
// Limit textures as well, so we can use fast bitsets with texture bindings. // Limit textures as well, so we can use fast bitsets with texture bindings.
LimitCap(&mState.mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES); LimitCap(&mState.mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
LimitCap(&mState.mCaps.maxShaderTextureImageUnits[ShaderType::Vertex], for (ShaderType shaderType : AllShaderTypes())
IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2); {
LimitCap(&mState.mCaps.maxShaderTextureImageUnits[ShaderType::Fragment], LimitCap(&mState.mCaps.maxShaderTextureImageUnits[shaderType],
IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2); IMPLEMENTATION_MAX_SHADER_TEXTURES);
}
LimitCap(&mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS); LimitCap(&mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS);
LimitCap(&mState.mCaps.maxCombinedAtomicCounterBuffers, LimitCap(&mState.mCaps.maxCombinedAtomicCounterBuffers,
IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS); IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS);
LimitCap(&mState.mCaps.maxShaderStorageBlocks[ShaderType::Compute], for (ShaderType shaderType : AllShaderTypes())
IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS); {
LimitCap(&mState.mCaps.maxShaderStorageBlocks[shaderType],
IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
}
LimitCap(&mState.mCaps.maxShaderStorageBufferBindings, LimitCap(&mState.mCaps.maxShaderStorageBufferBindings,
IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS); IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
LimitCap(&mState.mCaps.maxCombinedShaderStorageBlocks, LimitCap(&mState.mCaps.maxCombinedShaderStorageBlocks,
......
...@@ -384,9 +384,10 @@ class ProgramState final : angle::NonCopyable ...@@ -384,9 +384,10 @@ class ProgramState final : angle::NonCopyable
const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; }
bool hasLinkedShaderStage(ShaderType shaderType) const bool hasLinkedShaderStage(ShaderType shaderType) const
{ {
return mLinkedShaderStages.test(shaderType); return mLinkedShaderStages[shaderType];
} }
size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); } size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); }
bool isCompute() const { return hasLinkedShaderStage(ShaderType::Compute); }
bool hasAttachedShader() const; bool hasAttachedShader() const;
...@@ -588,8 +589,9 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -588,8 +589,9 @@ class Program final : angle::NonCopyable, public LabeledObject
bool hasLinkedShaderStage(ShaderType shaderType) const bool hasLinkedShaderStage(ShaderType shaderType) const
{ {
ASSERT(shaderType != ShaderType::InvalidEnum); ASSERT(shaderType != ShaderType::InvalidEnum);
return mState.mLinkedShaderStages[shaderType]; return mState.hasLinkedShaderStage(shaderType);
} }
bool isCompute() const { return mState.isCompute(); }
angle::Result loadBinary(const Context *context, angle::Result loadBinary(const Context *context,
GLenum binaryFormat, GLenum binaryFormat,
......
...@@ -231,10 +231,16 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, ...@@ -231,10 +231,16 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk,
angle::Result BufferVk::unmap(const gl::Context *context, GLboolean *result) angle::Result BufferVk::unmap(const gl::Context *context, GLboolean *result)
{ {
return unmapImpl(vk::GetImpl(context)); unmapImpl(vk::GetImpl(context));
// This should be false if the contents have been corrupted through external means. Vulkan
// doesn't provide such information.
*result = true;
return angle::Result::Continue;
} }
angle::Result BufferVk::unmapImpl(ContextVk *contextVk) void BufferVk::unmapImpl(ContextVk *contextVk)
{ {
ASSERT(mBuffer.valid()); ASSERT(mBuffer.valid());
...@@ -242,8 +248,6 @@ angle::Result BufferVk::unmapImpl(ContextVk *contextVk) ...@@ -242,8 +248,6 @@ angle::Result BufferVk::unmapImpl(ContextVk *contextVk)
mBuffer.onExternalWrite(VK_ACCESS_HOST_WRITE_BIT); mBuffer.onExternalWrite(VK_ACCESS_HOST_WRITE_BIT);
markConversionBuffersDirty(); markConversionBuffersDirty();
return angle::Result::Continue;
} }
angle::Result BufferVk::getIndexRange(const gl::Context *context, angle::Result BufferVk::getIndexRange(const gl::Context *context,
......
...@@ -97,7 +97,7 @@ class BufferVk : public BufferImpl ...@@ -97,7 +97,7 @@ class BufferVk : public BufferImpl
VkDeviceSize length, VkDeviceSize length,
GLbitfield access, GLbitfield access,
void **mapPtr); void **mapPtr);
angle::Result unmapImpl(ContextVk *contextVk); void unmapImpl(ContextVk *contextVk);
// Calls copyBuffer internally. // Calls copyBuffer internally.
angle::Result copyToBuffer(ContextVk *contextVk, angle::Result copyToBuffer(ContextVk *contextVk,
......
...@@ -88,6 +88,8 @@ const char *GetResourceTypeName(CommandGraphResourceType resourceType, ...@@ -88,6 +88,8 @@ const char *GetResourceTypeName(CommandGraphResourceType resourceType,
UNREACHABLE(); UNREACHABLE();
return "Query"; return "Query";
} }
case CommandGraphResourceType::Dispatcher:
return "Dispatcher";
case CommandGraphResourceType::EmulatedQuery: case CommandGraphResourceType::EmulatedQuery:
switch (function) switch (function)
{ {
...@@ -1032,6 +1034,7 @@ void CommandGraph::dumpGraphDotFile(std::ostream &out) const ...@@ -1032,6 +1034,7 @@ void CommandGraph::dumpGraphDotFile(std::ostream &out) const
int framebufferIDCounter = 1; int framebufferIDCounter = 1;
int imageIDCounter = 1; int imageIDCounter = 1;
int queryIDCounter = 1; int queryIDCounter = 1;
int dispatcherIDCounter = 1;
int fenceIDCounter = 1; int fenceIDCounter = 1;
int xfbIDCounter = 1; int xfbIDCounter = 1;
...@@ -1107,6 +1110,9 @@ void CommandGraph::dumpGraphDotFile(std::ostream &out) const ...@@ -1107,6 +1110,9 @@ void CommandGraph::dumpGraphDotFile(std::ostream &out) const
case CommandGraphResourceType::Image: case CommandGraphResourceType::Image:
id = imageIDCounter++; id = imageIDCounter++;
break; break;
case CommandGraphResourceType::Dispatcher:
id = dispatcherIDCounter++;
break;
case CommandGraphResourceType::FenceSync: case CommandGraphResourceType::FenceSync:
id = fenceIDCounter++; id = fenceIDCounter++;
break; break;
......
...@@ -32,6 +32,7 @@ enum class CommandGraphResourceType ...@@ -32,6 +32,7 @@ enum class CommandGraphResourceType
Framebuffer, Framebuffer,
Image, Image,
Query, Query,
Dispatcher,
// Transform feedback queries could be handled entirely on the CPU (if not using // Transform feedback queries could be handled entirely on the CPU (if not using
// VK_EXT_transform_feedback), but still need to generate a command graph barrier node. // VK_EXT_transform_feedback), but still need to generate a command graph barrier node.
EmulatedQuery, EmulatedQuery,
......
...@@ -331,6 +331,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -331,6 +331,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers; std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
angle::Result setupDraw(const gl::Context *context, angle::Result setupDraw(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
...@@ -356,6 +357,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -356,6 +357,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
const void *indices, const void *indices,
vk::CommandBuffer **commandBufferOut, vk::CommandBuffer **commandBufferOut,
size_t *numIndicesOut); size_t *numIndicesOut);
angle::Result setupDispatch(const gl::Context *context, vk::CommandBuffer **commandBufferOut);
void updateViewport(FramebufferVk *framebufferVk, void updateViewport(FramebufferVk *framebufferVk,
const gl::Rectangle &viewport, const gl::Rectangle &viewport,
...@@ -367,13 +369,19 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -367,13 +369,19 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
void updateFlipViewportDrawFramebuffer(const gl::State &glState); void updateFlipViewportDrawFramebuffer(const gl::State &glState);
void updateFlipViewportReadFramebuffer(const gl::State &glState); void updateFlipViewportReadFramebuffer(const gl::State &glState);
angle::Result updateActiveTextures(const gl::Context *context); angle::Result updateActiveTextures(const gl::Context *context,
vk::CommandGraphResource *recorder);
angle::Result updateDefaultAttribute(size_t attribIndex); angle::Result updateDefaultAttribute(size_t attribIndex);
ANGLE_INLINE void invalidateCurrentGraphicsPipeline() ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
{ {
mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE); mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE);
} }
ANGLE_INLINE void invalidateCurrentComputePipeline()
{
mComputeDirtyBits.set(DIRTY_BIT_PIPELINE);
mCurrentComputePipeline = nullptr;
}
void invalidateCurrentTextures(); void invalidateCurrentTextures();
void invalidateCurrentUniformAndStorageBuffers(); void invalidateCurrentUniformAndStorageBuffers();
...@@ -399,6 +407,24 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -399,6 +407,24 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
angle::Result handleDirtyGraphicsDescriptorSets(const gl::Context *context, angle::Result handleDirtyGraphicsDescriptorSets(const gl::Context *context,
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
// Handlers for compute pipeline dirty bits.
angle::Result handleDirtyComputePipeline(const gl::Context *context,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyComputeTextures(const gl::Context *context,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyComputeUniformAndStorageBuffers(const gl::Context *context,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyComputeDescriptorSets(const gl::Context *context,
vk::CommandBuffer *commandBuffer);
// Common parts of the common dirty bit handlers.
angle::Result handleDirtyTexturesImpl(const gl::Context *context,
vk::CommandBuffer *commandBuffer,
vk::CommandGraphResource *recorder);
angle::Result handleDirtyUniformAndStorageBuffersImpl(const gl::Context *context,
vk::CommandBuffer *commandBuffer,
vk::CommandGraphResource *recorder);
angle::Result submitFrame(const VkSubmitInfo &submitInfo, angle::Result submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer); vk::PrimaryCommandBuffer &&commandBuffer);
void freeAllInFlightResources(); void freeAllInFlightResources();
...@@ -416,6 +442,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -416,6 +442,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
void waitForSwapchainImageIfNecessary(); void waitForSwapchainImageIfNecessary();
vk::PipelineHelper *mCurrentGraphicsPipeline; vk::PipelineHelper *mCurrentGraphicsPipeline;
vk::PipelineAndSerial *mCurrentComputePipeline;
gl::PrimitiveMode mCurrentDrawMode; gl::PrimitiveMode mCurrentDrawMode;
WindowSurfaceVk *mCurrentWindowSurface; WindowSurfaceVk *mCurrentWindowSurface;
...@@ -434,15 +461,20 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -434,15 +461,20 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
// Dirty bits. // Dirty bits.
DirtyBits mGraphicsDirtyBits; DirtyBits mGraphicsDirtyBits;
DirtyBits mComputeDirtyBits;
DirtyBits mNonIndexedDirtyBitsMask; DirtyBits mNonIndexedDirtyBitsMask;
DirtyBits mIndexedDirtyBitsMask; DirtyBits mIndexedDirtyBitsMask;
DirtyBits mNewGraphicsCommandBufferDirtyBits; DirtyBits mNewGraphicsCommandBufferDirtyBits;
DirtyBits mNewComputeCommandBufferDirtyBits;
// Cached back-end objects. // Cached back-end objects.
VertexArrayVk *mVertexArray; VertexArrayVk *mVertexArray;
FramebufferVk *mDrawFramebuffer; FramebufferVk *mDrawFramebuffer;
ProgramVk *mProgram; ProgramVk *mProgram;
// Graph resource used to record dispatch commands and hold resource dependencies.
vk::DispatchHelper mDispatcher;
// The offset we had the last time we bound the index buffer. // The offset we had the last time we bound the index buffer.
const GLvoid *mLastIndexBufferOffset; const GLvoid *mLastIndexBufferOffset;
gl::DrawElementsType mCurrentDrawElementsType; gl::DrawElementsType mCurrentDrawElementsType;
......
...@@ -24,24 +24,19 @@ class GlslangWrapper ...@@ -24,24 +24,19 @@ class GlslangWrapper
static void GetShaderSource(const gl::ProgramState &programState, static void GetShaderSource(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
std::string *vertexSourceOut, gl::ShaderMap<std::string> *shaderSourcesOut);
std::string *fragmentSourceOut);
static angle::Result GetShaderCode(vk::Context *context, static angle::Result GetShaderCode(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableLineRasterEmulation, bool enableLineRasterEmulation,
const std::string &vertexSource, const gl::ShaderMap<std::string> &shaderSources,
const std::string &fragmentSource, gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut);
private: private:
static angle::Result GetShaderCodeImpl(vk::Context *context, static angle::Result GetShaderCodeImpl(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const std::string &vertexSource, const gl::ShaderMap<std::string> &shaderSources,
const std::string &fragmentSource, gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut);
}; };
} // namespace rx } // namespace rx
......
...@@ -195,25 +195,26 @@ ProgramVk::ShaderInfo::ShaderInfo() {} ...@@ -195,25 +195,26 @@ ProgramVk::ShaderInfo::ShaderInfo() {}
ProgramVk::ShaderInfo::~ShaderInfo() = default; ProgramVk::ShaderInfo::~ShaderInfo() = default;
angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk, angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk,
const std::string &vertexSource, const gl::ShaderMap<std::string> &shaderSources,
const std::string &fragmentSource,
bool enableLineRasterEmulation) bool enableLineRasterEmulation)
{ {
ASSERT(!valid()); ASSERT(!valid());
std::vector<uint32_t> vertexCode; gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
std::vector<uint32_t> fragmentCode; ANGLE_TRY(GlslangWrapper::GetShaderCode(
ANGLE_TRY(GlslangWrapper::GetShaderCode(contextVk, contextVk->getCaps(), contextVk, contextVk->getCaps(), enableLineRasterEmulation, shaderSources, &shaderCodes));
enableLineRasterEmulation, vertexSource, fragmentSource,
&vertexCode, &fragmentCode));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[gl::ShaderType::Vertex].get(), for (const gl::ShaderType shaderType : gl::AllShaderTypes())
vertexCode.data(), vertexCode.size() * sizeof(uint32_t))); {
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[gl::ShaderType::Fragment].get(), if (!shaderSources[shaderType].empty())
fragmentCode.data(), fragmentCode.size() * sizeof(uint32_t))); {
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[shaderType].get(),
shaderCodes[shaderType].data(),
shaderCodes[shaderType].size() * sizeof(uint32_t)));
mProgramHelper.setShader(gl::ShaderType::Vertex, &mShaders[gl::ShaderType::Vertex]); mProgramHelper.setShader(shaderType, &mShaders[shaderType]);
mProgramHelper.setShader(gl::ShaderType::Fragment, &mShaders[gl::ShaderType::Fragment]); }
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -223,7 +224,7 @@ angle::Result ProgramVk::loadShaderSource(ContextVk *contextVk, gl::BinaryInputS ...@@ -223,7 +224,7 @@ angle::Result ProgramVk::loadShaderSource(ContextVk *contextVk, gl::BinaryInputS
// Read in shader sources for all shader types // Read in shader sources for all shader types
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
mShaderSource[shaderType] = stream->readString(); mShaderSources[shaderType] = stream->readString();
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -234,7 +235,7 @@ void ProgramVk::saveShaderSource(gl::BinaryOutputStream *stream) ...@@ -234,7 +235,7 @@ void ProgramVk::saveShaderSource(gl::BinaryOutputStream *stream)
// Write out shader sources for all shader types // Write out shader sources for all shader types
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
stream->writeString(mShaderSource[shaderType]); stream->writeString(mShaderSources[shaderType]);
} }
} }
...@@ -338,8 +339,7 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context, ...@@ -338,8 +339,7 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
// assignment done in that function. // assignment done in that function.
linkResources(resources); linkResources(resources);
GlslangWrapper::GetShaderSource(mState, resources, &mShaderSource[gl::ShaderType::Vertex], GlslangWrapper::GetShaderSource(mState, resources, &mShaderSources);
&mShaderSource[gl::ShaderType::Fragment]);
// TODO(jie.a.chen@intel.com): Parallelize linking. // TODO(jie.a.chen@intel.com): Parallelize linking.
// http://crbug.com/849576 // http://crbug.com/849576
...@@ -1013,7 +1013,7 @@ void ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk) ...@@ -1013,7 +1013,7 @@ void ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
} }
void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk, void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk, vk::CommandGraphResource *recorder,
const std::vector<gl::InterfaceBlock> &blocks, const std::vector<gl::InterfaceBlock> &blocks,
VkDescriptorType descriptorType) VkDescriptorType descriptorType)
{ {
...@@ -1074,19 +1074,23 @@ void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -1074,19 +1074,23 @@ void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk,
if (isStorageBuffer) if (isStorageBuffer)
{ {
bufferHelper.onWrite(contextVk, framebufferVk, VK_ACCESS_SHADER_READ_BIT, bufferHelper.onWrite(contextVk, recorder, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT); VK_ACCESS_SHADER_WRITE_BIT);
} }
else else
{ {
bufferHelper.onRead(framebufferVk, VK_ACCESS_UNIFORM_READ_BIT); bufferHelper.onRead(recorder, VK_ACCESS_UNIFORM_READ_BIT);
} }
// If size is 0, we can't always use VK_WHOLE_SIZE (or bufferHelper.getSize()), as the // If size is 0, we can't always use VK_WHOLE_SIZE (or bufferHelper.getSize()), as the
// backing buffer may be larger than max*BufferRange. In that case, we use the minimum of // backing buffer may be larger than max*BufferRange. In that case, we use the minimum of
// the backing buffer size (what's left after offset) and the buffer size as defined by the // the backing buffer size (what's left after offset) and the buffer size as defined by the
// shader. // shader. That latter is only valid for UBOs, as SSBOs may have variable length arrays.
size = std::min(size > 0 ? size : (bufferHelper.getSize() - offset), blockSize); size = size > 0 ? size : (bufferHelper.getSize() - offset);
if (!isStorageBuffer)
{
size = std::min(size, blockSize);
}
VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[writeCount]; VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[writeCount];
...@@ -1118,13 +1122,13 @@ void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -1118,13 +1122,13 @@ void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk,
angle::Result ProgramVk::updateUniformAndStorageBuffersDescriptorSet( angle::Result ProgramVk::updateUniformAndStorageBuffersDescriptorSet(
ContextVk *contextVk, ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk) vk::CommandGraphResource *recorder)
{ {
ANGLE_TRY(allocateDescriptorSet(contextVk, kBufferDescriptorSetIndex)); ANGLE_TRY(allocateDescriptorSet(contextVk, kBufferDescriptorSetIndex));
updateBuffersDescriptorSet(contextVk, framebufferVk, mState.getUniformBlocks(), updateBuffersDescriptorSet(contextVk, recorder, mState.getUniformBlocks(),
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
updateBuffersDescriptorSet(contextVk, framebufferVk, mState.getShaderStorageBlocks(), updateBuffersDescriptorSet(contextVk, recorder, mState.getShaderStorageBlocks(),
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
return angle::Result::Continue; return angle::Result::Continue;
...@@ -1163,8 +1167,7 @@ void ProgramVk::updateTransformFeedbackDescriptorSetImpl(ContextVk *contextVk) ...@@ -1163,8 +1167,7 @@ void ProgramVk::updateTransformFeedbackDescriptorSetImpl(ContextVk *contextVk)
mDescriptorSets[kUniformsAndXfbDescriptorSetIndex]); mDescriptorSets[kUniformsAndXfbDescriptorSetIndex]);
} }
angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk, angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
vk::FramebufferHelper *framebuffer)
{ {
const vk::TextureDescriptorDesc &texturesDesc = contextVk->getActiveTexturesDesc(); const vk::TextureDescriptorDesc &texturesDesc = contextVk->getActiveTexturesDesc();
...@@ -1272,6 +1275,9 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk, ...@@ -1272,6 +1275,9 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
} }
} }
const VkPipelineBindPoint pipelineBindPoint =
mState.isCompute() ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
for (size_t descriptorSetIndex = 0; descriptorSetIndex < descriptorSetRange; for (size_t descriptorSetIndex = 0; descriptorSetIndex < descriptorSetRange;
++descriptorSetIndex) ++descriptorSetIndex)
{ {
...@@ -1305,7 +1311,7 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk, ...@@ -1305,7 +1311,7 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
descriptorSetIndex == kUniformsAndXfbDescriptorSetIndex ? mDynamicBufferOffsets.size() descriptorSetIndex == kUniformsAndXfbDescriptorSetIndex ? mDynamicBufferOffsets.size()
: 0; : 0;
commandBuffer->bindDescriptorSets(mPipelineLayout.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, commandBuffer->bindDescriptorSets(mPipelineLayout.get(), pipelineBindPoint,
descriptorSetIndex, 1, &descSet, uniformBlockOffsetCount, descriptorSetIndex, 1, &descSet, uniformBlockOffsetCount,
mDynamicBufferOffsets.data()); mDynamicBufferOffsets.data());
} }
......
...@@ -106,10 +106,9 @@ class ProgramVk : public ProgramImpl ...@@ -106,10 +106,9 @@ class ProgramVk : public ProgramImpl
// Also initializes the pipeline layout, descriptor set layouts, and used descriptor ranges. // Also initializes the pipeline layout, descriptor set layouts, and used descriptor ranges.
angle::Result updateUniforms(ContextVk *contextVk); angle::Result updateUniforms(ContextVk *contextVk);
angle::Result updateTexturesDescriptorSet(ContextVk *contextVk, angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
vk::FramebufferHelper *framebuffer);
angle::Result updateUniformAndStorageBuffersDescriptorSet(ContextVk *contextVk, angle::Result updateUniformAndStorageBuffersDescriptorSet(ContextVk *contextVk,
vk::FramebufferHelper *framebuffer); vk::CommandGraphResource *recorder);
angle::Result updateTransformFeedbackDescriptorSet(ContextVk *contextVk, angle::Result updateTransformFeedbackDescriptorSet(ContextVk *contextVk,
vk::FramebufferHelper *framebuffer); vk::FramebufferHelper *framebuffer);
...@@ -138,7 +137,7 @@ class ProgramVk : public ProgramImpl ...@@ -138,7 +137,7 @@ class ProgramVk : public ProgramImpl
vk::PipelineHelper **pipelineOut) vk::PipelineHelper **pipelineOut)
{ {
vk::ShaderProgramHelper *shaderProgram; vk::ShaderProgramHelper *shaderProgram;
ANGLE_TRY(initShaders(contextVk, mode, &shaderProgram)); ANGLE_TRY(initGraphicsShaders(contextVk, mode, &shaderProgram));
ASSERT(shaderProgram->isGraphicsProgram()); ASSERT(shaderProgram->isGraphicsProgram());
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
return shaderProgram->getGraphicsPipeline( return shaderProgram->getGraphicsPipeline(
...@@ -147,6 +146,14 @@ class ProgramVk : public ProgramImpl ...@@ -147,6 +146,14 @@ class ProgramVk : public ProgramImpl
mState.getAttributesTypeMask(), descPtrOut, pipelineOut); mState.getAttributesTypeMask(), descPtrOut, pipelineOut);
} }
angle::Result getComputePipeline(ContextVk *contextVk, vk::PipelineAndSerial **pipelineOut)
{
vk::ShaderProgramHelper *shaderProgram;
ANGLE_TRY(initComputeShader(contextVk, &shaderProgram));
ASSERT(!shaderProgram->isGraphicsProgram());
return shaderProgram->getComputePipeline(contextVk, mPipelineLayout.get(), pipelineOut);
}
// Used in testing only. // Used in testing only.
vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t poolIndex) vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t poolIndex)
{ {
...@@ -170,7 +177,7 @@ class ProgramVk : public ProgramImpl ...@@ -170,7 +177,7 @@ class ProgramVk : public ProgramImpl
void updateDefaultUniformsDescriptorSet(ContextVk *contextVk); void updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
void updateTransformFeedbackDescriptorSetImpl(ContextVk *contextVk); void updateTransformFeedbackDescriptorSetImpl(ContextVk *contextVk);
void updateBuffersDescriptorSet(ContextVk *contextVk, void updateBuffersDescriptorSet(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk, vk::CommandGraphResource *recorder,
const std::vector<gl::InterfaceBlock> &blocks, const std::vector<gl::InterfaceBlock> &blocks,
VkDescriptorType descriptorType); VkDescriptorType descriptorType);
...@@ -186,26 +193,40 @@ class ProgramVk : public ProgramImpl ...@@ -186,26 +193,40 @@ class ProgramVk : public ProgramImpl
uint32_t getUniformBlockBindingsOffset() const { return 0; } uint32_t getUniformBlockBindingsOffset() const { return 0; }
uint32_t getStorageBlockBindingsOffset() const { return mStorageBlockBindingsOffset; } uint32_t getStorageBlockBindingsOffset() const { return mStorageBlockBindingsOffset; }
class ShaderInfo;
ANGLE_INLINE angle::Result initShaders(ContextVk *contextVk, ANGLE_INLINE angle::Result initShaders(ContextVk *contextVk,
gl::PrimitiveMode mode, bool enableLineRasterEmulation,
ShaderInfo *shaderInfo,
vk::ShaderProgramHelper **shaderProgramOut) vk::ShaderProgramHelper **shaderProgramOut)
{ {
if (!shaderInfo->valid())
{
ANGLE_TRY(
shaderInfo->initShaders(contextVk, mShaderSources, enableLineRasterEmulation));
}
ASSERT(shaderInfo->valid());
*shaderProgramOut = &shaderInfo->getShaderProgram();
return angle::Result::Continue;
}
ANGLE_INLINE angle::Result initGraphicsShaders(ContextVk *contextVk,
gl::PrimitiveMode mode,
vk::ShaderProgramHelper **shaderProgramOut)
{
bool enableLineRasterEmulation = UseLineRaster(contextVk, mode); bool enableLineRasterEmulation = UseLineRaster(contextVk, mode);
ShaderInfo &shaderInfo = ShaderInfo &shaderInfo =
enableLineRasterEmulation ? mLineRasterShaderInfo : mDefaultShaderInfo; enableLineRasterEmulation ? mLineRasterShaderInfo : mDefaultShaderInfo;
if (!shaderInfo.valid()) return initShaders(contextVk, enableLineRasterEmulation, &shaderInfo, shaderProgramOut);
{ }
ANGLE_TRY(shaderInfo.initShaders(contextVk, mShaderSource[gl::ShaderType::Vertex],
mShaderSource[gl::ShaderType::Fragment],
enableLineRasterEmulation));
}
ASSERT(shaderInfo.valid());
*shaderProgramOut = &shaderInfo.getShaderProgram();
return angle::Result::Continue; ANGLE_INLINE angle::Result initComputeShader(ContextVk *contextVk,
vk::ShaderProgramHelper **shaderProgramOut)
{
return initShaders(contextVk, false, &mDefaultShaderInfo, shaderProgramOut);
} }
// Save and load implementation for GLES Program Binary support. // Save and load implementation for GLES Program Binary support.
...@@ -260,12 +281,15 @@ class ProgramVk : public ProgramImpl ...@@ -260,12 +281,15 @@ class ProgramVk : public ProgramImpl
~ShaderInfo(); ~ShaderInfo();
angle::Result initShaders(ContextVk *contextVk, angle::Result initShaders(ContextVk *contextVk,
const std::string &vertexSource, const gl::ShaderMap<std::string> &shaderSources,
const std::string &fragmentSource,
bool enableLineRasterEmulation); bool enableLineRasterEmulation);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
ANGLE_INLINE bool valid() const { return mShaders[gl::ShaderType::Vertex].get().valid(); } ANGLE_INLINE bool valid() const
{
return mShaders[gl::ShaderType::Vertex].get().valid() ||
mShaders[gl::ShaderType::Compute].get().valid();
}
vk::ShaderProgramHelper &getShaderProgram() { return mProgramHelper; } vk::ShaderProgramHelper &getShaderProgram() { return mProgramHelper; }
...@@ -278,7 +302,7 @@ class ProgramVk : public ProgramImpl ...@@ -278,7 +302,7 @@ class ProgramVk : public ProgramImpl
ShaderInfo mLineRasterShaderInfo; ShaderInfo mLineRasterShaderInfo;
// We keep the translated linked shader sources to use with shader draw call patching. // We keep the translated linked shader sources to use with shader draw call patching.
gl::ShaderMap<std::string> mShaderSource; gl::ShaderMap<std::string> mShaderSources;
// Storage buffers are placed after uniform buffers in their descriptor set. This cached value // Storage buffers are placed after uniform buffers in their descriptor set. This cached value
// contains the offset where storage buffer bindings start. // contains the offset where storage buffer bindings start.
......
...@@ -304,7 +304,7 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk, ...@@ -304,7 +304,7 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
0, numVertices, binding.getStride(), vertexFormat.vertexLoadFunction, 0, numVertices, binding.getStride(), vertexFormat.vertexLoadFunction,
&mCurrentArrayBuffers[attribIndex], &mCurrentArrayBuffers[attribIndex],
&conversion->lastAllocationOffset)); &conversion->lastAllocationOffset));
ANGLE_TRY(srcBuffer->unmapImpl(contextVk)); srcBuffer->unmapImpl(contextVk);
ASSERT(conversion->dirty); ASSERT(conversion->dirty);
conversion->dirty = false; conversion->dirty = false;
......
...@@ -1136,7 +1136,7 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con ...@@ -1136,7 +1136,7 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con
ANGLE_TRY(streamIndices(contextVk, glIndexType, indexCount, ANGLE_TRY(streamIndices(contextVk, glIndexType, indexCount,
static_cast<const uint8_t *>(srcDataMapping) + elementArrayOffset, static_cast<const uint8_t *>(srcDataMapping) + elementArrayOffset,
bufferOut, bufferOffsetOut, indexCountOut)); bufferOut, bufferOffsetOut, indexCountOut));
ANGLE_TRY(elementArrayBufferVk->unmapImpl(contextVk)); elementArrayBufferVk->unmapImpl(contextVk);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2628,6 +2628,11 @@ void FramebufferHelper::release(ContextVk *contextVk) ...@@ -2628,6 +2628,11 @@ void FramebufferHelper::release(ContextVk *contextVk)
contextVk->releaseObject(getStoredQueueSerial(), &mFramebuffer); contextVk->releaseObject(getStoredQueueSerial(), &mFramebuffer);
} }
// FramebufferHelper implementation.
DispatchHelper::DispatchHelper() : CommandGraphResource(CommandGraphResourceType::Dispatcher) {}
DispatchHelper::~DispatchHelper() = default;
// ShaderProgramHelper implementation. // ShaderProgramHelper implementation.
ShaderProgramHelper::ShaderProgramHelper() = default; ShaderProgramHelper::ShaderProgramHelper() = default;
......
...@@ -970,6 +970,15 @@ class FramebufferHelper : public CommandGraphResource ...@@ -970,6 +970,15 @@ class FramebufferHelper : public CommandGraphResource
Framebuffer mFramebuffer; Framebuffer mFramebuffer;
}; };
// A special command graph resource to hold resource dependencies for dispatch calls. It's the
// equivalent of FramebufferHelper, though it doesn't contain a Vulkan object.
class DispatchHelper : public CommandGraphResource
{
public:
DispatchHelper();
~DispatchHelper() override;
};
class ShaderProgramHelper : angle::NonCopyable class ShaderProgramHelper : angle::NonCopyable
{ {
public: public:
......
...@@ -627,17 +627,17 @@ ...@@ -627,17 +627,17 @@
// GL_MIN/MAX_PROGRAM_TEXTURE_GATHER_OFFSET not set. // GL_MIN/MAX_PROGRAM_TEXTURE_GATHER_OFFSET not set.
3605 VULKAN : dEQP-GLES31.functional.texture.gather.offset.* = FAIL 3605 VULKAN : dEQP-GLES31.functional.texture.gather.offset.* = FAIL
// Compute shaders: // Front-end query bugs:
3562 VULKAN : dEQP-GLES31.functional.shaders.builtin_var.compute.* = FAIL 3520 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_*query = FAIL
3562 VULKAN : dEQP-GLES31.functional.compute.* = FAIL 3520 VULKAN : dEQP-GLES31.functional.program_interface_query.program_*.resource_list.compute.empty = FAIL
3566 VULKAN : dEQP-GLES31.functional.ssbo.* = FAIL 3520 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL
3561 VULKAN : dEQP-GLES31.functional.synchronization.*.ssbo* = FAIL
3562 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.common.*compute = FAIL // glMemoryBarrier support:
3562 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.precision*compute* = FAIL 3574 VULKAN : dEQP-GLES31.functional.compute.*barrier* = SKIP
3563 VULKAN : dEQP-GLES31.functional.state_query.*compute* = SKIP 3574 VULKAN : dEQP-GLES31.functional.synchronization.*memory_barrier* = SKIP
3562 VULKAN : dEQP-GLES31.functional.state_query.program.compute_work_group_size_get_programiv = FAIL
3562 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_*query = FAIL // Indirect dispatch:
3562 VULKAN : dEQP-GLES31.functional.program_interface_query.program_*.resource_list.compute.empty = FAIL 3601 VULKAN : dEQP-GLES31.functional.compute.*indirect* = SKIP
// Shader support: // Shader support:
3569 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.* = FAIL 3569 VULKAN : dEQP-GLES31.functional.shaders.builtin_functions.common.frexp.* = FAIL
...@@ -655,10 +655,14 @@ ...@@ -655,10 +655,14 @@
3569 VULKAN : dEQP-GLES31.functional.shaders.builtin_constants.core.min_program_texel_offset = FAIL 3569 VULKAN : dEQP-GLES31.functional.shaders.builtin_constants.core.min_program_texel_offset = FAIL
3569 VULKAN : dEQP-GLES31.functional.shaders.uniform_block.es31.valid.* = FAIL 3569 VULKAN : dEQP-GLES31.functional.shaders.uniform_block.es31.valid.* = FAIL
// SSBO and Image qualifiers:
3602 VULKAN : dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite = FAIL
// Array of array and struct default uniforms: // Array of array and struct default uniforms:
3604 VULKAN : dEQP-GLES31.functional.program_interface_query.*float_struct = FAIL 3604 VULKAN : dEQP-GLES31.functional.program_interface_query.*float_struct = FAIL
3604 VULKAN : dEQP-GLES31.functional.program_interface_query.*float_struct_struct = FAIL
3604 VULKAN : dEQP-GLES31.functional.program_interface_query.*random* = FAIL 3604 VULKAN : dEQP-GLES31.functional.program_interface_query.*random* = FAIL
3604 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.* = SKIP 3604 VULKAN : dEQP-GLES31.functional.program_interface_query.*array*array* = SKIP
// Block name matching failure: // Block name matching failure:
3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL 3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
...@@ -674,10 +678,12 @@ ...@@ -674,10 +678,12 @@
// Atomic counters: // Atomic counters:
3566 VULKAN : dEQP-GLES31.functional.*atomic_counter* = FAIL 3566 VULKAN : dEQP-GLES31.functional.*atomic_counter* = FAIL
3566 VULKAN : dEQP-GLES31.functional.ssbo.layout.* = FAIL
// Storage image: // Storage image:
3563 VULKAN : dEQP-GLES31.functional.state_query.*image* = FAIL 3563 VULKAN : dEQP-GLES31.functional.state_query.*image* = FAIL
3563 VULKAN : dEQP-GLES31.functional.synchronization.*.image* = FAIL 3563 VULKAN : dEQP-GLES31.functional.synchronization.*.image* = FAIL
3563 VULKAN : dEQP-GLES31.functional.compute.*image* = FAIL
// Framebuffer parameters (FRAMEBUFFER_DEFAULT_SAMPLES): // Framebuffer parameters (FRAMEBUFFER_DEFAULT_SAMPLES):
3520 VULKAN : dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default_samples_get_framebuffer_parameteriv = FAIL 3520 VULKAN : dEQP-GLES31.functional.state_query.framebuffer_default.framebuffer_default_samples_get_framebuffer_parameteriv = FAIL
......
...@@ -36,12 +36,12 @@ ...@@ -36,12 +36,12 @@
// General Vulkan expectations // General Vulkan expectations
// Limits: // Limits:
// GL_MIN/MAX_PROGRAM_TEXTURE_GATHER_OFFSET not set. // GL_MIN/MAX_PROGRAM_TEXTURE_GATHER_OFFSET not set. Also crashes on memory barrier support missing.
3605 VULKAN : KHR-GLES31.core.texture_gather* = FAIL 3605 VULKAN : KHR-GLES31.core.texture_gather.* = SKIP
// Compute shaders // Memory barriers
3562 VULKAN : KHR-GLES31.core.constant_expressions.* = SKIP 3574 VULKAN : KHR-GLES31.core.compute_shader* = SKIP
3520 VULKAN : KHR-GLES31.core.compute_shader* = SKIP 3574 VULKAN : KHR-GLES31.core.shader_atomic_counters.basic-glsl-built-in = SKIP
// Multisampled textures: // Multisampled textures:
3565 VULKAN : KHR-GLES31.core.texture_storage_multisample.* = SKIP 3565 VULKAN : KHR-GLES31.core.texture_storage_multisample.* = SKIP
...@@ -67,14 +67,21 @@ ...@@ -67,14 +67,21 @@
3570 VULKAN : KHR-GLES31.core.sepshaderobjs* = FAIL 3570 VULKAN : KHR-GLES31.core.sepshaderobjs* = FAIL
// Shader support: // Shader support:
3569 VULKAN : KHR-GLES31.core.shader_bitfield_operation* = FAIL
3569 VULKAN : KHR-GLES31.core.shader_integer_mix.* = FAIL 3569 VULKAN : KHR-GLES31.core.shader_integer_mix.* = FAIL
3569 VULKAN : KHR-GLES31.core.shader_image* = SKIP 3569 VULKAN : KHR-GLES31.core.shader_image* = SKIP
3569 VULKAN : KHR-GLES31.core.shader_macros* = FAIL 3569 VULKAN : KHR-GLES31.core.shader_macros* = FAIL
3569 VULKAN : KHR-GLES31.core.shader_bitfield_operation.frexp.* = SKIP
3569 VULKAN : KHR-GLES31.core.shader_bitfield_operation.uaddCarry.* = SKIP
3569 VULKAN : KHR-GLES31.core.shader_bitfield_operation.usubBorrow.* = SKIP
3569 VULKAN : KHR-GLES31.core.shader_bitfield_operation.umulExtended.* = SKIP
3569 VULKAN : KHR-GLES31.core.shader_bitfield_operation.imulExtended.* = SKIP
/// Crash due to missing unsupported check in dEQP /// Crash due to missing unsupported check in dEQP
3571 VULKAN : KHR-GLES31.core.shader_macros*_geometry = SKIP 3571 VULKAN : KHR-GLES31.core.shader_macros*_geometry = SKIP
3571 VULKAN : KHR-GLES31.core.shader_macros*_tess_control = SKIP 3571 VULKAN : KHR-GLES31.core.shader_macros*_tess_control = SKIP
3571 VULKAN : KHR-GLES31.core.shader_macros*_tess_eval = SKIP 3571 VULKAN : KHR-GLES31.core.shader_macros*_tess_eval = SKIP
3571 VULKAN : KHR-GLES31.core.constant_expressions.*geometry = SKIP
3571 VULKAN : KHR-GLES31.core.constant_expressions.*tess_control = SKIP
3571 VULKAN : KHR-GLES31.core.constant_expressions.*tess_eval = SKIP
3520 VULKAN : KHR-GLES31.core.vertex_attrib_binding* = SKIP 3520 VULKAN : KHR-GLES31.core.vertex_attrib_binding* = SKIP
3520 VULKAN : KHR-GLES31.core.internalformat.texture2d.* = FAIL 3520 VULKAN : KHR-GLES31.core.internalformat.texture2d.* = FAIL
...@@ -85,7 +92,8 @@ ...@@ -85,7 +92,8 @@
// Draw indirect: // Draw indirect:
3564 VULKAN : KHR-GLES31.core.draw_indirect.* = SKIP 3564 VULKAN : KHR-GLES31.core.draw_indirect.* = SKIP
3520 VULKAN : KHR-GLES31.core.explicit_uniform_location.* = FAIL // Explicit uniform locations:
3597 VULKAN : KHR-GLES31.core.explicit_uniform_location.* = SKIP
3520 VULKAN : KHR-GLES31.core.program_interface_query.* = SKIP 3520 VULKAN : KHR-GLES31.core.program_interface_query.* = SKIP
...@@ -97,6 +105,10 @@ ...@@ -97,6 +105,10 @@
// Blend equations: // Blend equations:
3586 VULKAN : KHR-GLES31.core.blend_equation_advanced.* = SKIP 3586 VULKAN : KHR-GLES31.core.blend_equation_advanced.* = SKIP
// Storage image:
3563 VULKAN : KHR-GLES31.core.layout_binding.sampler2D_layout_binding_texture_ComputeShader = FAIL
3563 VULKAN : KHR-GLES31.core.layout_binding.block_layout_binding_block_ComputeShader = FAIL
3520 VULKAN : KHR-GLES31.core.internalformat.copy_tex_image* = FAIL 3520 VULKAN : KHR-GLES31.core.internalformat.copy_tex_image* = FAIL
3520 VULKAN : KHR-GLES31.core.internalformat.renderbuffer* = FAIL 3520 VULKAN : KHR-GLES31.core.internalformat.renderbuffer* = FAIL
......
...@@ -315,6 +315,9 @@ TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite) ...@@ -315,6 +315,9 @@ TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite)
// Tests modifying an existing shader storage buffer // Tests modifying an existing shader storage buffer
TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteSame) TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteSame)
{ {
// Vulkan doesn't support memory barriers yet. http://anglebug.com/3574
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr char kComputeShaderSource[] = constexpr char kComputeShaderSource[] =
R"(#version 310 es R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
...@@ -410,6 +413,9 @@ void main() ...@@ -410,6 +413,9 @@ void main()
// Tests reading and writing to a shader storage buffer bound at an offset. // Tests reading and writing to a shader storage buffer bound at an offset.
TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteOffset) TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWriteOffset)
{ {
// Vulkan doesn't support memory barriers yet. http://anglebug.com/3574
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr char kCS[] = R"(#version 310 es constexpr char kCS[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
...@@ -1593,8 +1599,10 @@ TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanValue) ...@@ -1593,8 +1599,10 @@ TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanValue)
// http://anglebug.com/1951 // http://anglebug.com/1951
ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux()); ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
// Seems to fail on Windows NVIDIA GL when tests are run without interruption. // Seems to fail on Windows NVIDIA GL when tests are run without interruption. It also happens
// on Vulkan. http://anglebug.com/3694
ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL()); ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL());
ANGLE_SKIP_TEST_IF(IsWindows() && IsVulkan());
constexpr char kComputeShaderSource[] = R"(#version 310 es constexpr char kComputeShaderSource[] = R"(#version 310 es
layout (local_size_x=1) in; layout (local_size_x=1) in;
...@@ -2072,6 +2080,10 @@ void main() ...@@ -2072,6 +2080,10 @@ void main()
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31, ES31_OPENGL(), ES31_OPENGLES(), ES31_D3D11()); ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31,
ES31_OPENGL(),
ES31_OPENGLES(),
ES31_D3D11(),
ES31_VULKAN());
} // namespace } // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment