Commit a48f95ab by Le Quyen Committed by Commit Bot

Move Vulkan GlslangWrapper code to a shared location.

Metal backend will reuse Vulkan's GlslangWrapper code. The Metal backend will use this code to translate glsl to spirv then cross compile to Metal Shading Language using spirv-cross. So the source code of GlslangWrapper should be moved outside vulkan folder. Bug: angleproject:2634 Change-Id: I208062daf0d77756c9d32cfdab925b7dfdf83e05 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1858042Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent d4affcdd
......@@ -582,6 +582,18 @@ angle_source_set("libANGLE_headers") {
]
}
angle_source_set("angle_glslang_wrapper") {
sources = [
"src/libANGLE/renderer/glslang_wrapper_utils.cpp",
"src/libANGLE/renderer/glslang_wrapper_utils.h",
]
deps = [
":libANGLE_headers",
"${angle_glslang_dir}:glslang_default_resource_limits_sources",
"${angle_glslang_dir}:glslang_sources",
]
}
angle_source_set("libANGLE_base") {
sources = libangle_sources
......
......@@ -794,6 +794,27 @@ std::string StripLastArrayIndex(const std::string &name)
return name;
}
bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
{
constexpr char kZERO_ELEMENT[] = "[0]";
size_t start = 0;
while (true)
{
start = name.find(kZERO_ELEMENT[0], start);
if (start == std::string::npos)
{
break;
}
if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
{
return true;
}
start++;
}
return false;
}
const sh::ShaderVariable *FindShaderVarField(const sh::ShaderVariable &var,
const std::string &fullName,
GLuint *fieldIndexOut)
......
......@@ -63,6 +63,8 @@ std::string ParseResourceName(const std::string &name, std::vector<unsigned int>
// Strips only the last array index from a resource name.
std::string StripLastArrayIndex(const std::string &name);
bool SamplerNameContainsNonZeroArrayElement(const std::string &name);
// Find the child field which matches 'fullName' == var.name + "." + field.name.
// Return nullptr if not found.
const sh::ShaderVariable *FindShaderVarField(const sh::ShaderVariable &var,
......
......@@ -56,7 +56,7 @@ void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
TInfoSinkBase &out = objSink();
// This isn't super clean, but it gets the job done.
// See corresponding code in GlslangWrapper.cpp.
// See corresponding code in glslang_wrapper_utils.cpp.
TIntermSymbol *symbol = variable->getAsSymbolNode();
ASSERT(symbol);
......
//
// Copyright 2019 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.
//
// Wrapper for Khronos glslang compiler. This file is used by Vulkan and Metal backends.
//
#ifndef LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_
#define LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_
#include <functional>
#include "libANGLE/renderer/ProgramImpl.h"
namespace rx
{
enum class GlslangError
{
InvalidShader,
};
struct GlslangSourceOptions
{
// Uniforms set index:
uint32_t uniformsAndXfbDescriptorSetIndex = 0;
// Textures set index:
uint32_t textureDescriptorSetIndex = 1;
// Other shader resources set index:
uint32_t shaderResourceDescriptorSetIndex = 2;
// ANGLE driver uniforms set index:
uint32_t driverUniformsDescriptorSetIndex = 3;
// Binding index start for transform feedback buffers:
uint32_t xfbBindingIndexStart = 16;
};
using GlslangErrorCallback = std::function<angle::Result(GlslangError)>;
void GlslangInitialize();
void GlslangRelease();
// Get the mapped sampler name after the soure is transformed by GlslangGetShaderSource()
std::string GlslangGetMappedSamplerName(const std::string &originalName);
// Transform the source to include actual binding points for various shader
// resources (textures, buffers, xfb, etc)
void GlslangGetShaderSource(const GlslangSourceOptions &options,
bool useOldRewriteStructSamplers,
const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
gl::ShaderMap<std::string> *shaderSourcesOut);
angle::Result GlslangGetShaderSpirvCode(GlslangErrorCallback callback,
const gl::Caps &glCaps,
bool enableLineRasterEmulation,
const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
} // namespace rx
#endif // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_
......@@ -39,8 +39,8 @@ _vulkan_backend_sources = [
"FenceNVVk.h",
"FramebufferVk.cpp",
"FramebufferVk.h",
"GlslangWrapper.cpp",
"GlslangWrapper.h",
"GlslangWrapperVk.cpp",
"GlslangWrapperVk.h",
"ImageVk.cpp",
"ImageVk.h",
"MemoryObjectVk.cpp",
......@@ -263,12 +263,11 @@ angle_source_set("angle_vulkan_backend") {
libs = []
deps = [
":angle_vulkan",
"$angle_glslang_dir:glslang_default_resource_limits_sources",
"$angle_glslang_dir:glslang_sources",
"$angle_root:angle_image_util",
"$angle_spirv_tools_dir:spvtools_val",
]
public_deps = [
"$angle_root:angle_glslang_wrapper",
"$angle_root:libANGLE_headers",
"$angle_root/third_party/vulkan-headers/src:vulkan_headers",
]
......
//
// Copyright 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.
//
// GlslangWrapperVk: Wrapper for Vulkan's glslang compiler.
//
#include "libANGLE/renderer/vulkan/GlslangWrapperVk.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
namespace rx
{
namespace
{
angle::Result ErrorHandler(vk::Context *context, GlslangError)
{
ANGLE_VK_CHECK(context, false, VK_ERROR_INVALID_SHADER_NV);
return angle::Result::Stop;
}
GlslangSourceOptions CreateSourceOptions()
{
GlslangSourceOptions options;
options.uniformsAndXfbDescriptorSetIndex = kUniformsAndXfbDescriptorSetIndex;
options.textureDescriptorSetIndex = kTextureDescriptorSetIndex;
options.shaderResourceDescriptorSetIndex = kShaderResourceDescriptorSetIndex;
options.driverUniformsDescriptorSetIndex = kDriverUniformsDescriptorSetIndex;
options.xfbBindingIndexStart = kXfbBindingIndexStart;
return options;
}
} // namespace
// static
void GlslangWrapperVk::GetShaderSource(bool useOldRewriteStructSamplers,
const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
gl::ShaderMap<std::string> *shaderSourcesOut)
{
GlslangGetShaderSource(CreateSourceOptions(), useOldRewriteStructSamplers, programState,
resources, shaderSourcesOut);
}
// static
angle::Result GlslangWrapperVk::GetShaderCode(vk::Context *context,
const gl::Caps &glCaps,
bool enableLineRasterEmulation,
const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{
return GlslangGetShaderSpirvCode(
[context](GlslangError error) { return ErrorHandler(context, error); }, glCaps,
enableLineRasterEmulation, shaderSources, shaderCodeOut);
}
} // namespace rx
......@@ -3,7 +3,7 @@
// 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.
// GlslangWrapperVk: Wrapper for Vulkan's glslang compiler.
//
#ifndef LIBANGLE_RENDERER_VULKAN_GLSLANG_WRAPPER_H_
......@@ -16,12 +16,9 @@ namespace rx
{
// This class currently holds no state. If we want to hold state we would need to solve the
// potential race conditions with multiple threads.
class GlslangWrapper
class GlslangWrapperVk
{
public:
static void Initialize();
static void Release();
static void GetShaderSource(bool useOldRewriteStructSamplers,
const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
......@@ -32,12 +29,6 @@ class GlslangWrapper
bool enableLineRasterEmulation,
const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
private:
static angle::Result GetShaderCodeImpl(vk::Context *context,
const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodesOut);
};
} // namespace rx
......
......@@ -10,11 +10,13 @@
#include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "common/debug.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
#include "libANGLE/renderer/vulkan/GlslangWrapperVk.h"
#include "libANGLE/renderer/vulkan/TextureVk.h"
namespace rx
......@@ -271,7 +273,7 @@ void AddTextureDescriptorSetDesc(const gl::ProgramState &programState,
// 2D arrays are split into multiple 1D arrays when generating
// LinkedUniforms. Since they are flattened into one array, ignore the
// nonzero elements and expand the array to the total array size.
if (vk::SamplerNameContainsNonZeroArrayElement(samplerUniform.name))
if (gl::SamplerNameContainsNonZeroArrayElement(samplerUniform.name))
{
continue;
}
......@@ -369,7 +371,7 @@ angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk,
ASSERT(!valid());
gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
ANGLE_TRY(GlslangWrapper::GetShaderCode(
ANGLE_TRY(GlslangWrapperVk::GetShaderCode(
contextVk, contextVk->getCaps(), enableLineRasterEmulation, shaderSources, &shaderCodes));
for (const gl::ShaderType shaderType : gl::AllShaderTypes())
......@@ -564,7 +566,7 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
// assignment done in that function.
linkResources(resources);
GlslangWrapper::GetShaderSource(contextVk->useOldRewriteStructSamplers(), mState, resources,
GlslangWrapperVk::GetShaderSource(contextVk->useOldRewriteStructSamplers(), mState, resources,
&mShaderSources);
reset(contextVk);
......@@ -1616,7 +1618,7 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
uint32_t uniformIndex = mState.getUniformIndexFromSamplerIndex(textureIndex);
const gl::LinkedUniform &samplerUniform = mState.getUniforms()[uniformIndex];
std::string mappedSamplerName = vk::GetMappedSamplerName(samplerUniform.name);
std::string mappedSamplerName = GlslangGetMappedSamplerName(samplerUniform.name);
if (useOldRewriteStructSamplers ||
mappedSamplerNameToBindingIndex.emplace(mappedSamplerName, currentBindingIndex).second)
......
......@@ -20,12 +20,12 @@
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
#include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h"
......@@ -566,7 +566,7 @@ void RendererVk::onDestroy(vk::Context *context)
mPipelineCache.destroy(mDevice);
GlslangWrapper::Release();
GlslangRelease();
if (mDevice)
{
......@@ -885,7 +885,7 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
// Store the physical device memory properties so we can find the right memory pools.
mMemoryProperties.init(mPhysicalDevice);
GlslangWrapper::Initialize();
GlslangInitialize();
// Initialize the format table.
mFormatTable.initialize(this, &mNativeTextureCaps, &mNativeCaps.compressedTextureFormats);
......
......@@ -14,14 +14,14 @@ complete. They are templated with markers that are filled in later at link time.
1. **Link-Time Translation**: During a call to `glLinkProgram` the Vulkan back-end can know the
necessary locations and properties to write to connect the shader stage interfaces. We get the
completed shader source using ANGLE's [GlslangWrapper][GlslangWrapper.cpp] helper class. We still
completed shader source using ANGLE's [GlslangWrapperVk][GlslangWrapperVk.cpp] helper class. We still
cannot generate `VkShaderModules` since some ANGLE features like [OpenGL line
rasterization](OpenGLLineSegmentRasterization.md) emulation depend on draw-time information.
1. **Draw-time SPIR-V Generation**: Once the application records a draw call we use Khronos'
[glslang][glslang] to convert the Vulkan-compatible GLSL into SPIR-V with the correct draw-time
defines. The SPIR-V is then compiled into `VkShaderModules`. For details please see
[GlslangWrapper.cpp][GlslangWrapper.cpp]. The `VkShaderModules` are then used by `VkPipelines`. Note
[GlslangWrapperVk.cpp][GlslangWrapperVk.cpp]. The `VkShaderModules` are then used by `VkPipelines`. Note
that we currently don't use [SPIRV-Tools][SPIRV-Tools] to perform any SPIR-V optimization. This
could be something to improve on in the future.
......@@ -32,7 +32,7 @@ participant App
participant "ANGLE Front-end"
participant "Vulkan Back-end"
participant "ANGLE Translator"
participant "GlslangWrapper"
participant "GlslangWrapperVk"
participant "Glslang"
App->"ANGLE Front-end": glCompileShader (VS)
......@@ -51,8 +51,8 @@ App->"ANGLE Front-end": glLinkProgram
Note right of "Vulkan Back-end": ProgramVk inits uniforms,\nlayouts, and descriptors.
"Vulkan Back-end"->GlslangWrapper: GlslangWrapper::GetShaderSource
GlslangWrapper- ->"Vulkan Back-end": return filled-in sources
"Vulkan Back-end"->GlslangWrapperVk: GlslangWrapperVk::GetShaderSource
GlslangWrapperVk- ->"Vulkan Back-end": return filled-in sources
Note right of "Vulkan Back-end": Source is templated with\ndefines to be resolved at\ndraw time.
......@@ -63,8 +63,8 @@ Note right of App: App execution continues...
App->"ANGLE Front-end": glDrawArrays (any draw)
"ANGLE Front-end"->"Vulkan Back-end": ContextVk::drawArrays
"Vulkan Back-end"->GlslangWrapper: GlslangWrapper::GetShaderCode (with defines)
GlslangWrapper->Glslang: GlslangToSpv
"Vulkan Back-end"->GlslangWrapperVk: GlslangWrapperVk::GetShaderCode (with defines)
GlslangWrapperVk->Glslang: GlslangToSpv
Glslang- ->"Vulkan Back-end": Return SPIR-V
Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nrecord the draw.
......@@ -76,7 +76,7 @@ Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nr
[GL_KHR_vulkan_glsl]: https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt
[glslang]: https://github.com/KhronosGroup/glslang
[GlslangWrapper.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
[GlslangWrapperVk.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/libANGLE/renderer/vulkan/GlslangWrapperVk.cpp
[SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools
[translator]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/compiler/translator/
[TranslatorVulkan.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/compiler/translator/TranslatorVulkan.cpp
......
......@@ -552,57 +552,6 @@ void GarbageObject::destroy(VkDevice device)
}
}
bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
{
constexpr char kZERO_ELEMENT[] = "[0]";
size_t start = 0;
while (true)
{
start = name.find(kZERO_ELEMENT[0], start);
if (start == std::string::npos)
{
break;
}
if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
{
return true;
}
start++;
}
return false;
}
std::string GetMappedSamplerName(const std::string &originalName)
{
std::string samplerName = originalName;
// Samplers in structs are extracted.
std::replace(samplerName.begin(), samplerName.end(), '.', '_');
// Remove array elements
auto out = samplerName.begin();
for (auto in = samplerName.begin(); in != samplerName.end(); in++)
{
if (*in == '[')
{
while (*in != ']')
{
in++;
ASSERT(in != samplerName.end());
}
}
else
{
*out++ = *in;
}
}
samplerName.erase(out, samplerName.end());
return samplerName;
}
} // namespace vk
// VK_EXT_debug_utils
......
......@@ -599,8 +599,6 @@ class Recycler final : angle::NonCopyable
std::vector<T> mObjectFreeList;
};
bool SamplerNameContainsNonZeroArrayElement(const std::string &name);
std::string GetMappedSamplerName(const std::string &originalName);
} // namespace vk
// List of function pointers for used extensions.
......
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