Commit d47044ad by Jamie Madill Committed by Commit Bot

Vulkan: Add framework for internal shaders.

Vulkan intenal shaders are stored in a ShaderLibrary, and this is owned by the RendererVk. This way the shaders are reused between all the different Contexts. They are initialized lazily to keep init time low. They also have an associated Serial (called a ProgramSerial) so they can be identified in a PipelineDesc (used by the Pipeline cache). We use a python script to build and invoke the glslang validator, that also produces SPIR-V binary code snippets. These snippets are gathered into an auto-generated file that is exposed via an auto-generated header file. The InternalShaderID enum class gives access to the internal shaders that are shared through the Vulkan back-end. This also adds simple clear shaders to be used in masked color clears. The patch doesn't add any functionality but it is split off from the color clear functionality to keep the code size down. Bug: angleproject:2339 Bug: angleproject:2455 Change-Id: Ie83043eda217c9f013817b198c92a3b7ba0878b4 Reviewed-on: https://chromium-review.googlesource.com/1031372 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 41529e5e
...@@ -435,9 +435,7 @@ if (angle_enable_vulkan) { ...@@ -435,9 +435,7 @@ if (angle_enable_vulkan) {
deps += [ "$angle_root/third_party/vulkan-validation-layers:libvulkan" ] deps += [ "$angle_root/third_party/vulkan-validation-layers:libvulkan" ]
data_deps += data_deps +=
[ "$angle_root/third_party/vulkan-validation-layers:VkICD_mock_icd" ] [ "$angle_root/third_party/vulkan-validation-layers:VkICD_mock_icd" ]
public_configs += [ public_configs += [ "$angle_root/third_party/vulkan-validation-layers:vulkan_loader_config" ]
"$angle_root/third_party/vulkan-validation-layers:vulkan_loader_config",
]
} }
if (angle_enable_vulkan_validation_layers) { if (angle_enable_vulkan_validation_layers) {
...@@ -552,6 +550,10 @@ static_library("libANGLE") { ...@@ -552,6 +550,10 @@ static_library("libANGLE") {
deps += [ ":angle_vulkan" ] deps += [ ":angle_vulkan" ]
public_deps += public_deps +=
[ "$angle_root/third_party/vulkan-validation-layers:vulkan_headers" ] [ "$angle_root/third_party/vulkan-validation-layers:vulkan_headers" ]
# Include generated shaders.
import("src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.gni")
sources += angle_vulkan_internal_shaders
} }
if (angle_enable_null) { if (angle_enable_null) {
......
...@@ -9,8 +9,25 @@ ...@@ -9,8 +9,25 @@
import os, subprocess, sys import os, subprocess, sys
# TODO(jmadill): Might be nice to have a standard way for scripts to return root_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
# their inputs and outputs rather than listing them here.
# auto_script is a standard way for scripts to return their inputs and outputs.
def grab_from_script(script, param):
res = subprocess.check_output(['python', script, param]).strip()
return [os.path.abspath(os.path.join(os.path.dirname(script), name)) for name in res.split(',')]
def auto_script(script):
# Set the CWD to the script directory.
os.chdir(os.path.dirname(os.path.abspath(script)))
base_script = os.path.basename(script)
return {
'script': script,
'inputs': grab_from_script(base_script, 'inputs'),
'outputs': grab_from_script(base_script, 'outputs'),
}
# TODO(jmadill): Convert everyting to auto-script.
generators = { generators = {
'ANGLE format': { 'ANGLE format': {
'inputs': [ 'inputs': [
...@@ -159,6 +176,8 @@ generators = { ...@@ -159,6 +176,8 @@ generators = {
], ],
'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py', 'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py',
}, },
'Vulkan internal shader programs':
auto_script('src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py'),
'Emulated HLSL functions': { 'Emulated HLSL functions': {
'inputs': [ 'inputs': [
'src/compiler/translator/emulated_builtin_function_data_hlsl.json' 'src/compiler/translator/emulated_builtin_function_data_hlsl.json'
...@@ -185,7 +204,6 @@ generators = { ...@@ -185,7 +204,6 @@ generators = {
}, },
} }
root_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
any_dirty = False any_dirty = False
for name, info in sorted(generators.iteritems()): for name, info in sorted(generators.iteritems()):
......
...@@ -127,13 +127,14 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -127,13 +127,14 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
bool clearColor = IsMaskFlagSet(static_cast<int>(mask), GL_COLOR_BUFFER_BIT); bool clearColor = IsMaskFlagSet(static_cast<int>(mask), GL_COLOR_BUFFER_BIT);
const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthStencilAttachment(); const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthStencilAttachment();
const gl::State &glState = context->getGLState();
// If we clear the depth OR the stencil but not both, and we have a packed depth stencil // If we clear the depth OR the stencil but not both, and we have a packed depth stencil
// attachment, we need to use clearAttachment instead of clearDepthStencil since Vulkan won't // attachment, we need to use clearAttachment instead of clearDepthStencil since Vulkan won't
// allow us to clear one or the other separately. // allow us to clear one or the other separately.
bool isSingleClearOnPackedDepthStencilAttachment = bool isSingleClearOnPackedDepthStencilAttachment =
depthStencilAttachment && (clearDepth != clearStencil); depthStencilAttachment && (clearDepth != clearStencil);
if (context->getGLState().isScissorTestEnabled() || isSingleClearOnPackedDepthStencilAttachment) if (glState.isScissorTestEnabled() || isSingleClearOnPackedDepthStencilAttachment)
{ {
// With scissor test enabled, we clear very differently and we don't need to access // With scissor test enabled, we clear very differently and we don't need to access
// the image inside each attachment we can just use clearCmdAttachments with our // the image inside each attachment we can just use clearCmdAttachments with our
...@@ -178,6 +179,8 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -178,6 +179,8 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
writingNode = getCurrentWritingNode(); writingNode = getCurrentWritingNode();
} }
// TODO(jmadill): Check for masked color clear. http://anglebug.com/2455
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t colorIndex : mState.getEnabledDrawBuffers()) for (size_t colorIndex : mState.getEnabledDrawBuffers())
......
...@@ -223,6 +223,7 @@ RendererVk::~RendererVk() ...@@ -223,6 +223,7 @@ RendererVk::~RendererVk()
mRenderPassCache.destroy(mDevice); mRenderPassCache.destroy(mDevice);
mPipelineCache.destroy(mDevice); mPipelineCache.destroy(mDevice);
mShaderLibrary.destroy(mDevice);
if (mGlslangWrapper) if (mGlslangWrapper)
{ {
...@@ -972,4 +973,8 @@ vk::Error RendererVk::getPipeline(const ProgramVk *programVk, ...@@ -972,4 +973,8 @@ vk::Error RendererVk::getPipeline(const ProgramVk *programVk,
programVk->getLinkedFragmentModule(), desc, pipelineOut); programVk->getLinkedFragmentModule(), desc, pipelineOut);
} }
vk::ShaderLibrary *RendererVk::getShaderLibrary()
{
return &mShaderLibrary;
}
} // namespace rx } // namespace rx
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h" #include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_internal_shaders.h"
namespace egl namespace egl
{ {
...@@ -127,6 +128,8 @@ class RendererVk : angle::NonCopyable ...@@ -127,6 +128,8 @@ class RendererVk : angle::NonCopyable
// Issues a new serial for linked shader modules. Used in the pipeline cache. // Issues a new serial for linked shader modules. Used in the pipeline cache.
Serial issueProgramSerial(); Serial issueProgramSerial();
vk::ShaderLibrary *getShaderLibrary();
private: private:
vk::Error initializeDevice(uint32_t queueFamilyIndex); vk::Error initializeDevice(uint32_t queueFamilyIndex);
void ensureCapsInitialized() const; void ensureCapsInitialized() const;
...@@ -185,6 +188,9 @@ class RendererVk : angle::NonCopyable ...@@ -185,6 +188,9 @@ class RendererVk : angle::NonCopyable
// See the design doc for an overview of the pipeline layout structure. // See the design doc for an overview of the pipeline layout structure.
vk::PipelineLayout mGraphicsPipelineLayout; vk::PipelineLayout mGraphicsPipelineLayout;
std::vector<vk::DescriptorSetLayout> mGraphicsDescriptorSetLayouts; std::vector<vk::DescriptorSetLayout> mGraphicsDescriptorSetLayouts;
// Internal shader library.
vk::ShaderLibrary mShaderLibrary;
}; };
} // namespace rx } // namespace rx
......
#!/usr/bin/python
# Copyright 2018 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.
#
# gen_vk_internal_shaders.py:
# Code generation for internal Vulkan shaders. Should be run when an intenal
# shader program is changed, added or removed.
from datetime import date
import os
import subprocess
import sys
out_file_cpp = 'vk_internal_shaders_autogen.cpp'
out_file_h = 'vk_internal_shaders_autogen.h'
out_file_gni = 'vk_internal_shaders_autogen.gni'
# Templates for the generated files:
template_shader_library_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}
//
// Copyright {copyright_year} 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.
//
// {out_file_name}:
// Pre-generated shader library for the ANGLE Vulkan back-end.
#include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
#include "common/debug.h"
namespace rx
{{
namespace vk
{{
namespace priv
{{
namespace
{{
{internal_shader_includes}
constexpr ShaderBlob kShaderBlobs[] = {{
{internal_shader_array_entries}
}};
}} // anonymous namespace
const ShaderBlob &GetInternalShaderBlob(InternalShaderID shaderID)
{{
ASSERT(static_cast<size_t>(shaderID) < static_cast<size_t>(InternalShaderID::EnumCount));
return kShaderBlobs[static_cast<size_t>(shaderID)];
}}
}} // namespace priv
}} // namespace vk
}} // namespace rx
"""
template_shader_library_h = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}
//
// Copyright {copyright_year} 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.
//
// {out_file_name}:
// Pre-generated shader library for the ANGLE Vulkan back-end.
#ifndef LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
#define LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
#include <stddef.h>
#include <stdint.h>
#include <utility>
namespace rx
{{
namespace vk
{{
enum class InternalShaderID
{{
{internal_shader_ids}
}};
namespace priv
{{
// This is SPIR-V binary blob and the size.
struct ShaderBlob
{{
const uint32_t *code;
size_t codeSize;
}};
const ShaderBlob &GetInternalShaderBlob(InternalShaderID shaderID);
}} // priv
}} // namespace vk
}} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
"""
template_shader_includes_gni = """# GENERATED FILE - DO NOT EDIT.
# Generated by {script_name} using data from {input_file_name}
#
# Copyright {copyright_year} 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.
#
# {out_file_name}:
# List of generated shaders for inclusion in ANGLE's build process.
angle_vulkan_internal_shaders = [
{shaders_list}
]
"""
# Gets the constant variable name for a generated shader.
def get_var_name(shader):
return "k" + os.path.basename(shader).replace(".", "_")
# Gets the internal ID string for a particular shader.
def get_shader_id(shader):
file = os.path.splitext(os.path.basename(shader))[0]
return file.replace(".", "_")
# Returns the name of the generated SPIR-V file for a shader.
def get_output_name(shader):
return os.path.join('shaders', 'gen', os.path.basename(shader) + ".inc")
# Finds a path to GN's out directory
def find_build_path(path):
out = os.path.join(path, "out")
if (os.path.isdir(out)):
for o in os.listdir(out):
subdir = os.path.join(out, o)
if os.path.isdir(subdir):
argsgn = os.path.join(subdir, "args.gn")
if os.path.isfile(argsgn):
return subdir
else:
parent = os.path.join(path, "..")
if (os.path.isdir(parent)):
return find_build_path(parent)
else:
raise Exception("Could not find GN out directory")
# Generates the code for a shader blob array entry.
def gen_shader_blob_entry(shader):
var_name = get_var_name(os.path.basename(shader))[0:-4]
return "{%s, %s}" % (var_name, "sizeof(%s)" % var_name)
def slash(s):
return s.replace('\\', '/')
def gen_shader_include(shader):
return '#include "libANGLE/renderer/vulkan/%s"' % slash(shader)
# STEP 0: Handle inputs/outputs for run_code_generation.py's auto_script
shaders_dir = os.path.join('shaders', 'src')
if not os.path.isdir(shaders_dir):
raise Exception("Could not find shaders directory")
input_shaders = sorted([os.path.join(shaders_dir, shader) for shader in os.listdir(shaders_dir)])
output_shaders = sorted([get_output_name(shader) for shader in input_shaders])
outputs = output_shaders + [out_file_cpp, out_file_h]
if len(sys.argv) == 2 and sys.argv[1] == 'inputs':
print(",".join(input_shaders))
sys.exit(0)
elif len(sys.argv) == 2 and sys.argv[1] == 'outputs':
print(",".join(outputs))
sys.exit(0)
# STEP 1: Call glslang to generate the internal shaders into small .inc files.
# a) Get the path to the glslang binary from the script directory.
build_path = find_build_path(".")
print("Using glslang_validator from '" + build_path + "'")
result = subprocess.call(['ninja', '-C', build_path, 'glslang_validator'])
if result != 0:
raise Exception("Error building glslang_validator")
glslang_binary = 'glslang_validator'
if os.name == 'nt':
glslang_binary += '.exe'
glslang_path = os.path.join(build_path, glslang_binary)
if not os.path.isfile(glslang_path):
raise Exception("Could not find " + glslang_binary)
# b) Iterate over the shaders and call glslang with the right arguments.
for shader_file in input_shaders:
glslang_args = [
glslang_path,
'-V', # Output mode is Vulkan
'--variable-name', get_var_name(shader_file), # C-style variable name
'-o', get_output_name(shader_file), # Output file
shader_file, # Input GLSL shader
]
result = subprocess.call(glslang_args)
if result != 0:
raise Exception("Error compiling " + shader_file)
# STEP 2: Consolidate the .inc files into an auto-generated cpp/h library.
with open(out_file_cpp, 'w') as outfile:
includes = "\n".join([gen_shader_include(shader) for shader in output_shaders])
array_entries = ",\n".join([gen_shader_blob_entry(shader) for shader in output_shaders])
outcode = template_shader_library_cpp.format(
script_name = __file__,
copyright_year = date.today().year,
out_file_name = out_file_cpp,
input_file_name = 'shaders/src/*',
internal_shader_includes = includes,
internal_shader_array_entries = array_entries)
outfile.write(outcode)
outfile.close()
with open(out_file_h, 'w') as outfile:
ids = ",\n".join([get_shader_id(shader) for shader in output_shaders] + ["EnumCount"])
outcode = template_shader_library_h.format(
script_name = __file__,
copyright_year = date.today().year,
out_file_name = out_file_h,
input_file_name = 'shaders/src/*',
internal_shader_ids = ids)
outfile.write(outcode)
outfile.close()
# STEP 3: Create a gni file with the generated files.
with open(out_file_gni, 'w') as outfile:
outcode = template_shader_includes_gni.format(
script_name = __file__,
copyright_year = date.today().year,
out_file_name = out_file_gni,
input_file_name = 'shaders/src/*',
shaders_list = ',\n'.join([' "' + slash(shader) + '"' for shader in output_shaders]))
outfile.write(outcode)
outfile.close()
// Overload400-PrecQual.2000 12-Apr-2017
#pragma once
const uint32_t kFullScreenQuad_vert[] = {
0x07230203,0x00010000,0x00080002,0x00000024,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000d,0x0000001b,0x00030003,
0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000b,
0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000000b,0x00000000,0x505f6c67,
0x7469736f,0x006e6f69,0x00070006,0x0000000b,0x00000001,0x505f6c67,0x746e696f,0x657a6953,
0x00000000,0x00070006,0x0000000b,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,
0x00070006,0x0000000b,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,
0x0000000d,0x00000000,0x00060005,0x0000001b,0x565f6c67,0x65747265,0x646e4978,0x00007865,
0x00050005,0x0000001e,0x65646e69,0x6c626178,0x00000065,0x00050048,0x0000000b,0x00000000,
0x0000000b,0x00000000,0x00050048,0x0000000b,0x00000001,0x0000000b,0x00000001,0x00050048,
0x0000000b,0x00000002,0x0000000b,0x00000003,0x00050048,0x0000000b,0x00000003,0x0000000b,
0x00000004,0x00030047,0x0000000b,0x00000002,0x00040047,0x0000001b,0x0000000b,0x0000002a,
0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,
0x00040017,0x00000007,0x00000006,0x00000004,0x00040015,0x00000008,0x00000020,0x00000000,
0x0004002b,0x00000008,0x00000009,0x00000001,0x0004001c,0x0000000a,0x00000006,0x00000009,
0x0006001e,0x0000000b,0x00000007,0x00000006,0x0000000a,0x0000000a,0x00040020,0x0000000c,
0x00000003,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000003,0x00040015,0x0000000e,
0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x0004002b,0x00000008,
0x00000010,0x00000006,0x0004001c,0x00000011,0x00000007,0x00000010,0x0004002b,0x00000006,
0x00000012,0xbf800000,0x0004002b,0x00000006,0x00000013,0x3f800000,0x0004002b,0x00000006,
0x00000014,0x00000000,0x0007002c,0x00000007,0x00000015,0x00000012,0x00000013,0x00000014,
0x00000013,0x0007002c,0x00000007,0x00000016,0x00000012,0x00000012,0x00000014,0x00000013,
0x0007002c,0x00000007,0x00000017,0x00000013,0x00000012,0x00000014,0x00000013,0x0007002c,
0x00000007,0x00000018,0x00000013,0x00000013,0x00000014,0x00000013,0x0009002c,0x00000011,
0x00000019,0x00000015,0x00000016,0x00000017,0x00000015,0x00000017,0x00000018,0x00040020,
0x0000001a,0x00000001,0x0000000e,0x0004003b,0x0000001a,0x0000001b,0x00000001,0x00040020,
0x0000001d,0x00000007,0x00000011,0x00040020,0x0000001f,0x00000007,0x00000007,0x00040020,
0x00000022,0x00000003,0x00000007,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,
0x000200f8,0x00000005,0x0004003b,0x0000001d,0x0000001e,0x00000007,0x0004003d,0x0000000e,
0x0000001c,0x0000001b,0x0003003e,0x0000001e,0x00000019,0x00050041,0x0000001f,0x00000020,
0x0000001e,0x0000001c,0x0004003d,0x00000007,0x00000021,0x00000020,0x00050041,0x00000022,
0x00000023,0x0000000d,0x0000000f,0x0003003e,0x00000023,0x00000021,0x000100fd,0x00010038
};
\ No newline at end of file
// Overload400-PrecQual.2000 12-Apr-2017
#pragma once
const uint32_t kUniformColor_frag[] = {
0x07230203,0x00010000,0x00080002,0x00000012,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0006000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x00030010,0x00000004,
0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,
0x00050005,0x00000009,0x6f6c6f63,0x74754f72,0x00000000,0x00040005,0x0000000a,0x636f6c62,
0x0000006b,0x00050006,0x0000000a,0x00000000,0x6f6c6f63,0x006e4972,0x00030005,0x0000000c,
0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00050048,0x0000000a,0x00000000,
0x00000023,0x00000000,0x00030047,0x0000000a,0x00000002,0x00040047,0x0000000c,0x00000022,
0x00000000,0x00040047,0x0000000c,0x00000021,0x00000001,0x00020013,0x00000002,0x00030021,
0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,
0x00000004,0x00040020,0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,
0x00000003,0x0003001e,0x0000000a,0x00000007,0x00040020,0x0000000b,0x00000002,0x0000000a,
0x0004003b,0x0000000b,0x0000000c,0x00000002,0x00040015,0x0000000d,0x00000020,0x00000001,
0x0004002b,0x0000000d,0x0000000e,0x00000000,0x00040020,0x0000000f,0x00000002,0x00000007,
0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,
0x0000000f,0x00000010,0x0000000c,0x0000000e,0x0004003d,0x00000007,0x00000011,0x00000010,
0x0003003e,0x00000009,0x00000011,0x000100fd,0x00010038
};
\ No newline at end of file
//
// Copyright 2018 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.
//
// FullScreenQuad.vert: Simple full-screen quad vertex shader.
#version 450 core
const vec4 kQuadVertices[] = {
vec4(-1, 1, 0, 1),
vec4(-1, -1, 0, 1),
vec4(1, -1, 0, 1),
vec4(-1, 1, 0, 1),
vec4(1, -1, 0, 1),
vec4(1, 1, 0, 1),
};
void main()
{
gl_Position = kQuadVertices[gl_VertexIndex];
}
//
// Copyright 2018 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.
//
// UniformColor.frag: Simple solid color fragment shader.
#version 450 core
layout(set = 0, binding = 1) uniform block {
vec4 colorIn;
};
layout(location = 0) out vec4 colorOut;
void main()
{
colorOut = colorIn;
}
//
// Copyright 2018 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.
//
// vk_internal_shaders.cpp:
// Pre-generated shader library for the ANGLE Vulkan back-end.
#include "libANGLE/renderer/vulkan/vk_internal_shaders.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx
{
namespace vk
{
ShaderLibrary::ShaderLibrary()
{
}
ShaderLibrary::~ShaderLibrary()
{
}
void ShaderLibrary::destroy(VkDevice device)
{
for (ShaderAndSerial &shader : mShaders)
{
shader.get().destroy(device);
}
}
Error ShaderLibrary::getShader(RendererVk *renderer,
InternalShaderID shaderID,
const ShaderAndSerial **shaderOut)
{
ShaderAndSerial &shader = mShaders[shaderID];
*shaderOut = &shader;
if (shader.get().valid())
{
return NoError();
}
const priv::ShaderBlob &shaderCode = priv::GetInternalShaderBlob(shaderID);
// Create shader lazily. Access will need to be locked for multi-threading.
VkShaderModuleCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.codeSize = shaderCode.codeSize;
createInfo.pCode = shaderCode.code;
ANGLE_TRY(shader.get().init(renderer->getDevice(), createInfo));
shader.updateSerial(renderer->issueProgramSerial());
return NoError();
}
} // namespace vk
} // namespace rx
//
// Copyright 2018 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.
//
// vk_internal_shaders.h:
// Pre-generated shader library for the ANGLE Vulkan back-end.
#ifndef LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_H_
#define LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_H_
#include "libANGLE/PackedEnums.h"
#include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx
{
namespace vk
{
class ShaderLibrary final : angle::NonCopyable
{
public:
ShaderLibrary();
~ShaderLibrary();
Error getShader(RendererVk *renderer,
InternalShaderID shaderID,
const ShaderAndSerial **shaderOut);
void destroy(VkDevice device);
private:
angle::PackedEnumMap<InternalShaderID, ShaderAndSerial> mShaders;
};
} // namespace vk
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_H_
// GENERATED FILE - DO NOT EDIT.
// Generated by gen_vk_internal_shaders.py using data from shaders/src/*
//
// Copyright 2018 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.
//
// vk_internal_shaders_autogen.cpp:
// Pre-generated shader library for the ANGLE Vulkan back-end.
#include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"
#include "common/debug.h"
namespace rx
{
namespace vk
{
namespace priv
{
namespace
{
#include "libANGLE/renderer/vulkan/shaders/gen/FullScreenQuad.vert.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/UniformColor.frag.inc"
constexpr ShaderBlob kShaderBlobs[] = {{kFullScreenQuad_vert, sizeof(kFullScreenQuad_vert)},
{kUniformColor_frag, sizeof(kUniformColor_frag)}};
} // anonymous namespace
const ShaderBlob &GetInternalShaderBlob(InternalShaderID shaderID)
{
ASSERT(static_cast<size_t>(shaderID) < static_cast<size_t>(InternalShaderID::EnumCount));
return kShaderBlobs[static_cast<size_t>(shaderID)];
}
} // namespace priv
} // namespace vk
} // namespace rx
# GENERATED FILE - DO NOT EDIT.
# Generated by gen_vk_internal_shaders.py using data from shaders/src/*
#
# Copyright 2018 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.
#
# vk_internal_shaders_autogen.gni:
# List of generated shaders for inclusion in ANGLE's build process.
angle_vulkan_internal_shaders = [
"shaders/gen/FullScreenQuad.vert.inc",
"shaders/gen/UniformColor.frag.inc",
]
// GENERATED FILE - DO NOT EDIT.
// Generated by gen_vk_internal_shaders.py using data from shaders/src/*
//
// Copyright 2018 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.
//
// vk_internal_shaders_autogen.h:
// Pre-generated shader library for the ANGLE Vulkan back-end.
#ifndef LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
#define LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
#include <stddef.h>
#include <stdint.h>
#include <utility>
namespace rx
{
namespace vk
{
enum class InternalShaderID
{
FullScreenQuad_vert,
UniformColor_frag,
EnumCount
};
namespace priv
{
// This is SPIR-V binary blob and the size.
struct ShaderBlob
{
const uint32_t *code;
size_t codeSize;
};
const ShaderBlob &GetInternalShaderBlob(InternalShaderID shaderID);
} // priv
} // namespace vk
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
...@@ -594,6 +594,8 @@ template <typename ObjT> ...@@ -594,6 +594,8 @@ template <typename ObjT>
class ObjectAndSerial final : angle::NonCopyable class ObjectAndSerial final : angle::NonCopyable
{ {
public: public:
ObjectAndSerial() {}
ObjectAndSerial(ObjT &&object, Serial queueSerial) ObjectAndSerial(ObjT &&object, Serial queueSerial)
: mObject(std::move(object)), mQueueSerial(queueSerial) : mObject(std::move(object)), mQueueSerial(queueSerial)
{ {
...@@ -645,6 +647,8 @@ Error AllocateImageMemory(VkDevice device, ...@@ -645,6 +647,8 @@ Error AllocateImageMemory(VkDevice device,
Image *image, Image *image,
DeviceMemory *deviceMemoryOut, DeviceMemory *deviceMemoryOut,
size_t *requiredSizeOut); size_t *requiredSizeOut);
using ShaderAndSerial = ObjectAndSerial<ShaderModule>;
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
......
...@@ -803,6 +803,10 @@ ...@@ -803,6 +803,10 @@
'libANGLE/renderer/vulkan/vk_format_utils.cpp', 'libANGLE/renderer/vulkan/vk_format_utils.cpp',
'libANGLE/renderer/vulkan/vk_helpers.cpp', 'libANGLE/renderer/vulkan/vk_helpers.cpp',
'libANGLE/renderer/vulkan/vk_helpers.h', 'libANGLE/renderer/vulkan/vk_helpers.h',
'libANGLE/renderer/vulkan/vk_internal_shaders.cpp',
'libANGLE/renderer/vulkan/vk_internal_shaders.h',
'libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h',
'libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp',
'libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp', 'libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp',
'libANGLE/renderer/vulkan/vk_utils.cpp', 'libANGLE/renderer/vulkan/vk_utils.cpp',
'libANGLE/renderer/vulkan/vk_utils.h', 'libANGLE/renderer/vulkan/vk_utils.h',
......
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