Refactor RenderMesh() to now purely render what's specified

* So RenderMesh doesn't pick up anything implicitly from the current
  event, log, pipeline state etc - everything it needs is explicitly
  provided by the config parameters (note this might include a buffer
  generated by postvs data fetching, but the implementation now doesn't
  need to care or treat it as a special case.
This commit is contained in:
baldurk
2015-01-25 14:04:41 +00:00
parent 92e830b801
commit 22c9775008
16 changed files with 385 additions and 326 deletions
+3 -1
View File
@@ -32,9 +32,10 @@ struct OutputConfig
struct MeshFormat
{
ResourceId idxbuf;
uint32_t idxoffs;
uint32_t idxByteWidth;
ResourceId buf;
ResourceId buf;
uint32_t offset;
uint32_t stride;
@@ -46,6 +47,7 @@ struct MeshFormat
bool showAlpha;
PrimitiveTopology topo;
uint32_t numVerts;
bool32 unproject;
float nearPlane;
+1 -1
View File
@@ -103,7 +103,7 @@ class ImageViewer : public IReplayDriver
// other operations are dropped/ignored, to avoid confusion
void ReadLogInitialisation() {}
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg) {}
void RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg) {}
vector<ResourceId> GetBuffers() { return vector<ResourceId>(); }
vector<DebugMessage> GetDebugMessages() { return vector<DebugMessage>(); }
FetchBuffer GetBuffer(ResourceId id) { FetchBuffer ret; RDCEraseEl(ret); return ret; }
+1 -1
View File
@@ -214,7 +214,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
}
}
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
void RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg)
{
if(m_Proxy)
m_Proxy->RenderCheckerboard(Vec3f(0.7f, 0.3f, 0.3f), Vec3f(0.3f, 0.3f, 0.7f));
+67
View File
@@ -63,6 +63,73 @@ HMODULE GetD3DCompiler()
return ret;
}
D3D11_PRIMITIVE_TOPOLOGY MakeD3D11PrimitiveTopology(PrimitiveTopology Topo)
{
switch(Topo)
{
case eTopology_LineLoop:
case eTopology_TriangleFan:
RDCWARN("Unsupported primitive topology on D3D11: %x", Topo);
break;
default:
case eTopology_Unknown:
return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
case eTopology_PointList:
return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
case eTopology_LineList:
return D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
case eTopology_LineStrip:
return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;
case eTopology_TriangleList:
return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case eTopology_TriangleStrip:
return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
case eTopology_LineList_Adj:
return D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
case eTopology_LineStrip_Adj:
return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;
case eTopology_TriangleList_Adj:
return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;
case eTopology_TriangleStrip_Adj:
return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;
case eTopology_PatchList_1CPs:
case eTopology_PatchList_2CPs:
case eTopology_PatchList_3CPs:
case eTopology_PatchList_4CPs:
case eTopology_PatchList_5CPs:
case eTopology_PatchList_6CPs:
case eTopology_PatchList_7CPs:
case eTopology_PatchList_8CPs:
case eTopology_PatchList_9CPs:
case eTopology_PatchList_10CPs:
case eTopology_PatchList_11CPs:
case eTopology_PatchList_12CPs:
case eTopology_PatchList_13CPs:
case eTopology_PatchList_14CPs:
case eTopology_PatchList_15CPs:
case eTopology_PatchList_16CPs:
case eTopology_PatchList_17CPs:
case eTopology_PatchList_18CPs:
case eTopology_PatchList_19CPs:
case eTopology_PatchList_20CPs:
case eTopology_PatchList_21CPs:
case eTopology_PatchList_22CPs:
case eTopology_PatchList_23CPs:
case eTopology_PatchList_24CPs:
case eTopology_PatchList_25CPs:
case eTopology_PatchList_26CPs:
case eTopology_PatchList_27CPs:
case eTopology_PatchList_28CPs:
case eTopology_PatchList_29CPs:
case eTopology_PatchList_30CPs:
case eTopology_PatchList_31CPs:
case eTopology_PatchList_32CPs:
return D3D11_PRIMITIVE_TOPOLOGY(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (Topo - eTopology_PatchList_1CPs));
}
return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
}
PrimitiveTopology MakePrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topo)
{
switch(Topo)
+1
View File
@@ -44,6 +44,7 @@ HMODULE GetD3DCompiler();
ResourceFormat MakeResourceFormat(DXGI_FORMAT fmt);
DXGI_FORMAT MakeDXGIFormat(ResourceFormat fmt);
PrimitiveTopology MakePrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topo);
D3D11_PRIMITIVE_TOPOLOGY MakeD3D11PrimitiveTopology(PrimitiveTopology Topo);
ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc);
+114 -255
View File
@@ -3729,6 +3729,7 @@ MeshFormat D3D11DebugManager::GetPostVSBuffers(uint32_t frameID, uint32_t eventI
ret.idxbuf = ((WrappedID3D11Buffer *)s.idxBuf)->GetResourceID();
else
ret.idxbuf = ResourceId();
ret.idxoffs = 0;
ret.idxByteWidth = s.idxFmt == DXGI_FORMAT_R16_UINT ? 2 : 4;
if(s.buf)
@@ -3747,6 +3748,7 @@ MeshFormat D3D11DebugManager::GetPostVSBuffers(uint32_t frameID, uint32_t eventI
ret.showAlpha = false;
ret.topo = MakePrimitiveTopology(s.topo);
ret.numVerts = s.numVerts;
ret.unproject = true;
ret.nearPlane = s.nearPlane;
@@ -4521,38 +4523,14 @@ FloatVector D3D11DebugManager::InterpretVertex(byte *data, uint32_t vert, MeshDi
return ret;
}
void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg)
{
DebugVertexCBuffer vertexData;
D3D11RenderStateTracker tracker(m_WrappedContext);
vertexData.LineStrip = 0;
D3D11PipelineState pipeState = m_WrappedDevice->GetReplay()->GetD3D11PipelineState();
D3D11RenderState *curRS = m_WrappedDevice->GetImmediateContext()->GetCurrentPipelineState();
float aspect = 1.0f;
// guess the output aspect ratio, for mesh calculation
if(pipeState.m_OM.DepthTarget.Resource != ResourceId())
{
FetchTexture desc = m_WrappedDevice->GetReplay()->GetTexture(m_ResourceManager->GetLiveID(pipeState.m_OM.DepthTarget.Resource));
aspect = float(desc.width)/float(desc.height);
}
else
{
for(int32_t i=0; i < pipeState.m_OM.RenderTargets.count; i++)
{
if(pipeState.m_OM.RenderTargets[i].Resource != ResourceId())
{
FetchTexture desc = m_WrappedDevice->GetReplay()->GetTexture(m_ResourceManager->GetLiveID(pipeState.m_OM.RenderTargets[i].Resource));
aspect = float(desc.width)/float(desc.height);
break;
}
}
}
Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth())/float(GetHeight()));
Camera cam;
@@ -4584,14 +4562,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
m_pImmediateContext->OMSetBlendState(m_WireframeHelpersBS, NULL, 0xffffffff);
// don't cull in wireframe mesh display
/*
if(pipeState.m_RS.m_State.CullMode != eCull_None && pipeState.m_RS.m_State.FrontCCW)
m_pImmediateContext->RSSetState(m_WireframeHelpersCullCWRS);
else if(pipeState.m_RS.m_State.CullMode != eCull_None && !pipeState.m_RS.m_State.FrontCCW)
m_pImmediateContext->RSSetState(m_WireframeHelpersCullCCWRS);
else
*/
m_pImmediateContext->RSSetState(m_WireframeHelpersRS);
m_pImmediateContext->RSSetState(m_WireframeHelpersRS);
ResourceFormat resFmt;
resFmt.compByteWidth = cfg.position.compByteWidth;
@@ -4665,194 +4636,97 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
m_PrevMeshFmt = resFmt;
m_PrevMeshFmt2 = resFmt2;
ID3D11Buffer *ibuf = NULL;
DXGI_FORMAT ifmt = DXGI_FORMAT_R16_UINT;
UINT ioffs = cfg.position.idxoffs;
D3D11_PRIMITIVE_TOPOLOGY topo = MakeD3D11PrimitiveTopology(cfg.position.topo);
if(cfg.position.unproject || events.size() > 1)
// render the mesh itself (solid, then wireframe)
{
float nearp = 0.1f;
float farp = 1000.0f;
for(size_t i=0; i < events.size(); i++)
if(cfg.position.unproject)
{
PostVSData data = GetPostVSBuffers(frameID, events[i]);
const PostVSData::StageData &stage = data.GetStage(cfg.type);
// 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.position.nearPlane, cfg.position.farPlane, cfg.aspect);
if(stage.buf && stage.nearPlane != stage.farPlane)
if(cfg.ortho)
{
nearp = stage.nearPlane;
farp = stage.farPlane;
break;
}
}
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, nearp, farp, aspect);
if(cfg.ortho)
{
guessProj = Matrix4f::Orthographic(nearp, farp);
}
guessProjInv = guessProj.Inverse();
vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv));
FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer));
m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer);
m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0);
m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer);
m_pImmediateContext->PSSetShader(m_DebugRender.MeshPS, NULL, 0);
{
if(events.size() > 1)
{
pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID;
pixelData.WireframeColour = Vec3f(cfg.prevMeshColour.x, cfg.prevMeshColour.y, cfg.prevMeshColour.z);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
}
m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout);
for(size_t i=0; i < events.size()-1; i++)
{
PostVSData data = GetPostVSBuffers(frameID, events[i]);
PostVSData::StageData stage = data.GetStage(cfg.type);
if(stage.buf == NULL && cfg.type == eMeshDataStage_GSOut)
stage = data.GetStage(eMeshDataStage_VSOut);
if(stage.buf)
{
if(stage.topo > D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST)
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
else
m_pImmediateContext->IASetPrimitiveTopology(stage.topo);
ID3D11Buffer *buf = UNWRAP(WrappedID3D11Buffer, stage.buf);
m_pImmediateContext->IASetVertexBuffers(0, 1, &buf, (UINT *)&stage.vertStride, (UINT *)&stage.posOffset);
if(stage.useIndices)
{
buf = UNWRAP(WrappedID3D11Buffer, stage.idxBuf);
m_pImmediateContext->IASetIndexBuffer(buf, stage.idxFmt, 0);
m_pImmediateContext->DrawIndexed(stage.numVerts, 0, 0);
}
else
{
m_pImmediateContext->Draw(stage.numVerts, 0);
}
}
}
m_pImmediateContext->IASetInputLayout(m_PostMeshDisplayLayout);
if(m_PostMeshDisplayLayout == NULL)
{
RDCWARN("Couldn't get a mesh display layout");
return;
}
PostVSData data = GetPostVSBuffers(frameID, events.back());
const PostVSData::StageData &stage = data.GetStage(cfg.type);
if(stage.buf)
{
if(stage.topo > D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST)
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
else
m_pImmediateContext->IASetPrimitiveTopology(stage.topo);
ID3D11Buffer *buf = UNWRAP(WrappedID3D11Buffer, stage.buf);
m_pImmediateContext->IASetVertexBuffers(0, 1, &buf, (UINT *)&stage.vertStride, (UINT *)&stage.posOffset);
UINT offset = cfg.second.offset;
m_pImmediateContext->IASetVertexBuffers(1, 1, &buf, (UINT *)&stage.vertStride, &offset);
if(stage.useIndices)
{
buf = UNWRAP(WrappedID3D11Buffer, stage.idxBuf);
m_pImmediateContext->IASetIndexBuffer(buf, stage.idxFmt, 0);
}
// draw solid shaded mode
if(cfg.solidShadeMode != eShade_None)
{
m_pImmediateContext->RSSetState(m_DebugRender.RastState);
pixelData.OutputDisplayFormat = (int)cfg.solidShadeMode;
if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha)
pixelData.OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA;
pixelData.WireframeColour = Vec3f(0.8f, 0.8f, 0.0f);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
if(cfg.solidShadeMode == eShade_Lit)
{
DebugGeometryCBuffer geomData;
geomData.InvProj = projMat.Inverse();
FillCBuffer(m_DebugRender.GenericGSCBuffer, (float *)&geomData, sizeof(DebugGeometryCBuffer));
m_pImmediateContext->GSSetConstantBuffers(0, 1, &m_DebugRender.GenericGSCBuffer);
m_pImmediateContext->GSSetShader(m_DebugRender.MeshGS, NULL, 0);
}
if(stage.useIndices)
m_pImmediateContext->DrawIndexed(stage.numVerts, 0, 0);
else
m_pImmediateContext->Draw(stage.numVerts, 0);
if(cfg.solidShadeMode == eShade_Lit)
m_pImmediateContext->GSSetShader(NULL, NULL, 0);
}
// draw wireframe mode
if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw)
{
m_pImmediateContext->RSSetState(m_WireframeHelpersRS);
m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0);
pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID;
if(cfg.solidShadeMode == eShade_None)
pixelData.WireframeColour = Vec3f(cfg.currentMeshColour.x, cfg.currentMeshColour.y, cfg.currentMeshColour.z);
else
pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
if(stage.useIndices)
m_pImmediateContext->DrawIndexed(stage.numVerts, 0, 0);
else
m_pImmediateContext->Draw(stage.numVerts, 0);
}
guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane);
}
if(cfg.solidShadeMode == eShade_Lit)
m_pImmediateContext->GSSetShader(NULL, NULL, 0);
guessProjInv = guessProj.Inverse();
vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv));
}
}
else
{
FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer));
m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer);
m_pImmediateContext->VSSetShader(m_DebugRender.MeshVS, NULL, 0);
m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer);
if(cfg.position.unproject)
m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0);
else
m_pImmediateContext->VSSetShader(m_DebugRender.MeshVS, NULL, 0);
m_pImmediateContext->PSSetShader(m_DebugRender.MeshPS, NULL, 0);
// secondary draws - this is the "draw since last clear" feature. We don't have
// full flexibility, it only draws wireframe, and only the final rasterized position.
if(secondaryDraws.size() > 0)
{
m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout);
pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID;
pixelData.WireframeColour = Vec3f(cfg.prevMeshColour.x, cfg.prevMeshColour.y, cfg.prevMeshColour.z);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
for(size_t i=0; i < secondaryDraws.size(); i++)
{
const MeshFormat &fmt = secondaryDraws[i];
if(fmt.buf != ResourceId())
{
D3D11_PRIMITIVE_TOPOLOGY d3d11topo = MakeD3D11PrimitiveTopology(fmt.topo);
m_pImmediateContext->IASetPrimitiveTopology(MakeD3D11PrimitiveTopology(fmt.topo));
auto it = WrappedID3D11Buffer::m_BufferList.find(fmt.buf);
ID3D11Buffer *buf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer);
m_pImmediateContext->IASetVertexBuffers(0, 1, &buf, (UINT *)&fmt.stride, (UINT *)&fmt.offset);
if(fmt.idxbuf != ResourceId())
{
it = WrappedID3D11Buffer::m_BufferList.find(fmt.idxbuf);
buf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer);
m_pImmediateContext->IASetIndexBuffer(buf, fmt.idxByteWidth == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, fmt.idxoffs);
m_pImmediateContext->DrawIndexed(fmt.numVerts, 0, 0);
}
else
{
m_pImmediateContext->Draw(fmt.numVerts, 0);
}
}
}
}
ID3D11InputLayout *layout = cfg.position.unproject ? m_PostMeshDisplayLayout : m_MeshDisplayLayout;
if(m_MeshDisplayLayout == NULL)
if(layout == NULL)
{
RDCWARN("Couldn't get a mesh display layout");
return;
}
m_pImmediateContext->IASetInputLayout(layout);
ID3D11Buffer *vbs[2] = { NULL, NULL };
UINT str[] = { cfg.position.stride, cfg.second.stride };
UINT offs[] = { cfg.position.offset, cfg.second.offset };
if(cfg.type == eMeshDataStage_VSIn)
{
auto it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.buf);
@@ -4863,27 +4737,27 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
if(it != WrappedID3D11Buffer::m_BufferList.end())
vbs[1] = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer);
}
else
{
PostVSData data = GetPostVSBuffers(frameID, events[0]);
if(cfg.type == eMeshDataStage_VSOut)
vbs[0] = vbs[1] = UNWRAP(WrappedID3D11Buffer, data.vsout.buf);
if(cfg.type == eMeshDataStage_GSOut)
vbs[0] = vbs[1] = UNWRAP(WrappedID3D11Buffer, data.gsout.buf);
it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.idxbuf);
if(it != WrappedID3D11Buffer::m_BufferList.end())
ibuf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer);
if(cfg.position.idxByteWidth == 4)
ifmt = DXGI_FORMAT_R32_UINT;
}
m_pImmediateContext->IASetVertexBuffers(0, 2, vbs, str, offs);
m_pImmediateContext->IASetInputLayout(m_MeshDisplayLayout);
const FetchDrawcall *drawcall = m_WrappedDevice->GetDrawcall(frameID, events.back());
if(ibuf)
m_pImmediateContext->IASetIndexBuffer(ibuf, ifmt, ioffs);
// draw solid shaded mode
if(cfg.solidShadeMode != eShade_None && drawcall->topology < eTopology_PatchList_1CPs)
if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList_1CPs)
{
m_pImmediateContext->RSSetState(m_DebugRender.RastState);
m_pImmediateContext->IASetPrimitiveTopology(topo);
pixelData.OutputDisplayFormat = (int)cfg.solidShadeMode;
if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha)
pixelData.OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA;
@@ -4904,29 +4778,40 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
m_pImmediateContext->GSSetShader(m_DebugRender.MeshGS, NULL, 0);
}
m_WrappedDevice->ReplayLog(frameID, 0, events[0], eReplay_OnlyDraw);
if(ibuf)
m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, 0);
else
m_pImmediateContext->Draw(cfg.position.numVerts, 0);
if(cfg.solidShadeMode == eShade_Lit)
m_pImmediateContext->GSSetShader(NULL, NULL, 0);
}
// draw wireframe mode
if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || drawcall->topology >= eTopology_PatchList_1CPs)
if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || cfg.position.topo >= eTopology_PatchList_1CPs)
{
m_pImmediateContext->RSSetState(m_WireframeHelpersRS);
m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0);
pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID;
pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f);
if(secondaryDraws.size() > 0 && cfg.solidShadeMode == eShade_None)
pixelData.WireframeColour = Vec3f(cfg.currentMeshColour.x, cfg.currentMeshColour.y, cfg.currentMeshColour.z);
else
pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer);
if(drawcall->topology >= eTopology_PatchList_1CPs)
if(cfg.position.topo >= eTopology_PatchList_1CPs)
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
m_WrappedDevice->ReplayLog(frameID, 0, events[0], eReplay_OnlyDraw);
else
m_pImmediateContext->IASetPrimitiveTopology(topo);
if(ibuf)
m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, 0);
else
m_pImmediateContext->Draw(cfg.position.numVerts, 0);
}
}
@@ -4974,44 +4859,20 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
if(cfg.highlightVert != ~0U)
{
const FetchDrawcall *drawcall = m_WrappedDevice->GetDrawcall(frameID, events.back());
MeshDataStage stage = cfg.type;
if(m_HighlightCache.EID != events.back() || m_HighlightCache.buf != cfg.position.buf || stage != m_HighlightCache.stage)
if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage)
{
m_HighlightCache.EID = events.back();
m_HighlightCache.buf = cfg.position.buf;
m_HighlightCache.EID = eventID;
m_HighlightCache.stage = stage;
ID3D11Buffer *idxBuf = curRS->IA.IndexBuffer;
DXGI_FORMAT idxFmt = curRS->IA.IndexFormat;
UINT idxOffs = curRS->IA.IndexOffset;
bool index16 = (idxFmt == DXGI_FORMAT_R16_UINT);
bool index16 = (ifmt == DXGI_FORMAT_R16_UINT);
UINT bytesize = index16 ? 2 : 4;
if(stage == eMeshDataStage_VSIn)
{
m_HighlightCache.data = GetBufferData(cfg.position.buf, 0, 0);
m_HighlightCache.topo = curRS->IA.Topo;
idxOffs += drawcall->indexOffset*bytesize;
}
else
{
MeshFormat postvs = GetPostVSBuffers(frameID, events.back(), stage);
m_HighlightCache.data = GetBufferData(postvs.buf, 0, 0);
m_HighlightCache.data = GetBufferData(cfg.position.buf, 0, 0);
m_HighlightCache.topo = topo;
const PostVSData::StageData &stagedata = GetPostVSBuffers(frameID, events.back()).GetStage(stage);
m_HighlightCache.topo = stagedata.topo;
idxBuf = stagedata.idxBuf;
idxFmt = stagedata.idxFmt;
idxOffs = 0;
index16 = (idxFmt == DXGI_FORMAT_R16_UINT);
bytesize = index16 ? 2 : 4;
}
if((drawcall->flags & eDraw_UseIBuffer) == 0 || stage == eMeshDataStage_GSOut)
if(ibuf == NULL || stage == eMeshDataStage_GSOut)
{
m_HighlightCache.indices.clear();
m_HighlightCache.useidx = false;
@@ -5020,12 +4881,12 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
{
m_HighlightCache.useidx = true;
vector<byte> idxdata = GetBufferData(idxBuf, idxOffs, drawcall->numIndices*bytesize);
vector<byte> idxdata = GetBufferData(cfg.position.idxbuf, ioffs, cfg.position.numVerts*bytesize);
uint16_t *idx16 = (uint16_t *)&idxdata[0];
uint32_t *idx32 = (uint32_t *)&idxdata[0];
uint32_t numIndices = RDCMIN(drawcall->numIndices, uint32_t(idxdata.size()/bytesize));
uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size()/bytesize));
m_HighlightCache.indices.resize(numIndices);
@@ -5042,8 +4903,6 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
byte *dataEnd = data + m_HighlightCache.data.size();
data += cfg.position.offset; // to start of position data
if(stage == eMeshDataStage_VSIn)
data += drawcall->vertexOffset*cfg.position.stride; // to first vertex
///////////////////////////////////////////////////////////////
// vectors to be set from buffers, depending on topology
@@ -5197,7 +5056,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &eve
// Triangle strip with adjacency is the most complex topology, as
// we need to handle the ends separately where the pattern breaks.
uint32_t numidx = drawcall->numIndices;
uint32_t numidx = cfg.position.numVerts;
if(numidx < 6)
{
+2 -3
View File
@@ -134,7 +134,7 @@ class D3D11DebugManager
void TimeDrawcalls(rdctype::array<FetchDrawcall> &arr);
void RenderText(float x, float y, const char *textfmt, ...);
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg);
void RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg);
ID3D11Buffer *MakeCBuffer(float *data, size_t size);
@@ -299,9 +299,8 @@ class D3D11DebugManager
// mesh, not jumping back and forth much between meshes.
struct HighlightCache
{
HighlightCache() : EID(0), buf(), stage(eMeshDataStage_Unknown), useidx(false) {}
HighlightCache() : EID(0), stage(eMeshDataStage_Unknown), useidx(false) {}
uint32_t EID;
ResourceId buf;
MeshDataStage stage;
bool useidx;
D3D11_PRIMITIVE_TOPOLOGY topo;
+2 -2
View File
@@ -1290,9 +1290,9 @@ void D3D11Replay::TimeDrawcalls(rdctype::array<FetchDrawcall> &arr)
return m_pDevice->GetDebugManager()->TimeDrawcalls(arr);
}
void D3D11Replay::RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
void D3D11Replay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg)
{
return m_pDevice->GetDebugManager()->RenderMesh(frameID, events, cfg);
return m_pDevice->GetDebugManager()->RenderMesh(frameID, eventID, secondaryDraws, cfg);
}
void D3D11Replay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors)
+1 -1
View File
@@ -101,7 +101,7 @@ class D3D11Replay : public IReplayDriver
ResourceId CreateProxyTexture(FetchTexture templateTex);
void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize);
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg);
void RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg);
bool RenderTexture(TextureDisplay cfg);
+1 -1
View File
@@ -1450,7 +1450,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl
return m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, DebugData.overlayTex));
}
void GLReplay::RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg)
{
#if 0
WrappedOpenGL &gl = *m_pDriver;
+1 -1
View File
@@ -97,7 +97,7 @@ class GLReplay : public IReplayDriver
void TimeDrawcalls(rdctype::array<FetchDrawcall> &arr);
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg);
void RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg);
void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors);
void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors);
+1 -1
View File
@@ -130,7 +130,7 @@ class IReplayDriver : public IRemoteDriver
virtual ResourceId CreateProxyTexture(FetchTexture templateTex) = 0;
virtual void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) = 0;
virtual void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg) = 0;
virtual void RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg) = 0;
virtual bool RenderTexture(TextureDisplay cfg) = 0;
virtual void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) = 0;
+20 -12
View File
@@ -541,15 +541,6 @@ void ReplayOutput::DisplayMesh()
if(m_RenderData.meshDisplay.type == eMeshDataStage_Unknown) return;
if((draw->flags & eDraw_Drawcall) == 0) return;
vector<uint32_t> events = passEvents;
if(m_RenderData.meshDisplay.type == eMeshDataStage_VSIn ||
m_RenderData.meshDisplay.thisDrawOnly)
{
events.clear();
events.push_back(draw->eventID);
}
if(draw && m_OverlayDirty)
{
m_pDevice->ReplayLog(m_FrameID, 0, m_EventID, eReplay_WithoutDraw);
@@ -561,16 +552,33 @@ void ReplayOutput::DisplayMesh()
m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0);
m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f));
RDCASSERT(!events.empty());
m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0);
MeshDisplay mesh = m_RenderData.meshDisplay;
mesh.position.buf = m_pDevice->GetLiveID(mesh.position.buf);
mesh.position.idxbuf = m_pDevice->GetLiveID(mesh.position.idxbuf);
mesh.second.buf = m_pDevice->GetLiveID(mesh.second.buf);
mesh.second.idxbuf = m_pDevice->GetLiveID(mesh.second.idxbuf);
vector<MeshFormat> secondaryDraws;
if(m_RenderData.meshDisplay.type != eMeshDataStage_VSIn &&
!m_RenderData.meshDisplay.thisDrawOnly)
{
mesh.position.unproject = true;
mesh.second.unproject = true;
m_pDevice->RenderMesh(m_FrameID, events, mesh);
for(size_t i=0; i < passEvents.size(); i++)
{
// get the 'most final' stage
MeshFormat fmt = m_pDevice->GetPostVSBuffers(m_FrameID, passEvents[i], eMeshDataStage_GSOut);
if(fmt.buf == ResourceId()) fmt = m_pDevice->GetPostVSBuffers(m_FrameID, passEvents[i], eMeshDataStage_VSOut);
secondaryDraws.push_back(fmt);
}
}
m_pDevice->RenderMesh(m_FrameID, m_EventID, secondaryDraws, mesh);
}
+26
View File
@@ -519,6 +519,32 @@ namespace renderdocui.Code
return null;
}
public ResourceId GetDepthTarget()
{
if (LogLoaded)
{
if (IsLogD3D11)
return m_D3D11.m_OM.DepthTarget.Resource;
else if (IsLogGL)
return m_GL.m_FB.m_DrawFBO.Depth;
}
return ResourceId.Null;
}
public ResourceId GetStencilTarget()
{
if (LogLoaded)
{
if (IsLogD3D11)
return m_D3D11.m_OM.DepthTarget.Resource;
else if (IsLogGL)
return m_GL.m_FB.m_DrawFBO.Stencil;
}
return ResourceId.Null;
}
public ResourceId[] GetOutputTargets()
{
if (LogLoaded)
+3 -1
View File
@@ -362,9 +362,10 @@ namespace renderdoc
public struct MeshFormat
{
public ResourceId idxbuf;
public UInt32 idxoffs;
public UInt32 idxByteWidth;
public ResourceId buf;
public ResourceId buf;
public UInt32 offset;
public UInt32 stride;
@@ -376,6 +377,7 @@ namespace renderdoc
public bool showAlpha;
public PrimitiveTopology topo;
public UInt32 numVerts;
public bool unproject;
public float nearPlane;
+141 -46
View File
@@ -86,6 +86,8 @@ namespace renderdocui.Windows
public uint IndexCount = 0;
public uint IndexAdd = 0;
public MeshFormat PostVS;
public PrimitiveTopology Topology = PrimitiveTopology.Unknown;
public byte[][] Buffers = null;
@@ -475,6 +477,8 @@ namespace renderdocui.Windows
UI_SetRowsData(MeshDataStage.VSOut, contentsVSOut, 0);
if (m_GSOut.m_Input != null)
UI_SetRowsData(MeshDataStage.GSOut, contentsGSOut, 0);
camGuess_PropChanged();
}));
});
}
@@ -579,6 +583,8 @@ namespace renderdocui.Windows
if (m_GSOut.m_Input != null)
UI_SetRowsData(MeshDataStage.GSOut, contentsGSOut, horizscroll[2]);
camGuess_PropChanged();
render.Invalidate();
}));
});
@@ -840,22 +846,22 @@ namespace renderdocui.Windows
if (type != MeshDataStage.VSIn)
{
var postvs = r.GetPostVSData(type);
ret.PostVS = r.GetPostVSData(type);
ret.Buffers = new byte[1][];
if (postvs.buf == ResourceId.Null)
if (ret.PostVS.buf == ResourceId.Null)
{
ret.IndexCount = 0;
ret.Topology = PrimitiveTopology.Unknown;
}
else
{
ret.Buffers[0] = r.GetBufferData(postvs.buf, 0, 0);
ret.Buffers[0] = r.GetBufferData(ret.PostVS.buf, 0, 0);
ret.Topology = postvs.topo;
ret.Topology = ret.PostVS.topo;
ret.IndexCount = (uint)ret.Buffers[0].Length / postvs.stride;
ret.IndexCount = (uint)ret.Buffers[0].Length / ret.PostVS.stride;
uint stride = 0;
foreach (var f in input.BufferFormats)
@@ -867,7 +873,7 @@ namespace renderdocui.Windows
ret.Indices = null;
if (postvs.buf != ResourceId.Null && type == MeshDataStage.VSOut &&
if (ret.PostVS.buf != ResourceId.Null && type == MeshDataStage.VSOut &&
(input.Drawcall.flags & DrawcallFlags.UseIBuffer) > 0 && input.IndexBuffer != ResourceId.Null)
{
ret.IndexCount = input.Drawcall.numIndices;
@@ -2197,32 +2203,87 @@ namespace renderdocui.Windows
{
var ui = GetUIState(m_MeshDisplay.type);
// set position data etc from postvs if relevant
// also need to bake in drawcall offsets etc
// set numVerts from drawcall or postvs data
if (ui.m_Input == null || ui.m_Input.BufferFormats == null ||
CurPosElement == -1 || CurPosElement >= ui.m_Input.BufferFormats.Length)
{
m_MeshDisplay.position.idxbuf = ResourceId.Null;
m_MeshDisplay.position.idxoffs = 0;
m_MeshDisplay.position.idxByteWidth = 0;
m_MeshDisplay.position.buf = ResourceId.Null;
m_MeshDisplay.position.offset = 0;
m_MeshDisplay.position.stride = 0;
m_MeshDisplay.position.compByteWidth = 0;
m_MeshDisplay.position.compCount = 0;
m_MeshDisplay.position.compByteWidth = 0;
m_MeshDisplay.position.compType = FormatComponentType.None;
m_MeshDisplay.position.specialFormat = SpecialFormat.Unknown;
m_MeshDisplay.position.showAlpha = false;
m_MeshDisplay.position.topo = PrimitiveTopology.Unknown;
m_MeshDisplay.position.numVerts = 0;
m_MeshDisplay.position.unproject = false;
// near and far plane handled elsewhere
}
else
{
FormatElement pos = ui.m_Input.BufferFormats[CurPosElement];
m_MeshDisplay.position.buf = m_VSIn.m_Input.Buffers[pos.buffer];
m_MeshDisplay.position.offset = pos.offset + ui.m_Input.Offsets[pos.buffer];
m_MeshDisplay.position.stride = ui.m_Input.Strides[pos.buffer];
m_MeshDisplay.position.compByteWidth = pos.format.compByteWidth;
m_MeshDisplay.position.idxbuf = ResourceId.Null;
m_MeshDisplay.position.idxoffs = 0;
m_MeshDisplay.position.idxByteWidth = 0;
m_MeshDisplay.position.buf = ResourceId.Null;
m_MeshDisplay.position.offset = 0;
m_MeshDisplay.position.stride = 0;
m_MeshDisplay.position.compCount = pos.format.compCount;
m_MeshDisplay.position.compByteWidth = pos.format.compByteWidth;
m_MeshDisplay.position.compType = pos.format.compType;
m_MeshDisplay.position.specialFormat = pos.format.special ? pos.format.specialFormat : SpecialFormat.Unknown;
m_MeshDisplay.position.showAlpha = false;
m_MeshDisplay.position.topo = PrimitiveTopology.Unknown;
m_MeshDisplay.position.numVerts = 0;
if (ui.m_Stage == MeshDataStage.VSIn && ui.m_Input.Drawcall != null)
{
m_MeshDisplay.position.idxbuf = m_VSIn.m_Input.IndexBuffer;
m_MeshDisplay.position.idxoffs = m_VSIn.m_Input.IndexOffset +
ui.m_Input.Drawcall.indexOffset * ui.m_Input.Drawcall.indexByteWidth;
m_MeshDisplay.position.idxByteWidth = ui.m_Input.Drawcall.indexByteWidth;
m_MeshDisplay.position.buf = m_VSIn.m_Input.Buffers[pos.buffer];
m_MeshDisplay.position.offset = pos.offset + ui.m_Input.Offsets[pos.buffer] +
ui.m_Input.Drawcall.vertexOffset * m_MeshDisplay.position.stride;
m_MeshDisplay.position.stride = ui.m_Input.Strides[pos.buffer];
m_MeshDisplay.position.topo = ui.m_Input.Drawcall.topology;
m_MeshDisplay.position.numVerts = ui.m_Input.Drawcall.numIndices;
}
else if (ui.m_Stage != MeshDataStage.VSIn && ui.m_Data != null && ui.m_Data.PostVS.buf != ResourceId.Null)
{
m_MeshDisplay.position.idxbuf = ui.m_Data.PostVS.idxbuf;
m_MeshDisplay.position.idxoffs = ui.m_Input.Drawcall.indexOffset * ui.m_Data.PostVS.idxByteWidth;
m_MeshDisplay.position.idxByteWidth = ui.m_Data.PostVS.idxByteWidth;
m_MeshDisplay.position.buf = ui.m_Data.PostVS.buf;
m_MeshDisplay.position.offset = pos.offset;
m_MeshDisplay.position.stride = ui.m_Data.PostVS.stride;
m_MeshDisplay.position.topo = ui.m_Data.PostVS.topo;
m_MeshDisplay.position.numVerts = ui.m_Data.PostVS.numVerts;
}
m_MeshDisplay.position.unproject = false;
// near and far plane handled elsewhere
if ((ui.m_Stage == MeshDataStage.VSOut && !m_Core.CurPipelineState.IsTessellationEnabled) || ui.m_Stage == MeshDataStage.GSOut)
{
@@ -2233,27 +2294,50 @@ namespace renderdocui.Windows
if (ui.m_Input == null || ui.m_Input.BufferFormats == null ||
CurSecondElement == -1 || CurSecondElement >= ui.m_Input.BufferFormats.Length)
{
m_MeshDisplay.secondary.idxbuf = ResourceId.Null;
m_MeshDisplay.secondary.idxoffs = 0;
m_MeshDisplay.secondary.idxByteWidth = 0;
m_MeshDisplay.secondary.buf = ResourceId.Null;
m_MeshDisplay.secondary.offset = 0;
m_MeshDisplay.secondary.stride = 0;
m_MeshDisplay.secondary.compByteWidth = 0;
m_MeshDisplay.secondary.compCount = 0;
m_MeshDisplay.secondary.compByteWidth = 0;
m_MeshDisplay.secondary.compType = FormatComponentType.None;
m_MeshDisplay.secondary.specialFormat = SpecialFormat.Unknown;
m_MeshDisplay.secondary.showAlpha = false;
m_MeshDisplay.secondary.topo = PrimitiveTopology.Unknown;
m_MeshDisplay.secondary.numVerts = 0;
m_MeshDisplay.secondary.unproject = false;
}
else
{
FormatElement tex = ui.m_Input.BufferFormats[CurSecondElement];
m_MeshDisplay.secondary.buf = m_VSIn.m_Input.Buffers[tex.buffer];
m_MeshDisplay.secondary.offset = tex.offset + ui.m_Input.Offsets[tex.buffer];
m_MeshDisplay.secondary.stride = ui.m_Input.Strides[tex.buffer];
m_MeshDisplay.secondary.compByteWidth = tex.format.compByteWidth;
m_MeshDisplay.secondary.compCount = tex.format.compCount;
m_MeshDisplay.secondary.compByteWidth = tex.format.compByteWidth;
m_MeshDisplay.secondary.compType = tex.format.compType;
m_MeshDisplay.secondary.specialFormat = tex.format.special ? tex.format.specialFormat : SpecialFormat.Unknown;
m_MeshDisplay.secondary.showAlpha = CurSecondShowAlpha;
if (ui.m_Stage == MeshDataStage.VSIn && ui.m_Input.Drawcall != null)
{
m_MeshDisplay.secondary.buf = m_VSIn.m_Input.Buffers[tex.buffer];
m_MeshDisplay.secondary.offset = tex.offset + ui.m_Input.Offsets[tex.buffer] +
ui.m_Input.Drawcall.vertexOffset * m_MeshDisplay.position.stride;
m_MeshDisplay.secondary.stride = ui.m_Input.Strides[tex.buffer];
}
else if (ui.m_Stage != MeshDataStage.VSIn && ui.m_Data != null && ui.m_Data.PostVS.buf != ResourceId.Null)
{
m_MeshDisplay.secondary.buf = ui.m_Data.PostVS.buf;
m_MeshDisplay.secondary.offset = tex.offset;
m_MeshDisplay.secondary.stride = ui.m_Data.PostVS.stride;
}
}
UI_UpdateAllColumns();
@@ -2263,50 +2347,61 @@ namespace renderdocui.Windows
{
m_MeshDisplay.ortho = matrixType.SelectedIndex == 1;
float fov;
if (float.TryParse(fovGuess.Text, out fov))
{
m_MeshDisplay.fov = fov;
}
float fov = 90.0f;
float.TryParse(fovGuess.Text, out fov);
m_MeshDisplay.fov = fov;
fovGuess.Text = m_MeshDisplay.fov.ToString("G");
m_MeshDisplay.aspect = 1.0f;
// take a guess for the aspect ratio, for if the user hasn't overridden it
ResourceId depth = m_Core.CurPipelineState.GetDepthTarget();
ResourceId[] targets = m_Core.CurPipelineState.GetOutputTargets();
float aspect = 0.0f;
if (aspectGuess.Text.Length > 0)
if (depth != ResourceId.Null || (targets != null && targets.Length > 0))
{
float.TryParse(aspectGuess.Text, out aspect);
foreach (var t in m_Core.CurTextures)
{
if (depth != ResourceId.Null && t.ID == depth)
{
m_MeshDisplay.aspect = (float)t.width / (float)t.height;
break;
}
if (depth == ResourceId.Null && targets != null && targets.Length > 0 && t.ID == targets[0])
{
m_MeshDisplay.aspect = (float)t.width / (float)t.height;
break;
}
}
}
m_MeshDisplay.aspect = aspect;
if (aspectGuess.Text.Length > 0 && float.TryParse(aspectGuess.Text, out m_MeshDisplay.aspect))
aspectGuess.Text = m_MeshDisplay.aspect.ToString("G");
else
aspectGuess.Text = "";
aspectGuess.Text = aspect > 0.0f ? aspect.ToString("G") : "";
// use estimates from post vs data (calculated from vertex position data) if the user
// hasn't overridden the values
m_MeshDisplay.position.nearPlane = 1.0f;
if (m_VSOut.m_Data != null && m_VSOut.m_Data.PostVS.buf != ResourceId.Null)
m_MeshDisplay.position.nearPlane = m_VSOut.m_Data.PostVS.nearPlane;
if (nearGuess.Text.Length > 0 && float.TryParse(nearGuess.Text, out m_MeshDisplay.position.nearPlane))
nearGuess.Text = m_MeshDisplay.position.nearPlane.ToString("G");
else
nearGuess.Text = "";
float near = -float.MaxValue;
if (nearGuess.Text.Length > 0)
{
float.TryParse(nearGuess.Text, out near);
}
m_MeshDisplay.position.farPlane = 10.0f;
m_MeshDisplay.position.nearPlane = near;
if (m_VSOut.m_Data != null && m_VSOut.m_Data.PostVS.buf != ResourceId.Null)
m_MeshDisplay.position.farPlane = m_VSOut.m_Data.PostVS.farPlane;
nearGuess.Text = near > -float.MaxValue ? near.ToString("G") : "";
float far = -float.MaxValue;
if (farGuess.Text.Length > 0)
{
float.TryParse(farGuess.Text, out far);
}
m_MeshDisplay.position.farPlane = far;
farGuess.Text = far > -float.MaxValue ? far.ToString("G") : "";
if (farGuess.Text.Length > 0 && float.TryParse(farGuess.Text, out m_MeshDisplay.position.farPlane))
farGuess.Text = m_MeshDisplay.position.farPlane.ToString("G");
else
farGuess.Text = "";
render.Invalidate();
}