You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: state_rebuilder.go
    path of file: ./repos/gapid/gapis/api/vulkan
    
    the code of the file until where you have to start completion: // Copyright (C) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package vulkan

import (
	"context"
	"fmt"
	"sort"

	"github.com/google/gapid/core/data/id"
	"github.com/google/gapid/core/log"
	"github.com/google/gapid/core/math/interval"
	"github.com/google/gapid/core/memory/arena"
	"github.com/google/gapid/gapis/api"
	"github.com/google/gapid/gapis/api/transform"
	"github.com/google/gapid/gapis/database"
	"github.com/google/gapid/gapis/memory"
)

const (
	queueFamilyIgnore = uint32(0xFFFFFFFF)
)

type stateBuilder struct {
	ctx                   context.Context
	s                     *State
	oldState              *api.GlobalState
	newState              *api.GlobalState
	out                   stateBuilderOutput
	cb                    CommandBuilder
	readMemories          []*api.AllocResult
	writeMemories         []*api.AllocResult
	extraReadIDsAndRanges []idAndRng
	memoryIntervals       interval.U64RangeList
	ta                    arena.Arena // temporary arena
	scratchRes            *scratchResources
}

type stateBuilderOutput interface {
	write(ctx context.Context, cmd api.Cmd, id api.CmdID)
	getOldState() *api.GlobalState
	getNewState() *api.GlobalState
}

type initialStateOutput struct {
	oldState *api.GlobalState
	newState *api.GlobalState
	cmds     []api.Cmd
}

func newInitialStateOutput(oldState *api.GlobalState) *initialStateOutput {
	return &initialStateOutput{
		oldState: oldState,
		newState: api.NewStateWithAllocator(memory.NewBasicAllocator(
			oldState.Allocator.FreeList()), oldState.MemoryLayout),
		cmds: []api.Cmd{},
	}
}

func (o *initialStateOutput) write(ctx context.Context, cmd api.Cmd, id api.CmdID) {
	if err := cmd.Mutate(ctx, id, o.newState, nil, nil); err != nil {
		log.W(ctx, "Initial cmd %v: %v - %v", len(o.cmds), cmd, err)
	} else {
		log.D(ctx, "Initial cmd %v: %v", len(o.cmds), cmd)
	}
	o.cmds = append(o.cmds, cmd)
}

func (o *initialStateOutput) getOldState() *api.GlobalState {
	return o.oldState
}

func (o *initialStateOutput) getNewState() *api
    
