mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	shader/track: Move bindless tracking to a separate function
This commit is contained in:
		@@ -409,8 +409,14 @@ private:
 | 
			
		||||
 | 
			
		||||
    std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;
 | 
			
		||||
 | 
			
		||||
    std::tuple<Node, TrackSampler> TrackBindlessSampler(Node tracked, const NodeBlock& code,
 | 
			
		||||
                                                        s64 cursor);
 | 
			
		||||
    std::pair<Node, TrackSampler> TrackBindlessSampler(Node tracked, const NodeBlock& code,
 | 
			
		||||
                                                       s64 cursor);
 | 
			
		||||
 | 
			
		||||
    std::pair<Node, TrackSampler> HandleBindlessIndirectRead(const CbufNode& cbuf,
 | 
			
		||||
                                                             const OperationNode& operation,
 | 
			
		||||
                                                             Node gpr, Node base_offset,
 | 
			
		||||
                                                             Node tracked, const NodeBlock& code,
 | 
			
		||||
                                                             s64 cursor);
 | 
			
		||||
 | 
			
		||||
    std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
namespace VideoCommon::Shader {
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
 | 
			
		||||
                                   OperationCode operation_code) {
 | 
			
		||||
    for (; cursor >= 0; --cursor) {
 | 
			
		||||
@@ -72,40 +73,27 @@ bool AmendNodeCv(std::size_t amend_index, Node node) {
 | 
			
		||||
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
std::tuple<Node, TrackSampler> ShaderIR::TrackBindlessSampler(Node tracked, const NodeBlock& code,
 | 
			
		||||
                                                              s64 cursor) {
 | 
			
		||||
std::pair<Node, TrackSampler> ShaderIR::TrackBindlessSampler(Node tracked, const NodeBlock& code,
 | 
			
		||||
                                                             s64 cursor) {
 | 
			
		||||
    if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) {
 | 
			
		||||
        const u32 cbuf_index = cbuf->GetIndex();
 | 
			
		||||
 | 
			
		||||
        // Constant buffer found, test if it's an immediate
 | 
			
		||||
        const auto& offset = cbuf->GetOffset();
 | 
			
		||||
        if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) {
 | 
			
		||||
            auto track =
 | 
			
		||||
                MakeTrackSampler<BindlessSamplerNode>(cbuf->GetIndex(), immediate->GetValue());
 | 
			
		||||
            auto track = MakeTrackSampler<BindlessSamplerNode>(cbuf_index, immediate->GetValue());
 | 
			
		||||
            return {tracked, track};
 | 
			
		||||
        }
 | 
			
		||||
        if (const auto operation = std::get_if<OperationNode>(&*offset)) {
 | 
			
		||||
            const u32 bound_buffer = registry.GetBoundBuffer();
 | 
			
		||||
            if (bound_buffer != cbuf->GetIndex()) {
 | 
			
		||||
            if (bound_buffer != cbuf_index) {
 | 
			
		||||
                return {};
 | 
			
		||||
            }
 | 
			
		||||
            const auto pair = DecoupleIndirectRead(*operation);
 | 
			
		||||
            if (!pair) {
 | 
			
		||||
                return {};
 | 
			
		||||
            if (const std::optional pair = DecoupleIndirectRead(*operation)) {
 | 
			
		||||
                auto [gpr, base_offset] = *pair;
 | 
			
		||||
                return HandleBindlessIndirectRead(*cbuf, *operation, gpr, base_offset, tracked,
 | 
			
		||||
                                                  code, cursor);
 | 
			
		||||
            }
 | 
			
		||||
            auto [gpr, base_offset] = *pair;
 | 
			
		||||
            const auto offset_inm = std::get_if<ImmediateNode>(&*base_offset);
 | 
			
		||||
            const auto& gpu_driver = registry.AccessGuestDriverProfile();
 | 
			
		||||
            const u32 bindless_cv = NewCustomVariable();
 | 
			
		||||
            Node op =
 | 
			
		||||
                Operation(OperationCode::UDiv, gpr, Immediate(gpu_driver.GetTextureHandlerSize()));
 | 
			
		||||
 | 
			
		||||
            const Node cv_node = GetCustomVariable(bindless_cv);
 | 
			
		||||
            Node amend_op = Operation(OperationCode::Assign, cv_node, std::move(op));
 | 
			
		||||
            const std::size_t amend_index = DeclareAmend(std::move(amend_op));
 | 
			
		||||
            AmendNodeCv(amend_index, code[cursor]);
 | 
			
		||||
            // TODO Implement Bindless Index custom variable
 | 
			
		||||
            auto track = MakeTrackSampler<ArraySamplerNode>(cbuf->GetIndex(),
 | 
			
		||||
                                                            offset_inm->GetValue(), bindless_cv);
 | 
			
		||||
            return {tracked, track};
 | 
			
		||||
        }
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
@@ -139,6 +127,26 @@ std::tuple<Node, TrackSampler> ShaderIR::TrackBindlessSampler(Node tracked, cons
 | 
			
		||||
    return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::pair<Node, TrackSampler> ShaderIR::HandleBindlessIndirectRead(
 | 
			
		||||
    const CbufNode& cbuf, const OperationNode& operation, Node gpr, Node base_offset, Node tracked,
 | 
			
		||||
    const NodeBlock& code, s64 cursor) {
 | 
			
		||||
    const auto offset_imm = std::get<ImmediateNode>(*base_offset);
 | 
			
		||||
    const auto& gpu_driver = registry.AccessGuestDriverProfile();
 | 
			
		||||
    const u32 bindless_cv = NewCustomVariable();
 | 
			
		||||
    const u32 texture_handler_size = gpu_driver.GetTextureHandlerSize();
 | 
			
		||||
    Node op = Operation(OperationCode::UDiv, gpr, Immediate(texture_handler_size));
 | 
			
		||||
 | 
			
		||||
    Node cv_node = GetCustomVariable(bindless_cv);
 | 
			
		||||
    Node amend_op = Operation(OperationCode::Assign, std::move(cv_node), std::move(op));
 | 
			
		||||
    const std::size_t amend_index = DeclareAmend(std::move(amend_op));
 | 
			
		||||
    AmendNodeCv(amend_index, code[cursor]);
 | 
			
		||||
 | 
			
		||||
    // TODO: Implement bindless index custom variable
 | 
			
		||||
    auto track =
 | 
			
		||||
        MakeTrackSampler<ArraySamplerNode>(cbuf.GetIndex(), offset_imm.GetValue(), bindless_cv);
 | 
			
		||||
    return {tracked, track};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code,
 | 
			
		||||
                                               s64 cursor) const {
 | 
			
		||||
    if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user