From 42ad5c1cc976b61a82421137b75fcba5bea392fc Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 6 Oct 2024 13:03:30 +0300 Subject: [PATCH] rpcsx-gpu: fix IT_DRAW_INDEX_2 fix IT_INDEX_BASE fix depth size fix image_get_lod --- rpcsx-gpu/Pipe.cpp | 16 ++++--- rpcsx-gpu/Registers.hpp | 20 ++++++++- rpcsx-gpu/Renderer.cpp | 41 ++++++++++++----- rpcsx-gpu/lib/gcn-shader/src/GcnConverter.cpp | 45 ++++++++++--------- .../lib/gcn-shader/src/GcnInstruction.cpp | 2 + 5 files changed, 85 insertions(+), 39 deletions(-) diff --git a/rpcsx-gpu/Pipe.cpp b/rpcsx-gpu/Pipe.cpp index 145bc6ef3..e9870e170 100644 --- a/rpcsx-gpu/Pipe.cpp +++ b/rpcsx-gpu/Pipe.cpp @@ -570,7 +570,7 @@ bool GraphicsPipe::drawIndexIndirect(Queue &queue) { return true; } bool GraphicsPipe::indexBase(Queue &queue) { - auto addressLo = queue.rptr[1] << 1; + auto addressLo = queue.rptr[1] & ~1; auto addressHi = queue.rptr[2] & ((1 << 16) - 1); auto address = addressLo | (static_cast(addressHi) << 32); vgtIndexBase = address; @@ -578,15 +578,19 @@ bool GraphicsPipe::indexBase(Queue &queue) { } bool GraphicsPipe::drawIndex2(Queue &queue) { auto maxSize = queue.rptr[1]; - auto indexOffset = queue.rptr[2]; - auto indexCount = queue.rptr[3]; - auto drawInitiator = queue.rptr[4]; + auto indexBaseLo = queue.rptr[2] & ~1; + auto indexBaseHi = queue.rptr[3] & ((1 << 16) - 1); + auto indexCount = queue.rptr[4]; + auto drawInitiator = queue.rptr[5]; context.vgtDrawInitiator = drawInitiator; uConfig.vgtNumIndices = indexCount; - draw(*this, queue.vmId, 0, indexCount, 0, uConfig.vgtNumInstances, - vgtIndexBase + indexOffset, 0, maxSize); + auto indexBase = + indexBaseLo | (static_cast(indexBaseHi) << 32); + + draw(*this, queue.vmId, 0, indexCount, 0, uConfig.vgtNumInstances, indexBase, + 0, maxSize); return true; } bool GraphicsPipe::indexType(Queue &queue) { diff --git a/rpcsx-gpu/Registers.hpp b/rpcsx-gpu/Registers.hpp index 5f228dba4..15e96d875 100644 --- a/rpcsx-gpu/Registers.hpp +++ b/rpcsx-gpu/Registers.hpp @@ -389,6 +389,24 @@ struct DbZInfo { }; }; +struct DbDepthSize { + union { + struct { + std::uint32_t pitchTileMax : 11; + std::uint32_t heightTileMax : 11; + }; + + std::uint32_t raw; + }; + + std::uint32_t getPitch() const { + return (pitchTileMax + 1) * 8; + } + std::uint32_t getHeight() const { + return (heightTileMax + 1) * 8; + } +}; + struct DbRenderControl { union { struct { @@ -657,7 +675,7 @@ struct Registers { Register<0x13> dbStencilReadBase; Register<0x14> dbZWriteBase; Register<0x15> dbStencilWriteBase; - Register<0x16> dbDepthSize; + Register<0x16, DbDepthSize> dbDepthSize; Register<0x17> dbDepthSlice; Register<0x20> taBcBaseAddr; Register<0x80> paScWindowOffset; diff --git a/rpcsx-gpu/Renderer.cpp b/rpcsx-gpu/Renderer.cpp index 3c8aa0e38..e2fbc03b3 100644 --- a/rpcsx-gpu/Renderer.cpp +++ b/rpcsx-gpu/Renderer.cpp @@ -33,22 +33,37 @@ VkRect2D toVkRect2D(amdgpu::PaScRect rect) { } amdgpu::PaScRect intersection(amdgpu::PaScRect lhs, amdgpu::PaScRect rhs) { - if (!lhs.isValid()) { - return rhs; + if (lhs.left > lhs.right) { + lhs.left = rhs.left; } - if (!rhs.isValid()) { - return lhs; + if (lhs.top > lhs.bottom) { + lhs.top = rhs.top; } - amdgpu::PaScRect result{ + if (rhs.left > rhs.right) { + rhs.left = lhs.left; + } + + if (rhs.top > rhs.bottom) { + rhs.top = lhs.top; + } + + return { .left = std::max(lhs.left, rhs.left), .top = std::max(lhs.top, rhs.top), .right = std::min(lhs.right, rhs.right), .bottom = std::min(lhs.bottom, rhs.bottom), }; +} - return result; +amdgpu::PaScRect extend(amdgpu::PaScRect lhs, amdgpu::PaScRect rhs) { + return { + .left = std::max(lhs.left, rhs.left), + .top = std::max(lhs.top, rhs.top), + .right = std::max(lhs.right, rhs.right), + .bottom = std::max(lhs.bottom, rhs.bottom), + }; } } // namespace gnm @@ -192,6 +207,8 @@ void amdgpu::draw(GraphicsPipe &pipe, int vmId, std::uint32_t firstVertex, // FIXME stencilAccess = Access::None; + amdgpu::PaScRect drawRect{}; + for (auto &cbColor : pipe.context.cbColor) { if (targetMask == 0) { break; @@ -211,6 +228,8 @@ void amdgpu::draw(GraphicsPipe &pipe, int vmId, std::uint32_t firstVertex, auto viewPortRect = gnm::toVkRect2D(viewPortScissor); + drawRect = gnm::extend(drawRect, viewPortScissor); + viewPorts[renderTargets].x = viewPortRect.offset.x; viewPorts[renderTargets].y = viewPortRect.offset.y; viewPorts[renderTargets].width = viewPortRect.extent.width; @@ -373,8 +392,6 @@ void amdgpu::draw(GraphicsPipe &pipe, int vmId, std::uint32_t firstVertex, } if (depthAccess != Access::None) { - auto screenRect = gnm::toVkRect2D(pipe.context.paScScreenScissor); - auto imageView = cacheTag.getImageView( { .readAddress = static_cast(pipe.context.dbZReadBase) @@ -386,11 +403,11 @@ void amdgpu::draw(GraphicsPipe &pipe, int vmId, std::uint32_t firstVertex, .nfmt = gnm::getNumericFormat(pipe.context.dbZInfo.format), .extent = { - .width = screenRect.extent.width, - .height = screenRect.extent.height, + .width = pipe.context.dbDepthSize.getPitch(), + .height = pipe.context.dbDepthSize.getHeight(), .depth = 1, }, - .pitch = screenRect.extent.width, + .pitch = pipe.context.dbDepthSize.getPitch(), .mipCount = 1, .arrayLayerCount = 1, .kind = ImageKind::Depth, @@ -466,7 +483,7 @@ void amdgpu::draw(GraphicsPipe &pipe, int vmId, std::uint32_t firstVertex, VkRenderingInfo renderInfo{ .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = gnm::toVkRect2D(pipe.context.paScScreenScissor), + .renderArea = gnm::toVkRect2D(drawRect), .layerCount = 1, .colorAttachmentCount = renderTargets, .pColorAttachments = colorAttachments, diff --git a/rpcsx-gpu/lib/gcn-shader/src/GcnConverter.cpp b/rpcsx-gpu/lib/gcn-shader/src/GcnConverter.cpp index 6298900e4..c44957047 100644 --- a/rpcsx-gpu/lib/gcn-shader/src/GcnConverter.cpp +++ b/rpcsx-gpu/lib/gcn-shader/src/GcnConverter.cpp @@ -1182,28 +1182,31 @@ static void instructionsToSpv(GcnConverter &converter, gcn::Import &importer, auto loc = inst.getLocation(); auto valueType = value.getOperand(0).getAsValue(); - if (valueType == ir::spv::OpTypeFloat) { - auto width = *valueType.getOperand(0).getAsInt32(); - if (abs) { - auto boolT = context.getTypeBool(); - auto c0 = width == 64 ? context.fimm64(0.0) : context.fimm32(0.0f); - value = builder.createSpvSelect( - loc, valueType, - builder.createSpvFOrdLessThan(loc, boolT, value, c0), - builder.createSpvFNegate(loc, valueType, value), value); - } - - if (neg) { - value = builder.createSpvFNegate(loc, valueType, value); - } - - if (valueType != resultType) { - value = builder.createSpvBitcast(loc, resultType, value); - } - - inst.staticCast().replaceAllUsesWith(value); + if (valueType == ir::spv::OpTypeInt) { + auto floatType = + context.getTypeFloat(*valueType.getOperand(0).getAsInt32()); + value = builder.createSpvBitcast(loc, floatType, value); + valueType = floatType; + } + auto width = *valueType.getOperand(0).getAsInt32(); + if (abs) { + auto boolT = context.getTypeBool(); + auto c0 = width == 64 ? context.fimm64(0.0) : context.fimm32(0.0f); + value = builder.createSpvSelect( + loc, valueType, + builder.createSpvFOrdLessThan(loc, boolT, value, c0), + builder.createSpvFNegate(loc, valueType, value), value); } + if (neg) { + value = builder.createSpvFNegate(loc, valueType, value); + } + + if (valueType != resultType) { + value = builder.createSpvBitcast(loc, resultType, value); + } + + inst.staticCast().replaceAllUsesWith(value); inst.remove(); continue; } @@ -1706,6 +1709,8 @@ gcn::convertToSpv(Context &context, ir::Region body, ir::spv::Capability::Int64Atomics); } + capabilities.createSpvCapability(context.getUnknownLocation(), ir::spv::Capability::ImageQuery); + extensions.createSpvExtension(context.getUnknownLocation(), "SPV_KHR_physical_storage_buffer"); diff --git a/rpcsx-gpu/lib/gcn-shader/src/GcnInstruction.cpp b/rpcsx-gpu/lib/gcn-shader/src/GcnInstruction.cpp index 974259178..d903b1932 100644 --- a/rpcsx-gpu/lib/gcn-shader/src/GcnInstruction.cpp +++ b/rpcsx-gpu/lib/gcn-shader/src/GcnInstruction.cpp @@ -574,6 +574,8 @@ readMimgInst(GcnInstruction &inst, std::uint64_t &address, op <= ir::mimg::Op::SAMPLE_C_CD_CL_O) { textureAccess = GcnOperand::R; hasSampler = true; + } else if (op == ir::mimg::Op::GET_LOD) { + hasSampler = true; } inst.op = op;