Hash :
f39e0f01
Author :
Date :
2020-09-07T23:07:37
Vulkan: Use subpass to unresolve render-to-texture attachments GL_EXT_multisampled_render_to_texture allows singlesampled textures to be used with multisampled framebuffers in such a way that the final resolve operation is automatically done. In Vulkan terminology, the render-to-texture GL attachment is used as a Vulkan subpass resolve attachment with an implicit (ideally-)lazy-memory multisampled image as the color attachment. This extension expects that if the texture is drawn to after the automatic resolve, the implicit multisampled image would take its fragment colors from the singlesampled image. In other words, the opposite of a resolve operation should be automatically performed at the start of the render pass. This change refers to this operation as "unresolve". The goal of this extension is to allow tiling GPUs to always keep multisampled data on tile memory and only ever load/store singlesampled data. The latter is achieved by using a subpass resolve attachment and setting storeOp of the multisampled color attachment to DONT_CARE. This change achieves the former by using an initial subpass that uses the resolve attachment as input attachment, draws into the multisampled color attachment and sets loadOp of said attachment to DONT_CARE. Bug: angleproject:4881 Change-Id: I99f410530365963567c77a7d62fc9db1500e5e3e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2397206 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//
// 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,
InvalidSpirv,
};
constexpr gl::ShaderMap<const char *> kDefaultUniformNames = {
{gl::ShaderType::Vertex, sh::vk::kDefaultUniformsNameVS},
{gl::ShaderType::Geometry, sh::vk::kDefaultUniformsNameGS},
{gl::ShaderType::Fragment, sh::vk::kDefaultUniformsNameFS},
{gl::ShaderType::Compute, sh::vk::kDefaultUniformsNameCS},
};
struct GlslangProgramInterfaceInfo
{
// Uniforms set index:
uint32_t uniformsAndXfbDescriptorSetIndex;
uint32_t currentUniformBindingIndex;
// Textures set index:
uint32_t textureDescriptorSetIndex;
uint32_t currentTextureBindingIndex;
// Other shader resources set index:
uint32_t shaderResourceDescriptorSetIndex;
uint32_t currentShaderResourceBindingIndex;
// ANGLE driver uniforms set index:
uint32_t driverUniformsDescriptorSetIndex;
uint32_t locationsUsedForXfbExtension;
};
struct GlslangSourceOptions
{
bool useOldRewriteStructSamplers = false;
bool supportsTransformFeedbackExtension = false;
bool emulateTransformFeedback = false;
bool emulateBresenhamLines = false;
};
using SpirvBlob = std::vector<uint32_t>;
using GlslangErrorCallback = std::function<angle::Result(GlslangError)>;
// Information for each shader interface variable. Not all fields are relevant to each shader
// interface variable. For example opaque uniforms require a set and binding index, while vertex
// attributes require a location.
struct ShaderInterfaceVariableInfo
{
ShaderInterfaceVariableInfo();
static constexpr uint32_t kInvalid = std::numeric_limits<uint32_t>::max();
// Used for interface blocks and opaque uniforms.
uint32_t descriptorSet = kInvalid;
uint32_t binding = kInvalid;
// Used for vertex attributes, fragment shader outputs and varyings. There could be different
// variables that share the same name, such as a vertex attribute and a fragment output. They
// will share this object since they have the same name, but will find possibly different
// locations in their respective slots.
uint32_t location = kInvalid;
uint32_t component = kInvalid;
// The stages this shader interface variable is active.
gl::ShaderBitSet activeStages;
// Used for transform feedback extension to decorate vertex shader output.
uint32_t xfbBuffer = kInvalid;
uint32_t xfbOffset = kInvalid;
uint32_t xfbStride = kInvalid;
// Indicates that the precision needs to be modified in the generated SPIR-V
// to support only transferring medium precision data when there's a precision
// mismatch between the shaders. For example, either the VS casts highp->mediump
// or the FS casts mediump->highp.
bool useRelaxedPrecision = false;
// Indicate if varying is input or output
bool varyingIsOutput = false;
};
// TODO: http://anglebug.com/4524: Need a different hash key than a string, since
// that's slow to calculate.
using ShaderInterfaceVariableInfoMap = std::unordered_map<std::string, ShaderInterfaceVariableInfo>;
using ShaderMapInterfaceVariableInfoMap = gl::ShaderMap<ShaderInterfaceVariableInfoMap>;
void GlslangInitialize();
void GlslangRelease();
bool GetImageNameWithoutIndices(std::string *name);
// Get the mapped sampler name after the soure is transformed by GlslangGetShaderSource()
std::string GetMappedSamplerNameOld(const std::string &originalName);
std::string GlslangGetMappedSamplerName(const std::string &originalName);
std::string GetXfbBufferName(const uint32_t bufferIndex);
void GlslangAssignLocations(GlslangSourceOptions &options,
const gl::ProgramExecutable &programExecutable,
const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<ShaderInterfaceVariableInfoMap> *variableInfoMapOut);
// Transform the source to include actual binding points for various shader resources (textures,
// buffers, xfb, etc). For some variables, these values are instead output to the variableInfoMap
// to be set during a SPIR-V transformation. This is a transitory step towards moving all variables
// to this map, at which point GlslangGetShaderSpirvCode will also be called by this function.
void GlslangGetShaderSource(GlslangSourceOptions &options,
const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut);
angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
const gl::ShaderType shaderType,
bool removeEarlyFragmentTestsOptimization,
bool removeDebugInfo,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob,
SpirvBlob *spirvBlobOut);
angle::Result GlslangGetShaderSpirvCode(const GlslangErrorCallback &callback,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources,
gl::ShaderMap<SpirvBlob> *spirvBlobsOut);
angle::Result GlslangCompileShaderOneOff(const GlslangErrorCallback &callback,
gl::ShaderType shaderType,
const std::string &shaderSource,
SpirvBlob *spirvBlobOut);
} // namespace rx
#endif // LIBANGLE_RENDERER_GLSLANG_WRAPPER_UTILS_H_