mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Implement the rest of Vulkan framebuffer depal. Not yet working though.
This commit is contained in:
parent
65e23bb9f3
commit
3f503ca297
7 changed files with 62 additions and 21 deletions
|
@ -269,6 +269,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
|||
0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
break;
|
||||
default:
|
||||
// If you planned to use UploadMip, you want VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. After the
|
||||
// upload, you can transition.
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang
|
|||
WRITE(p, "layout(set = 0, binding = 0) uniform sampler2D tex;\n");
|
||||
WRITE(p, "layout(set = 0, binding = 1) uniform sampler2D pal;\n");
|
||||
WRITE(p, "layout(location = 0) in vec2 v_texcoord0;\n");
|
||||
WRITE(p, "layout(location = 0) out vec4 fragColor0\n;");
|
||||
WRITE(p, "layout(location = 0) out vec4 fragColor0;\n");
|
||||
} else {
|
||||
if (gl_extensions.IsGLES) {
|
||||
WRITE(p, "#version 300 es\n");
|
||||
|
@ -288,4 +288,4 @@ void GenerateDepalShader(char *buffer, GEBufferFormat pixelFormat, ShaderLanguag
|
|||
}
|
||||
}
|
||||
|
||||
#undef WRITE
|
||||
#undef WRITE
|
||||
|
|
|
@ -22,6 +22,19 @@
|
|||
#include "GPU/Vulkan/VulkanUtil.h"
|
||||
#include "Common/Vulkan/VulkanImage.h"
|
||||
|
||||
static const char depal_vs[] = R"(#version 400
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec2 a_texcoord0;
|
||||
layout (location = 0) out vec2 v_texcoord0;
|
||||
out gl_PerVertex { vec4 gl_Position; };
|
||||
void main() {
|
||||
v_texcoord0 = a_texcoord0;
|
||||
gl_Position = vec4(a_position, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
static VkFormat GetClutDestFormat(GEPaletteFormat format) {
|
||||
switch (format) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
|
@ -38,11 +51,14 @@ static VkFormat GetClutDestFormat(GEPaletteFormat format) {
|
|||
|
||||
DepalShaderCacheVulkan::DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan)
|
||||
: draw_(draw), vulkan_(vulkan) {
|
||||
|
||||
std::string errors;
|
||||
vshader_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, depal_vs, &errors);
|
||||
assert(vshader_ != VK_NULL_HANDLE);
|
||||
}
|
||||
|
||||
DepalShaderCacheVulkan::~DepalShaderCacheVulkan() {
|
||||
|
||||
Clear();
|
||||
vulkan_->Delete().QueueDeleteShaderModule(vshader_);
|
||||
}
|
||||
|
||||
DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
|
||||
|
@ -53,15 +69,16 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod
|
|||
return shader->second;
|
||||
}
|
||||
|
||||
char *buffer = new char[2048];
|
||||
|
||||
VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::FRAMEBUFFER_RENDERPASS);
|
||||
|
||||
char *buffer = new char[2048];
|
||||
GenerateDepalShader(buffer, pixelFormat, GLSL_VULKAN);
|
||||
|
||||
std::string error;
|
||||
VkShaderModule fshader = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, buffer, &error);
|
||||
if (fshader == VK_NULL_HANDLE) {
|
||||
Crash();
|
||||
delete[] buffer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -74,10 +91,11 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod
|
|||
depal->pipeline = pipeline;
|
||||
depal->code = buffer;
|
||||
cache_[id] = depal;
|
||||
return nullptr;
|
||||
return depal;
|
||||
}
|
||||
|
||||
VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat, u32 clutID, u32 *rawClut) {
|
||||
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
|
||||
const u32 realClutID = clutID ^ clutFormat;
|
||||
|
||||
auto oldtex = texCache_.find(realClutID);
|
||||
|
@ -93,9 +111,12 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat
|
|||
uint32_t pushOffset = push_->PushAligned(rawClut, 1024, 4, &pushBuffer);
|
||||
|
||||
VulkanTexture *vktex = new VulkanTexture(vulkan_, alloc_);
|
||||
vktex->CreateDirect(cmd_, texturePixels, 1, 1, destFormat, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, nullptr);
|
||||
vktex->UploadMip(cmd_, 0, texturePixels, 1, pushBuffer, pushOffset, texturePixels);
|
||||
vktex->EndCreate(cmd_);
|
||||
if (!vktex->CreateDirect(cmd, texturePixels, 1, 1, destFormat,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, nullptr)) {
|
||||
Crash();
|
||||
}
|
||||
vktex->UploadMip(cmd, 0, texturePixels, 1, pushBuffer, pushOffset, texturePixels);
|
||||
vktex->EndCreate(cmd);
|
||||
|
||||
DepalTextureVulkan *tex = new DepalTextureVulkan();
|
||||
tex->texture = vktex;
|
||||
|
@ -107,6 +128,8 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat
|
|||
void DepalShaderCacheVulkan::Clear() {
|
||||
for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
|
||||
// Delete the shader/pipeline too.
|
||||
vulkan_->Delete().QueueDeletePipeline(shader->second->pipeline);
|
||||
delete[] shader->second->code;
|
||||
delete shader->second;
|
||||
}
|
||||
cache_.clear();
|
||||
|
@ -116,8 +139,6 @@ void DepalShaderCacheVulkan::Clear() {
|
|||
delete tex->second;
|
||||
}
|
||||
texCache_.clear();
|
||||
|
||||
// TODO: Delete vertex shader.
|
||||
}
|
||||
|
||||
void DepalShaderCacheVulkan::Decimate() {
|
||||
|
|
|
@ -66,7 +66,6 @@ public:
|
|||
private:
|
||||
u32 GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat);
|
||||
|
||||
VkCommandBuffer cmd_ = VK_NULL_HANDLE;
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
VulkanContext *vulkan_ = nullptr;
|
||||
VulkanPushBuffer *push_ = nullptr;
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "math/math_util.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "thin3d/VulkanRenderManager.h"
|
||||
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Host.h"
|
||||
|
@ -130,10 +132,19 @@ TextureCacheVulkan::TextureCacheVulkan(Draw::DrawContext *draw, VulkanContext *v
|
|||
lastBoundTexture = nullptr;
|
||||
allocator_ = new VulkanDeviceAllocator(vulkan_, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE);
|
||||
|
||||
VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samp.magFilter = VK_FILTER_NEAREST;
|
||||
samp.minFilter = VK_FILTER_NEAREST;
|
||||
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_);
|
||||
SetupTextureDecoder();
|
||||
}
|
||||
|
||||
TextureCacheVulkan::~TextureCacheVulkan() {
|
||||
vulkan_->Delete().QueueDeleteSampler(samplerNearest_);
|
||||
Clear(true);
|
||||
|
||||
if (allocator_) {
|
||||
|
@ -333,19 +344,19 @@ void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutB
|
|||
void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
|
||||
if (!entry || !entry->vkTex) {
|
||||
imageView_ = VK_NULL_HANDLE;
|
||||
sampler_ = VK_NULL_HANDLE;
|
||||
curSampler_ = VK_NULL_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
imageView_ = entry->vkTex->texture_->GetImageView();
|
||||
SamplerCacheKey key;
|
||||
UpdateSamplingParams(*entry, key);
|
||||
sampler_ = samplerCache_.GetOrCreateSampler(key);
|
||||
curSampler_ = samplerCache_.GetOrCreateSampler(key);
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::Unbind() {
|
||||
imageView_ = VK_NULL_HANDLE;
|
||||
sampler_ = VK_NULL_HANDLE;
|
||||
curSampler_ = VK_NULL_HANDLE;
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
|
@ -413,6 +424,13 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr
|
|||
verts[3].v = uvtop;
|
||||
}
|
||||
|
||||
VkBuffer pushed;
|
||||
uint32_t offset = push_->PushAligned(verts, sizeof(verts), 4, &pushed);
|
||||
VkImageView fbo = (VkImageView)draw_->GetFramebufferAPITexture(framebuffer->fbo, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
VkDescriptorSet descSet = vulkan2D_->GetDescriptorSet(fbo, samplerNearest_, clutTexture->GetImageView(), samplerNearest_);
|
||||
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager->Draw(vulkan2D_->GetPipelineLayout(), descSet, 0, nullptr, pushed, offset, 4);
|
||||
shaderManagerVulkan_->DirtyLastShader();
|
||||
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
|
@ -435,7 +453,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr
|
|||
|
||||
SamplerCacheKey samplerKey;
|
||||
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey);
|
||||
sampler_ = samplerCache_.GetOrCreateSampler(samplerKey);
|
||||
curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey);
|
||||
InvalidateLastTexture(entry);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
|
||||
void GetVulkanHandles(VkImageView &imageView, VkSampler &sampler) {
|
||||
imageView = imageView_;
|
||||
sampler = sampler_;
|
||||
sampler = curSampler_;
|
||||
}
|
||||
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
|
||||
|
||||
|
@ -144,7 +144,9 @@ private:
|
|||
|
||||
// Bound state to emulate an API similar to the others
|
||||
VkImageView imageView_ = VK_NULL_HANDLE;
|
||||
VkSampler sampler_ = VK_NULL_HANDLE;
|
||||
VkSampler curSampler_ = VK_NULL_HANDLE;
|
||||
|
||||
VkSampler samplerNearest_ = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
VkFormat getClutDestFormatVulkan(GEPaletteFormat format);
|
||||
|
|
|
@ -1140,7 +1140,6 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) {
|
|||
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vertexCount);
|
||||
}
|
||||
|
||||
// TODO: We should avoid this function as much as possible, instead use renderpass on-load clearing.
|
||||
void VKContext::Clear(int clearMask, uint32_t colorval, float depthVal, int stencilVal) {
|
||||
int mask = 0;
|
||||
if (clearMask & FBChannel::FB_COLOR_BIT)
|
||||
|
@ -1359,9 +1358,9 @@ void VKContext::HandleEvent(Event ev, int width, int height, void *param1, void
|
|||
renderManager_.CreateBackbuffers();
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
// Noop
|
||||
}
|
||||
|
||||
} // namespace Draw
|
||||
|
|
Loading…
Add table
Reference in a new issue