Permalink
Browse files

Some reorganization. Start implementing framebuffer depal for Vulkan.

  • Loading branch information...
hrydgard committed Oct 30, 2017
1 parent 6253280 commit 65e23bb9f350eefdc489ef14b08e8daa8074fa32
@@ -20,4 +20,6 @@
#include "GPU/ge_constants.h"
#include "GPU/Common/ShaderCommon.h"
static const int DEPAL_TEXTURE_OLD_AGE = 120;
void GenerateDepalShader(char *buffer, GEBufferFormat pixelFormat, ShaderLanguage language);
@@ -29,8 +29,6 @@
#include "GPU/D3D11/D3D11Util.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
static const int DEPAL_TEXTURE_OLD_AGE = 120;
#ifdef _WIN32
#define SHADERLOG
#endif
@@ -26,8 +26,6 @@
#include "ext/native/gfx/GLStateCache.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
static const int DEPAL_TEXTURE_OLD_AGE = 120;
#ifdef _WIN32
#define SHADERLOG
#endif
@@ -15,33 +15,124 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/Vulkan/VulkanContext.h"
#include "GPU/GPUState.h"
#include "GPU/Common/DepalettizeShaderCommon.h"
#include "GPU/Vulkan/DepalettizeShaderVulkan.h"
#include "GPU/Vulkan/VulkanUtil.h"
#include "Common/Vulkan/VulkanImage.h"
static VkFormat GetClutDestFormat(GEPaletteFormat format) {
switch (format) {
case GE_CMODE_16BIT_ABGR4444:
return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
case GE_CMODE_16BIT_ABGR5551:
return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
case GE_CMODE_16BIT_BGR5650:
return VK_FORMAT_R5G6B5_UNORM_PACK16;
case GE_CMODE_32BIT_ABGR8888:
return VK_FORMAT_R8G8B8A8_UNORM;
}
return VK_FORMAT_UNDEFINED;
}
DepalShaderCacheVulkan::DepalShaderCacheVulkan() {
DepalShaderCacheVulkan::DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan)
: draw_(draw), vulkan_(vulkan) {
}
DepalShaderCacheVulkan::~DepalShaderCacheVulkan() {
}
DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutMode, pixelFormat);
auto shader = cache_.find(id);
if (shader != cache_.end()) {
return shader->second;
}
char *buffer = new char[2048];
VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::FRAMEBUFFER_RENDERPASS);
GenerateDepalShader(buffer, pixelFormat, GLSL_VULKAN);
std::string error;
VkShaderModule fshader = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, buffer, &error);
if (fshader == VK_NULL_HANDLE) {
return nullptr;
}
VkPipeline pipeline = vulkan2D_->GetPipeline(rp, vshader_, fshader);
// Can delete the shader module now that the pipeline has been created.
// Maybe don't even need to queue it..
vulkan_->Delete().QueueDeleteShaderModule(fshader);
DepalShaderVulkan *depal = new DepalShaderVulkan();
depal->pipeline = pipeline;
depal->code = buffer;
cache_[id] = depal;
return nullptr;
}
VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut) {
return nullptr;
VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat, u32 clutID, u32 *rawClut) {
const u32 realClutID = clutID ^ clutFormat;
auto oldtex = texCache_.find(realClutID);
if (oldtex != texCache_.end()) {
oldtex->second->lastFrame = gpuStats.numFlips;
return oldtex->second->texture;
}
VkFormat destFormat = GetClutDestFormat(clutFormat);
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
VkBuffer pushBuffer;
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_);
DepalTextureVulkan *tex = new DepalTextureVulkan();
tex->texture = vktex;
tex->lastFrame = gpuStats.numFlips;
texCache_[realClutID] = tex;
return tex->texture;
}
void DepalShaderCacheVulkan::Clear() {}
void DepalShaderCacheVulkan::Clear() {
for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
// Delete the shader/pipeline too.
delete shader->second;
}
cache_.clear();
void DepalShaderCacheVulkan::Decimate() {}
for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) {
delete tex->second->texture;
delete tex->second;
}
texCache_.clear();
// TODO: Delete vertex shader.
}
u32 DepalShaderCacheVulkan::GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
return 0;
void DepalShaderCacheVulkan::Decimate() {
// We don't bother decimating the generated shaders, there are never very many of them.
for (auto tex = texCache_.begin(); tex != texCache_.end(); ) {
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
delete tex->second->texture;
delete tex->second;
texCache_.erase(tex++);
} else {
++tex;
}
}
}
bool DepalShaderCacheVulkan::CreateVertexShader() {
return false;
u32 DepalShaderCacheVulkan::GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat) {
return (clutMode & 0xFFFFFF) | (pixelFormat << 24);
}
@@ -20,42 +20,59 @@
#include <map>
#include "Common/CommonTypes.h"
#include "Common/Vulkan/VulkanContext.h"
#include "Common/Vulkan/VulkanImage.h"
#include "Common/Vulkan/VulkanMemory.h"
#include "GPU/ge_constants.h"
#include "thin3d/thin3d.h"
class DepalShaderVulkan {
public:
/*
GLuint program;
GLuint fragShader;
GLint a_position;
GLint a_texcoord0;
*/
~DepalShaderVulkan() {
delete[] code;
}
// A Vulkan2D pipeline. Set texture to slot 0 and palette texture to slot 1.
VkPipeline pipeline;
const char *code = nullptr;;
};
class DepalTextureVulkan {
public:
int texture;
VulkanTexture *texture;
int lastFrame;
};
class VulkanTexture;
class Vulkan2D;
// Caches both shaders and palette textures.
// Could even avoid bothering with palette texture and just use uniform data...
class DepalShaderCacheVulkan {
public:
DepalShaderCacheVulkan();
DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan);
~DepalShaderCacheVulkan();
// This also uploads the palette and binds the correct texture.
DepalShaderVulkan *GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
DepalShaderVulkan *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat);
VulkanTexture *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
void Clear();
void Decimate();
void SetVulkan2D(Vulkan2D *vk2d) { vulkan2D_ = vk2d; }
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
void SetAllocator(VulkanDeviceAllocator *alloc) { alloc_ = alloc; }
void SetVShader(VkShaderModule vshader) { vshader_ = vshader; }
private:
u32 GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
bool CreateVertexShader();
u32 GenerateShaderID(uint32_t clutMode, GEBufferFormat pixelFormat);
VkCommandBuffer cmd_ = VK_NULL_HANDLE;
Draw::DrawContext *draw_ = nullptr;
VulkanContext *vulkan_ = nullptr;
VulkanPushBuffer *push_ = nullptr;
VulkanDeviceAllocator *alloc_ = nullptr;
VkShaderModule vshader_ = VK_NULL_HANDLE;
Vulkan2D *vulkan2D_ = nullptr;
// GLuint vertexShader_;
std::map<u32, DepalShaderVulkan *> cache_;
Oops, something went wrong.

0 comments on commit 65e23bb

Please sign in to comment.