diff --git a/src/Pipeline/BUILD.gn b/src/Pipeline/BUILD.gn
index cf74d42..00747b5 100644
--- a/src/Pipeline/BUILD.gn
+++ b/src/Pipeline/BUILD.gn
@@ -41,6 +41,7 @@
     "SpirvShader.cpp",
     "SpirvShaderArithmetic.cpp",
     "SpirvShaderControlFlow.cpp",
+    "SpirvShaderDebugger.cpp",
     "SpirvShaderEnumNames.cpp",
     "SpirvShaderGLSLstd450.cpp",
     "SpirvShaderGroup.cpp",
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index be6125e..0df1cfd 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -18,6 +18,8 @@
 #include "Vulkan/VkPipelineLayout.hpp"
 #include "Vulkan/VkRenderPass.hpp"
 
+#include "marl/defer.h"
+
 #include <spirv/unified1/spirv.hpp>
 
 namespace sw {
@@ -39,6 +41,11 @@
 {
 	ASSERT(insns.size() > 0);
 
+	if(dbgctx)
+	{
+		dbgInit(dbgctx);
+	}
+
 	if(renderPass)
 	{
 		// capture formats of any input attachments present
@@ -719,6 +726,13 @@
 	{
 		it.second.AssignBlockFields();
 	}
+
+	dbgCreateFile();
+}
+
+SpirvShader::~SpirvShader()
+{
+	dbgTerm();
 }
 
 void SpirvShader::DeclareType(InsnIterator insn)
@@ -1452,6 +1466,7 @@
 	}
 
 	object.definition = insn;
+	dbgDeclareResult(insn, resultId);
 }
 
 OutOfBoundsBehavior SpirvShader::EmitState::getOutOfBoundsBehavior(spv::StorageClass storageClass) const
