From d67d187b728dd383b6cb85e57f36e3e4dee9a1c4 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 9 Jan 2016 11:07:14 +0100 Subject: [PATCH] Get untextured drawing working! (at least cube.elf) --- GPU/Vulkan/DrawEngineVulkan.cpp | 119 +++++++++++++++++++-------- GPU/Vulkan/DrawEngineVulkan.h | 3 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 4 + GPU/Vulkan/PipelineManagerVulkan.h | 10 +-- GPU/Vulkan/ShaderManagerVulkan.cpp | 6 +- GPU/Vulkan/ShaderManagerVulkan.h | 8 +- GPU/Vulkan/StateMappingVulkan.cpp | 3 + GPU/Vulkan/TextureCacheVulkan.cpp | 6 -- GPU/Vulkan/TextureCacheVulkan.h | 7 ++ ext/native/thin3d/VulkanContext.h | 9 +- 10 files changed, 113 insertions(+), 62 deletions(-) diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index b7b5c59b15..5a09088aa6 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -1,6 +1,3 @@ -#include "GPU/Vulkan/DrawEngineVulkan.h" - - // Copyright (c) 2012- PPSSPP Project. // This program is free software: you can redistribute it and/or modify @@ -47,6 +44,14 @@ #include "GPU/Vulkan/PipelineManagerVulkan.h" #include "GPU/Vulkan/GPU_Vulkan.h" +enum { + DRAW_BINDING_TEXTURE = 0, + DRAW_BINDING_2ND_TEXTURE = 1, + DRAW_BINDING_DYNUBO_BASE = 2, + DRAW_BINDING_DYNUBO_LIGHT = 3, + DRAW_BINDING_DYNUBO_BONE = 4, +}; + const VkPrimitiveTopology prim[8] = { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, @@ -99,27 +104,27 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) bindings[0].pImmutableSamplers = nullptr; bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[0].binding = 0; + bindings[0].binding = DRAW_BINDING_TEXTURE; bindings[1].descriptorCount = 1; bindings[1].pImmutableSamplers = nullptr; bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[1].binding = 1; + bindings[1].binding = DRAW_BINDING_2ND_TEXTURE; bindings[2].descriptorCount = 1; bindings[2].pImmutableSamplers = nullptr; bindings[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; bindings[2].stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[2].binding = 2; + bindings[2].binding = DRAW_BINDING_DYNUBO_BASE; bindings[3].descriptorCount = 1; bindings[3].pImmutableSamplers = nullptr; bindings[3].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; bindings[3].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - bindings[3].binding = 3; + bindings[3].binding = DRAW_BINDING_DYNUBO_LIGHT; bindings[4].descriptorCount = 1; bindings[4].pImmutableSamplers = nullptr; bindings[4].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; bindings[4].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - bindings[4].binding = 4; + bindings[4].binding = DRAW_BINDING_DYNUBO_BONE; VkDevice device = vulkan_->GetDevice(); @@ -131,7 +136,7 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); VkDescriptorPoolSize dpTypes[2]; - dpTypes[0].descriptorCount = 200; + dpTypes[0].descriptorCount = 800; dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; dpTypes[1].descriptorCount = 200; dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; @@ -139,8 +144,8 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) VkDescriptorPoolCreateInfo dp; dp.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; dp.pNext = nullptr; - dp.flags = 0; // Don't want to mess around with individually freeing these, let's go dynamic each frame. - dp.maxSets = 200; // 200 textures per frame should be enough for the UI... + dp.flags = 0; // Don't want to mess around with individually freeing these, let's go fixed each frame and zap the whole array. Might try the dynamic approach later. + dp.maxSets = 1000; dp.pPoolSizes = dpTypes; dp.poolSizeCount = ARRAY_SIZE(dpTypes); res = vkCreateDescriptorPool(device, &dp, nullptr, &frame_[0].descPool); @@ -167,6 +172,8 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) assert(VK_SUCCESS == res); VkSamplerCreateInfo samp = {}; + samp.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samp.pNext = nullptr; samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; @@ -377,13 +384,14 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) { } } -VkDescriptorSet DrawEngineVulkan::GetDescriptorSet(CachedTextureVulkan *texture, VkSampler sampler) { +VkDescriptorSet DrawEngineVulkan::GetDescriptorSet(CachedTextureVulkan *texture, VkSampler sampler, VkBuffer dynamicUbo) { DescriptorSetKey key; key.texture_ = texture; key.sampler_ = sampler; key.secondaryTexture_ = nullptr; - FrameData *frame = &frame_[curFrame_ & 1]; + key.buffer_ = dynamicUbo; + FrameData *frame = &frame_[curFrame_ & 1]; auto iter = frame->descSets.find(key); if (iter != frame->descSets.end()) { return iter->second; @@ -392,22 +400,59 @@ VkDescriptorSet DrawEngineVulkan::GetDescriptorSet(CachedTextureVulkan *texture, // Didn't find one in the frame cache, let's make a new one. VkDescriptorSet desc; + VkDescriptorSetAllocateInfo descAlloc; + descAlloc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descAlloc.pNext = nullptr; + descAlloc.pSetLayouts = &descriptorSetLayout_; + descAlloc.descriptorPool = frame->descPool; + descAlloc.descriptorSetCount = 1; + vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); + // We just don't write to the slots we don't care about. - VkWriteDescriptorSet writes[2]; + VkWriteDescriptorSet writes[4]; memset(writes, 0, sizeof(writes)); // Main texture - VkDescriptorImageInfo tex; + int n = 0; + if (texture) { + VkDescriptorImageInfo tex; + tex.imageLayout = texture->imageLayout; + tex.imageView = texture->imageView; + tex.sampler = sampler; + writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[n].pNext = nullptr; + writes[n].dstBinding = DRAW_BINDING_TEXTURE; + writes[n].pImageInfo = &tex; + writes[n].descriptorCount = 1; + writes[n].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writes[n].dstSet = desc; + n++; + } - // tex.imageView = texture->imageView; - tex.sampler = sampler; - writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes[0].dstBinding = 0; - writes[0].pImageInfo = &tex; - - vkUpdateDescriptorSets(vulkan_->GetDevice(), 2, writes, 0, nullptr); + // Skipping 2nd texture for now. + // Uniform buffer objects + VkDescriptorBufferInfo buf[3]; + buf[0].buffer = dynamicUbo; + buf[0].offset = 0; + buf[0].range = sizeof(UB_VS_FS_Base); + buf[1].buffer = dynamicUbo; + buf[1].offset = 0; + buf[1].range = sizeof(UB_VS_Lights); + buf[2].buffer = dynamicUbo; + buf[2].offset = 0; + buf[2].range = sizeof(UB_VS_Bones); + writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[n].pNext = nullptr; + writes[n].dstBinding = DRAW_BINDING_DYNUBO_BASE; + writes[n].pBufferInfo = &buf[0]; + writes[n].dstSet = desc; + writes[n].descriptorCount = 3; + writes[n].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + n++; + + vkUpdateDescriptorSets(vulkan_->GetDevice(), n, writes, 0, nullptr); frame->descSets[key] = desc; - return nullptr; + return desc; } // The inline wrapper in the header checks for numDrawCalls == 0d @@ -416,16 +461,19 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { FrameData *frame = &frame_[curFrame_ & 1]; -// CachedTextureVulkan *tex = textureCache_->ApplyTexture(); -// VkDescriptorSet ds = GetDescriptorSet(tex); - VkDescriptorSet ds; + // Note than when we implement overflow in pushbuffer, we need to make sure to overflow here, not between + // the three ubo pushes. The reason is that the three UBOs must be in the same buffer as that's how we + // designed the descriptor set. + + // CachedTextureVulkan *tex = textureCache_->ApplyTexture(); + VkDescriptorSet ds = GetDescriptorSet(nullptr, nullptr, frame->pushData->GetVkBuffer()); GEPrimitiveType prim = prevPrim_; - // ApplyDrawState(prim); + + bool useHWTransform = CanUseHardwareTransform(prim); VulkanVertexShader *vshader; VulkanFragmentShader *fshader; - shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader); uint32_t baseUBOOffset = 0; uint32_t lightUBOOffset = 0; @@ -434,7 +482,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { uint32_t ibOffset = 0; uint32_t vbOffset = 0; - if (vshader->UseHWTransform()) { + if (useHWTransform) { int vertexCount = 0; int maxIndex = 0; bool useElements = true; @@ -449,7 +497,6 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { } prim = indexGen.Prim(); - VERBOSE_LOG(G3D, "Flush prim %i! %i verts in one go", prim, vertexCount); bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); @@ -467,6 +514,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { vkCmdSetStencilWriteMask(cmd_, VK_STENCIL_FRONT_AND_BACK, dynState.stencilWriteMask); vkCmdSetStencilCompareMask(cmd_, VK_STENCIL_FRONT_AND_BACK, dynState.stencilCompareMask); // vkCmdSetBlendConstants(cmd_, dynState.blendColor); + shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader->GetModule(), fshader->GetModule(), true); vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw. @@ -481,21 +529,21 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { } VkBuffer buf[1] = {frame->pushData->GetVkBuffer()}; - uint32_t dynamicUBOOffsets[3] = { + const uint32_t dynamicUBOOffsets[3] = { baseUBOOffset, lightUBOOffset, boneUBOOffset, }; vkCmdBindDescriptorSets(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &ds, 3, dynamicUBOOffsets); - ibOffset = (uint32_t)frame->pushData->Push(decIndex, 2 * indexGen.VertexCount()); vbOffset = (uint32_t)frame->pushData->Push(decoded, vertexCount * dec_->GetDecVtxFmt().stride); VkDeviceSize offsets[1] = { vbOffset }; if (useElements) { + ibOffset = (uint32_t)frame->pushData->Push(decIndex, 2 * indexGen.VertexCount()); // TODO: Avoid rebinding vertex/index buffers if the vertex size stays the same by using the offset arguments // Might want to separate vertices out into a different push buffer in that case. vkCmdBindVertexBuffers(cmd_, 0, 1, buf, offsets); vkCmdBindIndexBuffer(cmd_, buf[0], ibOffset, VK_INDEX_TYPE_UINT16); - vkCmdDrawIndexed(cmd_, maxIndex + 1, 1, 0, 0, 0); + vkCmdDrawIndexed(cmd_, maxIndex, 1, 0, 0, 0); } else { vkCmdBindVertexBuffers(cmd_, 0, 1, buf, offsets); vkCmdDraw(cmd_, vertexCount, 1, 0, 0); @@ -548,6 +596,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { } // vkCmdSetBlendConstants(cmd_, dynState.blendColor); + shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader->GetModule(), fshader->GetModule(), false); vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw. @@ -555,17 +604,17 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { baseUBOOffset = shaderManager_->PushBaseBuffer(frame->pushData); } - uint32_t dynamicUBOOffsets[3] = { + const uint32_t dynamicUBOOffsets[3] = { baseUBOOffset, lightUBOOffset, boneUBOOffset, }; vkCmdBindDescriptorSets(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &ds, 3, dynamicUBOOffsets); - ibOffset = (uint32_t)frame->pushData->Push(decIndex, 2 * indexGen.VertexCount()); vbOffset = (uint32_t)frame->pushData->Push(decoded, numTrans * dec_->GetDecVtxFmt().stride); VkBuffer buf[1] = { frame->pushData->GetVkBuffer() }; VkDeviceSize offsets[1] = { vbOffset }; if (drawIndexed) { + ibOffset = (uint32_t)frame->pushData->Push(decIndex, 2 * indexGen.VertexCount()); // TODO: Have a buffer per frame, use a walking buffer pointer // TODO: Avoid rebinding if the vertex size stays the same by using the offset arguments vkCmdBindVertexBuffers(cmd_, 0, 1, buf, offsets); diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index e51c141842..936d8840ff 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -149,7 +149,7 @@ private: void DecodeVertsStep(); void DoFlush(VkCommandBuffer cmd); - VkDescriptorSet GetDescriptorSet(CachedTextureVulkan *texture, VkSampler sampler); + VkDescriptorSet GetDescriptorSet(CachedTextureVulkan *texture, VkSampler sampler, VkBuffer dynamicUbo); VertexDecoder *GetVertexDecoder(u32 vtype); @@ -163,6 +163,7 @@ private: void *texture_; void *secondaryTexture_; VkSampler sampler_; + VkBuffer buffer_; // All three UBO slots will be set to this. bool operator < (const DescriptorSetKey &other) const { if (texture_ < other.texture_) return true; else if (texture_ > other.texture_) return false; diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 9b77ac4b86..e7c97a0c92 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -283,6 +283,10 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VkShaderModule vShader, VkShaderModule fShader, bool useHwTransform) { VulkanPipelineKey key; key.raster = rasterKey; + key.useHWTransform = useHwTransform; + key.vShader = vShader; + key.fShader = fShader; + key.vtxDec = vtxDec; auto iter = pipelines_.find(key); if (iter != pipelines_.end()) { return iter->second; diff --git a/GPU/Vulkan/PipelineManagerVulkan.h b/GPU/Vulkan/PipelineManagerVulkan.h index 0805425fb2..3d86e50427 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.h +++ b/GPU/Vulkan/PipelineManagerVulkan.h @@ -37,20 +37,16 @@ enum class PspAttributeLocation { COUNT }; -// All the information needed. All PSP rendering (except full screen clears?) will make use of a single -// render pass definition. struct VulkanPipelineKey { - VulkanPipelineRasterStateKey raster; - int prim; - bool pretransformed; + VulkanPipelineRasterStateKey raster; // prim is included here + bool useHWTransform; const VertexDecoder *vtxDec; VkShaderModule vShader; VkShaderModule fShader; bool operator < (const VulkanPipelineKey &other) const { if (raster < other.raster) return true; else if (other.raster < raster) return false; - if (prim < other.prim) return true; else if (other.prim < prim) return false; - if (pretransformed < other.pretransformed) return true; else if (other.pretransformed < pretransformed) return false; + if (useHWTransform < other.useHWTransform) return true; else if (other.useHWTransform < useHWTransform) return false; if (vtxDec < other.vtxDec) return true; else if (other.vtxDec < vtxDec) return false; if (vShader < other.vShader) return true; else if (other.vShader < vShader) return false; if (fShader < other.fShader) return true; else if (other.fShader < fShader) return false; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 4b1de3306f..a3dda8833b 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -351,7 +351,7 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) { default: ERROR_LOG_REPORT(G3D, "Unexpected UV gen mode: %d", gstate.getUVGenMode()); - } + } CopyFloat4(ub_base.uvScaleOffset, uvscaleoff); } @@ -475,9 +475,7 @@ void ShaderManagerVulkan::DirtyLastShader() { // disables vertex arrays } -void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader) { - bool useHWTransform = CanUseHardwareTransform(prim); - +void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform) { ShaderID VSID; ComputeVertexShaderID(&VSID, vertType, useHWTransform); ShaderID FSID; diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index af96ca5b54..f1991426cb 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -81,7 +81,7 @@ enum { DIRTY_ALL = 0xFFFFFFFF }; -struct UB_VS_TransformCommon { +struct UB_VS_FS_Base { float proj[16]; float view[16]; float world[16]; @@ -107,7 +107,7 @@ R"( mat4 proj_mtx; mat4 view_mtx; mat4 world_mtx; mat4 tex_mtx; - vec4 uvScaleOffset; + vec4 uvscaleoffset; vec4 depthRange; vec2 fogCoef; vec4 matambientalpha; @@ -213,7 +213,7 @@ public: ~ShaderManagerVulkan(); void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected - void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader); + void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform); void DirtyShader(); void DirtyUniform(u32 what) { @@ -251,7 +251,7 @@ private: char *codeBuffer_; // Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time. - UB_VS_TransformCommon ub_base; + UB_VS_FS_Base ub_base; UB_VS_Lights ub_lights; UB_VS_Bones ub_bones; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 18e0a2e14b..acd959c8e2 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -188,6 +188,9 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, int prim, Vulk bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); key.cullMode = wantCull ? (gstate.getCullMode() ? VK_CULL_MODE_FRONT_BIT : VK_CULL_MODE_BACK_BIT) : VK_CULL_MODE_NONE; + // TODO: Remove (For debugging) + key.cullMode = VK_CULL_MODE_NONE; + // Depth Test if (gstate.isDepthTestEnabled()) { key.depthTestEnable = true; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 14cb54700f..4e52597a67 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -68,12 +68,6 @@ // Hack! extern int g_iNumVideos; -// texturePtr points to these. -class CachedTextureVulkan { -public: - VkImageView imageView; -}; - SamplerCache::~SamplerCache() { for (auto iter : cache_) { vulkan_->QueueDelete(iter.second); diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 809ef6cc55..f4f94d6918 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -47,12 +47,19 @@ struct SamplerCacheKey { } }; +// texturePtr points to these. +class CachedTextureVulkan { +public: + VkImageView imageView; + VkImageLayout imageLayout; +}; class SamplerCache { public: SamplerCache(VulkanContext *vulkan) : vulkan_(vulkan) {} ~SamplerCache(); VkSampler GetOrCreateSampler(const SamplerCacheKey &key); + private: VulkanContext *vulkan_; std::map cache_; diff --git a/ext/native/thin3d/VulkanContext.h b/ext/native/thin3d/VulkanContext.h index 71b6f63440..da3fbf06fe 100644 --- a/ext/native/thin3d/VulkanContext.h +++ b/ext/native/thin3d/VulkanContext.h @@ -384,13 +384,12 @@ private: VkFramebuffer framebuffer_; }; -// Use these to push vertex, index and uniform data. +// Use these to push vertex, index and uniform data. Generally you'll have two of these +// and alternate on each frame. // TODO: Make it possible to suballocate pushbuffers from a large DeviceMemory block. -// TODO: Make this dynamically grow by chaining new buffers in the future. -// Until then, we cap at a maximum size. // We'll have two of these that we alternate between on each frame. -// These will only be used for the "Thin3D" system - the PSP emulation etc will have -// their own similar buffer solutions. +// TODO: Make this auto-grow and shrink. Need to be careful about returning and using the new +// buffer handle on overflow. class VulkanPushBuffer { public: VulkanPushBuffer(VulkanContext *vulkan, size_t size) : offset_(0), size_(size), writePtr_(nullptr), deviceMemory_(nullptr) {