Return Post VS mesh data just with buffer ID & description

* This will allow shifting to RenderMesh being run locally just by
  the UI specifying the buffer and simple vertex specification, rather
  than by relying on any local log properties (or replaying the log).
* The reasoning behind this change is that it becomes much simpler to
  implement, rather than having to modify the draw to do what we want,
  we just do an entirely custom draw based on a few properties - similar
  to the texture rendering. This will help e.g. for writing a GL
  implementation.
* The second benefit is that we can just transfer the buffer contents
  across the network when replaying remotely, so mesh rendering can be
  implemented even for remote replay - the last unimplemented feature.
* It could also be used similar to the image viewer in future, to
  display mesh files.
This commit is contained in:
baldurk
2015-01-24 22:06:45 +00:00
parent 30516c31c6
commit 92e830b801
19 changed files with 113 additions and 74 deletions
+12 -2
View File
@@ -31,14 +31,25 @@ struct OutputConfig
struct MeshFormat
{
ResourceId idxbuf;
uint32_t idxByteWidth;
ResourceId buf;
uint32_t offset;
uint32_t stride;
uint32_t compCount;
uint32_t compByteWidth;
FormatComponentType compType;
SpecialFormat specialFormat;
bool showAlpha;
PrimitiveTopology topo;
bool32 unproject;
float nearPlane;
float farPlane;
};
struct MeshDisplay
@@ -50,14 +61,13 @@ struct MeshDisplay
FloatVector cameraRot;
bool32 ortho;
float fov, aspect, nearPlane, farPlane;
float fov, aspect;
bool32 thisDrawOnly;
uint32_t highlightVert;
MeshFormat position;
MeshFormat second;
bool32 unproject;
FloatVector prevMeshColour;
FloatVector currentMeshColour;
-7
View File
@@ -254,10 +254,3 @@ struct PixelModification
bool32 depthTestFailed;
bool32 stencilTestFailed;
};
struct PostVSMeshData
{
rdctype::array<byte> buf;
uint32_t numVerts;
PrimitiveTopology topo;
};
+1 -1
View File
@@ -164,7 +164,7 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableCo
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, const TextureSave &saveData, const char *path);
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, MeshDataStage stage, PostVSMeshData *data);
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, MeshDataStage stage, MeshFormat *data);
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval);
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool32 channels[4], rdctype::array<uint32_t> *histogram);
+1 -1
View File
@@ -118,7 +118,7 @@ class ImageViewer : public IReplayDriver
void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector<ShaderVariable> &outvars, const vector<byte> &data) {}
vector<byte> GetBufferData(ResourceId buff, uint32_t offset, uint32_t len) { return vector<byte>(); }
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID) {}
PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage) { PostVSMeshData ret; RDCEraseEl(ret); return ret; }
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage) { MeshFormat ret; RDCEraseEl(ret); return ret; }
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents) { return ResourceId(); }
ShaderReflection *GetShader(ResourceId id) { return NULL; }
bool HasCallstacks() { return false; }
+14 -5
View File
@@ -535,11 +535,20 @@ void Serialiser::Serialise(const char *name, ShaderVariable &el)
}
template<>
void Serialiser::Serialise(const char *name, PostVSMeshData &el)
void Serialiser::Serialise(const char *name, MeshFormat &el)
{
Serialise("", el.numVerts);
Serialise("", el.topo);
Serialise("", el.buf);
Serialise("", el.offset);
Serialise("", el.stride);
Serialise("", el.compCount);
Serialise("", el.compByteWidth);
Serialise("", el.compType);
Serialise("", el.specialFormat);
Serialise("", el.showAlpha);
Serialise("", el.topo);
Serialise("", el.unproject);
Serialise("", el.nearPlane);
Serialise("", el.farPlane);
}
template<>
@@ -1298,9 +1307,9 @@ void ProxySerialiser::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
}
}
PostVSMeshData ProxySerialiser::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
MeshFormat ProxySerialiser::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
{
PostVSMeshData ret;
MeshFormat ret;
m_ToReplaySerialiser->Serialise("", frameID);
m_ToReplaySerialiser->Serialise("", eventID);
+1 -1
View File
@@ -288,7 +288,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize);
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents);
+41 -21
View File
@@ -3718,18 +3718,39 @@ PostVSData D3D11DebugManager::GetPostVSBuffers(uint32_t frameID, uint32_t eventI
return empty;
}
PostVSMeshData D3D11DebugManager::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
MeshFormat D3D11DebugManager::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
{
PostVSMeshData ret;
MeshFormat ret;
PostVSData postvs = GetPostVSBuffers(frameID, eventID);
PostVSData::StageData s = postvs.GetStage(stage);
ret.numVerts = s.numVerts;
ret.topo = MakePrimitiveTopology(s.topo);
if(s.buf != NULL)
ret.buf = GetBufferData(s.buf, 0, 0);
if(s.useIndices && s.idxBuf)
ret.idxbuf = ((WrappedID3D11Buffer *)s.idxBuf)->GetResourceID();
else
RDCWARN("No buffer for this stage!");
ret.idxbuf = ResourceId();
ret.idxByteWidth = s.idxFmt == DXGI_FORMAT_R16_UINT ? 2 : 4;
if(s.buf)
ret.buf = ((WrappedID3D11Buffer *)s.buf)->GetResourceID();
else
ret.buf = ResourceId();
ret.offset = s.posOffset;
ret.stride = s.vertStride;
ret.compCount = 4;
ret.compByteWidth = 4;
ret.compType = eCompType_Float;
ret.specialFormat = eSpecial_Unknown;
ret.showAlpha = false;
ret.topo = MakePrimitiveTopology(s.topo);
ret.unproject = true;
ret.nearPlane = s.nearPlane;
ret.farPlane = s.farPlane;
return ret;
}
@@ -4645,7 +4666,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
m_PrevMeshFmt = resFmt;
m_PrevMeshFmt2 = resFmt2;
if(cfg.unproject || events.size() > 1)
if(cfg.position.unproject || events.size() > 1)
{
float nearp = 0.1f;
float farp = 1000.0f;
@@ -4663,17 +4684,17 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
}
}
if(cfg.position.nearPlane > -FLT_MAX) nearp = cfg.position.nearPlane;
if(cfg.position.farPlane > -FLT_MAX) farp = cfg.position.farPlane;
if(cfg.aspect > 0.0f) aspect = cfg.aspect;
// the derivation of the projection matrix might not be right (hell, it could be an
// orthographic projection). But it'll be close enough likely.
Matrix4f guessProj = Matrix4f::Perspective(cfg.fov,
cfg.nearPlane > -FLT_MAX ? cfg.nearPlane : nearp,
cfg.farPlane > -FLT_MAX ? cfg.farPlane : farp,
cfg.aspect > 0.0f ? cfg.aspect : aspect);
Matrix4f guessProj = Matrix4f::Perspective(cfg.fov, nearp, farp, aspect);
if(cfg.ortho)
{
guessProj = Matrix4f::Orthographic(cfg.nearPlane > -FLT_MAX ? cfg.nearPlane : nearp,
cfg.farPlane > -FLT_MAX ? cfg.farPlane : farp);
guessProj = Matrix4f::Orthographic(nearp, farp);
}
guessProjInv = guessProj.Inverse();
@@ -4927,7 +4948,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
}
// axis markers
if(!cfg.unproject)
if(!cfg.position.unproject)
{
m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer);
@@ -4977,9 +4998,8 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
}
else
{
PostVSMeshData postvs = GetPostVSBuffers(frameID, events.back(), stage);
m_HighlightCache.data.resize(postvs.buf.count);
memcpy(&m_HighlightCache.data[0], postvs.buf.elems, postvs.buf.count);
MeshFormat postvs = GetPostVSBuffers(frameID, events.back(), stage);
m_HighlightCache.data = GetBufferData(postvs.buf, 0, 0);
const PostVSData::StageData &stagedata = GetPostVSBuffers(frameID, events.back()).GetStage(stage);
@@ -5321,7 +5341,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
// prepare rendering (for both vertices & primitives)
// if data is from post transform, it will be in clipspace
if(cfg.unproject)
if(cfg.position.unproject)
{
vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv));
m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0);
@@ -5443,12 +5463,12 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
}
}
if(cfg.unproject)
if(cfg.position.unproject)
m_pImmediateContext->VSSetShader(m_DebugRender.WireframeVS, NULL, 0);
}
// 'fake' helper frustum
if(cfg.unproject)
if(cfg.position.unproject)
{
UINT strides[] = { sizeof(Vec3f) };
UINT offsets[] = { 0 };
+1 -1
View File
@@ -114,7 +114,7 @@ class D3D11DebugManager
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
PostVSData GetPostVSBuffers(uint32_t frameID, uint32_t eventID);
PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
uint32_t GetStructCount(ID3D11UnorderedAccessView *uav);
vector<byte> GetBufferData(ID3D11Buffer *buff, uint32_t offset, uint32_t len);
@@ -167,6 +167,12 @@ HRESULT WrappedID3D11Device::CreateBuffer(
record->AddChunk(chunk);
record->SetDataPtr(chunk->GetData());
}
else
{
WrappedID3D11Buffer *w = (WrappedID3D11Buffer *)wrapped;
GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped);
}
*ppBuffer = wrapped;
}
+1 -1
View File
@@ -1260,7 +1260,7 @@ bool D3D11Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mi
return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, sample, minval, maxval, channels, histogram);
}
PostVSMeshData D3D11Replay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
MeshFormat D3D11Replay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
{
return m_pDevice->GetDebugManager()->GetPostVSBuffers(frameID, eventID, stage);
}
+1 -1
View File
@@ -87,7 +87,7 @@ class D3D11Replay : public IReplayDriver
bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval);
bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector<uint32_t> &histogram);
PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
vector<byte> GetBufferData(ResourceId buff, uint32_t offset, uint32_t len);
byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize);
+2 -2
View File
@@ -2168,9 +2168,9 @@ void GLReplay::FreeCustomShader(ResourceId id)
RDCUNIMPLEMENTED("FreeCustomShader");
}
PostVSMeshData GLReplay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
MeshFormat GLReplay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage)
{
PostVSMeshData ret;
MeshFormat ret;
RDCEraseEl(ret);
GLNOTIMP("GLReplay::GetPostVSBuffers");
+1 -1
View File
@@ -87,7 +87,7 @@ class GLReplay : public IReplayDriver
bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval);
bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector<uint32_t> &histogram);
PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
vector<byte> GetBufferData(ResourceId buff, uint32_t offset, uint32_t len);
byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize);
+1 -1
View File
@@ -81,7 +81,7 @@ class IRemoteDriver
virtual ResourceId GetLiveID(ResourceId id) = 0;
virtual PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage) = 0;
virtual MeshFormat GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage) = 0;
virtual vector<byte> GetBufferData(ResourceId buff, uint32_t offset, uint32_t len) = 0;
virtual byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) = 0;
+4 -5
View File
@@ -356,15 +356,14 @@ bool ReplayRenderer::GetUsage(ResourceId id, rdctype::array<EventUsage> *usage)
return false;
}
bool ReplayRenderer::GetPostVSData(MeshDataStage stage, PostVSMeshData *data)
bool ReplayRenderer::GetPostVSData(MeshDataStage stage, MeshFormat *data)
{
if(data == NULL) return false;
FetchDrawcall *draw = GetDrawcallByEID(m_EventID, m_LastDeferredEvent);
PostVSMeshData ret;
ret.numVerts = 0;
ret.topo = eTopology_Unknown;
MeshFormat ret;
RDCEraseEl(ret);
if(draw == NULL || (draw->flags & eDraw_Drawcall) == 0) return false;
@@ -1522,7 +1521,7 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableCo
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, const TextureSave &saveData, const char *path)
{ return rend->SaveTexture(saveData, path); }
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, MeshDataStage stage, PostVSMeshData *data)
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, MeshDataStage stage, MeshFormat *data)
{ return rend->GetPostVSData(stage, data); }
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval)
+1 -1
View File
@@ -166,7 +166,7 @@ struct ReplayRenderer
bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace);
bool DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace);
bool GetPostVSData(MeshDataStage stage, PostVSMeshData *data);
bool GetPostVSData(MeshDataStage stage, MeshFormat *data);
bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval);
bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array<uint32_t> *histogram);
+12 -11
View File
@@ -361,14 +361,25 @@ namespace renderdoc
[StructLayout(LayoutKind.Sequential)]
public struct MeshFormat
{
public ResourceId idxbuf;
public UInt32 idxByteWidth;
public ResourceId buf;
public UInt32 offset;
public UInt32 stride;
public UInt32 compCount;
public UInt32 compByteWidth;
public FormatComponentType compType;
public SpecialFormat specialFormat;
public bool showAlpha;
public PrimitiveTopology topo;
public bool unproject;
public float nearPlane;
public float farPlane;
};
[StructLayout(LayoutKind.Sequential)]
@@ -382,14 +393,13 @@ namespace renderdoc
public bool ortho = false;
public float fov = 90.0f;
public float aspect = 0.0f, nearPlane = 0.0f, farPlane = 0.0f;
public float aspect = 0.0f;
public bool thisDrawOnly = true;
public UInt32 highlightVert;
public MeshFormat position;
public MeshFormat secondary;
public bool unproject;
public FloatVector prevMeshColour = new FloatVector();
public FloatVector currentMeshColour = new FloatVector();
@@ -542,13 +552,4 @@ namespace renderdoc
!stencilTestFailed;
}
};
[StructLayout(LayoutKind.Sequential)]
public class PostVSMeshData
{
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public byte[] buf;
public UInt32 numVerts;
public PrimitiveTopology topo;
};
}
+5 -4
View File
@@ -636,16 +636,17 @@ namespace renderdoc
return ret;
}
public PostVSMeshData GetPostVSData(MeshDataStage stage)
public MeshFormat GetPostVSData(MeshDataStage stage)
{
IntPtr mem = CustomMarshal.Alloc(typeof(PostVSMeshData));
IntPtr mem = CustomMarshal.Alloc(typeof(MeshFormat));
PostVSMeshData ret = null;
MeshFormat ret = new MeshFormat();
ret.buf = ResourceId.Null;
bool success = ReplayRenderer_GetPostVSData(m_Real, stage, mem);
if (success)
ret = (PostVSMeshData)CustomMarshal.PtrToStructure(mem, typeof(PostVSMeshData), true);
ret = (MeshFormat)CustomMarshal.PtrToStructure(mem, typeof(MeshFormat), true);
CustomMarshal.Free(mem);
+8 -8
View File
@@ -844,18 +844,18 @@ namespace renderdocui.Windows
ret.Buffers = new byte[1][];
if (postvs == null)
if (postvs.buf == ResourceId.Null)
{
ret.IndexCount = 0;
ret.Topology = PrimitiveTopology.Unknown;
}
else
{
ret.Buffers[0] = postvs.buf;
ret.Buffers[0] = r.GetBufferData(postvs.buf, 0, 0);
ret.Topology = postvs.topo;
ret.IndexCount = postvs.numVerts;
ret.IndexCount = (uint)ret.Buffers[0].Length / postvs.stride;
uint stride = 0;
foreach (var f in input.BufferFormats)
@@ -867,7 +867,7 @@ namespace renderdocui.Windows
ret.Indices = null;
if (postvs != null && type == MeshDataStage.VSOut &&
if (postvs.buf != ResourceId.Null && type == MeshDataStage.VSOut &&
(input.Drawcall.flags & DrawcallFlags.UseIBuffer) > 0 && input.IndexBuffer != ResourceId.Null)
{
ret.IndexCount = input.Drawcall.numIndices;
@@ -2222,11 +2222,11 @@ namespace renderdocui.Windows
m_MeshDisplay.position.specialFormat = pos.format.special ? pos.format.specialFormat : SpecialFormat.Unknown;
m_MeshDisplay.position.showAlpha = false;
m_MeshDisplay.unproject = false;
m_MeshDisplay.position.unproject = false;
if ((ui.m_Stage == MeshDataStage.VSOut && !m_Core.CurPipelineState.IsTessellationEnabled) || ui.m_Stage == MeshDataStage.GSOut)
{
m_MeshDisplay.unproject = pos.name.ToUpperInvariant() == "SV_POSITION";
m_MeshDisplay.position.unproject = pos.name.ToUpperInvariant() == "SV_POSITION";
}
}
@@ -2292,7 +2292,7 @@ namespace renderdocui.Windows
float.TryParse(nearGuess.Text, out near);
}
m_MeshDisplay.nearPlane = near;
m_MeshDisplay.position.nearPlane = near;
nearGuess.Text = near > -float.MaxValue ? near.ToString("G") : "";
@@ -2304,7 +2304,7 @@ namespace renderdocui.Windows
float.TryParse(farGuess.Text, out far);
}
m_MeshDisplay.farPlane = far;
m_MeshDisplay.position.farPlane = far;
farGuess.Text = far > -float.MaxValue ? far.ToString("G") : "";