#pragma once
#include "Common/CommonTypes.h"
#include "Common/Data/Collections/Hashmaps.h"
#include "GPU/Vulkan/VulkanUtil.h"
#include "GPU/GPUState.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Common/IndexGenerator.h"
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/Vulkan/StateMappingVulkan.h"
#include "GPU/Vulkan/VulkanRenderManager.h"
struct DecVtxFormat;
struct UVScale;
class ShaderManagerVulkan;
class PipelineManagerVulkan;
class TextureCacheVulkan;
class FramebufferManagerVulkan;
class VulkanContext;
class VulkanPushPool;
struct VulkanPipeline;
struct DrawEngineVulkanStats {
int pushVertexSpaceUsed;
int pushIndexSpaceUsed;
};
class VulkanRenderManager;
class TessellationDataTransferVulkan : public TessellationDataTransfer {
public:
TessellationDataTransferVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {}
void SetPushPool(VulkanPushPool *push) { push_ = push; }
void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override;
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
private:
VulkanContext *vulkan_;
VulkanPushPool *push_;
VkDescriptorBufferInfo bufInfo_[3]{};
};
enum {
DRAW_BINDING_TEXTURE = 0,
DRAW_BINDING_2ND_TEXTURE = 1,
DRAW_BINDING_DEPAL_TEXTURE = 2,
DRAW_BINDING_DYNUBO_BASE = 3,
DRAW_BINDING_DYNUBO_LIGHT = 4,
DRAW_BINDING_DYNUBO_BONE = 5,
DRAW_BINDING_TESS_STORAGE_BUF = 6,
DRAW_BINDING_TESS_STORAGE_BUF_WU = 7,
DRAW_BINDING_TESS_STORAGE_BUF_WV = 8,
DRAW_BINDING_COUNT = 9,
};
class DrawEngineVulkan : public DrawEngineCommon {
public:
DrawEngineVulkan(Draw::DrawContext *draw);
~DrawEngineVulkan();
void InitDeviceObjects();
void SetShaderManager(ShaderManagerVulkan *shaderManager) {
shaderManager_ = shaderManager;
}
void SetPipelineManager(PipelineManagerVulkan *pipelineManager) {
pipelineManager_ = pipelineManager;
}
void SetTextureCache(TextureCacheVulkan *textureCache) {
textureCache_ = textureCache;
}
void SetFramebufferManager(FramebufferManagerVulkan *fbManager) {
framebufferManager_ = fbManager;
}
void DeviceLost() override;
void DeviceRestore(Draw::DrawContext *draw) override;
void Flush() override;
void FinishDeferred() {
Flush();
}
VKRPipelineLayout *GetPipelineLayout() const {
return pipelineLayout_;
}
void BeginFrame() override;
void EndFrame();
void DirtyAllUBOs();
void DirtyPipeline() {
lastPipeline_ = nullptr;
}
VulkanPushPool *GetPushBufferForTextureData() {
return pushUBO_;
}
const DrawEngineVulkanStats &GetStats() const {
return stats_;
}
void SetDepalTexture(VkImageView depal, bool smooth) {
if (boundDepal_ != depal) {
boundDepal_ = depal;
boundDepalSmoothed_ = smooth;
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
}
private:
void Invalidate(InvalidationCallbackFlags flags);
void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant);
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);
void BindShaderBlendTex();
void DestroyDeviceObjects();
void UpdateUBOs();
NO_INLINE void ResetAfterDraw();
Draw::DrawContext *draw_;
VKRPipelineLayout *pipelineLayout_ = nullptr;
VulkanPipeline *lastPipeline_ = nullptr;
VkDescriptorSet lastDs_ = VK_NULL_HANDLE;
VkImageView boundSecondary_ = VK_NULL_HANDLE;
VkImageView boundDepal_ = VK_NULL_HANDLE;
bool boundDepalSmoothed_ = false;
VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE;
VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE;
struct DescriptorSetKey {
VkImageView imageView_;
VkImageView secondaryImageView_;
VkImageView depalImageView_;
VkSampler sampler_;
VkBuffer base_, light_, bone_;
};
GEPrimitiveType lastPrim_ = GE_PRIM_INVALID;
VulkanPushPool *pushUBO_ = nullptr;
VulkanPushPool *pushVertex_ = nullptr;
VulkanPushPool *pushIndex_ = nullptr;
ShaderManagerVulkan *shaderManager_ = nullptr;
PipelineManagerVulkan *pipelineManager_ = nullptr;
TextureCacheVulkan *textureCache_ = nullptr;
FramebufferManagerVulkan *framebufferManager_ = nullptr;
uint64_t dirtyUniforms_ = 0;
uint32_t baseUBOOffset = 0;
uint32_t lightUBOOffset = 0;
uint32_t boneUBOOffset = 0;
VkBuffer baseBuf = VK_NULL_HANDLE;
VkBuffer lightBuf = VK_NULL_HANDLE;
VkBuffer boneBuf = VK_NULL_HANDLE;
VkImageView imageView = VK_NULL_HANDLE;
VkSampler sampler = VK_NULL_HANDLE;
VkSampler nullSampler_ = VK_NULL_HANDLE;
DrawEngineVulkanStats stats_{};
VulkanPipelineRasterStateKey pipelineKey_{};
VulkanDynamicState dynState_{};
int tessOffset_ = 0;
FBOTexState fboTexBindState_ = FBO_TEX_NONE;
TessellationDataTransferVulkan *tessDataTransferVulkan = nullptr;
};