diff --git a/core/rend/TexCache.h b/core/rend/TexCache.h index 019d13dd7..670a8aff2 100644 --- a/core/rend/TexCache.h +++ b/core/rend/TexCache.h @@ -1,6 +1,7 @@ #pragma once #include #include "oslib/oslib.h" +#include "hw/pvr/pvr_regs.h" #include "hw/pvr/ta_structs.h" extern u8* vq_codebook; @@ -630,7 +631,7 @@ struct PvrTexInfo; template class PixelBuffer; typedef void TexConvFP(PixelBuffer* pb,u8* p_in,u32 Width,u32 Height); typedef void TexConvFP32(PixelBuffer* pb,u8* p_in,u32 Width,u32 Height); -enum class TextureType { _565, _5551, _4444, _8888 }; +enum class TextureType { _565, _5551, _4444, _8888, _8 }; struct BaseTextureCacheData { @@ -705,3 +706,13 @@ void CollectCleanup(); void killtex(); void ReadFramebuffer(PixelBuffer& pb, int& width, int& height); + +static inline void MakeFogTexture(u8 *tex_data) +{ + u8 *fog_table = (u8 *)FOG_TABLE; + for (int i = 0; i < 128; i++) + { + tex_data[i] = fog_table[i * 4]; + tex_data[i + 128] = fog_table[i * 4 + 1]; + } +} diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index dd9d15e9d..44d616398 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1387,11 +1387,8 @@ void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format glcache.BindTexture(GL_TEXTURE_2D, fogTextureId); u8 temp_tex_buffer[256]; - for (int i = 0; i < 128; i++) - { - temp_tex_buffer[i] = fog_table[i * 4]; - temp_tex_buffer[i + 128] = fog_table[i * 4 + 1]; - } + MakeFogTexture(temp_tex_buffer); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, fog_image_format, 128, 2, 0, fog_image_format, GL_UNSIGNED_BYTE, temp_tex_buffer); glCheck(); diff --git a/core/rend/vulkan/pipeline.cpp b/core/rend/vulkan/pipeline.cpp index 20f8c3343..24acc762c 100644 --- a/core/rend/vulkan/pipeline.cpp +++ b/core/rend/vulkan/pipeline.cpp @@ -202,7 +202,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol params.clipTest = 0; // always passes break; } - params.fog = 2; // TODO fog texture -> pp.tsp.FogCtrl; + params.fog = settings.rend.Fog ? pp.tsp.FogCtrl : 2; params.gouraud = pp.pcw.Gouraud; params.ignoreTexAlpha = pp.tsp.IgnoreTexA; params.offset = pp.pcw.Offset; diff --git a/core/rend/vulkan/pipeline.h b/core/rend/vulkan/pipeline.h index 2a44a7678..002a8e42c 100644 --- a/core/rend/vulkan/pipeline.h +++ b/core/rend/vulkan/pipeline.h @@ -50,7 +50,7 @@ public: vk::PipelineLayoutCreateInfo(vk::PipelineLayoutCreateFlags(), ARRAY_SIZE(layouts), layouts, 1, &pushConstant)); } - void UpdateUniforms(const vk::Buffer& vertexUniformBuffer, const vk::Buffer& fragmentUniformBuffer) + void UpdateUniforms(const vk::Buffer& vertexUniformBuffer, const vk::Buffer& fragmentUniformBuffer, vk::ImageView fogImageView) { while (perFrameDescSets.empty()) { @@ -63,12 +63,24 @@ public: while (perPolyDescSetsInFlight.size() < GetContext()->GetSwapChainSize()) perPolyDescSetsInFlight.push_back(std::map, vk::UniqueDescriptorSet>()); int currentImage = GetContext()->GetCurrentImageIndex(); + std::vector bufferInfos; bufferInfos.push_back(vk::DescriptorBufferInfo(vertexUniformBuffer, 0, VK_WHOLE_SIZE)); bufferInfos.push_back(vk::DescriptorBufferInfo(fragmentUniformBuffer, 0, VK_WHOLE_SIZE)); + std::vector writeDescriptorSets; writeDescriptorSets.push_back(vk::WriteDescriptorSet(*perFrameDescSets[currentImage], 0, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &bufferInfos[0], nullptr)); writeDescriptorSets.push_back(vk::WriteDescriptorSet(*perFrameDescSets[currentImage], 1, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &bufferInfos[1], nullptr)); + if (fogImageView) + { + TSP fogTsp = {}; + fogTsp.FilterMode = 1; + fogTsp.ClampU = 1; + fogTsp.ClampV = 1; + vk::Sampler fogSampler = samplerManager.GetSampler(fogTsp); + vk::DescriptorImageInfo imageInfo(fogSampler, fogImageView, vk::ImageLayout::eShaderReadOnlyOptimal); + writeDescriptorSets.push_back(vk::WriteDescriptorSet(*perFrameDescSets[currentImage], 2, 0, 1, vk::DescriptorType::eCombinedImageSampler, &imageInfo, nullptr, nullptr)); + } GetContext()->GetDevice()->updateDescriptorSets(writeDescriptorSets, nullptr); } @@ -176,7 +188,7 @@ private: | ((pp->tileclip >> 28) << 4); hash |= ((listType >> 1) << 6); hash |= (pp->tsp.ShadInstr << 8) | (pp->tsp.IgnoreTexA << 10) | (pp->tsp.UseAlpha << 11) - | (pp->tsp.ColorClamp << 12) | (pp->tsp.FogCtrl << 13) | (pp->tsp.SrcInstr << 15) + | (pp->tsp.ColorClamp << 12) | ((settings.rend.Fog ? pp->tsp.FogCtrl : 2) << 13) | (pp->tsp.SrcInstr << 15) | (pp->tsp.DstInstr << 18); hash |= (pp->isp.ZWriteDis << 21) | (pp->isp.CullMode << 22) | (pp->isp.DepthMode << 24); hash |= (u32)sortTriangles << 27; diff --git a/core/rend/vulkan/shaders.cpp b/core/rend/vulkan/shaders.cpp index 4681d8d5c..63ff26b96 100644 --- a/core/rend/vulkan/shaders.cpp +++ b/core/rend/vulkan/shaders.cpp @@ -129,20 +129,20 @@ layout (location = 1) INTERPOLATION in lowp vec4 vtx_offs; layout (location = 2) in mediump vec2 vtx_uv; #if pp_FogCtrl != 2 -layout (set = 1, binding = 1) uniform sampler2D fog_table; +layout (set = 0, binding = 2) uniform sampler2D fog_table; -lowp float fog_mode2(float w) +float fog_mode2(float w) { float z = clamp(w * uniformBuffer.extra_depth_scale * uniformBuffer.sp_FOG_DENSITY, 1.0, 255.9999); float exp = floor(log2(z)); float m = z * 16.0 / pow(2.0, exp) - 16.0; - lowp float idx = floor(m) + exp * 16.0 + 0.5; + float idx = floor(m) + exp * 16.0 + 0.5; vec4 fog_coef = texture(fog_table, vec2(idx / 128.0, 0.75 - (m - floor(m)) / 2.0)); return fog_coef.r; } #endif -vec4 colorClamp(lowp vec4 col) +vec4 colorClamp(vec4 col) { #if ColorClamping == 1 return clamp(col, uniformBuffer.colorClampMin, uniformBuffer.colorClampMax); @@ -166,7 +166,7 @@ void main() discard; #endif - lowp vec4 color = vtx_base; + vec4 color = vtx_base; #if pp_UseAlpha == 0 color.a = 1.0; #endif @@ -175,7 +175,7 @@ void main() #endif #if pp_Texture == 1 { - lowp vec4 texcol = texture(tex, vtx_uv); + vec4 texcol = texture(tex, vtx_uv); #if pp_BumpMap == 1 float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0; @@ -260,7 +260,7 @@ out vec4 FragColor; layout (std140, binding = 1) uniform buffer { - lowp float sp_ShaderColor; + float sp_ShaderColor; } uniformBuffer; void main() diff --git a/core/rend/vulkan/texture.cpp b/core/rend/vulkan/texture.cpp index 49518e9ed..45b2f4179 100644 --- a/core/rend/vulkan/texture.cpp +++ b/core/rend/vulkan/texture.cpp @@ -145,6 +145,10 @@ void Texture::UploadToGPU(int width, int height, u8 *data) format = vk::Format::eR8G8B8A8Unorm; dataSize *= 2; break; + case TextureType::_8: + format = vk::Format::eR8Unorm; + dataSize /= 2; + break; } Init(width, height, format); SetImage(VulkanContext::Instance()->GetCurrentCommandPool(), dataSize, data); diff --git a/core/rend/vulkan/vulkan_renderer.cpp b/core/rend/vulkan/vulkan_renderer.cpp index ae17c9420..e0f325fd1 100644 --- a/core/rend/vulkan/vulkan_renderer.cpp +++ b/core/rend/vulkan/vulkan_renderer.cpp @@ -195,11 +195,8 @@ public: fragUniforms.colorClampMax[2] = ((pvrrc.fog_clamp_max >> 0) & 0xFF) / 255.0f; fragUniforms.colorClampMax[3] = ((pvrrc.fog_clamp_max >> 24) & 0xFF) / 255.0f; - if (fog_needs_update && settings.rend.Fog) - { - fog_needs_update = false; - // TODO UpdateFogTexture((u8 *)FOG_TABLE, GL_TEXTURE1, gl.fog_image_format); - } + CheckFogTexture(); + fragUniforms.cp_AlphaTestValue = (PT_ALPHA_REF & 0xFF) / 255.0f; ModVolShaderUniforms modVolUniforms; @@ -207,8 +204,6 @@ public: UploadUniforms(vtxUniforms, fragUniforms, modVolUniforms); - // TODO this upload should go in a cmd buffer? - GetContext()->BeginRenderPass(); vk::CommandBuffer cmdBuffer = GetContext()->GetCurrentCommandBuffer(); @@ -220,7 +215,7 @@ public: indexBuffers[GetCurrentImage()]->upload(GetContext()->GetDevice().get(), pvrrc.idx.bytes(), pvrrc.idx.head()); // Update per-frame descriptor set and bind it - pipelineManager.GetDescriptorSets().UpdateUniforms(*vertexUniformBuffer, *fragmentUniformBuffer); + pipelineManager.GetDescriptorSets().UpdateUniforms(*vertexUniformBuffer, *fragmentUniformBuffer, fogTexture->GetImageView()); pipelineManager.GetDescriptorSets().BindPerFrameDescriptorSets(cmdBuffer); // Reset per-poly descriptor set pool pipelineManager.GetDescriptorSets().Reset(); @@ -379,7 +374,6 @@ private: return clip_mode; } - void DrawList(const vk::CommandBuffer& cmdBuffer, u32 listType, bool sortTriangles, const List& polys, u32 first, u32 count) { for (u32 i = first; i < count; i++) @@ -492,9 +486,25 @@ private: } } + void CheckFogTexture() + { + if (!fogTexture) + { + fogTexture = std::unique_ptr(new Texture(GetContext()->GetPhysicalDevice(), *GetContext()->GetDevice())); + fogTexture->tex_type = TextureType::_8; + } + if (!fog_needs_update || !settings.rend.Fog) + return; + fog_needs_update = false; + u8 texData[256]; + MakeFogTexture(texData); + fogTexture->UploadToGPU(128, 2, texData); + } + // temp stuff float scale_x; float scale_y; + std::unique_ptr fogTexture; // Uniforms vk::UniqueBuffer vertexUniformBuffer;