func (sb *stateBuilder) createSwapchain(swp SwapchainObjectʳ) {
	extent := NewVkExtent2D(sb.ta,
		swp.Info().Extent().Width(),
		swp.Info().Extent().Height(),
	)

	pNext := NewVoidᶜᵖ(memory.Nullptr)
	if !swp.Info().ViewFormatList().IsNil() {
		pNext = NewVoidᶜᵖ(sb.MustAllocReadData(
			NewVkImageFormatListCreateInfoKHR(sb.ta,
				VkStructureType_VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // sType
				pNext, // pNext
				uint32(swp.Info().ViewFormatList().ViewFormats().Len()),                                    // viewFormatCount
				NewVkFormatᶜᵖ(sb.MustUnpackReadMap(swp.Info().ViewFormatList().ViewFormats().All()).Ptr()), // pViewFormats
			),
		).Ptr())
	}

	sb.write(sb.cb.VkCreateSwapchainKHR(
		swp.Device(),
		sb.MustAllocReadData(NewVkSwapchainCreateInfoKHR(sb.ta,
			VkStructureType_VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // sType
			0,                                   // pNext
			swp.Flags(),                         // flags
			swp.Surface().VulkanHandle(),        // surface
			uint32(swp.SwapchainImages().Len()), // minImageCount
			swp.Info().Fmt(),                    // imageFormat
			swp.ColorSpace(),                    // imageColorSpace
			extent,                              // imageExtent
			swp.Info().ArrayLayers(),            // imageArrayLayers
			swp.Info().Usage(),                  // imageUsage
			swp.Info().SharingMode(),            // imageSharingMode
			uint32(swp.Info().QueueFamilyIndices().Len()),                         // queueFamilyIndexCount
			NewU32ᶜᵖ(sb.MustUnpackReadMap(swp.Info().QueueFamilyIndices()).Ptr()), // pQueueFamilyIndices
			swp.PreTransform(),   // preTransform
			swp.CompositeAlpha(), // compositeAlpha
			swp.PresentMode(),    // presentMode
			swp.Clipped(),        // clipped
			0,                    // oldSwapchain
		)).Ptr(),
		memory.Nullptr,
		sb.MustAllocWriteData(swp.VulkanHandle()).Ptr(),
		VkResult_VK_SUCCESS,
	))

	if !swp.HDRMetadata().IsNil() {
		sb.write(sb.cb.VkSetHdrMetadataEXT(
			swp.Device(),
			1,
			sb.MustAllocReadData(swp.VulkanHandle()).Ptr(),
			sb.MustAllocReadData(NewVkHdrMetadataEXT(sb.ta,
				VkStructureType_VK_STRUCTURE_TYPE_HDR_METADATA_EXT,
				0, // pNext
				swp.HDRMetadata().DisplayPrimaryRed(),
				swp.HDRMetadata().DisplayPrimaryGreen(),
				swp.HDRMetadata().DisplayPrimaryBlue(),
				swp.HDRMetadata().WhitePoint(),
				swp.HDRMetadata().MaxLuminance(),
				swp.HDRMetadata().MinLuminance(),
				swp.HDRMetadata().MaxContentLightLevel(),
				swp.HDRMetadata().MaxFrameAverageLightLevel(),
			)).Ptr(),
		))
	}

	images := []VkImage{}
	for _, v := range swp.SwapchainImages().Keys() {
		images = append(images, swp.SwapchainImages().Get(v).VulkanHandle())
	}

	sb.write(sb.cb.VkGetSwapchainImagesKHR(
		swp.Device(),
		swp.VulkanHandle(),
		NewU32ᶜᵖ(sb.MustAllocReadData(uint32(swp.SwapchainImages().Len())).Ptr()),
		sb.MustAllocWriteData(images).Ptr(),
		VkResult_VK_SUCCESS,
	))

	for _, v := range swp.SwapchainImages().All() {
		layoutBarriers := ipImageLayoutTransitionBarriers(sb, v, useSpecifiedLayout(VkImageLayout_VK_IMAGE_LAYOUT_UNDEFINED), sameLayoutsOfImage(v))
		layoutQueue := sb.getQueueFor(
			VkQueueFlagBits_VK_QUEUE_GRAPHICS_BIT|VkQueueFlagBits_VK_QUEUE_COMPUTE_BIT|VkQueueFlagBits_VK_QUEUE_TRANSFER_BIT,
			queueFamilyIndicesToU32Slice(v.Info().QueueFamilyIndices()),
			v.Device(),
			v.LastBoundQueue())
		if layoutQueue.IsNil() {
			log.E(sb.ctx, "could not get a queue for swapchain image layout transition")
			return
		}
		queueHandler := sb.scratchRes.GetQueueCommandHandler(sb, layoutQueue.VulkanHandle())
		err := ipRecordImageMemoryBarriers(sb, queueHandler, layoutBarriers...)
		if err != nil {
			log.E(sb.ctx, "failed at swapchain image layout transition, err: %v", err)
		}

		ownerTransferInfo := []imageQueueFamilyTransferInfo{}
		walkImageSubresourceRange(sb, v, sb.imageWholeSubresourceRange(v),
			func(aspect VkImageAspectFlagBits, layer, level uint32, unused byteSizeAndExtent) {
				l := v.Aspects().Get(aspect).Layers().Get(layer).Levels().Get(level)
				if !l.LastBoundQueue().IsNil() && (layoutQueue.Family() != l.LastBoundQueue().Family()) {
					ownerTransferInfo = append(ownerTransferInfo, imageQueueFamilyTransferInfo{
						image:      v.VulkanHandle(),
						aspectMask: VkImageAspectFlags(aspect),
						layer:      layer,
						level:      level,
						layout:     l.Layout(),
						oldQueue:   layoutQueue.VulkanHandle(),
						newQueue:   l.LastBoundQueue().VulkanHandle(),
					})
				}
			})
		sb.transferImageQueueFamilyOwnership(ownerTransferInfo...)
	}
}