Open shader source from resource inspector

This commit is contained in:
baldurk
2017-11-22 18:21:26 +00:00
parent c084778e0a
commit 5564e8b263
25 changed files with 224 additions and 15 deletions
+1
View File
@@ -207,6 +207,7 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderSourceFile)
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderVariable)
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, SigParameter)
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, TextureDescription)
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderEntryPoint)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, Attachment)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, BindingElement)
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, Blend)
+36 -1
View File
@@ -163,6 +163,8 @@ void ResourceInspector::Inspect(ResourceId id)
ui->viewContents->setVisible(m_Ctx.GetTexture(id) || m_Ctx.GetBuffer(id));
m_Entries.clear();
m_ResourceModel->reset();
m_FilterModel->sort(0);
@@ -181,7 +183,16 @@ void ResourceInspector::Inspect(ResourceId id)
m_Ctx.Replay().AsyncInvoke([this, id](IReplayController *r) {
rdcarray<EventUsage> usage = r->GetUsage(id);
GUIInvoke::call([this, id, usage] {
rdcarray<ShaderEntryPoint> entries = r->GetShaderEntryPoints(id);
GUIInvoke::call([this, id, entries, usage] {
if(!entries.isEmpty())
{
m_Entries = entries;
ui->viewContents->setVisible(true);
}
CombineUsageEvents(
m_Ctx, usage, [this, id](uint32_t startEID, uint32_t endEID, ResourceUsage use) {
QString text;
@@ -392,6 +403,30 @@ void ResourceInspector::on_viewContents_clicked()
m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this);
}
else if(!m_Entries.isEmpty())
{
ShaderEntryPoint entry = m_Entries[0];
if(m_Entries.count() > 1)
{
// TODO need to let the user choose the entry point
}
ResourceId id = m_Resource;
ICaptureContext *ctx = &m_Ctx;
m_Ctx.Replay().AsyncInvoke([ctx, id, entry](IReplayController *r) {
ShaderReflection *refl = r->GetShader(id, entry);
if(!refl)
return;
GUIInvoke::call([ctx, refl] {
IShaderViewer *viewer = ctx->ViewShader(refl, ResourceId());
ctx->AddDockWindow(viewer->Widget(), DockReference::MainToolArea, NULL);
});
});
}
}
void ResourceInspector::on_resourceUsage_doubleClicked(const QModelIndex &index)
+2
View File
@@ -74,6 +74,8 @@ private:
Ui::ResourceInspector *ui;
ICaptureContext &m_Ctx;
rdcarray<ShaderEntryPoint> m_Entries;
ResourceId m_Resource;
ResourceListItemModel *m_ResourceModel;
QSortFilterProxyModel *m_FilterModel;
+21
View File
@@ -844,6 +844,27 @@ newly generated messages will be returned after that.
)");
virtual rdcarray<DebugMessage> GetDebugMessages() = 0;
DOCUMENT(R"(Retrieve a list of entry points for a shader.
If the given ID doesn't specify a shader, an empty list will be return. On some APIs, the list will
only ever have one result (only one entry point per shader).
:param ResourceId shader: The shader to look up entry points for.
:return: The list of the :class:`ShaderEntryPoint` messages.
:rtype: ``list`` of :class:`ShaderEntryPoint`
)");
virtual rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader) = 0;
DOCUMENT(R"(Retrieve the information about the frame contained in the capture.
:param ResourceId shader: The shader to get reflection data for.
:param ShaderEntryPoint entry: The entry point within the shader to reflect. May be ignored on some
APIs
:return: The frame information.
:rtype: ShaderReflection
)");
virtual ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry) = 0;
DOCUMENT(R"(Retrieve the history of modifications to the selected pixel on the selected texture.
:param ResourceId texture: The texture to search for modifications.
+12
View File
@@ -451,6 +451,18 @@ able to be read from and written to arbitrarily.
DECLARE_REFLECTION_STRUCT(ShaderResource);
DOCUMENT("Describes an entry point in a shader.");
struct ShaderEntryPoint
{
DOCUMENT("The name of the entry point.");
rdcstr name;
DOCUMENT("The :class:`ShaderStage` for this entry point .");
ShaderStage stage;
};
DECLARE_REFLECTION_STRUCT(ShaderEntryPoint);
DOCUMENT("Contains a single flag used at compile-time on a shader.");
struct ShaderCompileFlag
{
+1
View File
@@ -202,6 +202,7 @@ public:
{
return ResourceId();
}
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader) { return {}; }
ShaderReflection *GetShader(ResourceId shader, string entryPoint) { return NULL; }
vector<string> GetDisassemblyTargets() { return {"N/A"}; }
string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const string &target)
+32
View File
@@ -783,6 +783,38 @@ ResourceId ReplayProxy::RenderOverlay(ResourceId texid, CompType typeHint, Debug
PROXY_FUNCTION(RenderOverlay, texid, typeHint, overlay, eventID, passEvents);
}
template <typename ParamSerialiser, typename ReturnSerialiser>
rdcarray<ShaderEntryPoint> ReplayProxy::Proxied_GetShaderEntryPoints(ParamSerialiser &paramser,
ReturnSerialiser &retser,
ResourceId id)
{
const ReplayProxyPacket packet = eReplayProxy_GetShaderEntryPoints;
rdcarray<ShaderEntryPoint> ret;
{
BEGIN_PARAMS();
SERIALISE_ELEMENT(id);
END_PARAMS();
}
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
ret = m_Remote->GetShaderEntryPoints(id);
{
ReturnSerialiser &ser = retser;
PACKET_HEADER(packet);
SERIALISE_ELEMENT(ret);
ser.EndChunk();
}
return ret;
}
rdcarray<ShaderEntryPoint> ReplayProxy::GetShaderEntryPoints(ResourceId id)
{
PROXY_FUNCTION(GetShaderEntryPoints, id);
}
template <typename ParamSerialiser, typename ReturnSerialiser>
ShaderReflection *ReplayProxy::Proxied_GetShader(ParamSerialiser &paramser, ReturnSerialiser &retser,
ResourceId id, std::string entryPoint)
+2
View File
@@ -47,6 +47,7 @@ enum ReplayProxyPacket
eReplayProxy_GetTexture,
eReplayProxy_GetBuffers,
eReplayProxy_GetBuffer,
eReplayProxy_GetShaderEntryPoints,
eReplayProxy_GetShader,
eReplayProxy_GetDebugMessages,
@@ -439,6 +440,7 @@ public:
DebugOverlay overlay, uint32_t eventID,
const std::vector<uint32_t> &passEvents);
IMPLEMENT_FUNCTION_PROXIED(rdcarray<ShaderEntryPoint>, GetShaderEntryPoints, ResourceId shader);
IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId shader,
std::string entryPoint);
+12
View File
@@ -228,6 +228,18 @@ TextureDescription D3D11Replay::GetTexture(ResourceId id)
return tex;
}
rdcarray<ShaderEntryPoint> D3D11Replay::GetShaderEntryPoints(ResourceId shader)
{
auto it = WrappedShader::m_ShaderList.find(shader);
if(it == WrappedShader::m_ShaderList.end())
return {};
ShaderReflection &ret = it->second->GetDetails();
return {{"main", ret.Stage}};
}
ShaderReflection *D3D11Replay::GetShader(ResourceId shader, string entryPoint)
{
auto it = WrappedShader::m_ShaderList.find(shader);
+1
View File
@@ -59,6 +59,7 @@ public:
vector<DebugMessage> GetDebugMessages();
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
ShaderReflection *GetShader(ResourceId shader, string entryPoint);
vector<string> GetDisassemblyTargets();
+13
View File
@@ -234,6 +234,19 @@ TextureDescription D3D12Replay::GetTexture(ResourceId id)
return ret;
}
rdcarray<ShaderEntryPoint> D3D12Replay::GetShaderEntryPoints(ResourceId shader)
{
WrappedID3D12Shader *sh =
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12Shader>(shader);
if(!sh)
return {};
ShaderReflection &ret = sh->GetDetails();
return {{"main", ret.Stage}};
}
ShaderReflection *D3D12Replay::GetShader(ResourceId shader, string entryPoint)
{
WrappedID3D12Shader *sh =
+1
View File
@@ -57,6 +57,7 @@ public:
vector<DebugMessage> GetDebugMessages();
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
ShaderReflection *GetShader(ResourceId shader, string entryPoint);
vector<string> GetDisassemblyTargets();
+16
View File
@@ -1071,6 +1071,22 @@ TextureFilter MakeFilter(GLenum minf, GLenum magf, bool shadowSampler, float max
return ret;
}
ShaderStage MakeShaderStage(GLenum type)
{
switch(type)
{
case eGL_VERTEX_SHADER: return ShaderStage::Vertex;
case eGL_TESS_CONTROL_SHADER: return ShaderStage::Tess_Control;
case eGL_TESS_EVALUATION_SHADER: return ShaderStage::Tess_Eval;
case eGL_GEOMETRY_SHADER: return ShaderStage::Geometry;
case eGL_FRAGMENT_SHADER: return ShaderStage::Fragment;
case eGL_COMPUTE_SHADER: return ShaderStage::Compute;
default: RDCERR("Unexpected shader stage %s", ToStr(type).c_str());
}
return ShaderStage::Count;
}
CompareFunc MakeCompareFunc(GLenum func)
{
switch(func)
+1
View File
@@ -296,6 +296,7 @@ GLenum MakeGLPrimitiveTopology(Topology Topo);
BufferCategory MakeBufferCategory(GLenum bufferTarget);
AddressMode MakeAddressMode(GLenum addr);
TextureFilter MakeFilter(GLenum minf, GLenum magf, bool shadowSampler, float maxAniso);
ShaderStage MakeShaderStage(GLenum type);
CompareFunc MakeCompareFunc(GLenum func);
StencilOp MakeStencilOp(GLenum op);
LogicOp MakeLogicOp(GLenum op);
+16
View File
@@ -759,6 +759,22 @@ vector<DebugMessage> GLReplay::GetDebugMessages()
return m_pDriver->GetDebugMessages();
}
rdcarray<ShaderEntryPoint> GLReplay::GetShaderEntryPoints(ResourceId shader)
{
if(m_pDriver->m_Shaders.find(shader) == m_pDriver->m_Shaders.end())
return {};
WrappedOpenGL::ShaderData &shaderDetails = m_pDriver->m_Shaders[shader];
if(shaderDetails.prog == 0)
{
RDCERR("Can't get shader details without separable program");
return {};
}
return {{"main", MakeShaderStage(shaderDetails.type)}};
}
ShaderReflection *GLReplay::GetShader(ResourceId shader, string entryPoint)
{
auto &shaderDetails = m_pDriver->m_Shaders[shader];
+2
View File
@@ -101,6 +101,8 @@ public:
std::vector<ResourceId> GetTextures();
TextureDescription GetTexture(ResourceId id);
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
ShaderReflection *GetShader(ResourceId shader, string entryPoint);
vector<string> GetDisassemblyTargets();
@@ -117,20 +117,7 @@ void WrappedOpenGL::ShaderData::Compile(WrappedOpenGL &gl, ResourceId id, GLuint
reflection.ID = id;
reflection.EntryPoint = "main";
switch(settings.stage)
{
case SPIRVShaderStage::Vertex: reflection.Stage = ShaderStage::Vertex; break;
case SPIRVShaderStage::TessControl: reflection.Stage = ShaderStage::Tess_Control; break;
case SPIRVShaderStage::TessEvaluation: reflection.Stage = ShaderStage::Tess_Eval; break;
case SPIRVShaderStage::Geometry: reflection.Stage = ShaderStage::Geometry; break;
case SPIRVShaderStage::Fragment: reflection.Stage = ShaderStage::Fragment; break;
case SPIRVShaderStage::Compute: reflection.Stage = ShaderStage::Compute; break;
case SPIRVShaderStage::Invalid:
default:
RDCERR("Unexpected shader stage %u", settings.stage);
reflection.Stage = ShaderStage::Vertex;
break;
}
reflection.Stage = MakeShaderStage(type);
// TODO sort these so that the first file contains the entry point
reflection.DebugInfo.files.resize(sources.size());
@@ -129,6 +129,7 @@ struct SPVModule
SPVInstruction *GetByID(uint32_t id);
string Disassemble(const string &entryPoint);
std::vector<std::string> EntryPoints() const;
ShaderStage StageForEntry(const string &entryPoint) const;
void MakeReflection(ShaderStage stage, const string &entryPoint, ShaderReflection &reflection,
@@ -3877,6 +3877,17 @@ void AddSignatureParameter(bool isInput, ShaderStage stage, uint32_t id,
}
}
std::vector<std::string> SPVModule::EntryPoints() const
{
std::vector<std::string> ret;
for(SPVInstruction *inst : entries)
if(inst->entry)
ret.push_back(inst->entry->name);
return ret;
}
ShaderStage SPVModule::StageForEntry(const string &entryPoint) const
{
for(SPVInstruction *inst : entries)
+17
View File
@@ -879,6 +879,23 @@ BufferDescription VulkanReplay::GetBuffer(ResourceId id)
return ret;
}
rdcarray<ShaderEntryPoint> VulkanReplay::GetShaderEntryPoints(ResourceId shader)
{
auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader);
if(shad == m_pDriver->m_CreationInfo.m_ShaderModule.end())
return {};
std::vector<std::string> entries = shad->second.spirv.EntryPoints();
rdcarray<ShaderEntryPoint> ret;
for(const std::string &e : entries)
ret.push_back({e, shad->second.spirv.StageForEntry(e)});
return ret;
}
ShaderReflection *VulkanReplay::GetShader(ResourceId shader, string entryPoint)
{
auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader);
+1
View File
@@ -145,6 +145,7 @@ public:
std::vector<ResourceId> GetTextures();
TextureDescription GetTexture(ResourceId id);
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
ShaderReflection *GetShader(ResourceId shader, string entryPoint);
vector<string> GetDisassemblyTargets();
+10
View File
@@ -224,6 +224,15 @@ void DoSerialise(SerialiserType &ser, ShaderResource &el)
SIZE_CHECK(80);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, ShaderEntryPoint &el)
{
SERIALISE_MEMBER(name);
SERIALISE_MEMBER(stage);
SIZE_CHECK(24);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, ShaderCompileFlag &el)
{
@@ -2199,6 +2208,7 @@ INSTANTIATE_SERIALISE_TYPE(ShaderConstant)
INSTANTIATE_SERIALISE_TYPE(ConstantBlock)
INSTANTIATE_SERIALISE_TYPE(ShaderSampler)
INSTANTIATE_SERIALISE_TYPE(ShaderResource)
INSTANTIATE_SERIALISE_TYPE(ShaderEntryPoint)
INSTANTIATE_SERIALISE_TYPE(ShaderCompileFlags)
INSTANTIATE_SERIALISE_TYPE(ShaderDebugChunk)
INSTANTIATE_SERIALISE_TYPE(ShaderReflection)
+10
View File
@@ -318,6 +318,16 @@ rdcarray<DebugMessage> ReplayController::GetDebugMessages()
return m_pDevice->GetDebugMessages();
}
rdcarray<ShaderEntryPoint> ReplayController::GetShaderEntryPoints(ResourceId shader)
{
return m_pDevice->GetShaderEntryPoints(m_pDevice->GetLiveID(shader));
}
ShaderReflection *ReplayController::GetShader(ResourceId shader, ShaderEntryPoint entry)
{
return m_pDevice->GetShader(m_pDevice->GetLiveID(shader), entry.name);
}
rdcarray<EventUsage> ReplayController::GetUsage(ResourceId id)
{
id = m_pDevice->GetLiveID(id);
+3
View File
@@ -167,6 +167,9 @@ public:
const rdcarray<ResourceDescription> &GetResources();
rdcarray<DebugMessage> GetDebugMessages();
rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader);
ShaderReflection *GetShader(ResourceId shader, ShaderEntryPoint entry);
rdcarray<PixelModification> PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice,
uint32_t mip, uint32_t sampleIdx, CompType typeHint);
ShaderDebugTrace *DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset,
+1
View File
@@ -100,6 +100,7 @@ public:
virtual vector<DebugMessage> GetDebugMessages() = 0;
virtual rdcarray<ShaderEntryPoint> GetShaderEntryPoints(ResourceId shader) = 0;
virtual ShaderReflection *GetShader(ResourceId shader, string entryPoint) = 0;
virtual vector<string> GetDisassemblyTargets() = 0;