diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index ee56b0a9bf..139eac9296 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -19,6 +19,7 @@ #include "base/logging.h" #include "base/timeutil.h" +#include "math/dataconv.h" #include "Common/MemoryUtil.h" #include "Core/MemMap.h" @@ -148,7 +149,7 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) for (int i = 0; i < 2; i++) { VkResult res = vkCreateDescriptorPool(vulkan_->GetDevice(), &dp, nullptr, &frame_[i].descPool); assert(VK_SUCCESS == res); - frame_[i].pushData = new VulkanPushBuffer(vulkan_, 4 * 1024 * 1024); // TODO: Do something more dynamic + frame_[i].pushData = new VulkanPushBuffer(vulkan_, 32 * 1024 * 1024); // TODO: Do something more dynamic } VkPipelineLayoutCreateInfo pl; @@ -175,20 +176,6 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) assert(VK_SUCCESS == res); } -void DrawEngineVulkan::BeginFrame() { - FrameData *frame = &frame_[curFrame_ & 1]; - vkResetDescriptorPool(vulkan_->GetDevice(), frame->descPool, 0); - frame->descSets.clear(); - frame->pushData->Begin(vulkan_->GetDevice()); - frame->pushData->Reset(); -} - -void DrawEngineVulkan::EndFrame() { - FrameData *frame = &frame_[curFrame_ & 1]; - frame->pushData->End(vulkan_->GetDevice()); - curFrame_++; -} - DrawEngineVulkan::~DrawEngineVulkan() { FreeMemoryPages(decoded, DECODED_VERTEX_BUFFER_SIZE); FreeMemoryPages(decIndex, DECODED_INDEX_BUFFER_SIZE); @@ -203,6 +190,20 @@ DrawEngineVulkan::~DrawEngineVulkan() { vulkan_->QueueDelete(depalSampler_); } +void DrawEngineVulkan::BeginFrame() { + FrameData *frame = &frame_[curFrame_ & 1]; + vkResetDescriptorPool(vulkan_->GetDevice(), frame->descPool, 0); + frame->descSets.clear(); + frame->pushData->Begin(vulkan_->GetDevice()); + frame->pushData->Reset(); +} + +void DrawEngineVulkan::EndFrame() { + FrameData *frame = &frame_[curFrame_ & 1]; + frame->pushData->End(vulkan_->GetDevice()); + curFrame_++; +} + VertexDecoder *DrawEngineVulkan::GetVertexDecoder(u32 vtype) { auto iter = decoderMap_.find(vtype); if (iter != decoderMap_.end()) @@ -402,7 +403,7 @@ VkDescriptorSet DrawEngineVulkan::GetDescriptorSet(VkImageView imageView, VkSamp assert(result == VK_SUCCESS); // We just don't write to the slots we don't care about. - VkWriteDescriptorSet writes[4]; + VkWriteDescriptorSet writes[2]; memset(writes, 0, sizeof(writes)); // Main texture int n = 0; @@ -514,14 +515,16 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { VulkanPipelineRasterStateKey pipelineKey; VulkanDynamicState dynState; - ConvertStateToVulkanKey(*framebufferManager_, prim, pipelineKey, dynState); + ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey, dynState); // TODO: Dirty-flag these. vkCmdSetScissor(cmd_, 0, 1, &dynState.scissor); vkCmdSetViewport(cmd_, 0, 1, &dynState.viewport); vkCmdSetStencilReference(cmd_, VK_STENCIL_FRONT_AND_BACK, dynState.stencilRef); vkCmdSetStencilWriteMask(cmd_, VK_STENCIL_FRONT_AND_BACK, dynState.stencilWriteMask); vkCmdSetStencilCompareMask(cmd_, VK_STENCIL_FRONT_AND_BACK, dynState.stencilCompareMask); - // vkCmdSetBlendConstants(cmd_, dynState.blendColor); + float bc[4]; + Uint8x4ToFloat4(bc, dynState.blendColor); + vkCmdSetBlendConstants(cmd_, bc); shaderManager_->UpdateUniforms(); shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader->GetModule(), fshader->GetModule(), true); @@ -589,7 +592,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { if (result.action == SW_DRAW_PRIMITIVES) { VulkanPipelineRasterStateKey pipelineKey; VulkanDynamicState dynState; - ConvertStateToVulkanKey(*framebufferManager_, prim, pipelineKey, dynState); + ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey, dynState); // TODO: Dirty-flag these. vkCmdSetScissor(cmd_, 0, 1, &dynState.scissor); vkCmdSetViewport(cmd_, 0, 1, &dynState.viewport); @@ -604,7 +607,9 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { vkCmdSetStencilReference(cmd_, VK_STENCIL_FRONT_AND_BACK, dynState.stencilRef); } - // vkCmdSetBlendConstants(cmd_, dynState.blendColor); + float bc[4]; + Uint8x4ToFloat4(bc, dynState.blendColor); + vkCmdSetBlendConstants(cmd_, bc); shaderManager_->UpdateUniforms(); shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader->GetModule(), fshader->GetModule(), false); diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index b8751455d9..89034ff8e4 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -34,7 +34,7 @@ static const DeclTypeInfo VComp[] = { { VK_FORMAT_R32G32B32_SFLOAT, "R32G32B32_SFLOAT " }, // DEC_FLOAT_3, { VK_FORMAT_R32G32B32A32_SFLOAT, "R32G32B32A32_SFLOAT " }, // DEC_FLOAT_4, - { VK_FORMAT_R8G8B8A8_SNORM, "UNDEFINED" }, // DEC_S8_3, + { VK_FORMAT_R8G8B8A8_SNORM, "R8G8B8A8_SNORM" }, // DEC_S8_3, { VK_FORMAT_R16G16B16A16_SNORM, "R16G16B16A16_SNORM " }, // DEC_S16_3, { VK_FORMAT_R8G8B8A8_UNORM, "R8G8B8A8_UNORM " }, // DEC_U8_1, @@ -46,8 +46,8 @@ static const DeclTypeInfo VComp[] = { { VK_FORMAT_R16G16B16A16_UNORM, "R16G16B16A16_UNORM " }, // DEC_U16_3, { VK_FORMAT_R16G16B16A16_UNORM, "R16G16B16A16_UNORM " }, // DEC_U16_4, // Not supported in regular DX9 so faking, will cause graphics bugs until worked around - { VK_FORMAT_R8G8_UINT, "VK_FORMAT_UNDEFINED" }, // DEC_U8A_2, - { VK_FORMAT_R16G16_UINT, "VK_FORMAT_UNDEFINED" }, // DEC_U16A_2, + { VK_FORMAT_R8G8_UINT, "R8G8_UINT" }, // DEC_U8A_2, + { VK_FORMAT_R16G16_UINT, "R16G16_UINT" }, // DEC_U16A_2, }; void VertexAttribSetup(VkVertexInputAttributeDescription *attr, int fmt, int offset, PspAttributeLocation location) { diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index dfa435dc32..50c95843a1 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -514,6 +514,9 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader lastFSID_ = FSID; + lastVShader_ = vs; + lastFShader_ = fs; + *vshader = vs; *fshader = fs; } diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index 0c3eb7385a..14fd1b32a0 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -110,7 +110,7 @@ R"( mat4 proj_mtx; mat4 tex_mtx; vec4 uvscaleoffset; vec4 depthRange; - vec2 fogCoef; + vec2 fogcoef; vec4 matambientalpha; vec3 blendFixA; vec3 blendFixB; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 8c2a56c187..6fb68e0eec 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -30,6 +30,7 @@ #include "GPU/Vulkan/PipelineManagerVulkan.h" #include "GPU/Vulkan/TextureCacheVulkan.h" #include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/ShaderManagerVulkan.h" //#include "GPU/Vulkan/PixelShaderGeneratorVulkan.h" // These tables all fit into u8s. @@ -110,7 +111,9 @@ void ResetShaderBlending() { // TODO: Do this more progressively. No need to compute the entire state if the entire state hasn't changed. // In Vulkan, we simply collect all the state together into a "pipeline key" - we don't actually set any state here // (the caller is responsible for setting the little dynamic state that is supported, dynState). -void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState) { +void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState) { + memset(&key, 0, sizeof(key)); + memset(&dynState, 0, sizeof(dynState)); // Unfortunately, this isn't implemented yet. gstate_c.allowShaderBlend = false; @@ -148,7 +151,7 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, int prim, Vulk key.destColor = vkBlendFactorLookup[(size_t)blendState.dstColor]; key.destAlpha = vkBlendFactorLookup[(size_t)blendState.dstAlpha]; if (blendState.dirtyShaderBlend) { - //shaderManager_->DirtyUniform(DIRTY_SHADERBLEND); + shaderManager->DirtyUniform(DIRTY_SHADERBLEND); } dynState.useBlendColor = blendState.useBlendColor; if (blendState.useBlendColor) { @@ -270,7 +273,7 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, int prim, Vulk vp.minDepth = vpAndScissor.depthRangeMin; vp.maxDepth = vpAndScissor.depthRangeMax; if (vpAndScissor.dirtyProj) { - // shaderManager_->DirtyUniform(DIRTY_PROJMATRIX); + shaderManager->DirtyUniform(DIRTY_PROJMATRIX); } VkRect2D &scissor = dynState.scissor; @@ -285,10 +288,10 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, int prim, Vulk if (depthMin < 0.0f) depthMin = 0.0f; if (depthMax > 1.0f) depthMax = 1.0f; if (vpAndScissor.dirtyProj) { - // shaderManager_->DirtyUniform(DIRTY_PROJMATRIX); + shaderManager->DirtyUniform(DIRTY_PROJMATRIX); } if (vpAndScissor.dirtyDepth) { - // shaderManager_->DirtyUniform(DIRTY_DEPTHRANGE); + shaderManager->DirtyUniform(DIRTY_DEPTHRANGE); } } diff --git a/GPU/Vulkan/StateMappingVulkan.h b/GPU/Vulkan/StateMappingVulkan.h index fe0abe9386..f0ee8bd715 100644 --- a/GPU/Vulkan/StateMappingVulkan.h +++ b/GPU/Vulkan/StateMappingVulkan.h @@ -58,5 +58,5 @@ struct VulkanPipelineRasterStateKey { } }; - -void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState); +class ShaderManagerVulkan; +void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 900f169890..7ec887c1ce 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -66,7 +66,7 @@ #define TEXCACHE_SECOND_MIN_PRESSURE 4 * 1024 * 1024 #define VULKAN_4444_FORMAT VK_FORMAT_R4G4B4A4_UNORM_PACK16 -#define VULKAN_1555_FORMAT VK_FORMAT_A1R5G5B5_UNORM_PACK16 +#define VULKAN_1555_FORMAT VK_FORMAT_R5G5B5A1_UNORM_PACK16 // TODO: Switch to the one that matches the PSP better. #define VULKAN_565_FORMAT VK_FORMAT_R5G6B5_UNORM_PACK16 #define VULKAN_8888_FORMAT VK_FORMAT_R8G8B8A8_UNORM @@ -1507,7 +1507,7 @@ VkFormat TextureCacheVulkan::GetDestFormat(GETextureFormat format, GEPaletteForm case GE_TFMT_DXT3: case GE_TFMT_DXT5: default: - return VK_FORMAT_R8G8B8A8_UNORM; + return VULKAN_8888_FORMAT; } } @@ -1628,7 +1628,7 @@ void *TextureCacheVulkan::DecodeTextureLevel(GETextureFormat format, GEPaletteFo case GE_TFMT_8888: if (!swizzled) { // Special case: if we don't need to deal with packing, we don't need to copy. - if ((scaleFactor == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE)) || w == bufw) { + if (scaleFactor == 1 || w == bufw) { finalBuf = (void *)texptr; } else { tmpTexBuf32.resize(std::max(bufw, w) * h); @@ -1715,36 +1715,19 @@ void *TextureCacheVulkan::DecodeTextureLevel(GETextureFormat format, GEPaletteFo ERROR_LOG_REPORT(G3D, "NO finalbuf! Will crash!"); } - if (!(scaleFactor == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE)) && w != bufw) { - int pixelSize; - switch (dstFmt) { - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - pixelSize = 2; - break; - default: - pixelSize = 4; - break; - } - - // Need to rearrange the buffer to simulate GL_UNPACK_ROW_LENGTH etc. - finalBuf = RearrangeBuf(finalBuf, bufw * pixelSize, w * pixelSize, h); - } - return finalBuf; } TextureCacheVulkan::TexCacheEntry::Status TextureCacheVulkan::CheckAlpha(const u32 *pixelData, VkFormat dstFmt, int stride, int w, int h) { CheckAlphaResult res; switch (dstFmt) { - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VULKAN_4444_FORMAT: res = CheckAlphaABGR4444Basic(pixelData, stride, w, h); break; - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VULKAN_1555_FORMAT: res = CheckAlphaABGR1555Basic(pixelData, stride, w, h); break; - case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VULKAN_565_FORMAT: // Never has any alpha. res = CHECKALPHA_FULL; break; @@ -1775,8 +1758,8 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, int level, bool if (finalBuf == NULL) { return; } - decPitch = w * (dstFmt == VULKAN_8888_FORMAT ? 4 : 2); - rowBytes = decPitch; + decPitch = bufw * (dstFmt == VULKAN_8888_FORMAT ? 4 : 2); + rowBytes = w * (dstFmt == VULKAN_8888_FORMAT ? 4 : 2); gpuStats.numTexturesDecoded++; pixelData = (u32 *)finalBuf; diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index 4eac7a04ef..ea35594545 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -55,14 +55,14 @@ static const char * const boneWeightDecl[9] = { "#ERROR#", - "layout(location = 0) in float w1;\n", - "layout(location = 0) in vec2 w1;\n", - "layout(location = 0) in vec3 w1;\n", - "layout(location = 0) in vec4 w1;\n", - "layout(location = 0) in vec4 w1;\nin float w2;\n", - "layout(location = 0) in vec4 w1;\nin vec2 w2;\n", - "layout(location = 0) in vec4 w1;\nin vec3 w2;\n", - "layout(location = 0) in vec4 w1, w2;\n", + "layout(location = 3) in float w1;\n", + "layout(location = 3) in vec2 w1;\n", + "layout(location = 3) in vec3 w1;\n", + "layout(location = 3) in vec4 w1;\n", + "layout(location = 3) in vec4 w1;\nlayout(location = 4) in float w2;\n", + "layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec2 w2;\n", + "layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec3 w2;\n", + "layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec4 w2;\n", }; enum DoLightComputation { @@ -139,7 +139,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) { WRITE(p, "\n"); WRITE(p, "layout (std140, set = 0, binding = 2) uniform baseVars {\n%s\n} base;\n", ub_baseStr); - if (enableLighting) + if (enableLighting || doShadeMapping) WRITE(p, "layout (std140, set = 0, binding = 3) uniform lightVars {\n%s\n} light;\n", ub_vs_lightsStr); if (enableBones) WRITE(p, "layout (std140, set = 0, binding = 4) uniform boneVars {\n%s\n} bone;\n", ub_vs_bonesStr); @@ -497,7 +497,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) { break; } // Transform by texture matrix. XYZ as we are doing projection mapping. - WRITE(p, " v_texcoord = (base.texmtx * %s).xyz * vec3(base.uvscaleoffset.xy, 1.0);\n", temp_tc.c_str()); + WRITE(p, " v_texcoord = (base.tex_mtx * %s).xyz * vec3(base.uvscaleoffset.xy, 1.0);\n", temp_tc.c_str()); } break; diff --git a/ext/native/thin3d/VulkanContext.cpp b/ext/native/thin3d/VulkanContext.cpp index c254cd930a..e29c1f4bd3 100644 --- a/ext/native/thin3d/VulkanContext.cpp +++ b/ext/native/thin3d/VulkanContext.cpp @@ -1275,7 +1275,6 @@ void VulkanTexture::Unlock(VulkanContext *vulkan) { VkMemoryAllocateInfo mem_alloc = {}; mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; mem_alloc.pNext = NULL; - mem_alloc.allocationSize = 0; mem_alloc.memoryTypeIndex = 0; mem_alloc.allocationSize = mem_reqs.size; diff --git a/ext/native/thin3d/VulkanContext.h b/ext/native/thin3d/VulkanContext.h index 51093503e2..4115e8435e 100644 --- a/ext/native/thin3d/VulkanContext.h +++ b/ext/native/thin3d/VulkanContext.h @@ -343,8 +343,8 @@ private: class VulkanTexture { public: VulkanTexture() - : image(nullptr), mem(nullptr), view(nullptr), tex_width(0), tex_height(0), format_(VK_FORMAT_UNDEFINED), - mappableImage(nullptr), mappableMemory(nullptr) { + : image(nullptr), imageLayout(VK_IMAGE_LAYOUT_UNDEFINED), mem(nullptr), view(nullptr), tex_width(0), tex_height(0), format_(VK_FORMAT_UNDEFINED), + mappableImage(nullptr), mappableMemory(nullptr), needStaging(false) { } // Always call Create, Lock, Unlock. Unlock performs the upload if necessary. // Can later Lock and Unlock again. This cannot change the format. Create cannot