Commit 8ecf7f9b by Jamie Madill Committed by Commit Bot

Vulkan: Implement shader compilation.

This hooks up the Vulkan GLSL, decorated with locations, to glslang, and then pipes the SPIRV back to the Program implementation for later use when making pipelines to run draw calls. The program compilation tests work now, but don't really test anything other than not generating Vulkan validation layer errors during compilation and shader object generation. BUG=angleproject:1576 Change-Id: I625e42219f4b4d1433dd3109b94e1a2f666ba4bd Reviewed-on: https://chromium-review.googlesource.com/408519 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0844f2db
...@@ -582,8 +582,10 @@ void Program::pathFragmentInputGen(GLint index, ...@@ -582,8 +582,10 @@ void Program::pathFragmentInputGen(GLint index,
// The attached shaders are checked for linking errors by matching up their variables. // The attached shaders are checked for linking errors by matching up their variables.
// Uniform, input and output variables get collected. // Uniform, input and output variables get collected.
// The code gets compiled into binaries. // The code gets compiled into binaries.
Error Program::link(const ContextState &data) Error Program::link(const gl::Context *context)
{ {
const auto &data = context->getContextState();
unlink(false); unlink(false);
mInfoLog.reset(); mInfoLog.reset();
...@@ -635,8 +637,9 @@ Error Program::link(const ContextState &data) ...@@ -635,8 +637,9 @@ Error Program::link(const ContextState &data)
return NoError(); return NoError();
} }
gl::VaryingPacking noVaryingPacking(0, PackMode::ANGLE_RELAXED); gl::VaryingPacking noPacking(0, PackMode::ANGLE_RELAXED);
ANGLE_TRY_RESULT(mProgram->link(data, noVaryingPacking, mInfoLog), mLinked); ANGLE_TRY_RESULT(mProgram->link(context->getImplementation(), noPacking, mInfoLog),
mLinked);
if (!mLinked) if (!mLinked)
{ {
return NoError(); return NoError();
...@@ -705,7 +708,8 @@ Error Program::link(const ContextState &data) ...@@ -705,7 +708,8 @@ Error Program::link(const ContextState &data)
return NoError(); return NoError();
} }
ANGLE_TRY_RESULT(mProgram->link(data, varyingPacking, mInfoLog), mLinked); ANGLE_TRY_RESULT(mProgram->link(context->getImplementation(), varyingPacking, mInfoLog),
mLinked);
if (!mLinked) if (!mLinked)
{ {
return NoError(); return NoError();
......
...@@ -290,7 +290,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -290,7 +290,7 @@ class Program final : angle::NonCopyable, public LabeledObject
GLint components, GLint components,
const GLfloat *coeffs); const GLfloat *coeffs);
Error link(const ContextState &data); Error link(const gl::Context *context);
bool isLinked() const; bool isLinked() const;
Error loadBinary(const Context *context, Error loadBinary(const Context *context,
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
#include <cstddef> #include <cstddef>
class RefCountObject : angle::NonCopyable class RefCountObjectNoID : angle::NonCopyable
{ {
public: public:
explicit RefCountObject(GLuint id) : mId(id), mRefCount(0) {} RefCountObjectNoID() : mRefCount(0) {}
void addRef() const { ++mRefCount; } void addRef() const { ++mRefCount; }
...@@ -35,19 +35,29 @@ class RefCountObject : angle::NonCopyable ...@@ -35,19 +35,29 @@ class RefCountObject : angle::NonCopyable
} }
} }
GLuint id() const { return mId; }
size_t getRefCount() const { return mRefCount; } size_t getRefCount() const { return mRefCount; }
protected: protected:
virtual ~RefCountObject() { ASSERT(mRefCount == 0); } virtual ~RefCountObjectNoID() { ASSERT(mRefCount == 0); }
private: private:
GLuint mId;
mutable std::size_t mRefCount; mutable std::size_t mRefCount;
}; };
class RefCountObject : public RefCountObjectNoID
{
public:
explicit RefCountObject(GLuint id) : mId(id) {}
GLuint id() const { return mId; }
protected:
~RefCountObject() override {}
private:
GLuint mId;
};
template <class ObjectType> template <class ObjectType>
class BindingPointer class BindingPointer
{ {
......
...@@ -29,6 +29,8 @@ struct BlockMemberInfo; ...@@ -29,6 +29,8 @@ struct BlockMemberInfo;
namespace rx namespace rx
{ {
class ContextImpl;
using LinkResult = gl::ErrorOrResult<bool>; using LinkResult = gl::ErrorOrResult<bool>;
class ContextImpl; class ContextImpl;
...@@ -45,7 +47,7 @@ class ProgramImpl : angle::NonCopyable ...@@ -45,7 +47,7 @@ class ProgramImpl : angle::NonCopyable
virtual gl::Error save(gl::BinaryOutputStream *stream) = 0; virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
virtual void setBinaryRetrievableHint(bool retrievable) = 0; virtual void setBinaryRetrievableHint(bool retrievable) = 0;
virtual LinkResult link(const gl::ContextState &data, virtual LinkResult link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) = 0; gl::InfoLog &infoLog) = 0;
virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0; virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0;
...@@ -94,6 +96,6 @@ class ProgramImpl : angle::NonCopyable ...@@ -94,6 +96,6 @@ class ProgramImpl : angle::NonCopyable
const gl::ProgramState &mState; const gl::ProgramState &mState;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_ #endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_
...@@ -27,8 +27,7 @@ class MockProgramImpl : public rx::ProgramImpl ...@@ -27,8 +27,7 @@ class MockProgramImpl : public rx::ProgramImpl
MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *)); MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *));
MOCK_METHOD1(setBinaryRetrievableHint, void(bool)); MOCK_METHOD1(setBinaryRetrievableHint, void(bool));
MOCK_METHOD3(link, MOCK_METHOD3(link, LinkResult(ContextImpl *, const gl::VaryingPacking &, gl::InfoLog &));
LinkResult(const gl::ContextState &, const gl::VaryingPacking &, gl::InfoLog &));
MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *)); MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *));
MOCK_METHOD3(setUniform1fv, void(GLint, GLsizei, const GLfloat *)); MOCK_METHOD3(setUniform1fv, void(GLint, GLsizei, const GLfloat *));
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/VaryingPacking.h" #include "libANGLE/VaryingPacking.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
#include "libANGLE/features.h" #include "libANGLE/features.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
...@@ -1464,10 +1465,12 @@ LinkResult ProgramD3D::compileComputeExecutable(gl::InfoLog &infoLog) ...@@ -1464,10 +1465,12 @@ LinkResult ProgramD3D::compileComputeExecutable(gl::InfoLog &infoLog)
return mComputeExecutable.get() != nullptr; return mComputeExecutable.get() != nullptr;
} }
LinkResult ProgramD3D::link(const gl::ContextState &data, LinkResult ProgramD3D::link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) gl::InfoLog &infoLog)
{ {
const auto &data = contextImpl->getContextState();
reset(); reset();
const gl::Shader *computeShader = mState.getAttachedComputeShader(); const gl::Shader *computeShader = mState.getAttachedComputeShader();
......
...@@ -180,7 +180,7 @@ class ProgramD3D : public ProgramImpl ...@@ -180,7 +180,7 @@ class ProgramD3D : public ProgramImpl
ShaderExecutableD3D **outExecutable, ShaderExecutableD3D **outExecutable,
gl::InfoLog *infoLog); gl::InfoLog *infoLog);
LinkResult link(const gl::ContextState &data, LinkResult link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) override; gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
......
...@@ -111,7 +111,7 @@ void ProgramGL::setBinaryRetrievableHint(bool retrievable) ...@@ -111,7 +111,7 @@ void ProgramGL::setBinaryRetrievableHint(bool retrievable)
} }
} }
LinkResult ProgramGL::link(const gl::ContextState &data, LinkResult ProgramGL::link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) gl::InfoLog &infoLog)
{ {
......
...@@ -37,7 +37,7 @@ class ProgramGL : public ProgramImpl ...@@ -37,7 +37,7 @@ class ProgramGL : public ProgramImpl
gl::Error save(gl::BinaryOutputStream *stream) override; gl::Error save(gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override; void setBinaryRetrievableHint(bool retrievable) override;
LinkResult link(const gl::ContextState &data, LinkResult link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) override; gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
......
...@@ -38,7 +38,7 @@ void ProgramNULL::setBinaryRetrievableHint(bool retrievable) ...@@ -38,7 +38,7 @@ void ProgramNULL::setBinaryRetrievableHint(bool retrievable)
{ {
} }
LinkResult ProgramNULL::link(const gl::ContextState &data, LinkResult ProgramNULL::link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) gl::InfoLog &infoLog)
{ {
......
...@@ -27,7 +27,7 @@ class ProgramNULL : public ProgramImpl ...@@ -27,7 +27,7 @@ class ProgramNULL : public ProgramImpl
gl::Error save(gl::BinaryOutputStream *stream) override; gl::Error save(gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override; void setBinaryRetrievableHint(bool retrievable) override;
LinkResult link(const gl::ContextState &data, LinkResult link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) override; gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
......
//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// GlslangWrapper: Wrapper for Vulkan's glslang compiler.
//
#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
// glslang's version of ShaderLang.h, not to be confused with ANGLE's.
// Our function defs conflict with theirs, but we carefully manage our includes to prevent this.
#include <ShaderLang.h>
// Other glslang includes.
#include <StandAlone/ResourceLimits.h>
#include <SPIRV/GlslangToSpv.h>
#include <array>
namespace rx
{
// static
GlslangWrapper *GlslangWrapper::mInstance = nullptr;
// static
GlslangWrapper *GlslangWrapper::GetReference()
{
if (!mInstance)
{
mInstance = new GlslangWrapper();
}
mInstance->addRef();
return mInstance;
}
// static
void GlslangWrapper::ReleaseReference()
{
if (mInstance->getRefCount() == 1)
{
mInstance->release();
mInstance = nullptr;
}
else
{
mInstance->release();
}
}
GlslangWrapper::GlslangWrapper()
{
int result = ShInitialize();
ASSERT(result != 0);
}
GlslangWrapper::~GlslangWrapper()
{
int result = ShFinalize();
ASSERT(result != 0);
}
LinkResult GlslangWrapper::linkProgram(const std::string &vertexSource,
const std::string &fragmentSource,
std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut)
{
std::array<const char *, 2> strings = {{vertexSource.c_str(), fragmentSource.c_str()}};
std::array<int, 2> lengths = {
{static_cast<int>(vertexSource.length()), static_cast<int>(fragmentSource.length())}};
// Enable SPIR-V and Vulkan rules when parsing GLSL
EShMessages messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
glslang::TShader vertexShader(EShLangVertex);
vertexShader.setStringsWithLengths(&strings[0], &lengths[0], 1);
vertexShader.setEntryPoint("main");
bool vertexResult = vertexShader.parse(&glslang::DefaultTBuiltInResource, 450, ECoreProfile,
false, false, messages);
if (!vertexResult)
{
return gl::InternalError() << "Internal error parsing Vulkan vertex shader:\n"
<< vertexShader.getInfoLog() << "\n"
<< vertexShader.getInfoDebugLog() << "\n";
}
glslang::TShader fragmentShader(EShLangFragment);
fragmentShader.setStringsWithLengths(&strings[1], &lengths[1], 1);
fragmentShader.setEntryPoint("main");
bool fragmentResult = fragmentShader.parse(&glslang::DefaultTBuiltInResource, 450, ECoreProfile,
false, false, messages);
if (!fragmentResult)
{
return gl::InternalError() << "Internal error parsing Vulkan fragment shader:\n"
<< fragmentShader.getInfoLog() << "\n"
<< fragmentShader.getInfoDebugLog() << "\n";
}
glslang::TProgram program;
program.addShader(&vertexShader);
program.addShader(&fragmentShader);
bool linkResult = program.link(messages);
if (!linkResult)
{
return gl::InternalError() << "Internal error linking Vulkan shaders:\n"
<< program.getInfoLog() << "\n";
}
glslang::TIntermediate *vertexStage = program.getIntermediate(EShLangVertex);
glslang::TIntermediate *fragmentStage = program.getIntermediate(EShLangFragment);
glslang::GlslangToSpv(*vertexStage, *vertexCodeOut);
glslang::GlslangToSpv(*fragmentStage, *fragmentCodeOut);
return true;
}
} // namespace rx
//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// GlslangWrapper: Wrapper for Vulkan's glslang compiler.
//
#ifndef LIBANGLE_RENDERER_VULKAN_GLSLANG_WRAPPER_H_
#define LIBANGLE_RENDERER_VULKAN_GLSLANG_WRAPPER_H_
#include "libANGLE/RefCountObject.h"
#include "libANGLE/renderer/ProgramImpl.h"
namespace rx
{
class GlslangWrapper : public RefCountObjectNoID
{
public:
// Increases the reference count.
// TODO(jmadill): Determine how to handle this atomically.
static GlslangWrapper *GetReference();
static void ReleaseReference();
LinkResult linkProgram(const std::string &vertexSource,
const std::string &fragmentSource,
std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut);
private:
GlslangWrapper();
~GlslangWrapper() override;
static GlslangWrapper *mInstance;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_GLSLANG_WRAPPER_H_
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include "libANGLE/renderer/vulkan/ProgramVk.h" #include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx namespace rx
{ {
...@@ -41,12 +44,56 @@ void ProgramVk::setBinaryRetrievableHint(bool retrievable) ...@@ -41,12 +44,56 @@ void ProgramVk::setBinaryRetrievableHint(bool retrievable)
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
LinkResult ProgramVk::link(const gl::ContextState &data, LinkResult ProgramVk::link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) gl::InfoLog &infoLog)
{ {
UNIMPLEMENTED(); ContextVk *context = GetAs<ContextVk>(contextImpl);
return gl::Error(GL_INVALID_OPERATION); RendererVk *renderer = context->getRenderer();
GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
const std::string &vertexSource = mState.getAttachedVertexShader()->getTranslatedSource();
const std::string &fragmentSource = mState.getAttachedFragmentShader()->getTranslatedSource();
std::vector<uint32_t> vertexCode;
std::vector<uint32_t> fragmentCode;
bool linkSuccess = false;
ANGLE_TRY_RESULT(
glslangWrapper->linkProgram(vertexSource, fragmentSource, &vertexCode, &fragmentCode),
linkSuccess);
if (!linkSuccess)
{
return false;
}
vk::ShaderModule vertexModule(renderer->getDevice());
vk::ShaderModule fragmentModule(renderer->getDevice());
{
VkShaderModuleCreateInfo vertexShaderInfo;
vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
vertexShaderInfo.pNext = nullptr;
vertexShaderInfo.flags = 0;
vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t);
vertexShaderInfo.pCode = vertexCode.data();
ANGLE_TRY(vertexModule.init(vertexShaderInfo));
}
{
VkShaderModuleCreateInfo fragmentShaderInfo;
fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
fragmentShaderInfo.pNext = nullptr;
fragmentShaderInfo.flags = 0;
fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t);
fragmentShaderInfo.pCode = fragmentCode.data();
ANGLE_TRY(fragmentModule.init(fragmentShaderInfo));
}
mLinkedVertexModule = std::move(vertexModule);
mLinkedFragmentModule = std::move(fragmentModule);
return true;
} }
GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog) GLboolean ProgramVk::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
...@@ -213,4 +260,16 @@ void ProgramVk::setPathFragmentInputGen(const std::string &inputName, ...@@ -213,4 +260,16 @@ void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
const vk::ShaderModule &ProgramVk::getLinkedVertexModule() const
{
ASSERT(mLinkedVertexModule.getHandle() != VK_NULL_HANDLE);
return mLinkedVertexModule;
}
const vk::ShaderModule &ProgramVk::getLinkedFragmentModule() const
{
ASSERT(mLinkedFragmentModule.getHandle() != VK_NULL_HANDLE);
return mLinkedFragmentModule;
}
} // namespace rx } // namespace rx
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_ #define LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
#include "libANGLE/renderer/ProgramImpl.h" #include "libANGLE/renderer/ProgramImpl.h"
#include "libANGLE/renderer/vulkan/renderervk_utils.h"
namespace rx namespace rx
{ {
...@@ -27,7 +28,7 @@ class ProgramVk : public ProgramImpl ...@@ -27,7 +28,7 @@ class ProgramVk : public ProgramImpl
gl::Error save(gl::BinaryOutputStream *stream) override; gl::Error save(gl::BinaryOutputStream *stream) override;
void setBinaryRetrievableHint(bool retrievable) override; void setBinaryRetrievableHint(bool retrievable) override;
LinkResult link(const gl::ContextState &data, LinkResult link(ContextImpl *contextImpl,
const gl::VaryingPacking &packing, const gl::VaryingPacking &packing,
gl::InfoLog &infoLog) override; gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
...@@ -97,6 +98,13 @@ class ProgramVk : public ProgramImpl ...@@ -97,6 +98,13 @@ class ProgramVk : public ProgramImpl
GLenum genMode, GLenum genMode,
GLint components, GLint components,
const GLfloat *coeffs) override; const GLfloat *coeffs) override;
const vk::ShaderModule &getLinkedVertexModule() const;
const vk::ShaderModule &getLinkedFragmentModule() const;
private:
vk::ShaderModule mLinkedVertexModule;
vk::ShaderModule mLinkedFragmentModule;
}; };
} // namespace rx } // namespace rx
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "libANGLE/renderer/driver_utils.h" #include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h" #include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h" #include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
#include "libANGLE/renderer/vulkan/TextureVk.h" #include "libANGLE/renderer/vulkan/TextureVk.h"
#include "libANGLE/renderer/vulkan/VertexArrayVk.h" #include "libANGLE/renderer/vulkan/VertexArrayVk.h"
#include "libANGLE/renderer/vulkan/formatutilsvk.h" #include "libANGLE/renderer/vulkan/formatutilsvk.h"
...@@ -92,12 +93,19 @@ RendererVk::RendererVk() ...@@ -92,12 +93,19 @@ RendererVk::RendererVk()
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()), mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mDevice(VK_NULL_HANDLE), mDevice(VK_NULL_HANDLE),
mCommandPool(VK_NULL_HANDLE), mCommandPool(VK_NULL_HANDLE),
mHostVisibleMemoryIndex(std::numeric_limits<uint32_t>::max()) mHostVisibleMemoryIndex(std::numeric_limits<uint32_t>::max()),
mGlslangWrapper(nullptr)
{ {
} }
RendererVk::~RendererVk() RendererVk::~RendererVk()
{ {
if (mGlslangWrapper)
{
GlslangWrapper::ReleaseReference();
mGlslangWrapper = nullptr;
}
mCommandBuffer.reset(nullptr); mCommandBuffer.reset(nullptr);
if (mCommandPool) if (mCommandPool)
...@@ -332,6 +340,8 @@ vk::Error RendererVk::initialize(const egl::AttributeMap &attribs) ...@@ -332,6 +340,8 @@ vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
ANGLE_VK_CHECK(mHostVisibleMemoryIndex < std::numeric_limits<uint32_t>::max(), ANGLE_VK_CHECK(mHostVisibleMemoryIndex < std::numeric_limits<uint32_t>::max(),
VK_ERROR_INITIALIZATION_FAILED); VK_ERROR_INITIALIZATION_FAILED);
mGlslangWrapper = GlslangWrapper::GetReference();
return vk::NoError(); return vk::NoError();
} }
...@@ -507,12 +517,14 @@ void RendererVk::ensureCapsInitialized() const ...@@ -507,12 +517,14 @@ void RendererVk::ensureCapsInitialized() const
} }
} }
void RendererVk::generateCaps(gl::Caps * /*outCaps*/, void RendererVk::generateCaps(gl::Caps *outCaps,
gl::TextureCapsMap * /*outTextureCaps*/, gl::TextureCapsMap * /*outTextureCaps*/,
gl::Extensions *outExtensions, gl::Extensions *outExtensions,
gl::Limitations * /* outLimitations */) const gl::Limitations * /* outLimitations */) const
{ {
// TODO(jmadill): Caps. // TODO(jmadill): Caps.
outCaps->maxDrawBuffers = 1;
outCaps->maxVertexAttributes = 1;
// Enable this for simple buffer readback testing, but some functionality is missing. // Enable this for simple buffer readback testing, but some functionality is missing.
// TODO(jmadill): Support full mapBufferRange extension. // TODO(jmadill): Support full mapBufferRange extension.
...@@ -618,4 +630,9 @@ vk::ErrorOrResult<vk::StagingImage> RendererVk::createStagingImage(TextureDimens ...@@ -618,4 +630,9 @@ vk::ErrorOrResult<vk::StagingImage> RendererVk::createStagingImage(TextureDimens
return std::move(stagingImage); return std::move(stagingImage);
} }
GlslangWrapper *RendererVk::getGlslangWrapper()
{
return mGlslangWrapper;
}
} // namespace rx } // namespace rx
...@@ -24,6 +24,7 @@ class AttributeMap; ...@@ -24,6 +24,7 @@ class AttributeMap;
namespace rx namespace rx
{ {
class GlslangWrapper;
namespace vk namespace vk
{ {
...@@ -63,6 +64,8 @@ class RendererVk : angle::NonCopyable ...@@ -63,6 +64,8 @@ class RendererVk : angle::NonCopyable
const vk::Format &format, const vk::Format &format,
const gl::Extents &extent); const gl::Extents &extent);
GlslangWrapper *getGlslangWrapper();
private: private:
void ensureCapsInitialized() const; void ensureCapsInitialized() const;
void generateCaps(gl::Caps *outCaps, void generateCaps(gl::Caps *outCaps,
...@@ -90,6 +93,7 @@ class RendererVk : angle::NonCopyable ...@@ -90,6 +93,7 @@ class RendererVk : angle::NonCopyable
VkCommandPool mCommandPool; VkCommandPool mCommandPool;
std::unique_ptr<vk::CommandBuffer> mCommandBuffer; std::unique_ptr<vk::CommandBuffer> mCommandBuffer;
uint32_t mHostVisibleMemoryIndex; uint32_t mHostVisibleMemoryIndex;
GlslangWrapper *mGlslangWrapper;
}; };
} // namespace rx } // namespace rx
......
...@@ -25,19 +25,18 @@ ShaderVk::~ShaderVk() ...@@ -25,19 +25,18 @@ ShaderVk::~ShaderVk()
ShCompileOptions ShaderVk::prepareSourceAndReturnOptions(std::stringstream *sourceStream, ShCompileOptions ShaderVk::prepareSourceAndReturnOptions(std::stringstream *sourceStream,
std::string *sourcePath) std::string *sourcePath)
{ {
UNIMPLEMENTED(); *sourceStream << mData.getSource();
return int(); return 0;
} }
bool ShaderVk::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) bool ShaderVk::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
{ {
UNIMPLEMENTED(); // No work to do here.
return bool(); return true;
} }
std::string ShaderVk::getDebugInfo() const std::string ShaderVk::getDebugInfo() const
{ {
UNIMPLEMENTED();
return std::string(); return std::string();
} }
......
...@@ -807,6 +807,41 @@ Error Buffer::bindMemory() ...@@ -807,6 +807,41 @@ Error Buffer::bindMemory()
return NoError(); return NoError();
} }
// ShaderModule implementation.
ShaderModule::ShaderModule()
{
}
ShaderModule::ShaderModule(VkDevice device) : WrappedObject(device)
{
}
ShaderModule::ShaderModule(ShaderModule &&other) : WrappedObject(std::move(other))
{
}
ShaderModule::~ShaderModule()
{
if (mHandle != VK_NULL_HANDLE)
{
ASSERT(validDevice());
vkDestroyShaderModule(mDevice, mHandle, nullptr);
}
}
ShaderModule &ShaderModule::operator=(ShaderModule &&other)
{
assignOpBase(std::move(other));
return *this;
}
Error ShaderModule::init(const VkShaderModuleCreateInfo &createInfo)
{
ASSERT(validDevice() && !valid());
ANGLE_VK_TRY(vkCreateShaderModule(mDevice, &createInfo, nullptr, &mHandle));
return NoError();
}
} // namespace vk } // namespace vk
Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps, Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps,
......
...@@ -290,6 +290,18 @@ class Buffer final : public WrappedObject<VkBuffer> ...@@ -290,6 +290,18 @@ class Buffer final : public WrappedObject<VkBuffer>
DeviceMemory mMemory; DeviceMemory mMemory;
}; };
class ShaderModule final : public WrappedObject<VkShaderModule>
{
public:
ShaderModule();
ShaderModule(VkDevice device);
ShaderModule(ShaderModule &&other);
~ShaderModule() override;
ShaderModule &operator=(ShaderModule &&other);
Error init(const VkShaderModuleCreateInfo &createInfo);
};
} // namespace vk } // namespace vk
Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps, Optional<uint32_t> FindMemoryType(const VkPhysicalDeviceMemoryProperties &memoryProps,
......
...@@ -621,6 +621,8 @@ ...@@ -621,6 +621,8 @@
'libANGLE/renderer/vulkan/FenceSyncVk.h', 'libANGLE/renderer/vulkan/FenceSyncVk.h',
'libANGLE/renderer/vulkan/FramebufferVk.cpp', 'libANGLE/renderer/vulkan/FramebufferVk.cpp',
'libANGLE/renderer/vulkan/FramebufferVk.h', 'libANGLE/renderer/vulkan/FramebufferVk.h',
'libANGLE/renderer/vulkan/GlslangWrapper.cpp',
'libANGLE/renderer/vulkan/GlslangWrapper.h',
'libANGLE/renderer/vulkan/ImageVk.cpp', 'libANGLE/renderer/vulkan/ImageVk.cpp',
'libANGLE/renderer/vulkan/ImageVk.h', 'libANGLE/renderer/vulkan/ImageVk.h',
'libANGLE/renderer/vulkan/ProgramVk.cpp', 'libANGLE/renderer/vulkan/ProgramVk.cpp',
......
...@@ -1812,7 +1812,7 @@ void GL_APIENTRY LinkProgram(GLuint program) ...@@ -1812,7 +1812,7 @@ void GL_APIENTRY LinkProgram(GLuint program)
return; return;
} }
Error error = programObject->link(context->getContextState()); Error error = programObject->link(context);
if (error.isError()) if (error.isError())
{ {
context->handleError(error); context->handleError(error);
......
...@@ -54,13 +54,6 @@ void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum ...@@ -54,13 +54,6 @@ void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum
TEST_P(SimpleOperationTest, CompileVertexShader) TEST_P(SimpleOperationTest, CompileVertexShader)
{ {
if (IsVulkan())
{
// TODO(jmadill): Complete Vulkan implementation.
std::cout << "Test skipped on Vulkan." << std::endl;
return;
}
const std::string source = SHADER_SOURCE const std::string source = SHADER_SOURCE
( (
attribute vec4 a_input; attribute vec4 a_input;
...@@ -79,13 +72,6 @@ TEST_P(SimpleOperationTest, CompileVertexShader) ...@@ -79,13 +72,6 @@ TEST_P(SimpleOperationTest, CompileVertexShader)
TEST_P(SimpleOperationTest, CompileFragmentShader) TEST_P(SimpleOperationTest, CompileFragmentShader)
{ {
if (IsVulkan())
{
// TODO(jmadill): Complete Vulkan implementation.
std::cout << "Test skipped on Vulkan." << std::endl;
return;
}
const std::string source = SHADER_SOURCE const std::string source = SHADER_SOURCE
( (
precision mediump float; precision mediump float;
...@@ -105,13 +91,6 @@ TEST_P(SimpleOperationTest, CompileFragmentShader) ...@@ -105,13 +91,6 @@ TEST_P(SimpleOperationTest, CompileFragmentShader)
TEST_P(SimpleOperationTest, LinkProgram) TEST_P(SimpleOperationTest, LinkProgram)
{ {
if (IsVulkan())
{
// TODO(jmadill): Complete Vulkan implementation.
std::cout << "Test skipped on Vulkan." << std::endl;
return;
}
const std::string vsSource = SHADER_SOURCE const std::string vsSource = SHADER_SOURCE
( (
void main() void main()
......
...@@ -16,6 +16,7 @@ vulkan_gypi = ...@@ -16,6 +16,7 @@ vulkan_gypi =
[ [
rebase_path("vulkan.gypi"), rebase_path("vulkan.gypi"),
"--replace=<(angle_gen_path)=$target_gen_dir/angle", "--replace=<(angle_gen_path)=$target_gen_dir/angle",
"--replace=<(glslang_path)=../$glslang_dir",
"--replace=<(spirv_headers_path)=../$spirv_headers_dir", "--replace=<(spirv_headers_path)=../$spirv_headers_dir",
"--replace=<(spirv_tools_path)=../$spirv_tools_dir", "--replace=<(spirv_tools_path)=../$spirv_tools_dir",
"--replace=<(vulkan_layers_path)=../$vulkan_layers_dir", "--replace=<(vulkan_layers_path)=../$vulkan_layers_dir",
...@@ -308,6 +309,44 @@ static_library("spirv_tools") { ...@@ -308,6 +309,44 @@ static_library("spirv_tools") {
public_configs = [ ":spirv_tools_config" ] public_configs = [ ":spirv_tools_config" ]
} }
# glslang
# -------
config("glslang_config") {
include_dirs = [
glslang_dir,
"$glslang_dir/glslang/Public",
]
}
config("glslang_internal_config") {
if (is_clang || !is_win) {
cflags = [
"-Wno-reorder",
"-Wno-ignored-qualifiers",
]
}
}
static_library("glslang") {
sources = rebase_path(vulkan_gypi.glslang_sources, ".", "src")
public_configs = [ ":glslang_config" ]
configs += [ ":glslang_internal_config" ]
if (is_win) {
cflags = [
"/wd4100", # Unreferenced formal parameter
"/wd4456", # Declaration hides previous local declaration
"/wd4457", # Declaration hides function parameter
"/wd4458", # Declaration hides class member
"/wd4702", # Unreachable code (from glslang_tab.cpp)
"/wd4718", # Recursive call has no side effects (from PpContext.cpp)
]
sources += rebase_path(vulkan_gypi.glslang_win_sources, ".", "src")
}
}
# The validation layers # The validation layers
# --------------------- # ---------------------
...@@ -370,6 +409,7 @@ foreach(index, layer_indexes) { ...@@ -370,6 +409,7 @@ foreach(index, layer_indexes) {
# Use this target to include everything ANGLE needs for Vulkan. # Use this target to include everything ANGLE needs for Vulkan.
group("angle_vulkan") { group("angle_vulkan") {
deps = [ deps = [
":glslang",
":vulkan_loader", ":vulkan_loader",
] ]
data_deps = [ data_deps = [
...@@ -378,5 +418,8 @@ group("angle_vulkan") { ...@@ -378,5 +418,8 @@ group("angle_vulkan") {
foreach(layer, layer_names) { foreach(layer, layer_names) {
data_deps += [ ":VkLayer_$layer" ] data_deps += [ ":VkLayer_$layer" ]
} }
public_configs = [ ":vulkan_loader_config" ] public_configs = [
":vulkan_loader_config",
":glslang_config",
]
} }
...@@ -51,6 +51,115 @@ ...@@ -51,6 +51,115 @@
'/wd4706', # Assignment within conditional expression '/wd4706', # Assignment within conditional expression
'/wd4996', # Unsafe stdlib function '/wd4996', # Unsafe stdlib function
], ],
'glslang_sources':
[
'<(glslang_path)/glslang/GenericCodeGen/CodeGen.cpp',
'<(glslang_path)/glslang/GenericCodeGen/Link.cpp',
'<(glslang_path)/glslang/Include/arrays.h',
'<(glslang_path)/glslang/Include/BaseTypes.h',
'<(glslang_path)/glslang/Include/Common.h',
'<(glslang_path)/glslang/Include/ConstantUnion.h',
'<(glslang_path)/glslang/Include/InfoSink.h',
'<(glslang_path)/glslang/Include/InitializeGlobals.h',
'<(glslang_path)/glslang/Include/intermediate.h',
'<(glslang_path)/glslang/Include/PoolAlloc.h',
'<(glslang_path)/glslang/Include/ResourceLimits.h',
'<(glslang_path)/glslang/Include/revision.h',
'<(glslang_path)/glslang/Include/ShHandle.h',
'<(glslang_path)/glslang/Include/Types.h',
'<(glslang_path)/glslang/MachineIndependent/Constant.cpp',
'<(glslang_path)/glslang/MachineIndependent/gl_types.h',
'<(glslang_path)/glslang/MachineIndependent/glslang.y',
'<(glslang_path)/glslang/MachineIndependent/glslang_tab.cpp',
'<(glslang_path)/glslang/MachineIndependent/glslang_tab.cpp.h',
'<(glslang_path)/glslang/MachineIndependent/InfoSink.cpp',
'<(glslang_path)/glslang/MachineIndependent/Initialize.cpp',
'<(glslang_path)/glslang/MachineIndependent/Initialize.h',
'<(glslang_path)/glslang/MachineIndependent/Intermediate.cpp',
'<(glslang_path)/glslang/MachineIndependent/intermOut.cpp',
'<(glslang_path)/glslang/MachineIndependent/IntermTraverse.cpp',
'<(glslang_path)/glslang/MachineIndependent/iomapper.cpp',
'<(glslang_path)/glslang/MachineIndependent/iomapper.h',
'<(glslang_path)/glslang/MachineIndependent/limits.cpp',
'<(glslang_path)/glslang/MachineIndependent/linkValidate.cpp',
'<(glslang_path)/glslang/MachineIndependent/LiveTraverser.h',
'<(glslang_path)/glslang/MachineIndependent/localintermediate.h',
'<(glslang_path)/glslang/MachineIndependent/parseConst.cpp',
'<(glslang_path)/glslang/MachineIndependent/ParseContextBase.cpp',
'<(glslang_path)/glslang/MachineIndependent/ParseHelper.cpp',
'<(glslang_path)/glslang/MachineIndependent/ParseHelper.h',
'<(glslang_path)/glslang/MachineIndependent/parseVersions.h',
'<(glslang_path)/glslang/MachineIndependent/PoolAlloc.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/Pp.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpAtom.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpContext.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpContext.h',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpMemory.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpScanner.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpSymbols.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpTokens.cpp',
'<(glslang_path)/glslang/MachineIndependent/preprocessor/PpTokens.h',
'<(glslang_path)/glslang/MachineIndependent/propagateNoContraction.cpp',
'<(glslang_path)/glslang/MachineIndependent/propagateNoContraction.h',
'<(glslang_path)/glslang/MachineIndependent/reflection.cpp',
'<(glslang_path)/glslang/MachineIndependent/reflection.h',
'<(glslang_path)/glslang/MachineIndependent/RemoveTree.cpp',
'<(glslang_path)/glslang/MachineIndependent/RemoveTree.h',
'<(glslang_path)/glslang/MachineIndependent/Scan.cpp',
'<(glslang_path)/glslang/MachineIndependent/Scan.h',
'<(glslang_path)/glslang/MachineIndependent/ScanContext.h',
'<(glslang_path)/glslang/MachineIndependent/ShaderLang.cpp',
'<(glslang_path)/glslang/MachineIndependent/SymbolTable.cpp',
'<(glslang_path)/glslang/MachineIndependent/SymbolTable.h',
'<(glslang_path)/glslang/MachineIndependent/Versions.cpp',
'<(glslang_path)/glslang/MachineIndependent/Versions.h',
'<(glslang_path)/glslang/OSDependent/osinclude.h',
'<(glslang_path)/glslang/Public/ShaderLang.h',
'<(glslang_path)/hlsl/hlslAttributes.cpp',
'<(glslang_path)/hlsl/hlslAttributes.h',
'<(glslang_path)/hlsl/hlslGrammar.cpp',
'<(glslang_path)/hlsl/hlslGrammar.h',
'<(glslang_path)/hlsl/hlslOpMap.cpp',
'<(glslang_path)/hlsl/hlslOpMap.h',
'<(glslang_path)/hlsl/hlslParseables.cpp',
'<(glslang_path)/hlsl/hlslParseables.h',
'<(glslang_path)/hlsl/hlslParseHelper.cpp',
'<(glslang_path)/hlsl/hlslParseHelper.h',
'<(glslang_path)/hlsl/hlslScanContext.cpp',
'<(glslang_path)/hlsl/hlslScanContext.h',
'<(glslang_path)/hlsl/hlslTokens.h',
'<(glslang_path)/hlsl/hlslTokenStream.cpp',
'<(glslang_path)/hlsl/hlslTokenStream.h',
'<(glslang_path)/OGLCompilersDLL/InitializeDll.cpp',
'<(glslang_path)/OGLCompilersDLL/InitializeDll.h',
'<(glslang_path)/SPIRV/bitutils.h',
'<(glslang_path)/SPIRV/disassemble.cpp',
'<(glslang_path)/SPIRV/disassemble.h',
'<(glslang_path)/SPIRV/doc.cpp',
'<(glslang_path)/SPIRV/doc.h',
'<(glslang_path)/SPIRV/GLSL.ext.KHR.h',
'<(glslang_path)/SPIRV/GLSL.std.450.h',
'<(glslang_path)/SPIRV/GlslangToSpv.cpp',
'<(glslang_path)/SPIRV/GlslangToSpv.h',
'<(glslang_path)/SPIRV/hex_float.h',
'<(glslang_path)/SPIRV/InReadableOrder.cpp',
'<(glslang_path)/SPIRV/Logger.cpp',
'<(glslang_path)/SPIRV/Logger.h',
'<(glslang_path)/SPIRV/spirv.hpp',
'<(glslang_path)/SPIRV/SpvBuilder.cpp',
'<(glslang_path)/SPIRV/SpvBuilder.h',
'<(glslang_path)/SPIRV/spvIR.h',
'<(glslang_path)/StandAlone/ResourceLimits.cpp',
'<(glslang_path)/StandAlone/ResourceLimits.h',
],
'glslang_win_sources':
[
'<(glslang_path)/glslang/OSDependent/Windows/ossource.cpp',
],
'glslang_unix_sources':
[
'<(glslang_path)/glslang/OSDependent/Unix/ossource.cpp',
],
'spirv_tools_sources': 'spirv_tools_sources':
[ [
'<(angle_gen_path)/vulkan/core.insts-1.0.inc', '<(angle_gen_path)/vulkan/core.insts-1.0.inc',
...@@ -310,6 +419,56 @@ ...@@ -310,6 +419,56 @@
}, },
{ {
'target_name': 'glslang',
'type': 'static_library',
'sources':
[
'<@(glslang_sources)',
],
'include_dirs':
[
'<(glslang_path)',
],
'msvs_settings':
{
'VCCLCompilerTool':
{
'PreprocessorDefinitions':
[
'_HAS_EXCEPTIONS=0',
],
'AdditionalOptions':
[
'/wd4100', # Unreferenced formal parameter
'/wd4456', # Declaration hides previous local declaration
'/wd4457', # Declaration hides function parameter
'/wd4458', # Declaration hides class member
'/wd4702', # Unreachable code (from glslang_tab.cpp)
'/wd4718', # Recursive call has no side effects (from PpContext.cpp)
],
},
},
'direct_dependent_settings':
{
'include_dirs':
[
'<(glslang_path)/glslang/Public',
'<(glslang_path)',
],
},
'conditions':
[
['OS=="win"',
{
'sources':
[
'<@(glslang_win_sources)',
],
}],
],
},
{
'target_name': 'spirv_tools', 'target_name': 'spirv_tools',
'type': 'static_library', 'type': 'static_library',
'sources': 'sources':
...@@ -953,6 +1112,7 @@ ...@@ -953,6 +1112,7 @@
'type': 'none', 'type': 'none',
'dependencies': 'dependencies':
[ [
'glslang',
'VkLayer_core_validation', 'VkLayer_core_validation',
'VkLayer_image', 'VkLayer_image',
'VkLayer_object_tracker', 'VkLayer_object_tracker',
...@@ -964,6 +1124,7 @@ ...@@ -964,6 +1124,7 @@
], ],
'export_dependent_settings': 'export_dependent_settings':
[ [
'glslang',
'vulkan_loader', 'vulkan_loader',
], ],
} }
......
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