@@ -1542,6 +1557,9 @@
 {
 	EmitState state(routine, entryPoint, activeLaneMask, storesAndAtomicsMask, descriptorSets, robustBufferAccess, executionModel);
 
+	dbgBeginEmit(&state);
+	defer(dbgEndEmit(&state));
+
 	// Emit everything up to the first label
 	// TODO: Separate out dispatch of block from non-block instructions?
 	for(auto insn : *this)
@@ -1577,6 +1595,9 @@
 
 SpirvShader::EmitResult SpirvShader::EmitInstruction(InsnIterator insn, EmitState *state) const
 {
+	dbgBeginEmitInstruction(insn, state);
+	defer(dbgEndEmitInstruction(insn, state));
+
 	auto opcode = insn.opcode();
 
 	switch(opcode)
@@ -1624,7 +1645,6 @@
 		case spv::OpSource:
 		case spv::OpSourceContinued:
 		case spv::OpSourceExtension:
-		case spv::OpLine:
 		case spv::OpNoLine:
 		case spv::OpModuleProcessed:
 		case spv::OpString:
@@ -1632,6 +1652,9 @@
 			// or don't require any work at all.
 			return EmitResult::Continue;
 
+		case spv::OpLine:
+			return EmitLine(insn, state);
+
 		case spv::OpLabel:
 			return EmitResult::Continue;
 
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index ea5bb61..d46f760 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -497,6 +497,8 @@
 	            bool robustBufferAccess,
 	            const std::shared_ptr<vk::dbg::Context> &dbgctx);
 
+	~SpirvShader();
+
 	struct Modes
 	{
 		bool EarlyFragmentTests : 1;
@@ -1090,6 +1092,7 @@
 	EmitResult EmitSelect(InsnIterator insn, EmitState *state) const;
 	EmitResult EmitExtendedInstruction(InsnIterator insn, EmitState *state) const;
 	EmitResult EmitExtGLSLstd450(InsnIterator insn, EmitState *state) const;
+	EmitResult EmitLine(InsnIterator insn, EmitState *state) const;
 	EmitResult EmitAny(InsnIterator insn, EmitState *state) const;
 	EmitResult EmitAll(InsnIterator insn, EmitState *state) const;
 	EmitResult EmitBranch(InsnIterator insn, EmitState *state) const;
@@ -1170,14 +1173,58 @@
 	// Returns 0 when invalid.
 	static VkShaderStageFlagBits executionModelToStage(spv::ExecutionModel model);
 
-	// Impl holds private forward declaration structs that are implemented
-	// in the corresponding SpirvShaderXXX.cpp files.
+	// Debugger API functions. When ENABLE_VK_DEBUGGER is not defined, these
+	// are all no-ops.
+
+	// dbgInit() initializes the debugger code generation.
+	// All other dbgXXX() functions are no-op until this is called.
+	void dbgInit(const std::shared_ptr<vk::dbg::Context> &dbgctx);
+
+	// dbgTerm() terminates the debugger code generation.
+	void dbgTerm();
+
+	// dbgCreateFile() generates a synthetic file containing the disassembly
+	// of the SPIR-V shader. This is the file displayed in the debug
+	// session.
+	void dbgCreateFile();
+
+	// dbgBeginEmit() sets up the debugging state for the shader.
+	void dbgBeginEmit(EmitState *state) const;
+
+	// dbgEndEmit() tears down the debugging state for the shader.
+	void dbgEndEmit(EmitState *state) const;
+
+	// dbgBeginEmitInstruction() updates the current debugger location for
+	// the given instruction.
+	void dbgBeginEmitInstruction(InsnIterator insn, EmitState *state) const;
+
+	// dbgEndEmitInstruction() creates any new debugger variables for the
+	// instruction that just completed.
+	void dbgEndEmitInstruction(InsnIterator insn, EmitState *state) const;
+
+	// dbgExposeIntermediate() exposes the intermediate with the given ID to
+	// the debugger.
+	void dbgExposeIntermediate(Object::ID id, EmitState *state) const;
+
+	// dbgUpdateActiveLaneMask() updates the active lane masks to the
+	// debugger.
+	void dbgUpdateActiveLaneMask(RValue<SIMD::Int> mask, EmitState *state) const;
+
+	// dbgDeclareResult() associates resultId as the result of the given
+	// instruction.
+	void dbgDeclareResult(const InsnIterator &insn, Object::ID resultId) const;
+
+	// Impl holds forward declaration structs and pointers to state for the
+	// private implementations in the corresponding SpirvShaderXXX.cpp files.
 	// This allows access to the private members of the SpirvShader, without
 	// littering the header with implementation details.
 	struct Impl
 	{
+		struct Debugger;
 		struct Group;
+		Debugger *debugger = nullptr;
 	};
+	Impl impl;
 };
 
 class SpirvRoutine
@@ -1230,6 +1277,8 @@
 	std::array<SIMD::Int, 3> localInvocationID;
 	std::array<SIMD::Int, 3> globalInvocationID;
 
+	Pointer<Byte> dbgState;  // Pointer to a debugger state.
+
 	void createVariable(SpirvShader::Object::ID id, uint32_t size)
 	{
 		bool added = variables.emplace(id, Variable(size)).second;
diff --git a/src/Pipeline/SpirvShaderControlFlow.cpp b/src/Pipeline/SpirvShaderControlFlow.cpp
index 7826415..824e468 100644
--- a/src/Pipeline/SpirvShaderControlFlow.cpp
+++ b/src/Pipeline/SpirvShaderControlFlow.cpp
@@ -702,6 +702,7 @@
 void SpirvShader::SetActiveLaneMask(RValue<SIMD::Int> mask, EmitState *state) const
 {
 	state->activeLaneMaskValue = mask.value;
+	dbgUpdateActiveLaneMask(mask, state);
 }
 
 }  // namespace sw
\ No newline at end of file
diff --git a/src/Pipeline/SpirvShaderDebugger.cpp b/src/Pipeline/SpirvShaderDebugger.cpp
new file mode 100644
index 0000000..ab596f7
--- /dev/null
+++ b/src/Pipeline/SpirvShaderDebugger.cpp
@@ -0,0 +1,686 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// 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.
+
+#include "SpirvShader.hpp"
+
+#ifdef ENABLE_VK_DEBUGGER
+
+#	include "Vulkan/Debug/Context.hpp"
+#	include "Vulkan/Debug/File.hpp"
+#	include "Vulkan/Debug/Thread.hpp"
+#	include "Vulkan/Debug/Variable.hpp"
+
+#	include "spirv-tools/libspirv.h"
+
+#	include <algorithm>
+
+namespace spvtools {
+
+// Function implemented in third_party/SPIRV-Tools/source/disassemble.cpp
+// but with no public header.
+// This is a C++ function, so the name is mangled, and signature changes will
+// result in a linker error instead of runtime signature mismatches.
+extern std::string spvInstructionBinaryToText(const spv_target_env env,
+                                              const uint32_t *inst_binary,
+                                              const size_t inst_word_count,
+                                              const uint32_t *binary,
+                                              const size_t word_count,
+                                              const uint32_t options);
+
+}  // namespace spvtools
+
+namespace {
+
+const char *laneNames[] = { "Lane 0", "Lane 1", "Lane 2", "Lane 3" };
+static_assert(sizeof(laneNames) / sizeof(laneNames[0]) == sw::SIMD::Width,
+              "laneNames must have SIMD::Width entries");
+
+template<typename T>
+std::string tostring(const T &s)
+{
+	return std::to_string(s);
+}
+std::string tostring(const char *s)
+{
+	return s;
+}
+std::string tostring(sw::SpirvShader::Object::ID id)
+{
+	return "%" + std::to_string(id.value());
+}
+
+}  // anonymous namespace
+
+namespace rr {
+
+////////////////////////////////////////////////////////////////////////////////
+// rr::CToReactor<T> specializations.
+////////////////////////////////////////////////////////////////////////////////
+template<typename T>
+struct CToReactor<sw::SpirvID<T>>
+{
+	using type = rr::Int;
+	static rr::Int cast(sw::SpirvID<T> id) { return rr::Int(id.value()); }
+};
+
+template<typename T>
+struct CToReactor<vk::dbg::ID<T>>
+{
+	using type = rr::Int;
+	static rr::Int cast(vk::dbg::ID<T> id) { return rr::Int(id.value()); }
+};
+
+}  // namespace rr
+
+namespace sw {
+
+////////////////////////////////////////////////////////////////////////////////
+// sw::SpirvShader::Impl::Debugger
+//
+// Private struct holding debugger information for the SpirvShader.
+////////////////////////////////////////////////////////////////////////////////
+struct SpirvShader::Impl::Debugger
+{
+	class Group;
+	class State;
+
+	void setPosition(EmitState *state, const std::string &path, uint32_t line, uint32_t column);
+
+	// exposeVariable exposes the variable with the given ID to the debugger
+	// using the specified key.
+	template<typename Key>
+	void exposeVariable(
+	    const SpirvShader *shader,
+	    const Key &key,
+	    Object::ID id,
+	    EmitState *state) const;
+
+	// exposeVariable exposes the variable with the given ID to the
+	// debugger under the specified group, for the specified SIMD lane.
+	template<typename Key>
+	void exposeVariable(
+	    const SpirvShader *shader,
+	    const Group &group,
+	    int lane,
+	    const Key &key,
+	    Object::ID id,
+	    EmitState *state,
+	    int wordOffset = 0) const;
+
+	std::shared_ptr<vk::dbg::Context> ctx;
+	std::shared_ptr<vk::dbg::File> spirvFile;
+	std::unordered_map<const void *, int> spirvLineMappings;  // instruction pointer to line
+	std::unordered_map<const void *, Object::ID> results;     // instruction pointer to result ID
+
+private:
+	std::unordered_map<std::string, vk::dbg::File::ID> fileIDs;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// sw::SpirvShader::Impl::Debugger::State
+//
+// State holds the runtime data structures for the shader debug session.
+////////////////////////////////////////////////////////////////////////////////
+class SpirvShader::Impl::Debugger::State
+{
+public:
+	static State *create(const Debugger *debugger, const char *name);
+	static void destroy(State *);
+
+	State(const Debugger *debugger, const char *stackBase, vk::dbg::Context::Lock &lock);
+	~State();
+
+	void enter(vk::dbg::Context::Lock &lock, const char *name);
+	void exit();
+	void updateActiveLaneMask(int lane, bool enabled);
+	void update(vk::dbg::File::ID file, int line, int column);
+
+	vk::dbg::VariableContainer *locals();
+	vk::dbg::VariableContainer *hovers();
+	vk::dbg::VariableContainer *localsLane(int lane);
+
+	template<typename K>
+	vk::dbg::VariableContainer *group(vk::dbg::VariableContainer *vc, K key);
+
+	template<typename K, typename V>
+	void putVal(vk::dbg::VariableContainer *vc, K key, V value);
+
+	struct Scopes
+	{
+		std::shared_ptr<vk::dbg::Scope> locals;
+		std::shared_ptr<vk::dbg::Scope> hovers;
+		std::array<std::shared_ptr<vk::dbg::VariableContainer>, sw::SIMD::Width> localsByLane;
+	};
+
+	const Debugger *debugger;
+	const std::shared_ptr<vk::dbg::Thread> thread;
+	Scopes threadScopes;
+};
+
+SpirvShader::Impl::Debugger::State *SpirvShader::Impl::Debugger::State::create(const Debugger *debugger, const char *name)
+{
+	auto lock = debugger->ctx->lock();
+	return new State(debugger, name, lock);
+}
+
+void SpirvShader::Impl::Debugger::State::destroy(State *state)
+{
+	delete state;
+}
+
+SpirvShader::Impl::Debugger::State::State(const Debugger *debugger, const char *stackBase, vk::dbg::Context::Lock &lock)
+    : debugger(debugger)
+    , thread(lock.currentThread())
+{
+	enter(lock, stackBase);
+	thread->update([&](vk::dbg::Frame &frame) {
+		threadScopes.locals = frame.locals;
+		threadScopes.hovers = frame.hovers;
+		for(int i = 0; i < sw::SIMD::Width; i++)
+		{
+			threadScopes.localsByLane[i] = lock.createVariableContainer();
+			frame.locals->variables->put(laneNames[i], threadScopes.localsByLane[i]);
+		}
+	});
+}
+
+SpirvShader::Impl::Debugger::State::~State()
+{
+	exit();
+}
+
+void SpirvShader::Impl::Debugger::State::enter(vk::dbg::Context::Lock &lock, const char *name)
+{
+	thread->enter(lock, debugger->spirvFile, name);
+}
+
+void SpirvShader::Impl::Debugger::State::exit()
+{
+	thread->exit();
+}
+
+void SpirvShader::Impl::Debugger::State::updateActiveLaneMask(int lane, bool enabled)
+{
+	threadScopes.localsByLane[lane]->put("enabled", vk::dbg::make_constant(enabled));
+}
+
+void SpirvShader::Impl::Debugger::State::update(vk::dbg::File::ID fileID, int line, int column)
+{
+	auto file = debugger->ctx->lock().get(fileID);
+	thread->update([&](vk::dbg::Frame &frame) {
+		frame.location = { file, line, column };
+	});
+}
+
+vk::dbg::VariableContainer *SpirvShader::Impl::Debugger::State::locals()
+{
+	return threadScopes.locals->variables.get();
+}
+
+vk::dbg::VariableContainer *SpirvShader::Impl::Debugger::State::hovers()
+{
+	return threadScopes.hovers->variables.get();
+}
+
+vk::dbg::VariableContainer *SpirvShader::Impl::Debugger::State::localsLane(int i)
+{
+	return threadScopes.localsByLane[i].get();
+}
+
+template<typename K>
+vk::dbg::VariableContainer *SpirvShader::Impl::Debugger::State::group(vk::dbg::VariableContainer *vc, K key)
+{
+	auto out = debugger->ctx->lock().createVariableContainer();
+	vc->put(tostring(key), out);
+	return out.get();
+}
+
+template<typename K, typename V>
+void SpirvShader::Impl::Debugger::State::putVal(vk::dbg::VariableContainer *vc, K key, V value)
+{
+	vc->put(tostring(key), vk::dbg::make_constant(value));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// sw::SpirvShader::Impl::Debugger::Group
+//
+// This provides a convenient C++ interface for adding debugger values to
+// VariableContainers.
+////////////////////////////////////////////////////////////////////////////////
+class SpirvShader::Impl::Debugger::Group
+{
+public:
+	using Ptr = rr::Pointer<rr::Byte>;
+
+	static Group hovers(Ptr state);
+	static Group locals(Ptr state);
+	static Group localsLane(Ptr state, int lane);
+
+	Group(Ptr state, Ptr group);
+
+	template<typename K, typename RK>
+	Group group(RK key) const;
+
+	template<typename K, typename V, typename RK, typename RV>
+	void put(RK key, RV value) const;
+
+	template<typename K, typename V, typename RK, typename RV>
+	void put(RK key, RV x, RV y) const;
+
+	template<typename K, typename V, typename RK, typename RV>
+	void put(RK key, RV x, RV y, RV z) const;
+
+	template<typename K, typename V, typename RK, typename RV>
+	void put(RK key, RV x, RV y, RV z, RV w) const;
+
+	template<typename K, typename V, typename VEC>
+	void putVec3(K key, const VEC &v) const;
+
+private:
+	Ptr state;
+	Ptr ptr;
+};
+
+SpirvShader::Impl::Debugger::Group
+SpirvShader::Impl::Debugger::Group::hovers(Ptr state)
+{
+	return Group(state, rr::Call(&State::hovers, state));
+}
+
+SpirvShader::Impl::Debugger::Group
+SpirvShader::Impl::Debugger::Group::locals(Ptr state)
+{
+	return Group(state, rr::Call(&State::locals, state));
+}
+
+SpirvShader::Impl::Debugger::Group
+SpirvShader::Impl::Debugger::Group::localsLane(Ptr state, int lane)
+{
+	return Group(state, rr::Call(&State::localsLane, state, lane));
+}
+
+SpirvShader::Impl::Debugger::Group::Group(Ptr state, Ptr group)
+    : state(state)
+    , ptr(group)
+{}
+
+template<typename K, typename RK>
+SpirvShader::Impl::Debugger::Group SpirvShader::Impl::Debugger::Group::group(RK key) const
+{
+	return Group(state, rr::Call(&State::group<K>, state, ptr, key));
+}
+
+template<typename K, typename V, typename RK, typename RV>
+void SpirvShader::Impl::Debugger::Group::put(RK key, RV value) const
+{
+	rr::Call(&State::putVal<K, V>, state, ptr, key, value);
+}
+
+template<typename K, typename V, typename RK, typename RV>
+void SpirvShader::Impl::Debugger::Group::put(RK key, RV x, RV y) const
+{
+	auto vec = group<K>(key);
+	vec.template put<const char *, V>("x", x);
+	vec.template put<const char *, V>("y", y);
+}
+
+template<typename K, typename V, typename RK, typename RV>
+void SpirvShader::Impl::Debugger::Group::put(RK key, RV x, RV y, RV z) const
+{
+	auto vec = group<K>(key);
+	vec.template put<const char *, V>("x", x);
+	vec.template put<const char *, V>("y", y);
+	vec.template put<const char *, V>("z", z);
+}
+
+template<typename K, typename V, typename RK, typename RV>
+void SpirvShader::Impl::Debugger::Group::put(RK key, RV x, RV y, RV z, RV w) const
+{
+	auto vec = group<K>(key);
+	vec.template put<const char *, V>("x", x);
+	vec.template put<const char *, V>("y", y);
+	vec.template put<const char *, V>("z", z);
+	vec.template put<const char *, V>("w", w);
+}
+
+template<typename K, typename V, typename VEC>
+void SpirvShader::Impl::Debugger::Group::putVec3(K key, const VEC &v) const
+{
+	auto vec = group<K>(key);
+	vec.template put<const char *, V>("x", Extract(v, 0));
+	vec.template put<const char *, V>("y", Extract(v, 1));
+	vec.template put<const char *, V>("z", Extract(v, 2));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// sw::SpirvShader::Impl::Debugger methods
+////////////////////////////////////////////////////////////////////////////////
+void SpirvShader::Impl::Debugger::setPosition(EmitState *state, const std::string &path, uint32_t line, uint32_t column)
+{
+	auto it = fileIDs.find(path);
+	if(it != fileIDs.end())
+	{
+		rr::Call(&State::update, state->routine->dbgState, it->second, line, column);
+	}
+}
+
+template<typename Key>
+void SpirvShader::Impl::Debugger::exposeVariable(
+    const SpirvShader *shader,
+    const Key &key,
+    Object::ID id,
+    EmitState *state) const
+{
+	auto dbgState = state->routine->dbgState;
+	auto hover = Group::hovers(dbgState).group<Key>(key);
+	for(int lane = 0; lane < SIMD::Width; lane++)
+	{
+		exposeVariable(shader, Group::localsLane(dbgState, lane), lane, key, id, state);
+		exposeVariable(shader, hover, lane, laneNames[lane], id, state);
+	}
+}
+
+template<typename Key>
+void SpirvShader::Impl::Debugger::exposeVariable(
+    const SpirvShader *shader,
+    const Group &group,
+    int l,
+    const Key &key,
+    Object::ID id,
+    EmitState *state,
+    int wordOffset /* = 0 */) const
+{
+	GenericValue val(shader, state, id);
+	switch(shader->getType(val.type).opcode())
+	{
+		case spv::OpTypeInt:
+		{
+			group.put<Key, int>(key, Extract(val.Int(0), l));
+		}
+		break;
+		case spv::OpTypeFloat:
+		{
+			group.put<Key, float>(key, Extract(val.Float(0), l));
+		}
+		break;
+		case spv::OpTypeVector:
+		{
+			auto count = shader->getType(val.type).definition.word(3);
+			switch(count)
+			{
+				case 1:
+					group.put<Key, float>(key, Extract(val.Float(0), l));
+					break;
+				case 2:
+					group.put<Key, float>(key, Extract(val.Float(0), l), Extract(val.Float(1), l));
+					break;
+				case 3:
+					group.put<Key, float>(key, Extract(val.Float(0), l), Extract(val.Float(1), l), Extract(val.Float(2), l));
+					break;
+				case 4:
+					group.put<Key, float>(key, Extract(val.Float(0), l), Extract(val.Float(1), l), Extract(val.Float(2), l), Extract(val.Float(3), l));
+					break;
+				default:
+				{
+					auto vec = group.group<Key>(key);
+					for(uint32_t i = 0; i < count; i++)
+					{
+						vec.template put<int, float>(i, Extract(val.Float(i), l));
+					}
+				}
+				break;
+			}
+		}
+		break;
+		case spv::OpTypePointer:
+		{
+			auto objectTy = shader->getType(shader->getObject(id).type);
+			bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass);
+			auto ptr = state->getPointer(id);
+			auto ptrGroup = group.group<Key>(key);
+			shader->VisitMemoryObject(id, [&](const MemoryElement &el) {
+				auto p = ptr + el.offset;
+				if(interleavedByLane) { p = InterleaveByLane(p); }  // TODO: Interleave once, then add offset?
+				auto simd = p.Load<SIMD::Float>(sw::OutOfBoundsBehavior::Nullify, state->activeLaneMask());
+				ptrGroup.template put<int, float>(el.index, Extract(simd, l));
+			});
+		}
+		break;
+		default:
+			break;
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// sw::SpirvShader
+////////////////////////////////////////////////////////////////////////////////
+void SpirvShader::dbgInit(const std::shared_ptr<vk::dbg::Context> &dbgctx)
+{
+	impl.debugger = new Impl::Debugger();
+	impl.debugger->ctx = dbgctx;
+}
+
+void SpirvShader::dbgTerm()
+{
+	if(impl.debugger)
+	{
+		delete impl.debugger;
+	}
+}
+
+void SpirvShader::dbgCreateFile()
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	int currentLine = 1;
+	std::string source;
+	for(auto insn : *this)
+	{
+		auto instruction = spvtools::spvInstructionBinaryToText(
+		                       SPV_ENV_VULKAN_1_1,
+		                       insn.wordPointer(0),
+		                       insn.wordCount(),
+		                       insns.data(),
+		                       insns.size(),
+		                       SPV_BINARY_TO_TEXT_OPTION_NO_HEADER) +
+		                   "\n";
+		dbg->spirvLineMappings[insn.wordPointer(0)] = currentLine;
+		currentLine += std::count(instruction.begin(), instruction.end(), '\n');
+		source += instruction;
+	}
+	std::string name;
+	switch(executionModel)
+	{
+		case spv::ExecutionModelVertex: name = "VertexShader"; break;
+		case spv::ExecutionModelFragment: name = "FragmentShader"; break;
+		case spv::ExecutionModelGLCompute: name = "ComputeShader"; break;
+		default: name = "SPIR-V Shader"; break;
+	}
+	static std::atomic<int> id = { 0 };
+	name += std::to_string(id++) + ".spvasm";
+	dbg->spirvFile = dbg->ctx->lock().createVirtualFile(name.c_str(), source.c_str());
+}
+
+void SpirvShader::dbgBeginEmit(EmitState *state) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	using Group = Impl::Debugger::Group;
+
+	auto routine = state->routine;
+
+	auto type = "SPIR-V";
+	switch(executionModel)
+	{
+		case spv::ExecutionModelVertex: type = "VertexShader"; break;
+		case spv::ExecutionModelFragment: type = "FragmentShader"; break;
+		case spv::ExecutionModelGLCompute: type = "ComputeShader"; break;
+		default: type = "SPIR-V Shader"; break;
+	}
+	auto dbgState = rr::Call(&Impl::Debugger::State::create, dbg, type);
+
+	routine->dbgState = dbgState;
+
+	SetActiveLaneMask(state->activeLaneMask(), state);
+
+	auto locals = Group::locals(dbgState);
+	locals.put<const char *, int>("subgroupSize", routine->invocationsPerSubgroup);
+
+	switch(executionModel)
+	{
+		case spv::ExecutionModelGLCompute:
+			locals.putVec3<const char *, int>("numWorkgroups", routine->numWorkgroups);
+			locals.putVec3<const char *, int>("workgroupID", routine->workgroupID);
+			locals.putVec3<const char *, int>("workgroupSize", routine->workgroupSize);
+			locals.put<const char *, int>("numSubgroups", routine->subgroupsPerWorkgroup);
+			locals.put<const char *, int>("subgroupIndex", routine->subgroupIndex);
+
+			for(int i = 0; i < SIMD::Width; i++)
+			{
+				auto lane = Group::localsLane(dbgState, i);
+				lane.put<const char *, int>("globalInvocationId",
+				                            rr::Extract(routine->globalInvocationID[0], i),
+				                            rr::Extract(routine->globalInvocationID[1], i),
+				                            rr::Extract(routine->globalInvocationID[2], i));
+				lane.put<const char *, int>("localInvocationId",
+				                            rr::Extract(routine->localInvocationID[0], i),
+				                            rr::Extract(routine->localInvocationID[1], i),
+				                            rr::Extract(routine->localInvocationID[2], i));
+				lane.put<const char *, int>("localInvocationIndex", rr::Extract(routine->localInvocationIndex, i));
+			}
+			break;
+
+		case spv::ExecutionModelFragment:
+			locals.put<const char *, int>("viewIndex", routine->viewID);
+			for(int i = 0; i < SIMD::Width; i++)
+			{
+				auto lane = Group::localsLane(dbgState, i);
+				lane.put<const char *, float>("fragCoord",
+				                              rr::Extract(routine->fragCoord[0], i),
+				                              rr::Extract(routine->fragCoord[1], i),
+				                              rr::Extract(routine->fragCoord[2], i),
+				                              rr::Extract(routine->fragCoord[3], i));
+				lane.put<const char *, float>("pointCoord",
+				                              rr::Extract(routine->pointCoord[0], i),
+				                              rr::Extract(routine->pointCoord[1], i));
+				lane.put<const char *, int>("windowSpacePosition",
+				                            rr::Extract(routine->windowSpacePosition[0], i),
+				                            rr::Extract(routine->windowSpacePosition[1], i));
+				lane.put<const char *, int>("helperInvocation", rr::Extract(routine->helperInvocation, i));
+			}
+			break;
+
+		default:
+			break;
+	}
+}
+
+void SpirvShader::dbgEndEmit(EmitState *state) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	rr::Call(&Impl::Debugger::State::destroy, state->routine->dbgState);
+}
+
+void SpirvShader::dbgBeginEmitInstruction(InsnIterator insn, EmitState *state) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	auto line = dbg->spirvLineMappings.at(insn.wordPointer(0));
+	auto column = 0;
+	rr::Call(&Impl::Debugger::State::update, state->routine->dbgState, dbg->spirvFile->id, line, column);
+}
+
+void SpirvShader::dbgEndEmitInstruction(InsnIterator insn, EmitState *state) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	auto resIt = dbg->results.find(insn.wordPointer(0));
+	if(resIt != dbg->results.end())
+	{
+		auto id = resIt->second;
+		dbgExposeIntermediate(id, state);
+	}
+}
+
+void SpirvShader::dbgExposeIntermediate(Object::ID id, EmitState *state) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	dbg->exposeVariable(this, id, id, state);
+}
+
+void SpirvShader::dbgUpdateActiveLaneMask(RValue<SIMD::Int> mask, EmitState *state) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	for(int lane = 0; lane < SIMD::Width; lane++)
+	{
+		rr::Call(&Impl::Debugger::State::updateActiveLaneMask, state->routine->dbgState, lane, rr::Extract(mask, lane) != 0);
+	}
+}
+
+void SpirvShader::dbgDeclareResult(const InsnIterator &insn, Object::ID resultId) const
+{
+	auto dbg = impl.debugger;
+	if(!dbg) { return; }
+
+	dbg->results.emplace(insn.wordPointer(0), resultId);
+}
+
+SpirvShader::EmitResult SpirvShader::EmitLine(InsnIterator insn, EmitState *state) const
+{
+	if(auto dbg = impl.debugger)
+	{
+		auto path = getString(insn.word(1));
+		auto line = insn.word(2);
+		auto column = insn.word(3);
+		dbg->setPosition(state, path, line, column);
+	}
+	return EmitResult::Continue;
+}
+
+}  // namespace sw
+
+#else  // ENABLE_VK_DEBUGGER
+
+// Stub implementations of the dbgXXX functions.
+namespace sw {
+
+void SpirvShader::dbgInit(const std::shared_ptr<vk::dbg::Context> &dbgctx) {}
+void SpirvShader::dbgTerm() {}
+void SpirvShader::dbgCreateFile() {}
+void SpirvShader::dbgBeginEmit(EmitState *state) const {}
+void SpirvShader::dbgEndEmit(EmitState *state) const {}
+void SpirvShader::dbgBeginEmitInstruction(InsnIterator insn, EmitState *state) const {}
+void SpirvShader::dbgEndEmitInstruction(InsnIterator insn, EmitState *state) const {}
+void SpirvShader::dbgExposeIntermediate(Object::ID id, EmitState *state) const {}
+void SpirvShader::dbgUpdateActiveLaneMask(RValue<SIMD::Int> mask, EmitState *state) const {}
+void SpirvShader::dbgDeclareResult(const InsnIterator &insn, Object::ID resultId) const {}
+
+SpirvShader::EmitResult SpirvShader::EmitLine(InsnIterator insn, EmitState *state) const
+{
+	return EmitResult::Continue;
+}
+
+}  // namespace sw
+
+#endif  // ENABLE_VK_DEBUGGER
