vulkan: fog support
This commit is contained in:
parent
8f8f270cfc
commit
b82a97853f
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <atomic>
|
||||
#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 pixel_type> class PixelBuffer;
|
||||
typedef void TexConvFP(PixelBuffer<u16>* pb,u8* p_in,u32 Width,u32 Height);
|
||||
typedef void TexConvFP32(PixelBuffer<u32>* 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<u32>& 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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<std::pair<u64, u32>, vk::UniqueDescriptorSet>());
|
||||
int currentImage = GetContext()->GetCurrentImageIndex();
|
||||
|
||||
std::vector<vk::DescriptorBufferInfo> bufferInfos;
|
||||
bufferInfos.push_back(vk::DescriptorBufferInfo(vertexUniformBuffer, 0, VK_WHOLE_SIZE));
|
||||
bufferInfos.push_back(vk::DescriptorBufferInfo(fragmentUniformBuffer, 0, VK_WHOLE_SIZE));
|
||||
|
||||
std::vector<vk::WriteDescriptorSet> 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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<PolyParam>& 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<Texture>(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<Texture> fogTexture;
|
||||
|
||||
// Uniforms
|
||||
vk::UniqueBuffer vertexUniformBuffer;
|
||||
|
|
Loading…
Reference in New Issue