Commit dbc605ce by Jamie Madill Committed by Commit Bot

Vulkan: Optimize VBO state changes.

Also has some minor optimizations for the front-end. 12% improvement on the Vulkan VBO change test. Bug: angleproject:3014 Change-Id: I38e1a8194edfc14bfe57424be348cb9688e928f4 Reviewed-on: https://chromium-review.googlesource.com/c/1369286Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 624ce6a3
......@@ -6,7 +6,7 @@
"ANGLE format:src/libANGLE/renderer/angle_format_map.json":
"be9f9bdbdf785dda05920146e8c55dbb",
"ANGLE format:src/libANGLE/renderer/gen_angle_format_table.py":
"01c2f2a74d2575f65f4f61c05e81c26a",
"809c5211278023fc159ff276d5fa6f7b",
"ANGLE load functions table:src/libANGLE/renderer/gen_load_functions_table.py":
"8afc7eecce2a3ba9f0b4beacb1aa7fe2",
"ANGLE load functions table:src/libANGLE/renderer/load_functions_data.json":
......@@ -34,7 +34,7 @@
"DXGI format:src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py":
"8ea01df6cb7f160772d3c85dd5164890",
"DXGI format:src/libANGLE/renderer/gen_angle_format_table.py":
"01c2f2a74d2575f65f4f61c05e81c26a",
"809c5211278023fc159ff276d5fa6f7b",
"ESSL static builtins:src/compiler/translator/builtin_function_declarations.txt":
"e5e567406476306ea06984d885be028d",
"ESSL static builtins:src/compiler/translator/builtin_variables.json":
......
......@@ -591,20 +591,14 @@ bool IsTriangleMode(PrimitiveMode drawMode)
return false;
}
bool IsLineMode(PrimitiveMode primitiveMode)
namespace priv
{
switch (primitiveMode)
{
case PrimitiveMode::LineLoop:
case PrimitiveMode::LineStrip:
case PrimitiveMode::LineStripAdjacency:
case PrimitiveMode::Lines:
return true;
default:
return false;
}
}
const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
{{PrimitiveMode::LineLoop, true},
{PrimitiveMode::LineStrip, true},
{PrimitiveMode::LineStripAdjacency, true},
{PrimitiveMode::Lines, true}}};
} // namespace priv
bool IsIntegerFormat(GLenum unsizedFormat)
{
......
......@@ -73,7 +73,17 @@ IndexRange ComputeIndexRange(DrawElementsType indexType,
GLuint GetPrimitiveRestartIndex(DrawElementsType indexType);
bool IsTriangleMode(PrimitiveMode drawMode);
bool IsLineMode(PrimitiveMode primitiveMode);
namespace priv
{
extern const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes;
} // namespace priv
ANGLE_INLINE bool IsLineMode(PrimitiveMode primitiveMode)
{
return priv::gLineModes[primitiveMode];
}
bool IsIntegerFormat(GLenum unsizedFormat);
// Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently
......
......@@ -1642,21 +1642,6 @@ void State::setVertexAttribi(GLuint index, const GLint values[4])
mCurrentValuesTypeMask.setIndex(GL_INT, index);
}
void State::setVertexAttribPointer(const Context *context,
unsigned int attribNum,
Buffer *boundBuffer,
GLint size,
GLenum type,
bool normalized,
bool pureInteger,
GLsizei stride,
const void *pointer)
{
getVertexArray()->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
normalized, pureInteger, stride, pointer);
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}
void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
{
getVertexArray()->setVertexAttribDivisor(context, index, divisor);
......
......@@ -25,7 +25,7 @@
#include "libANGLE/Texture.h"
#include "libANGLE/TransformFeedback.h"
#include "libANGLE/Version.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/angletypes.h"
namespace gl
......@@ -340,15 +340,22 @@ class State : angle::NonCopyable
void setVertexAttribf(GLuint index, const GLfloat values[4]);
void setVertexAttribu(GLuint index, const GLuint values[4]);
void setVertexAttribi(GLuint index, const GLint values[4]);
void setVertexAttribPointer(const Context *context,
unsigned int attribNum,
Buffer *boundBuffer,
GLint size,
GLenum type,
bool normalized,
bool pureInteger,
GLsizei stride,
const void *pointer);
ANGLE_INLINE void setVertexAttribPointer(const Context *context,
unsigned int attribNum,
Buffer *boundBuffer,
GLint size,
GLenum type,
bool normalized,
bool pureInteger,
GLsizei stride,
const void *pointer)
{
mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
normalized, pureInteger, stride, pointer);
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}
void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
{
......
......@@ -92,8 +92,9 @@ struct SwizzleState final
};
// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
struct TextureState final : private angle::NonCopyable
class TextureState final : private angle::NonCopyable
{
public:
TextureState(TextureType type);
~TextureState();
......
......@@ -13,11 +13,11 @@
#ifndef LIBANGLE_VERTEXARRAY_H_
#define LIBANGLE_VERTEXARRAY_H_
#include "common/Optional.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Observer.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/State.h"
#include "libANGLE/VertexAttribute.h"
#include <vector>
......
......@@ -1625,11 +1625,6 @@ angle::FormatID GetVertexFormatID(GLenum type,
}
}
angle::FormatID GetVertexFormatID(const VertexAttribute &attrib)
{
return GetVertexFormatID(attrib.type, attrib.normalized, attrib.size, attrib.pureInteger);
}
angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, GLenum currentValueType)
{
if (!attrib.enabled)
......
......@@ -17,6 +17,7 @@
#include "libANGLE/Caps.h"
#include "libANGLE/Error.h"
#include "libANGLE/Version.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/angletypes.h"
namespace gl
......@@ -250,7 +251,12 @@ angle::FormatID GetVertexFormatID(GLenum type,
GLboolean normalized,
GLuint components,
bool pureInteger);
angle::FormatID GetVertexFormatID(const VertexAttribute &attrib);
ANGLE_INLINE angle::FormatID GetVertexFormatID(const VertexAttribute &attrib)
{
return GetVertexFormatID(attrib.type, attrib.normalized, attrib.size, attrib.pureInteger);
}
angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, GLenum currentValueType);
const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID);
size_t GetVertexFormatSize(angle::FormatID vertexFormatID);
......
......@@ -12,12 +12,15 @@
#ifndef LIBANGLE_RENDERER_FORMAT_H_
#define LIBANGLE_RENDERER_FORMAT_H_
#include "libANGLE/renderer/FormatID_autogen.h"
#include "libANGLE/renderer/renderer_utils.h"
namespace angle
{
enum class FormatID;
extern const Format gFormatInfoTable[];
struct Format final : private angle::NonCopyable
{
constexpr Format(FormatID id,
......@@ -36,10 +39,12 @@ struct Format final : private angle::NonCopyable
GLuint depthBits,
GLuint stencilBits,
GLuint pixelBytes,
GLuint componentAlignmentMask,
bool isBlock,
bool isFixed);
static const Format &Get(FormatID id);
static const Format &Get(FormatID id) { return gFormatInfoTable[static_cast<int>(id)]; }
static FormatID InternalFormatToID(GLenum internalFormat);
constexpr bool hasDepthOrStencilBits() const;
......@@ -84,6 +89,10 @@ struct Format final : private angle::NonCopyable
GLuint pixelBytes;
// For 1-byte components, is MAX_UINT. For 2-byte, is 0x1. For 4-byte, is 0x3. For all others,
// 0x0.
GLuint componentAlignmentMask;
bool isBlock;
bool isFixed;
};
......@@ -104,6 +113,7 @@ constexpr Format::Format(FormatID id,
GLuint depthBits,
GLuint stencilBits,
GLuint pixelBytes,
GLuint componentAlignmentMask,
bool isBlock,
bool isFixed)
: id(id),
......@@ -122,6 +132,7 @@ constexpr Format::Format(FormatID id,
depthBits(depthBits),
stencilBits(stencilBits),
pixelBytes(pixelBytes),
componentAlignmentMask(componentAlignmentMask),
isBlock(isBlock),
isFixed(isFixed)
{}
......@@ -171,6 +182,4 @@ constexpr bool Format::isFloat() const
} // namespace angle
#include "libANGLE/renderer/FormatID_autogen.inc"
#endif // LIBANGLE_RENDERER_FORMAT_H_
......@@ -7,6 +7,11 @@
//
// ANGLE format enumeration.
#ifndef LIBANGLE_RENDERER_FORMATID_H_
#define LIBANGLE_RENDERER_FORMATID_H_
#include <cstdint>
namespace angle
{
......@@ -194,3 +199,5 @@ enum class FormatID
constexpr uint32_t kNumANGLEFormats = 177;
} // namespace angle
#endif // LIBANGLE_RENDERER_FORMATID_H_
......@@ -16,7 +16,9 @@
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Program.h"
#include "libANGLE/ProgramPipeline.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Texture.h"
#include "libANGLE/TransformFeedback.h"
#include "libANGLE/VertexArray.h"
......
......@@ -33,7 +33,7 @@ struct Offset;
struct Rectangle;
class Framebuffer;
struct PixelUnpackState;
struct TextureState;
class TextureState;
} // namespace gl
namespace rx
......
......@@ -24,6 +24,11 @@ template_autogen_h = """// GENERATED FILE - DO NOT EDIT.
//
// ANGLE format enumeration.
#ifndef LIBANGLE_RENDERER_FORMATID_H_
#define LIBANGLE_RENDERER_FORMATID_H_
#include <cstdint>
namespace angle
{{
......@@ -35,6 +40,8 @@ enum class FormatID
constexpr uint32_t kNumANGLEFormats = {num_angle_formats};
}} // namespace angle
#endif // LIBANGLE_RENDERER_FORMATID_H_
"""
template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
......@@ -61,9 +68,9 @@ static constexpr rx::FastCopyFunctionMap::Entry BGRAEntry = {{angle::FormatID::R
static constexpr rx::FastCopyFunctionMap BGRACopyFunctions = {{&BGRAEntry, 1}};
static constexpr rx::FastCopyFunctionMap NoCopyFunctions;
constexpr Format g_formatInfoTable[] = {{
const Format gFormatInfoTable[] = {{
// clang-format off
{{ FormatID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, false }},
{{ FormatID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false }},
{angle_format_info_cases} // clang-format on
}};
......@@ -76,12 +83,10 @@ FormatID Format::InternalFormatToID(GLenum internalFormat)
}}
}}
// static
const Format &Format::Get(FormatID id)
const Format *GetFormatInfoTable()
{{
return g_formatInfoTable[static_cast<size_t>(id)];
return gFormatInfoTable;
}}
}} // namespace angle
"""
......@@ -170,7 +175,7 @@ def get_color_write_function(angle_format):
return 'WriteColor<' + channel_struct + ', '+ write_component_type + '>'
format_entry_template = """ {{ FormatID::{id}, {glInternalFormat}, {fboImplementationInternalFormat}, {mipGenerationFunction}, {fastCopyFunctions}, {colorReadFunction}, {colorWriteFunction}, {namedComponentType}, {R}, {G}, {B}, {A}, {L}, {D}, {S}, {pixelBytes}, {isBlock}, {isFixed} }},
format_entry_template = """ {{ FormatID::{id}, {glInternalFormat}, {fboImplementationInternalFormat}, {mipGenerationFunction}, {fastCopyFunctions}, {colorReadFunction}, {colorWriteFunction}, {namedComponentType}, {R}, {G}, {B}, {A}, {L}, {D}, {S}, {pixelBytes}, {componentAlignmentMask}, {isBlock}, {isFixed} }},
"""
def get_named_component_type(component_type):
......@@ -189,6 +194,28 @@ def get_named_component_type(component_type):
else:
raise ValueError("Unknown component type for " + component_type)
def get_component_alignment_mask(channels, bits):
if channels == None or bits == None:
return "std::numeric_limits<GLuint>::max()"
bitness = bits[channels[0].upper()]
for channel in channels:
if channel not in "rgba":
return "std::numeric_limits<GLuint>::max()"
# Can happen for RGB10A2 formats.
if bits[channel.upper()] != bitness:
return "std::numeric_limits<GLuint>::max()"
component_bytes = (int(bitness) >> 3)
if component_bytes == 1:
return "0"
elif component_bytes == 2:
return "1"
elif component_bytes == 4:
return "3"
else:
# Can happen for 4-bit RGBA.
return "std::numeric_limits<GLuint>::max()"
def json_to_table_data(format_id, json, angle_to_gl):
table_data = ""
......@@ -236,6 +263,8 @@ def json_to_table_data(format_id, json, angle_to_gl):
for channel in angle_format.kChannels:
sum_of_bits += int(parsed[channel])
parsed["pixelBytes"] = sum_of_bits / 8
parsed["componentAlignmentMask"] = get_component_alignment_mask(
parsed["channels"], parsed["bits"])
parsed["isBlock"] = "true" if format_id.endswith("_BLOCK") else "false"
parsed["isFixed"] = "true" if "FIXED" in format_id else "false"
......@@ -300,6 +329,6 @@ output_h = template_autogen_h.format(
angle_format_enum = enum_data,
data_source_name = data_source_name,
num_angle_formats = num_angle_formats)
with open('FormatID_autogen.inc', 'wt') as out_file:
with open('FormatID_autogen.h', 'wt') as out_file:
out_file.write(output_h)
out_file.close()
......@@ -239,27 +239,6 @@ angle::Result ContextVk::finish(const gl::Context *context)
return mRenderer->finish(this);
}
angle::Result ContextVk::initPipeline()
{
ASSERT(!mCurrentPipeline);
const gl::AttributesMask activeAttribLocationsMask =
mProgram->getState().getActiveAttribLocationsMask();
// Ensure the topology of the pipeline description is updated.
mGraphicsPipelineDesc->updateTopology(mCurrentDrawMode);
// Copy over the latest attrib and binding descriptions.
mVertexArray->getPackedInputDescriptions(mGraphicsPipelineDesc.get());
// Ensure that the RenderPass description is updated.
mGraphicsPipelineDesc->updateRenderPassDesc(mDrawFramebuffer->getRenderPassDesc());
// Draw call shader patching, shader compilation, and pipeline cache query.
return mProgram->getGraphicsPipeline(this, mCurrentDrawMode, *mGraphicsPipelineDesc,
activeAttribLocationsMask, &mCurrentPipeline);
}
angle::Result ContextVk::setupDraw(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
......@@ -274,6 +253,7 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
{
invalidateCurrentPipeline();
mCurrentDrawMode = mode;
mGraphicsPipelineDesc->updateTopology(mCurrentDrawMode);
}
if (!mDrawFramebuffer->appendToStartedRenderPass(mRenderer, commandBufferOut))
......@@ -385,7 +365,13 @@ angle::Result ContextVk::handleDirtyPipeline(const gl::Context *context,
{
if (!mCurrentPipeline)
{
ANGLE_TRY(initPipeline());
// Copy over the latest attrib and binding descriptions. This should be done more lazily.
mVertexArray->getPackedInputDescriptions(mGraphicsPipelineDesc.get());
// Draw call shader patching, shader compilation, and pipeline cache query.
ANGLE_TRY(mProgram->getGraphicsPipeline(this, mCurrentDrawMode, *mGraphicsPipelineDesc,
mProgram->getState().getActiveAttribLocationsMask(),
&mCurrentPipeline));
}
commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->get());
......@@ -842,6 +828,7 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getDrawFramebuffer());
mGraphicsPipelineDesc->updateStencilBackWriteMask(glState.getDepthStencilState(),
glState.getDrawFramebuffer());
mGraphicsPipelineDesc->updateRenderPassDesc(mDrawFramebuffer->getRenderPassDesc());
break;
}
case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
......@@ -1050,21 +1037,6 @@ std::vector<PathImpl *> ContextVk::createPaths(GLsizei)
return std::vector<PathImpl *>();
}
void ContextVk::invalidateVertexAndIndexBuffers()
{
invalidateCurrentPipeline();
mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
}
void ContextVk::invalidateCurrentPipeline()
{
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
mCurrentPipeline = nullptr;
}
void ContextVk::invalidateCurrentTextures()
{
ASSERT(mProgram);
......@@ -1081,6 +1053,13 @@ void ContextVk::invalidateDriverUniforms()
mDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
}
void ContextVk::onFramebufferChange(const vk::RenderPassDesc &renderPassDesc)
{
// Ensure that the RenderPass description is updated.
invalidateCurrentPipeline();
mGraphicsPipelineDesc->updateRenderPassDesc(renderPassDesc);
}
angle::Result ContextVk::dispatchCompute(const gl::Context *context,
GLuint numGroupsX,
GLuint numGroupsY,
......@@ -1137,11 +1116,6 @@ VkColorComponentFlags ContextVk::getClearColorMask() const
return mClearColorMask;
}
const angle::FeaturesVk &ContextVk::getFeatures() const
{
return mRenderer->getFeatures();
}
angle::Result ContextVk::handleDirtyDriverUniforms(const gl::Context *context,
vk::CommandBuffer *commandBuffer)
{
......
......@@ -14,6 +14,7 @@
#include "common/PackedEnums.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace angle
......@@ -161,11 +162,19 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
VkDevice getDevice() const;
const angle::FeaturesVk &getFeatures() const;
void invalidateVertexAndIndexBuffers();
ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
ANGLE_INLINE void invalidateVertexAndIndexBuffers()
{
invalidateCurrentPipeline();
mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
}
void invalidateDefaultAttribute(size_t attribIndex);
void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
void onFramebufferChange(const vk::RenderPassDesc &renderPassDesc);
vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t descriptorSetIndex);
vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
......@@ -210,7 +219,6 @@ class ContextVk : public ContextImpl, public vk::Context
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mDirtyBitHandlers;
angle::Result initPipeline();
angle::Result setupDraw(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
......@@ -246,7 +254,14 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttribute(size_t attribIndex);
void invalidateCurrentPipeline();
ANGLE_INLINE void invalidateCurrentPipeline()
{
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
mCurrentPipeline = nullptr;
}
void invalidateCurrentTextures();
void invalidateDriverUniforms();
......
......@@ -785,27 +785,23 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
mActiveColorComponentMasksForClear[0].any(), mActiveColorComponentMasksForClear[1].any(),
mActiveColorComponentMasksForClear[2].any(), mActiveColorComponentMasksForClear[3].any());
mRenderPassDesc.reset();
mFramebuffer.release(renderer);
// Will freeze the current set of dependencies on this FBO. The next time we render we will
// create a new entry in the command graph.
mFramebuffer.finishCurrentCommands(renderer);
// No need to notify the ContextVk. A new command buffer will be started automatically.
// Notify the ContextVk to update the pipeline desc.
updateRenderPassDesc();
contextVk->onFramebufferChange(mRenderPassDesc);
return angle::Result::Continue;
}
const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc()
void FramebufferVk::updateRenderPassDesc()
{
if (mRenderPassDesc.valid())
{
return mRenderPassDesc.value();
}
vk::RenderPassDesc desc;
desc.setSamples(getSamples());
mRenderPassDesc = {};
mRenderPassDesc.setSamples(getSamples());
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors();
......@@ -813,17 +809,14 @@ const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc()
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
desc.packAttachment(colorRenderTarget->getImage().getFormat());
mRenderPassDesc.packAttachment(colorRenderTarget->getImage().getFormat());
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
desc.packAttachment(depthStencilRenderTarget->getImage().getFormat());
mRenderPassDesc.packAttachment(depthStencilRenderTarget->getImage().getFormat());
}
mRenderPassDesc = desc;
return mRenderPassDesc.value();
}
angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut)
......@@ -835,10 +828,9 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
return angle::Result::Continue;
}
const vk::RenderPassDesc &desc = getRenderPassDesc();
vk::RenderPass *renderPass = nullptr;
ANGLE_TRY(contextVk->getRenderer()->getCompatibleRenderPass(contextVk, desc, &renderPass));
ANGLE_TRY(
contextVk->getRenderer()->getCompatibleRenderPass(contextVk, mRenderPassDesc, &renderPass));
// If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
if (mBackbuffer)
......@@ -1083,9 +1075,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
gl::Rectangle renderArea =
gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
return mFramebuffer.beginRenderPass(contextVk, *framebuffer, renderArea,
mRenderPassDesc.value(), attachmentClearValues,
commandBufferOut);
return mFramebuffer.beginRenderPass(contextVk, *framebuffer, renderArea, mRenderPassDesc,
attachmentClearValues, commandBufferOut);
}
void FramebufferVk::updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a)
......
......@@ -91,7 +91,6 @@ class FramebufferVk : public FramebufferImpl
size_t index,
GLfloat *xy) const override;
RenderTargetVk *getDepthStencilRenderTarget() const;
const vk::RenderPassDesc &getRenderPassDesc();
// Internal helper function for readPixels operations.
angle::Result readPixelsImpl(ContextVk *contextVk,
......@@ -119,6 +118,8 @@ class FramebufferVk : public FramebufferImpl
RenderTargetVk *getFirstRenderTarget() const;
GLint getSamples() const;
const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; }
private:
FramebufferVk(RendererVk *renderer,
const gl::FramebufferState &state,
......@@ -165,10 +166,11 @@ class FramebufferVk : public FramebufferImpl
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags);
void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
void updateRenderPassDesc();
WindowSurfaceVk *mBackbuffer;
Optional<vk::RenderPassDesc> mRenderPassDesc;
vk::RenderPassDesc mRenderPassDesc;
vk::FramebufferHelper mFramebuffer;
RenderTargetCache<RenderTargetVk> mRenderTargetCache;
......
......@@ -10,7 +10,6 @@
#include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "common/debug.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
......@@ -132,11 +131,6 @@ angle::Result SyncDefaultUniformBlock(ContextVk *contextVk,
ANGLE_TRY(dynamicBuffer->flush(contextVk));
return angle::Result::Continue;
}
bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
{
return contextVk->getFeatures().basicGLLineRasterization && gl::IsLineMode(mode);
}
} // anonymous namespace
// ProgramVk::ShaderInfo implementation.
......@@ -149,23 +143,21 @@ angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk,
const std::string &fragmentSource,
bool enableLineRasterEmulation)
{
if (!valid())
{
std::vector<uint32_t> vertexCode;
std::vector<uint32_t> fragmentCode;
ANGLE_TRY(GlslangWrapper::GetShaderCode(contextVk, contextVk->getCaps(),
enableLineRasterEmulation, vertexSource,
fragmentSource, &vertexCode, &fragmentCode));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[gl::ShaderType::Vertex].get(),
vertexCode.data(), vertexCode.size() * sizeof(uint32_t)));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[gl::ShaderType::Fragment].get(),
fragmentCode.data(),
fragmentCode.size() * sizeof(uint32_t)));
mProgramHelper.setShader(gl::ShaderType::Vertex, &mShaders[gl::ShaderType::Vertex]);
mProgramHelper.setShader(gl::ShaderType::Fragment, &mShaders[gl::ShaderType::Fragment]);
}
ASSERT(!valid());
std::vector<uint32_t> vertexCode;
std::vector<uint32_t> fragmentCode;
ANGLE_TRY(GlslangWrapper::GetShaderCode(contextVk, contextVk->getCaps(),
enableLineRasterEmulation, vertexSource, fragmentSource,
&vertexCode, &fragmentCode));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[gl::ShaderType::Vertex].get(),
vertexCode.data(), vertexCode.size() * sizeof(uint32_t)));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[gl::ShaderType::Fragment].get(),
fragmentCode.data(), fragmentCode.size() * sizeof(uint32_t)));
mProgramHelper.setShader(gl::ShaderType::Vertex, &mShaders[gl::ShaderType::Vertex]);
mProgramHelper.setShader(gl::ShaderType::Fragment, &mShaders[gl::ShaderType::Fragment]);
return angle::Result::Continue;
}
......@@ -180,11 +172,6 @@ void ProgramVk::ShaderInfo::release(RendererVk *renderer)
}
}
bool ProgramVk::ShaderInfo::valid() const
{
return mShaders[gl::ShaderType::Vertex].get().valid();
}
// ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
: storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
......@@ -727,27 +714,6 @@ void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
UNIMPLEMENTED();
}
angle::Result ProgramVk::initShaders(ContextVk *contextVk,
gl::PrimitiveMode mode,
vk::ShaderProgramHelper **programOut)
{
if (UseLineRaster(contextVk, mode))
{
ANGLE_TRY(
mLineRasterShaderInfo.initShaders(contextVk, mVertexSource, mFragmentSource, true));
ASSERT(mLineRasterShaderInfo.valid());
*programOut = &mLineRasterShaderInfo.getShaderProgram();
}
else
{
ANGLE_TRY(mDefaultShaderInfo.initShaders(contextVk, mVertexSource, mFragmentSource, false));
ASSERT(mDefaultShaderInfo.valid());
*programOut = &mDefaultShaderInfo.getShaderProgram();
}
return angle::Result::Continue;
}
angle::Result ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex)
{
// Write out to a new a descriptor set.
......@@ -886,8 +852,8 @@ angle::Result ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk,
for (uint32_t arrayElement = 0; arrayElement < samplerBinding.boundTextureUnits.size();
++arrayElement)
{
GLuint textureUnit = samplerBinding.boundTextureUnits[arrayElement];
TextureVk *textureVk = activeTextures[textureUnit];
GLuint textureUnit = samplerBinding.boundTextureUnits[arrayElement];
TextureVk *textureVk = activeTextures[textureUnit];
// Ensure any writes to the textures are flushed before we read from them.
ANGLE_TRY(textureVk->ensureImageInitialized(contextVk));
......
......@@ -12,6 +12,7 @@
#include <array>
#include "common/utilities.h"
#include "libANGLE/renderer/ProgramImpl.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
......@@ -19,6 +20,11 @@
namespace rx
{
ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
{
return contextVk->getFeatures().basicGLLineRasterization && gl::IsLineMode(mode);
}
class ProgramVk : public ProgramImpl
{
public:
......@@ -122,8 +128,11 @@ class ProgramVk : public ProgramImpl
vk::ShaderProgramHelper *shaderProgram;
ANGLE_TRY(initShaders(contextVk, mode, &shaderProgram));
ASSERT(shaderProgram->isGraphicsProgram());
return shaderProgram->getGraphicsPipeline(contextVk, mPipelineLayout.get(), desc,
activeAttribLocations, pipelineOut);
RendererVk *renderer = contextVk->getRenderer();
return shaderProgram->getGraphicsPipeline(
contextVk, &renderer->getRenderPassCache(), renderer->getPipelineCache(),
renderer->getCurrentQueueSerial(), mPipelineLayout.get(), desc, activeAttribLocations,
pipelineOut);
}
private:
......@@ -148,9 +157,35 @@ class ProgramVk : public ProgramImpl
const gl::ProgramLinkedResources &resources,
gl::InfoLog &infoLog);
angle::Result initShaders(ContextVk *contextVk,
gl::PrimitiveMode mode,
vk::ShaderProgramHelper **shaderProgramOut);
ANGLE_INLINE angle::Result initShaders(ContextVk *contextVk,
gl::PrimitiveMode mode,
vk::ShaderProgramHelper **shaderProgramOut)
{
if (UseLineRaster(contextVk, mode))
{
if (!mLineRasterShaderInfo.valid())
{
ANGLE_TRY(mLineRasterShaderInfo.initShaders(contextVk, mVertexSource,
mFragmentSource, true));
}
ASSERT(mLineRasterShaderInfo.valid());
*shaderProgramOut = &mLineRasterShaderInfo.getShaderProgram();
}
else
{
if (!mDefaultShaderInfo.valid())
{
ANGLE_TRY(mDefaultShaderInfo.initShaders(contextVk, mVertexSource, mFragmentSource,
false));
}
ASSERT(mDefaultShaderInfo.valid());
*shaderProgramOut = &mDefaultShaderInfo.getShaderProgram();
}
return angle::Result::Continue;
}
// State for the default uniform blocks.
struct DefaultUniformBlock final : private angle::NonCopyable
......@@ -201,7 +236,8 @@ class ProgramVk : public ProgramImpl
const std::string &fragmentSource,
bool enableLineRasterEmulation);
void release(RendererVk *renderer);
bool valid() const;
ANGLE_INLINE bool valid() const { return mShaders[gl::ShaderType::Vertex].get().valid(); }
vk::ShaderProgramHelper &getShaderProgram() { return mProgramHelper; }
......
......@@ -186,6 +186,7 @@ class RendererVk : angle::NonCopyable
bool isMockICDEnabled() const { return mEnableMockICD; }
RenderPassCache &getRenderPassCache() { return mRenderPassCache; }
const vk::PipelineCache &getPipelineCache() const { return mPipelineCache; }
// Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
......
......@@ -306,6 +306,8 @@ angle::Result UtilsVk::setupProgram(vk::Context *context,
const vk::BindingPointer<vk::PipelineLayout> &pipelineLayout = mPipelineLayouts[function];
Serial serial = renderer->getCurrentQueueSerial();
vk::PipelineAndSerial *pipelineAndSerial;
if (isCompute)
{
......@@ -316,12 +318,14 @@ angle::Result UtilsVk::setupProgram(vk::Context *context,
{
program->setShader(gl::ShaderType::Vertex, vsShader);
program->setShader(gl::ShaderType::Fragment, fsCsShader);
ANGLE_TRY(program->getGraphicsPipeline(context, pipelineLayout.get(), *pipelineDesc,
gl::AttributesMask(), &pipelineAndSerial));
ANGLE_TRY(program->getGraphicsPipeline(
context, &renderer->getRenderPassCache(), renderer->getPipelineCache(), serial,
pipelineLayout.get(), *pipelineDesc, gl::AttributesMask(), &pipelineAndSerial));
}
commandBuffer->bindPipeline(bindPoint, pipelineAndSerial->get());
pipelineAndSerial->updateSerial(renderer->getCurrentQueueSerial());
pipelineAndSerial->updateSerial(serial);
if (descriptorSet != VK_NULL_HANDLE)
{
......
......@@ -32,9 +32,21 @@ constexpr VkBufferUsageFlags kIndexBufferUsageFlags = VK_BUFFER_USAGE_INDEX_BUFF
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
bool BindingIsAligned(const gl::VertexBinding &binding, unsigned componentSize)
ANGLE_INLINE bool BindingIsAligned(const gl::VertexBinding &binding,
const angle::Format &angleFormat,
unsigned int attribSize)
{
return (binding.getOffset() % componentSize == 0) && (binding.getStride() % componentSize == 0);
GLuint mask = angleFormat.componentAlignmentMask;
if (mask != std::numeric_limits<GLuint>::max())
{
return ((binding.getOffset() & mask) == 0 && (binding.getStride() & mask) == 0);
}
else
{
unsigned int formatSize = angleFormat.pixelBytes;
return ((binding.getOffset() * attribSize) % formatSize == 0) &&
((binding.getStride() * attribSize) % formatSize == 0);
}
}
angle::Result StreamVertexData(ContextVk *contextVk,
......@@ -393,9 +405,9 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
if (bufferGL)
{
BufferVk *bufferVk = vk::GetImpl(bufferGL);
unsigned componentSize =
mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes / attrib.size;
bool bindingIsAligned = BindingIsAligned(binding, componentSize);
const angle::Format &angleFormat =
mCurrentArrayBufferFormats[attribIndex]->angleFormat();
bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
!bindingIsAligned)
......@@ -459,18 +471,9 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
return angle::Result::Continue;
}
void VertexArrayVk::getPackedInputDescriptions(vk::GraphicsPipelineDesc *pipelineDesc)
{
updatePackedInputDescriptions();
pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
}
void VertexArrayVk::updatePackedInputDescriptions()
{
if (!mDirtyPackedInputs.any())
{
return;
}
ASSERT(mDirtyPackedInputs.any());
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
......
......@@ -36,7 +36,14 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexArray::DirtyAttribBitsArray &attribBits,
const gl::VertexArray::DirtyBindingBitsArray &bindingBits) override;
void getPackedInputDescriptions(vk::GraphicsPipelineDesc *pipelineDesc);
ANGLE_INLINE void getPackedInputDescriptions(vk::GraphicsPipelineDesc *pipelineDesc)
{
if (mDirtyPackedInputs.any())
{
updatePackedInputDescriptions();
}
pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
}
void updateDefaultAttrib(RendererVk *renderer,
size_t attribIndex,
......
......@@ -672,13 +672,6 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
return angle::Result::Continue;
}
void GraphicsPipelineDesc::updateVertexInputInfo(const VertexInputBindings &bindings,
const VertexInputAttributes &attribs)
{
mVertexInputBindings = bindings;
mVertexInputAttribs = attribs;
}
void GraphicsPipelineDesc::updateTopology(gl::PrimitiveMode drawMode)
{
mInputAssembltyAndColorBlendStateInfo.topology =
......@@ -1034,23 +1027,11 @@ void RenderPassCache::destroy(VkDevice device)
mPayload.clear();
}
angle::Result RenderPassCache::getCompatibleRenderPass(vk::Context *context,
Serial serial,
const vk::RenderPassDesc &desc,
vk::RenderPass **renderPassOut)
angle::Result RenderPassCache::addRenderPass(vk::Context *context,
Serial serial,
const vk::RenderPassDesc &desc,
vk::RenderPass **renderPassOut)
{
auto outerIt = mPayload.find(desc);
if (outerIt != mPayload.end())
{
InnerCache &innerCache = outerIt->second;
ASSERT(!innerCache.empty());
// Find the first element and return it.
innerCache.begin()->second.updateSerial(serial);
*renderPassOut = &innerCache.begin()->second.get();
return angle::Result::Continue;
}
// Insert some dummy attachment ops.
// It would be nice to pre-populate the cache in the Renderer so we rarely miss here.
vk::AttachmentOpsArray ops;
......@@ -1145,7 +1126,7 @@ void GraphicsPipelineCache::release(RendererVk *renderer)
mPayload.clear();
}
angle::Result GraphicsPipelineCache::getPipeline(
angle::Result GraphicsPipelineCache::insertPipeline(
vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const vk::RenderPass &compatibleRenderPass,
......@@ -1156,13 +1137,6 @@ angle::Result GraphicsPipelineCache::getPipeline(
const vk::GraphicsPipelineDesc &desc,
vk::PipelineAndSerial **pipelineOut)
{
auto item = mPayload.find(desc);
if (item != mPayload.end())
{
*pipelineOut = &item->second;
return angle::Result::Continue;
}
vk::Pipeline newPipeline;
// This "if" is left here for the benefit of VulkanPipelineCachePerfTest.
......
......@@ -268,8 +268,12 @@ class GraphicsPipelineDesc final
Pipeline *pipelineOut) const;
// Vertex input state
void updateVertexInputInfo(const VertexInputBindings &bindings,
const VertexInputAttributes &attribs);
ANGLE_INLINE void updateVertexInputInfo(const VertexInputBindings &bindings,
const VertexInputAttributes &attribs)
{
mVertexInputBindings = bindings;
mVertexInputAttribs = attribs;
}
// Input assembly info
void updateTopology(gl::PrimitiveMode drawMode);
......@@ -475,10 +479,26 @@ class RenderPassCache final : angle::NonCopyable
void destroy(VkDevice device);
angle::Result getCompatibleRenderPass(vk::Context *context,
Serial serial,
const vk::RenderPassDesc &desc,
vk::RenderPass **renderPassOut);
ANGLE_INLINE angle::Result getCompatibleRenderPass(vk::Context *context,
Serial serial,
const vk::RenderPassDesc &desc,
vk::RenderPass **renderPassOut)
{
auto outerIt = mPayload.find(desc);
if (outerIt != mPayload.end())
{
InnerCache &innerCache = outerIt->second;
ASSERT(!innerCache.empty());
// Find the first element and return it.
innerCache.begin()->second.updateSerial(serial);
*renderPassOut = &innerCache.begin()->second.get();
return angle::Result::Continue;
}
return addRenderPass(context, serial, desc, renderPassOut);
}
angle::Result getRenderPassWithOps(vk::Context *context,
Serial serial,
const vk::RenderPassDesc &desc,
......@@ -486,6 +506,11 @@ class RenderPassCache final : angle::NonCopyable
vk::RenderPass **renderPassOut);
private:
angle::Result addRenderPass(vk::Context *context,
Serial serial,
const vk::RenderPassDesc &desc,
vk::RenderPass **renderPassOut);
// Use a two-layer caching scheme. The top level matches the "compatible" RenderPass elements.
// The second layer caches the attachment load/store ops and initial/final layout.
using InnerCache = std::unordered_map<vk::AttachmentOpsArray, vk::RenderPassAndSerial>;
......@@ -505,17 +530,40 @@ class GraphicsPipelineCache final : angle::NonCopyable
void release(RendererVk *renderer);
void populate(const vk::GraphicsPipelineDesc &desc, vk::Pipeline &&pipeline);
angle::Result getPipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const vk::RenderPass &compatibleRenderPass,
const vk::PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
const vk::ShaderModule &vertexModule,
const vk::ShaderModule &fragmentModule,
const vk::GraphicsPipelineDesc &desc,
vk::PipelineAndSerial **pipelineOut);
ANGLE_INLINE angle::Result getPipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const vk::RenderPass &compatibleRenderPass,
const vk::PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
const vk::ShaderModule &vertexModule,
const vk::ShaderModule &fragmentModule,
const vk::GraphicsPipelineDesc &desc,
vk::PipelineAndSerial **pipelineOut)
{
auto item = mPayload.find(desc);
if (item != mPayload.end())
{
*pipelineOut = &item->second;
return angle::Result::Continue;
}
return insertPipeline(context, pipelineCacheVk, compatibleRenderPass, pipelineLayout,
activeAttribLocationsMask, vertexModule, fragmentModule, desc,
pipelineOut);
}
private:
angle::Result insertPipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const vk::RenderPass &compatibleRenderPass,
const vk::PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
const vk::ShaderModule &vertexModule,
const vk::ShaderModule &fragmentModule,
const vk::GraphicsPipelineDesc &desc,
vk::PipelineAndSerial **pipelineOut);
std::unordered_map<vk::GraphicsPipelineDesc, vk::PipelineAndSerial> mPayload;
};
......
......@@ -153,21 +153,6 @@ void Format::initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo
vertexLoadRequiresConversion = info[i].vertexLoadRequiresConversion;
}
const angle::Format &Format::textureFormat() const
{
return angle::Format::Get(textureFormatID);
}
const angle::Format &Format::bufferFormat() const
{
return angle::Format::Get(bufferFormatID);
}
const angle::Format &Format::angleFormat() const
{
return angle::Format::Get(angleFormatID);
}
bool operator==(const Format &lhs, const Format &rhs)
{
return &lhs == &rhs;
......@@ -216,18 +201,6 @@ void FormatTable::initialize(RendererVk *renderer,
}
}
}
const Format &FormatTable::operator[](GLenum internalFormat) const
{
angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
return mFormatData[static_cast<size_t>(formatID)];
}
const Format &FormatTable::operator[](angle::FormatID formatID) const
{
return mFormatData[static_cast<size_t>(formatID)];
}
} // namespace vk
size_t GetVertexInputAlignment(const vk::Format &format)
......
......@@ -62,9 +62,9 @@ struct Format final : private angle::NonCopyable
void initTextureFallback(RendererVk *renderer, const TextureFormatInitInfo *info, int numInfo);
void initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo *info, int numInfo);
const angle::Format &angleFormat() const;
const angle::Format &textureFormat() const;
const angle::Format &bufferFormat() const;
const angle::Format &angleFormat() const { return angle::Format::Get(angleFormatID); }
const angle::Format &textureFormat() const { return angle::Format::Get(textureFormatID); }
const angle::Format &bufferFormat() const { return angle::Format::Get(bufferFormatID); }
angle::FormatID angleFormatID;
GLenum internalFormat;
......@@ -97,8 +97,16 @@ class FormatTable final : angle::NonCopyable
gl::TextureCapsMap *outTextureCapsMap,
std::vector<GLenum> *outCompressedTextureFormats);
const Format &operator[](GLenum internalFormat) const;
const Format &operator[](angle::FormatID formatID) const;
ANGLE_INLINE const Format &operator[](GLenum internalFormat) const
{
angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
return mFormatData[static_cast<size_t>(formatID)];
}
ANGLE_INLINE const Format &operator[](angle::FormatID formatID) const
{
return mFormatData[static_cast<size_t>(formatID)];
}
private:
// The table data is indexed by angle::FormatID.
......
......@@ -973,17 +973,6 @@ void BufferHelper::release(RendererVk *renderer)
renderer->releaseObject(getStoredQueueSerial(), &mDeviceMemory);
}
void BufferHelper::onRead(RecordableGraphResource *reader, VkAccessFlagBits readAccessType)
{
addReadDependency(reader);
if (mCurrentWriteAccess != 0 && (mCurrentReadAccess & readAccessType) == 0)
{
reader->addGlobalMemoryBarrier(mCurrentWriteAccess, readAccessType);
mCurrentReadAccess |= readAccessType;
}
}
void BufferHelper::onWrite(VkAccessFlagBits writeAccessType)
{
if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0)
......@@ -1632,26 +1621,6 @@ void ShaderProgramHelper::setShader(gl::ShaderType shaderType, RefCounted<Shader
mShaders[shaderType].set(shader);
}
angle::Result ShaderProgramHelper::getGraphicsPipeline(
Context *context,
const PipelineLayout &pipelineLayout,
const GraphicsPipelineDesc &pipelineDesc,
const gl::AttributesMask &activeAttribLocationsMask,
PipelineAndSerial **pipelineOut)
{
RendererVk *renderer = context->getRenderer();
// Pull in a compatible RenderPass.
vk::RenderPass *compatibleRenderPass = nullptr;
ANGLE_TRY(renderer->getCompatibleRenderPass(context, pipelineDesc.getRenderPassDesc(),
&compatibleRenderPass));
return mGraphicsPipelines.getPipeline(
context, renderer->getPipelineCache(), *compatibleRenderPass, pipelineLayout,
activeAttribLocationsMask, mShaders[gl::ShaderType::Vertex].get().get(),
mShaders[gl::ShaderType::Fragment].get().get(), pipelineDesc, pipelineOut);
}
angle::Result ShaderProgramHelper::getComputePipeline(Context *context,
const PipelineLayout &pipelineLayout,
PipelineAndSerial **pipelineOut)
......
......@@ -392,7 +392,17 @@ class BufferHelper final : public RecordableGraphResource
const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
// Helpers for setting the graph dependencies *and* setting the appropriate barrier.
void onRead(RecordableGraphResource *reader, VkAccessFlagBits readAccessType);
ANGLE_INLINE void onRead(RecordableGraphResource *reader, VkAccessFlagBits readAccessType)
{
addReadDependency(reader);
if (mCurrentWriteAccess != 0 && (mCurrentReadAccess & readAccessType) == 0)
{
reader->addGlobalMemoryBarrier(mCurrentWriteAccess, readAccessType);
mCurrentReadAccess |= readAccessType;
}
}
void onWrite(VkAccessFlagBits writeAccessType);
// Also implicitly sets up the correct barriers.
......@@ -617,11 +627,27 @@ class ShaderProgramHelper : angle::NonCopyable
void setShader(gl::ShaderType shaderType, RefCounted<ShaderAndSerial> *shader);
// For getting a vk::Pipeline and from the pipeline cache.
angle::Result getGraphicsPipeline(Context *context,
const PipelineLayout &pipelineLayout,
const GraphicsPipelineDesc &pipelineDesc,
const gl::AttributesMask &activeAttribLocationsMask,
PipelineAndSerial **pipelineOut);
ANGLE_INLINE angle::Result getGraphicsPipeline(
Context *context,
RenderPassCache *renderPassCache,
const PipelineCache &pipelineCache,
Serial currentQueueSerial,
const PipelineLayout &pipelineLayout,
const GraphicsPipelineDesc &pipelineDesc,
const gl::AttributesMask &activeAttribLocationsMask,
PipelineAndSerial **pipelineOut)
{
// Pull in a compatible RenderPass.
vk::RenderPass *compatibleRenderPass = nullptr;
ANGLE_TRY(renderPassCache->getCompatibleRenderPass(
context, currentQueueSerial, pipelineDesc.getRenderPassDesc(), &compatibleRenderPass));
return mGraphicsPipelines.getPipeline(
context, pipelineCache, *compatibleRenderPass, pipelineLayout,
activeAttribLocationsMask, mShaders[gl::ShaderType::Vertex].get().get(),
mShaders[gl::ShaderType::Fragment].get().get(), pipelineDesc, pipelineOut);
}
angle::Result getComputePipeline(Context *context,
const PipelineLayout &pipelineLayout,
PipelineAndSerial **pipelineOut);
......
......@@ -276,7 +276,7 @@ libangle_sources = [
"src/libANGLE/renderer/DisplayImpl.h",
"src/libANGLE/renderer/EGLImplFactory.h",
"src/libANGLE/renderer/FenceNVImpl.h",
"src/libANGLE/renderer/FormatID_autogen.inc",
"src/libANGLE/renderer/FormatID_autogen.h",
"src/libANGLE/renderer/Format_table_autogen.cpp",
"src/libANGLE/renderer/Format.h",
"src/libANGLE/renderer/FramebufferAttachmentObjectImpl.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