vulkan: make staging buffer visible to host for rtt2vram. Minor changes

This commit is contained in:
Flyinghead 2019-10-11 12:38:09 +02:00
parent 2bac2afe98
commit 459a2b973e
6 changed files with 16 additions and 140 deletions

View File

@ -141,8 +141,9 @@ void Drawer::DrawPoly(const vk::CommandBuffer& cmdBuffer, u32 listType, bool sor
trilinearAlpha = 1.f;
std::array<float, 5> pushConstants = { 0, 0, 0, 0, trilinearAlpha };
SetTileClip(poly.tileclip, &pushConstants[0]);
cmdBuffer.pushConstants<float>(pipelineManager->GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants);
int tileClip = SetTileClip(poly.tileclip, &pushConstants[0]);
if (tileClip != 0 || trilinearAlpha != 1.f)
cmdBuffer.pushConstants<float>(pipelineManager->GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants);
if (poly.pcw.Texture)
GetCurrentDescSet().SetTexture(poly.texid, poly.tsp);
@ -500,7 +501,6 @@ vk::CommandBuffer TextureDrawer::BeginRenderPass()
texture->Create();
if (texture->format != vk::Format::eR8G8B8A8Unorm)
{
//texture->Init(newWidth, newHeight, format);
texture->extent = vk::Extent2D(widthPow2, heightPow2);
texture->format = vk::Format::eR8G8B8A8Unorm;
texture->CreateImage(vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eSampled,

View File

@ -165,7 +165,7 @@ void PipelineManager::CreateModVolPipeline(ModVolMode mode)
vk::LogicOp::eNoOp, // logicOp
1, // attachmentCount
&pipelineColorBlendAttachmentState, // pAttachments
{ { (1.0f, 1.0f, 1.0f, 1.0f) } } // blendConstants
{ { 1.0f, 1.0f, 1.0f, 1.0f } } // blendConstants
);
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
@ -235,7 +235,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
// Depth and stencil
vk::CompareOp depthOp;
if (listType == ListType_Punch_Through || (listType == ListType_Translucent && sortTriangles))
if (listType == ListType_Punch_Through || sortTriangles)
depthOp = vk::CompareOp::eGreaterOrEqual;
else
depthOp = depthOps[pp.isp.DepthMode];
@ -308,7 +308,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
vk::LogicOp::eNoOp, // logicOp
1, // attachmentCount
&pipelineColorBlendAttachmentState, // pAttachments
{ { (1.0f, 1.0f, 1.0f, 1.0f) } } // blendConstants
{ { 1.0f, 1.0f, 1.0f, 1.0f } } // blendConstants
);
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };

View File

@ -245,7 +245,6 @@ public:
vk::AttachmentDescription attachmentDescriptions[] = {
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), vk::Format::eR8G8B8A8Unorm, vk::SampleCountFlagBits::e1,
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
// vk::ImageLayout::eUndefined, settings.rend.RenderToTextureBuffer ? vk::ImageLayout::eTransferSrcOptimal : vk::ImageLayout::eColorAttachmentOptimal),
vk::ImageLayout::eColorAttachmentOptimal,
settings.rend.RenderToTextureBuffer ? vk::ImageLayout::eTransferSrcOptimal : vk::ImageLayout::eShaderReadOnlyOptimal),
vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), vk::Format::eD32SfloatS8Uint, vk::SampleCountFlagBits::e1,

View File

