blob: 11c006ca99a734e4c39c577fb99566c1348facdd [file] [log] [blame]
/* Copyright (c) 2019-2024 The Khronos Group Inc.
* Copyright (c) 2019-2024 Valve Corporation
* Copyright (c) 2019-2024 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <vulkan/vulkan.h>
#include "sync/sync_common.h"
#include "sync/sync_access_context.h"
#include "sync/sync_op.h"
class CommandExecutionContext;
struct ClearAttachmentInfo;
struct LastBound;
namespace syncval_state {
enum class AttachmentType { kColor, kDepth, kStencil };
struct DynamicRenderingInfo {
struct Attachment {
const vku::safe_VkRenderingAttachmentInfo &info;
std::shared_ptr<const ImageViewState> view;
std::shared_ptr<const ImageViewState> resolve_view;
ImageRangeGen view_gen;
std::optional<ImageRangeGen> resolve_gen;
AttachmentType type;
Attachment(const SyncValidator &state, const vku::safe_VkRenderingAttachmentInfo &info, const AttachmentType type_,
const VkOffset3D &offset, const VkExtent3D &extent);
SyncAccessIndex GetLoadUsage() const;
SyncAccessIndex GetStoreUsage() const;
SyncOrdering GetOrdering() const;
Location GetLocation(const Location &loc, uint32_t index = 0) const;
bool IsWriteable(const LastBound &last_bound_state) const;
bool IsValid() const { return view.get(); }
};
// attachments store references to this info, so make sure this doesn't get moved around.
DynamicRenderingInfo(const DynamicRenderingInfo &) = delete;
DynamicRenderingInfo(DynamicRenderingInfo &&) = delete;
DynamicRenderingInfo &operator=(const DynamicRenderingInfo &) = delete;
DynamicRenderingInfo &operator=(DynamicRenderingInfo &&) = delete;
DynamicRenderingInfo(const SyncValidator &state, const VkRenderingInfo &rendering_info);
ClearAttachmentInfo GetClearAttachmentInfo(const VkClearAttachment &clear_attachment, const VkClearRect &rect) const;
vku::safe_VkRenderingInfo info;
std::vector<Attachment> attachments; // All attachments (with internal typing)
};
struct BeginRenderingCmdState {
BeginRenderingCmdState(std::shared_ptr<const syncval_state::CommandBuffer> &&cb_state_) : cb_state(std::move(cb_state_)) {}
void AddRenderingInfo(const SyncValidator &state, const VkRenderingInfo &rendering_info);
const DynamicRenderingInfo &GetRenderingInfo() const;
std::shared_ptr<const CommandBuffer> cb_state;
std::unique_ptr<DynamicRenderingInfo> info;
};
} // namespace syncval_state
void InitSubpassContexts(VkQueueFlags queue_flags, const vvl::RenderPass &rp_state, const AccessContext *external_context,
std::vector<AccessContext> &subpass_contexts);
struct ClearAttachmentInfo {
using ImageViewState = syncval_state::ImageViewState;
const ImageViewState *view = nullptr;
VkImageAspectFlags aspects_to_clear = {};
VkImageSubresourceRange subresource_range{};
VkOffset3D offset = {};
VkExtent3D extent = {};
uint32_t attachment_index = VK_ATTACHMENT_UNUSED;
uint32_t subpass = 0;
static VkImageSubresourceRange RestrictSubresourceRange(const VkClearRect &clear_rect, const ImageViewState &view);
static VkImageAspectFlags GetAspectsToClear(VkImageAspectFlags clear_aspect_mask, const ImageViewState &view);
ClearAttachmentInfo() = default;
ClearAttachmentInfo(const VkClearAttachment &clear_attachment, const VkClearRect &rect, const ImageViewState &view_,
uint32_t attachment_index_ = VK_ATTACHMENT_UNUSED /* renderpass instance only */,
uint32_t subpass_ = 0 /* renderpass instance only */);
// ClearAttachmentInfo can be invalid for several reasons based on the VkClearAttachment and the rendering
// attachment state, including some caught by the constructor. Consumers *must* check validity before use
bool IsValid() const { return view && (aspects_to_clear != 0U) && (subresource_range.layerCount != 0U); }
std::string GetSubpassAttachmentText() const;
};
class RenderPassAccessContext {
public:
static AttachmentViewGenVector CreateAttachmentViewGen(
const VkRect2D &render_area, const std::vector<const syncval_state::ImageViewState *> &attachment_views);
RenderPassAccessContext() : rp_state_(nullptr), render_area_(VkRect2D()), current_subpass_(0) {}
RenderPassAccessContext(const vvl::RenderPass &rp_state, const VkRect2D &render_area, VkQueueFlags queue_flags,
const std::vector<const syncval_state::ImageViewState *> &attachment_views,
const AccessContext *external_context);
static bool ValidateLayoutTransitions(const CommandBufferAccessContext &cb_context, const AccessContext &access_context,
const vvl::RenderPass &rp_state, const VkRect2D &render_area, uint32_t subpass,
const AttachmentViewGenVector &attachment_views, vvl::Func command);
static bool ValidateLoadOperation(const CommandBufferAccessContext &cb_context, const AccessContext &access_context,
const vvl::RenderPass &rp_state, const VkRect2D &render_area, uint32_t subpass,
const AttachmentViewGenVector &attachment_views, vvl::Func command);
bool ValidateStoreOperation(const CommandBufferAccessContext &cb_context, vvl::Func command) const;
bool ValidateResolveOperations(const CommandBufferAccessContext &cb_context, vvl::Func command) const;
static void UpdateAttachmentResolveAccess(const vvl::RenderPass &rp_state, const AttachmentViewGenVector &attachment_views,
uint32_t subpass, const ResourceUsageTag tag, AccessContext access_context);
static void UpdateAttachmentStoreAccess(const vvl::RenderPass &rp_state, const AttachmentViewGenVector &attachment_views,
uint32_t subpass, const ResourceUsageTag tag, AccessContext &access_context);
static void RecordLayoutTransitions(const vvl::RenderPass &rp_state, uint32_t subpass,
const AttachmentViewGenVector &attachment_views, const ResourceUsageTag tag,
AccessContext &access_context);
bool ValidateDrawSubpassAttachment(const CommandBufferAccessContext &cb_context, vvl::Func command) const;
void RecordDrawSubpassAttachment(const vvl::CommandBuffer &cmd_buffer, ResourceUsageTag tag);
uint32_t GetAttachmentIndex(const VkClearAttachment &clear_attachment) const;
ClearAttachmentInfo GetClearAttachmentInfo(const VkClearAttachment &clear_attachment, const VkClearRect &rect) const;
bool ValidateNextSubpass(const CommandBufferAccessContext &cb_context, vvl::Func command) const;
bool ValidateEndRenderPass(const CommandBufferAccessContext &cb_context, vvl::Func command) const;
bool ValidateFinalSubpassLayoutTransitions(const CommandBufferAccessContext &cb_context, vvl::Func command) const;
void RecordLayoutTransitions(ResourceUsageTag tag);
void RecordLoadOperations(ResourceUsageTag tag);
void RecordBeginRenderPass(ResourceUsageTag tag, ResourceUsageTag load_tag);
void RecordNextSubpass(ResourceUsageTag store_tag, ResourceUsageTag barrier_tag, ResourceUsageTag load_tag);
void RecordEndRenderPass(AccessContext *external_context, ResourceUsageTag store_tag, ResourceUsageTag barrier_tag);
AccessContext &CurrentContext() { return subpass_contexts_[current_subpass_]; }
const AccessContext &CurrentContext() const { return subpass_contexts_[current_subpass_]; }
const std::vector<AccessContext> &GetContexts() const { return subpass_contexts_; }
uint32_t GetCurrentSubpass() const { return current_subpass_; }
const vvl::RenderPass *GetRenderPassState() const { return rp_state_; }
AccessContext *CreateStoreResolveProxy() const;
private:
const vvl::RenderPass *rp_state_;
const VkRect2D render_area_;
uint32_t current_subpass_;
std::vector<AccessContext> subpass_contexts_;
AttachmentViewGenVector attachment_views_;
};