Permalink
Browse files

Implement the rest of Vulkan framebuffer depal. Not yet working though.

  • Loading branch information...
hrydgard committed Oct 30, 2017
1 parent 65e23bb commit 3f503ca29730203ec58cc7dda671bc17b720c114
@@ -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 @@ class DepalShaderCacheVulkan {
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 @@ class TextureCacheVulkan : public TextureCacheCommon {
void GetVulkanHandles(VkImageView &imageView, VkSampler &sampler) {
imageView = imageView_;
sampler = sampler_;
sampler = curSampler_;
}
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
@@ -144,7 +144,9 @@ class TextureCacheVulkan : public TextureCacheCommon {
// 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

0 comments on commit 3f503ca

Please sign in to comment.