@ -270,8 +270,7 @@ void FramebufferAttachment::Init(u32 width, u32 height, vk::Format format)
{
usage |= vk::ImageUsageFlagBits::eTransferSrc;
stagingBufferData = std::unique_ptr<BufferData>(new BufferData(VulkanContext::Instance()->GetPhysicalDevice(), *VulkanContext::Instance()->GetDevice(),
width * height * 4, vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent));
width * height * 4, vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst));
}
else
{

View File

@ -115,134 +115,3 @@ private:
vk::PhysicalDevice physicalDevice;
vk::Device device;
};
class RenderToTexture
{
public:
RenderToTexture() : colorAttachment(VulkanContext::Instance()->GetPhysicalDevice(), *VulkanContext::Instance()->GetDevice()),
depthAttachment(VulkanContext::Instance()->GetPhysicalDevice(), *VulkanContext::Instance()->GetDevice())
{}
void PrepareRender(vk::RenderPass rttRenderPass)
{
DEBUG_LOG(RENDERER, "RenderToTexture packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
u32 newWidth = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
u32 newHeight = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
int fbh = 2;
while (fbh < newHeight)
fbh *= 2;
int fbw = 2;
while (fbw < newWidth)
fbw *= 2;
if (settings.rend.RenderToTextureUpscale > 1 && !settings.rend.RenderToTextureBuffer)
{
newWidth *= settings.rend.RenderToTextureUpscale;
newHeight *= settings.rend.RenderToTextureUpscale;
fbw *= settings.rend.RenderToTextureUpscale;
fbh *= settings.rend.RenderToTextureUpscale;
}
VulkanContext *context = VulkanContext::Instance();
if (newWidth != this->width || newHeight != this->height)
{
width = newWidth;
height = newHeight;
colorAttachment.Init(width, height, vk::Format::eR8G8B8A8Unorm);
depthAttachment.Init(width, height, vk::Format::eD32SfloatS8Uint);
vk::ImageView imageViews[] = {
*colorAttachment.GetImageView(),
*depthAttachment.GetImageView(),
};
framebuffer = context->GetDevice()->createFramebufferUnique(vk::FramebufferCreateInfo(vk::FramebufferCreateFlags(),
rttRenderPass, ARRAY_SIZE(imageViews), imageViews, newWidth, newHeight, 1));
}
const vk::ClearValue clear_colors[] = { vk::ClearColorValue(std::array<float, 4>{0.f, 0.f, 0.f, 1.f}), vk::ClearDepthStencilValue{ 0.f, 0 } };
VulkanContext::Instance()->GetCurrentCommandBuffer().beginRenderPass(vk::RenderPassBeginInfo(rttRenderPass, *framebuffer,
vk::Rect2D({0, 0}, {width, height}), 2, clear_colors), vk::SubpassContents::eInline);
VulkanContext::Instance()->GetCurrentCommandBuffer().setViewport(0, vk::Viewport(0.0f, 0.0f, (float)width, (float)height, 1.0f, 0.0f));
// FIXME if the texture exists, need to transition it first
}
void EndRender()
{
VulkanContext::Instance()->GetCurrentCommandBuffer().endRenderPass();
u32 w = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
u32 h = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
u32 stride = FB_W_LINESTRIDE.stride * 8;
if (stride == 0)
stride = w * 2;
else if (w * 2 > stride) {
// Happens for Virtua Tennis
w = stride / 2;
}
u32 size = w * h * 2;
const u8 fb_packmode = FB_W_CTRL.fb_packmode;
if (settings.rend.RenderToTextureBuffer)
{
// wait! need to synchronize buddy!
// FIXME wtf? need a different cmd buffer if writing back to vram PITA
u32 tex_addr = FB_W_SOF1 & VRAM_MASK;
// Remove all vram locks before calling glReadPixels
// (deadlock on rpi)
u32 page_tex_addr = tex_addr & PAGE_MASK;
u32 page_size = size + tex_addr - page_tex_addr;
page_size = ((page_size - 1) / PAGE_SIZE + 1) * PAGE_SIZE;
for (u32 page = page_tex_addr; page < page_tex_addr + page_size; page += PAGE_SIZE)
VramLockedWriteOffset(page);
die("Not implemented");
}
else
{
//memset(&vram[fb_rtt.TexAddr << 3], '\0', size);
}
if (w > 1024 || h > 1024 || settings.rend.RenderToTextureBuffer) {
// TODO glcache.DeleteTextures(1, &gl.rtt.tex);
}
else
{
// TexAddr : fb_rtt.TexAddr, Reserved : 0, StrideSel : 0, ScanOrder : 1
TCW tcw = { { (FB_W_SOF1 & VRAM_MASK) >> 3, 0, 0, 1 } };
switch (fb_packmode) {
case 0:
case 3:
tcw.PixelFmt = Pixel1555;
break;
case 1:
tcw.PixelFmt = Pixel565;
break;
case 2:
tcw.PixelFmt = Pixel4444;
break;
}
TSP tsp = { 0 };
for (tsp.TexU = 0; tsp.TexU <= 7 && (8 << tsp.TexU) < w; tsp.TexU++);
for (tsp.TexV = 0; tsp.TexV <= 7 && (8 << tsp.TexV) < h; tsp.TexV++);
Texture* texture = static_cast<Texture*>(getTextureCacheData(tsp, tcw, [](){
return (BaseTextureCacheData *)new Texture(VulkanContext::Instance()->GetPhysicalDevice(), *VulkanContext::Instance()->GetDevice());
}));
if (texture->IsNew())
texture->Create();
// TODO replace tex vk:: stuff
texture->dirty = 0;
if (texture->lock_block == NULL)
texture->lock_block = libCore_vramlock_Lock(texture->sa_tex, texture->sa + texture->size - 1, texture);
}
}
private:
u32 width = 0;
u32 height = 0;
vk::UniqueFramebuffer framebuffer;
FramebufferAttachment colorAttachment;
FramebufferAttachment depthAttachment;
};

View File

@ -383,6 +383,15 @@ void VulkanContext::CreateSwapChain()
// The FIFO present mode is guaranteed by the spec to be supported
vk::PresentModeKHR swapchainPresentMode = vk::PresentModeKHR::eFifo;
for (auto& presentMode : physicalDevice.getSurfacePresentModesKHR(surface))
{
if (presentMode == vk::PresentModeKHR::eMailbox)
{
INFO_LOG(RENDERER, "Using mailbox present mode");
swapchainPresentMode = vk::PresentModeKHR::eMailbox;
break;
}
}
vk::SurfaceTransformFlagBitsKHR preTransform = (surfaceCapabilities.supportedTransforms & vk::SurfaceTransformFlagBitsKHR::eIdentity) ? vk::SurfaceTransformFlagBitsKHR::eIdentity : surfaceCapabilities.currentTransform;