vulkan: copy provoking vertex. crash when rtt2vram. rtt vram stride
setImageLayout was missing TransferSrcOptimal as source layout Vulkan needs the first vertex to be the provoking vertex so copy 3rd on 1st when flat shading. VRAM stride was incorrect (RTT to VRAM)
This commit is contained in:
parent
637ad3b214
commit
066093553f
|
@ -152,6 +152,33 @@ void BaseDrawer::SetBaseScissor()
|
|||
currentScissor = { 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// Vulkan uses the color values of the first vertex for flat shaded triangle strips.
|
||||
// On Dreamcast the last vertex is the provoking one so we must copy it onto the first.
|
||||
void BaseDrawer::SetProvokingVertices()
|
||||
{
|
||||
auto setProvokingVertex = [](const List<PolyParam>& list) {
|
||||
for (int i = 0; i < list.used(); i++)
|
||||
{
|
||||
const PolyParam& pp = list.head()[i];
|
||||
if (!pp.pcw.Gouraud && pp.count > 2)
|
||||
{
|
||||
for (int i = 0; i < pp.count - 2; i++)
|
||||
{
|
||||
Vertex *vertex = &pvrrc.verts.head()[pvrrc.idx.head()[pp.first + i]];
|
||||
Vertex *lastVertex = &pvrrc.verts.head()[pvrrc.idx.head()[pp.first + i + 2]];
|
||||
memcpy(vertex->col, lastVertex->col, 4);
|
||||
memcpy(vertex->spc, lastVertex->spc, 4);
|
||||
memcpy(vertex->col1, lastVertex->col1, 4);
|
||||
memcpy(vertex->spc1, lastVertex->spc1, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
setProvokingVertex(pvrrc.global_param_op);
|
||||
setProvokingVertex(pvrrc.global_param_pt);
|
||||
setProvokingVertex(pvrrc.global_param_tr);
|
||||
}
|
||||
|
||||
void Drawer::DrawPoly(const vk::CommandBuffer& cmdBuffer, u32 listType, bool sortTriangles, const PolyParam& poly, u32 first, u32 count)
|
||||
{
|
||||
vk::Rect2D scissorRect;
|
||||
|
@ -331,6 +358,8 @@ bool Drawer::Draw(const Texture *fogTexture)
|
|||
|
||||
vk::CommandBuffer cmdBuffer = BeginRenderPass();
|
||||
|
||||
SetProvokingVertices();
|
||||
|
||||
// Upload vertex and index buffers
|
||||
UploadMainBuffer(vtxUniforms, fragUniforms);
|
||||
|
||||
|
@ -530,10 +559,18 @@ void TextureDrawer::EndRenderPass()
|
|||
{
|
||||
currentCommandBuffer.endRenderPass();
|
||||
|
||||
u32 clippedWidth = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
||||
u32 clippedHeight = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
||||
|
||||
u32 stride = FB_W_LINESTRIDE.stride * 8;
|
||||
if (clippedWidth * 2 > stride)
|
||||
// Happens for Virtua Tennis
|
||||
clippedWidth = stride / 2;
|
||||
|
||||
if (settings.rend.RenderToTextureBuffer)
|
||||
{
|
||||
vk::BufferImageCopy copyRegion(0, width, height, vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), vk::Offset3D(0, 0, 0),
|
||||
vk::Extent3D(vk::Extent2D(width, height), 1));
|
||||
vk::BufferImageCopy copyRegion(0, clippedWidth, clippedHeight, vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), vk::Offset3D(0, 0, 0),
|
||||
vk::Extent3D(vk::Extent2D(clippedWidth, clippedHeight), 1));
|
||||
currentCommandBuffer.copyImageToBuffer(colorAttachment->GetImage(), vk::ImageLayout::eTransferSrcOptimal,
|
||||
*colorAttachment->GetBufferData()->buffer, copyRegion);
|
||||
|
||||
|
@ -561,9 +598,9 @@ void TextureDrawer::EndRenderPass()
|
|||
u16 *dst = (u16 *)&vram[textureAddr];
|
||||
|
||||
PixelBuffer<u32> tmpBuf;
|
||||
tmpBuf.init(width, height);
|
||||
colorAttachment->GetBufferData()->download(width * height * 4, tmpBuf.data());
|
||||
WriteTextureToVRam(width, height, (u8 *)tmpBuf.data(), dst);
|
||||
tmpBuf.init(clippedWidth, clippedHeight);
|
||||
colorAttachment->GetBufferData()->download(clippedWidth * clippedHeight * 4, tmpBuf.data());
|
||||
WriteTextureToVRam(clippedWidth, clippedHeight, (u8 *)tmpBuf.data(), dst);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ protected:
|
|||
VulkanContext *GetContext() const { return VulkanContext::Instance(); }
|
||||
TileClipping SetTileClip(u32 val, vk::Rect2D& clipRect);
|
||||
void SetBaseScissor();
|
||||
void SetProvokingVertices();
|
||||
|
||||
u32 align(vk::DeviceSize offset, u32 alignment)
|
||||
{
|
||||
|
|
|
@ -258,6 +258,8 @@ bool OITDrawer::Draw(const Texture *fogTexture)
|
|||
|
||||
oitBuffers->OnNewFrame(cmdBuffer);
|
||||
|
||||
SetProvokingVertices();
|
||||
|
||||
// Upload vertex and index buffers
|
||||
UploadMainBuffer(vtxUniforms, fragUniforms);
|
||||
|
||||
|
@ -578,11 +580,19 @@ void OITTextureDrawer::EndFrame()
|
|||
{
|
||||
currentCommandBuffer.endRenderPass();
|
||||
|
||||
u32 clippedWidth = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
||||
u32 clippedHeight = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
||||
|
||||
u32 stride = FB_W_LINESTRIDE.stride * 8;
|
||||
if (clippedWidth * 2 > stride)
|
||||
// Happens for Virtua Tennis
|
||||
clippedWidth = stride / 2;
|
||||
|
||||
if (settings.rend.RenderToTextureBuffer)
|
||||
{
|
||||
vk::BufferImageCopy copyRegion(0, viewport.extent.width, viewport.extent.height,
|
||||
vk::BufferImageCopy copyRegion(0, clippedWidth, clippedHeight,
|
||||
vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1), vk::Offset3D(0, 0, 0),
|
||||
vk::Extent3D(viewport.extent, 1));
|
||||
vk::Extent3D(clippedWidth, clippedHeight, 1));
|
||||
currentCommandBuffer.copyImageToBuffer(colorAttachment->GetImage(), vk::ImageLayout::eTransferSrcOptimal,
|
||||
*colorAttachment->GetBufferData()->buffer, copyRegion);
|
||||
|
||||
|
@ -611,9 +621,9 @@ void OITTextureDrawer::EndFrame()
|
|||
u16 *dst = (u16 *)&vram[textureAddr];
|
||||
|
||||
PixelBuffer<u32> tmpBuf;
|
||||
tmpBuf.init(viewport.extent.width, viewport.extent.height);
|
||||
colorAttachment->GetBufferData()->download(viewport.extent.width * viewport.extent.height * 4, tmpBuf.data());
|
||||
WriteTextureToVRam(viewport.extent.width, viewport.extent.height, (u8 *)tmpBuf.data(), dst);
|
||||
tmpBuf.init(clippedWidth, clippedHeight);
|
||||
colorAttachment->GetBufferData()->download(clippedWidth * clippedHeight * 4, tmpBuf.data());
|
||||
WriteTextureToVRam(clippedWidth, clippedHeight, (u8 *)tmpBuf.data(), dst);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -80,30 +80,6 @@ public:
|
|||
compileTrModVolFragmentShader(mode);
|
||||
return *trModVolShaders[(size_t)mode];
|
||||
}
|
||||
// vk::ShaderModule GetQuadVertexShader()
|
||||
// {
|
||||
// if (!quadVertexShader)
|
||||
// quadVertexShader = compileQuadVertexShader();
|
||||
// return *quadVertexShader;
|
||||
// }
|
||||
// vk::ShaderModule GetQuadFragmentShader()
|
||||
// {
|
||||
// if (!quadFragmentShader)
|
||||
// quadFragmentShader = compileQuadFragmentShader();
|
||||
// return *quadFragmentShader;
|
||||
// }
|
||||
// vk::ShaderModule GetOSDVertexShader()
|
||||
// {
|
||||
// if (!osdVertexShader)
|
||||
// osdVertexShader = compileOSDVertexShader();
|
||||
// return *osdVertexShader;
|
||||
// }
|
||||
// vk::ShaderModule GetOSDFragmentShader()
|
||||
// {
|
||||
// if (!osdFragmentShader)
|
||||
// osdFragmentShader = compileOSDFragmentShader();
|
||||
// return *osdFragmentShader;
|
||||
// }
|
||||
|
||||
vk::ShaderModule GetFinalShader(bool autosort)
|
||||
{
|
||||
|
@ -148,10 +124,6 @@ private:
|
|||
vk::UniqueShaderModule compileModVolVertexShader();
|
||||
vk::UniqueShaderModule compileModVolFragmentShader();
|
||||
void compileTrModVolFragmentShader(ModVolMode mode);
|
||||
// vk::UniqueShaderModule compileQuadVertexShader();
|
||||
// vk::UniqueShaderModule compileQuadFragmentShader();
|
||||
// vk::UniqueShaderModule compileOSDVertexShader();
|
||||
// vk::UniqueShaderModule compileOSDFragmentShader();
|
||||
vk::UniqueShaderModule compileFinalShader(bool autosort);
|
||||
vk::UniqueShaderModule compileFinalVertexShader();
|
||||
vk::UniqueShaderModule compileClearShader();
|
||||
|
@ -161,10 +133,6 @@ private:
|
|||
vk::UniqueShaderModule modVolVertexShader;
|
||||
vk::UniqueShaderModule modVolShader;
|
||||
std::vector<vk::UniqueShaderModule> trModVolShaders;
|
||||
// vk::UniqueShaderModule quadVertexShader;
|
||||
// vk::UniqueShaderModule quadFragmentShader;
|
||||
// vk::UniqueShaderModule osdVertexShader;
|
||||
// vk::UniqueShaderModule osdFragmentShader;
|
||||
|
||||
vk::UniqueShaderModule finalVertexShader;
|
||||
vk::UniqueShaderModule finalAutosortShader;
|
||||
|
|
|
@ -30,6 +30,9 @@ void setImageLayout(vk::CommandBuffer const& commandBuffer, vk::Image image, vk:
|
|||
case vk::ImageLayout::eTransferDstOptimal:
|
||||
sourceAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
break;
|
||||
case vk::ImageLayout::eTransferSrcOptimal:
|
||||
sourceAccessMask = vk::AccessFlagBits::eTransferRead;
|
||||
break;
|
||||
case vk::ImageLayout::ePreinitialized:
|
||||
sourceAccessMask = vk::AccessFlagBits::eHostWrite;
|
||||
break;
|
||||
|
@ -52,6 +55,7 @@ void setImageLayout(vk::CommandBuffer const& commandBuffer, vk::Image image, vk:
|
|||
sourceStage = vk::PipelineStageFlagBits::eHost;
|
||||
break;
|
||||
case vk::ImageLayout::eTransferDstOptimal:
|
||||
case vk::ImageLayout::eTransferSrcOptimal:
|
||||
sourceStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
break;
|
||||
case vk::ImageLayout::eUndefined:
|
||||
|
@ -176,7 +180,7 @@ void Texture::Init(u32 width, u32 height, vk::Format format)
|
|||
this->extent = vk::Extent2D(width, height);
|
||||
this->format = format;
|
||||
mipmapLevels = 1;
|
||||
if (tcw.MipMapped)
|
||||
if (tcw.MipMapped && settings.rend.UseMipmaps)
|
||||
mipmapLevels += floor(log2(std::max(width, height)));
|
||||
|
||||
vk::FormatProperties formatProperties = physicalDevice.getFormatProperties(format);
|
||||
|
|
Loading…
Reference in New Issue