diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp index 67555fd3..ed70d1df 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp @@ -272,9 +272,11 @@ namespace skyline::gpu::interconnect::maxwell3d { u32 vertexOffset; u32 firstInstance; bool indexed; + bool transformFeedbackEnable; }; auto *drawParams{ctx.executor.allocator->EmplaceUntracked(DrawParams{stateUpdater, - count, first, instanceCount, vertexOffset, firstInstance, indexed})}; + count, first, instanceCount, vertexOffset, firstInstance, indexed, + ctx.gpu.traits.supportsTransformFeedback ? transformFeedbackEnable : false})}; const auto &surfaceClip{clearEngineRegisters.surfaceClip}; vk::Rect2D scissor{ @@ -285,11 +287,16 @@ namespace skyline::gpu::interconnect::maxwell3d { ctx.executor.AddSubpass([drawParams](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr &, GPU &gpu, vk::RenderPass, u32) { drawParams->stateUpdater.RecordAll(gpu, commandBuffer); + if (drawParams->transformFeedbackEnable) + commandBuffer.beginTransformFeedbackEXT(0, {}, {}); + if (drawParams->indexed) commandBuffer.drawIndexed(drawParams->count, drawParams->instanceCount, drawParams->first, static_cast(drawParams->vertexOffset), drawParams->firstInstance); else commandBuffer.draw(drawParams->count, drawParams->instanceCount, drawParams->first, drawParams->firstInstance); + if (drawParams->transformFeedbackEnable) + commandBuffer.endTransformFeedbackEXT(0, {}, {}); }, scissor, {}, activeState.GetColorAttachments(), activeState.GetDepthAttachment(), !ctx.gpu.traits.quirks.relaxedRenderPassCompatibility); constantBuffers.ResetQuickBind(); diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h index 7e23fb74..64909003 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h @@ -84,6 +84,6 @@ namespace skyline::gpu::interconnect::maxwell3d { void Clear(engine::ClearSurface &clearSurface); - void Draw(engine::DrawTopology topology, bool indexed, u32 count, u32 first, u32 instanceCount, u32 vertexOffset, u32 firstInstance); + void Draw(engine::DrawTopology topology, bool transformFeedbackEnable, bool indexed, u32 count, u32 first, u32 instanceCount, u32 vertexOffset, u32 firstInstance); }; } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h index b7c1d76e..25cd468d 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h @@ -959,15 +959,17 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { }; static_assert(sizeof(StreamOutBuffer) == (sizeof(u32) * 8)); - struct TransformFeedbackBufferState { - u32 bufferIndex; - u32 varyingCount; - u32 stride; + struct StreamOutControl { + u8 streamSelect : 2; + u32 _pad0_ : 30; + u8 componentCount : 8; + u32 _pad1_ : 24; + u32 strideBytes; u32 _pad_; }; - static_assert(sizeof(TransformFeedbackBufferState) == (sizeof(u32) * 4)); + static_assert(sizeof(StreamOutControl) == (sizeof(u32) * 4)); - constexpr static size_t TransformFeedbackVaryingCount{0x80}; + constexpr static size_t StreamOutLayoutSelectAttributeCount{0x80}; struct VertexStream { union { diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp index c7ecc3c0..64e0975e 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp @@ -23,6 +23,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d { .rasterizationRegisters = {*registers.rasterEnable, *registers.frontPolygonMode, *registers.backPolygonMode, *registers.oglCullEnable, *registers.oglCullFace, *registers.windowOrigin, *registers.oglFrontFace, *registers.viewportClipControl, *registers.polyOffset, *registers.provokingVertex, *registers.pointSize, *registers.zClipRange}, .depthStencilRegisters = {*registers.depthTestEnable, *registers.depthWriteEnable, *registers.depthFunc, *registers.depthBoundsTestEnable, *registers.stencilTestEnable, *registers.twoSidedStencilTestEnable, *registers.stencilOps, *registers.stencilBack}, .colorBlendRegisters = {*registers.logicOp, *registers.singleCtWriteControl, *registers.ctWrites, *registers.blendStatePerTargetEnable, *registers.blendPerTargets, *registers.blend}, + .transformFeedbackRegisters = {*registers.streamOutputEnable, *registers.streamOutControls, *registers.streamOutLayoutSelect}, .globalShaderConfigRegisters = {*registers.postVtgShaderAttributeSkipMask, *registers.bindlessTexture, *registers.apiMandatedEarlyZEnable}, .ctSelect = *registers.ctSelect }; @@ -33,7 +34,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d { .pipelineRegisters = MakePipelineStateRegisters(registers), .vertexBuffersRegisters = util::MergeInto(*registers.vertexStreams, *registers.vertexStreamLimits), .indexBufferRegisters = {*registers.indexBuffer}, - .transformFeedbackBuffersRegisters = util::MergeInto(*registers.streamOutBuffers, *registers.streamOutEnable), + .transformFeedbackBuffersRegisters = util::MergeInto(*registers.streamOutBuffers, *registers.streamOutputEnable), .viewportsRegisters = util::MergeInto(registers.viewports[0], registers.viewportClips[0], *registers.viewports, *registers.viewportClips, *registers.windowOrigin, *registers.viewportScaleOffsetEnable), .scissorsRegisters = util::MergeInto(*registers.scissors), .lineWidthRegisters = {*registers.lineWidth, *registers.lineWidthAliased, *registers.aliasedLineWidthEnable}, @@ -74,7 +75,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d { __attribute__((always_inline)) void Maxwell3D::FlushDeferredDraw() { if (batchEnableState.drawActive) { batchEnableState.drawActive = false; - interconnect.Draw(deferredDraw.drawTopology, deferredDraw.indexed, deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount, deferredDraw.drawBaseVertex, deferredDraw.drawBaseInstance); + interconnect.Draw(deferredDraw.drawTopology, *registers.streamOutputEnable, deferredDraw.indexed, deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount, deferredDraw.drawBaseVertex, deferredDraw.drawBaseInstance); deferredDraw.instanceCount = 1; } } @@ -346,7 +347,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d { registers.globalBaseInstanceIndex = globalBaseInstanceIndex; } - interconnect.Draw(topology, false, vertexArrayCount, vertexArrayStart, instanceCount, 0, globalBaseInstanceIndex); + interconnect.Draw(topology, *registers.streamOutputEnable, false, vertexArrayCount, vertexArrayStart, instanceCount, 0, globalBaseInstanceIndex); } void Maxwell3D::DrawIndexedInstanced(bool setRegs, u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) { @@ -359,6 +360,6 @@ namespace skyline::soc::gm20b::engine::maxwell3d { registers.globalBaseInstanceIndex = globalBaseInstanceIndex; } - interconnect.Draw(topology, true, indexBufferCount, indexBufferFirst, instanceCount, globalBaseVertexIndex, globalBaseInstanceIndex); + interconnect.Draw(topology, *registers.streamOutputEnable, true, indexBufferCount, indexBufferFirst, instanceCount, globalBaseVertexIndex, globalBaseInstanceIndex); } } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h index dfaedb5d..57db0dc8 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h @@ -119,8 +119,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d { Register<0xDF, u32> rasterEnable; Register<0xE0, std::array> streamOutBuffers; - Register<0x1C0, std::array> transformFeedbackBufferStates; - Register<0x1D1, u32> streamOutEnable; + Register<0x1C0, std::array> streamOutControls; + Register<0x1D1, u32> streamOutputEnable; Register<0x200, std::array> colorTargets; Register<0x280, std::array> viewports; @@ -354,7 +354,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d { Register<0x982, type::BindlessTexture> bindlessTexture; //!< The index of the constant buffer containing bindless texture descriptors - Register<0xA00, std::array> transformFeedbackVaryings; + Register<0xA00, std::array, type::StreamOutBufferCount>> streamOutLayoutSelect; }; static_assert(sizeof(Registers) == (EngineMethodsEnd * sizeof(u32))); #pragma pack(pop)