Start tracking current state

This commit is contained in:
baldurk
2016-02-07 18:38:47 +01:00
parent 332c5e4289
commit d9d90097ad
6 changed files with 335 additions and 2 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ win32 {
LIBS += -L$$_PRO_FILE_PWD_/../renderdoc -lrenderdoc
QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN\''
QMAKE_CXXFLAGS += -std=c++11 -Wno-unused-parameter
QMAKE_CXXFLAGS += -std=c++11 -Wno-unused-parameter -Wno-reorder
QT += x11extras
+1
View File
@@ -104,6 +104,7 @@ struct ResourceId
#include "d3d11_pipestate.h"
#include "gl_pipestate.h"
#include "vk_pipestate.h"
// for C++ expose the interface as a virtual interface
#ifdef __cplusplus
+227
View File
@@ -0,0 +1,227 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2015 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
struct VulkanPipelineState
{
VulkanPipelineState() : pipelineFlags(0) {}
ResourceId pipeline;
uint32_t pipelineFlags;
// VKTODOMED renderpass/subpass?
struct InputAssembly
{
InputAssembly() : primitiveRestartEnable(false) {}
bool32 primitiveRestartEnable;
struct IndexBuffer
{
IndexBuffer() : offs(0) {}
ResourceId buf;
uint64_t offs;
// byte width is latched per-draw for GL
} ibuffer;
} IA;
struct VertexInput
{
struct Attribute
{
Attribute() : binding(0), format(), byteoffset(0) {}
uint32_t binding;
ResourceFormat format;
uint32_t byteoffset;
};
rdctype::array<Attribute> attrs;
struct Binding
{
Binding() : vbufferBinding(0), bytestride(0), perInstance(false) {}
uint32_t vbufferBinding; // VKTODO I believe this is the meaning
uint32_t bytestride;
bool32 perInstance;
};
rdctype::array<Binding> binds;
struct VertexBuffer
{
VertexBuffer() : offset(0) {}
ResourceId buffer;
uint64_t offset;
};
rdctype::array<VertexBuffer> vbuffers;
} VI;
struct ShaderStage
{
ShaderStage() : Shader(), ShaderDetails(NULL), customName(false) {}
ResourceId Shader;
rdctype::str ShaderName;
bool32 customName;
ShaderReflection *ShaderDetails;
// VKTODOMED this might no longer make sense
ShaderBindpointMapping BindpointMapping;
ShaderStageType stage;
// VKTODOMED specialization info
} VS, TCS, TES, GS, FS, CS;
struct Tessellation
{
Tessellation() : numControlPoints(0) { }
uint32_t numControlPoints;
} Tess;
struct ViewportScissor
{
ResourceId state;
struct Viewport
{
Viewport() : x(0), y(0), width(0), height(0), mindepth(0), maxdepth(0) {}
float x, y, width, height, mindepth, maxdepth;
} vp;
struct Scissor
{
Scissor() : x(0), y(0), width(0), height(0) {}
int32_t x, y, width, height;
} scissor;
};
rdctype::array<ViewportScissor> viewportScissors;
struct Raster
{
Raster()
: depthClipEnable(false), rasterizerDiscardEnable(false), FrontCCW(false), FillMode(eFill_Solid), CullMode(eCull_None)
, depthBias(0), depthBiasClamp(0), slopeScaledDepthBias(0), lineWidth(0) {}
bool32 depthClipEnable, rasterizerDiscardEnable, FrontCCW;
TriangleFillMode FillMode;
TriangleCullMode CullMode;
// from dynamic state
ResourceId state;
float depthBias, depthBiasClamp, slopeScaledDepthBias, lineWidth;
} RS;
struct MultiSample
{
MultiSample() : rasterSamples(0), sampleShadingEnable(false), minSampleShading(0), sampleMask(~0U) {}
uint32_t rasterSamples;
bool32 sampleShadingEnable;
float minSampleShading;
uint32_t sampleMask;
} MSAA;
struct ColorBlend
{
bool32 alphaToCoverageEnable, logicOpEnable;
rdctype::str logicOp;
struct Attachment
{
Attachment() : blendEnable(false), writeMask(0)
{
blendConst[0] = blendConst[1] = blendConst[2] = blendConst[3] = 0.0f;
}
bool32 blendEnable;
struct BlendOp
{
rdctype::str Source;
rdctype::str Destination;
rdctype::str Operation;
} blend, alphaBlend;
uint8_t writeMask;
ResourceId state;
float blendConst[4];
};
rdctype::array<Attachment> attachments;
} CB;
struct DepthStencil
{
DepthStencil()
: testEnable(false), writeEnable(false), boundsEnable(false), stencilTestEnable(false)
, minDepthBounds(0), maxDepthBounds(0) {}
bool32 testEnable, writeEnable, boundsEnable;
rdctype::str compareOp;
bool32 stencilTestEnable;
struct StencilOp
{
StencilOp() : mask(0), ref(0) {}
rdctype::str failOp;
rdctype::str depthFailOp;
rdctype::str passOp;
rdctype::str func;
uint32_t mask;
uint32_t ref;
} front, back;
ResourceId state;
float minDepthBounds, maxDepthBounds;
} DS;
struct CurrentPass
{
struct RenderPass
{
ResourceId obj;
// VKTODOMED renderpass and subpass information here
} renderpass;
struct Framebuffer
{
Framebuffer() : width(0), height(0), layers(0) {}
ResourceId obj;
struct Attachment
{
ResourceId view;
// VKTODOLOW need layout here?
};
rdctype::array<Attachment> attachments;
uint32_t width, height, layers;
} framebuffer;
struct RenderArea
{
RenderArea() : x(0), y(0), width(0), height(0) {}
int32_t x, y, width, height;
} renderArea;
} Pass;
};
+56
View File
@@ -3833,7 +3833,13 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(
pipeline = (VkPipeline)GetResourceManager()->GetLiveResource(pipeid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindPipeline(PartialCmdBuf(), bind, pipeline);
if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
m_PartialReplayData.state.graphics.pipeline = pipeid;
else
m_PartialReplayData.state.compute.pipeline = pipeid;
}
}
else if(m_State == READING)
{
@@ -3903,7 +3909,22 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
layout = (VkPipelineLayout)GetResourceManager()->GetLiveResource(layoutid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindDescriptorSets(PartialCmdBuf(), bind, layout, first, numSets, sets, offsCount, offs);
vector<ResourceId> &descsets =
(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_PartialReplayData.state.graphics.descSets
: m_PartialReplayData.state.compute.descSets;
// expand as necessary
if(descsets.size() < first + numSets)
descsets.resize(first + numSets);
// VKTODOMED use layout to bake in dynamic offsets?
for(uint32_t i=0; i < numSets; i++)
descsets[first+i] = descriptorIDs[i];
}
}
else if(m_State == READING)
{
@@ -3960,7 +3981,10 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicViewportState(
dynamicViewportState = (VkDynamicViewportState)GetResourceManager()->GetLiveResource(stateid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindDynamicViewportState(PartialCmdBuf(), dynamicViewportState);
m_PartialReplayData.state.dynamicVP = stateid;
}
}
else if(m_State == READING)
{
@@ -4003,7 +4027,10 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicRasterState(
dynamicRasterState = (VkDynamicRasterState)GetResourceManager()->GetLiveResource(stateid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindDynamicRasterState(PartialCmdBuf(), dynamicRasterState);
m_PartialReplayData.state.dynamicRS = stateid;
}
}
else if(m_State == READING)
{
@@ -4046,7 +4073,10 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicColorBlendState(
dynamicColorBlendState = (VkDynamicColorBlendState)GetResourceManager()->GetLiveResource(stateid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindDynamicColorBlendState(PartialCmdBuf(), dynamicColorBlendState);
m_PartialReplayData.state.dynamicCB = stateid;
}
}
else if(m_State == READING)
{
@@ -4089,7 +4119,10 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicDepthStencilState(
dynamicDepthStencilState = (VkDynamicDepthStencilState)GetResourceManager()->GetLiveResource(stateid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindDynamicDepthStencilState(PartialCmdBuf(), dynamicDepthStencilState);
m_PartialReplayData.state.dynamicDS = stateid;
}
}
else if(m_State == READING)
{
@@ -4131,6 +4164,7 @@ bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(
SERIALISE_ELEMENT(uint32_t, start, startBinding);
SERIALISE_ELEMENT(uint32_t, count, bindingCount);
vector<ResourceId> bufids;
vector<VkBuffer> bufs;
vector<VkDeviceSize> offs;
@@ -4149,6 +4183,7 @@ bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(
if(m_State < WRITING)
{
bufids.push_back(id);
bufs.push_back((VkBuffer)GetResourceManager()->GetLiveResource(id).handle);
offs.push_back(o);
}
@@ -4157,7 +4192,18 @@ bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindVertexBuffers(PartialCmdBuf(), start, count, &bufs[0], &offs[0]);
if(m_PartialReplayData.state.vbuffers.size() < start + count)
m_PartialReplayData.state.vbuffers.resize(start + count);
for(uint32_t i=0; i < count; i++)
{
m_PartialReplayData.state.vbuffers[start + i].buf = bufids[i];
m_PartialReplayData.state.vbuffers[start + i].offs = offs[i];
}
}
}
else if(m_State == READING)
{
@@ -4208,7 +4254,13 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(
buffer = (VkBuffer)GetResourceManager()->GetLiveResource(bufid).handle;
if(IsPartialCmd(cmdid) && InPartialRange())
{
m_Real.vkCmdBindIndexBuffer(PartialCmdBuf(), buffer, offs, idxType);
m_PartialReplayData.state.ibuffer.buf = bufid;
m_PartialReplayData.state.ibuffer.offs = offs;
m_PartialReplayData.state.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2;
}
}
else if(m_State == READING)
{
@@ -5348,6 +5400,7 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
RDCASSERT(m_PartialReplayData.resultPartialCmdBuffer == VK_NULL_HANDLE);
m_PartialReplayData.partialParent = ResourceId();
m_PartialReplayData.baseEvent = 0;
m_PartialReplayData.state = PartialReplayData::StateVector();
}
else if(m_State == READING)
{
@@ -7011,6 +7064,9 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents)
draw.depthOut = ResourceId();
// VKTODOHIGH set index byte width here
// VKTODOHIGH set topology here
m_CurDrawcallID++;
if(hasEvents)
{
+49 -1
View File
@@ -187,7 +187,7 @@ private:
// on capture).
ResourceId m_CurCmdBufferID;
struct
struct PartialReplayData
{
// if we're doing a partial replay, by definition only one command
// buffer will be partial at any one time. While replaying through
@@ -233,6 +233,54 @@ private:
// reach the vkEndCommandBuffer that we also need to end a render
// pass.
bool renderPassActive;
// There is only a state while currently partially replaying, it's
// undefined/empty otherwise.
// All IDs are original IDs, not live.
struct StateVector
{
StateVector()
{
compute.pipeline = graphics.pipeline =
dynamicVP = dynamicRS = dynamicCB = dynamicDS = ResourceId();
compute.descSets.clear();
graphics.descSets.clear();
RDCEraseEl(ibuffer);
vbuffers.clear();
}
ResourceId dynamicVP;
ResourceId dynamicRS;
ResourceId dynamicCB;
ResourceId dynamicDS;
ResourceId renderPass;
ResourceId framebuffer;
VkRect2D renderArea;
struct
{
ResourceId pipeline;
// VKTODOMED might need something more sophisticated here, for
// dynamic offsets
vector<ResourceId> descSets;
} compute, graphics;
struct IdxBuffer
{
ResourceId buf;
VkDeviceSize offs;
int bytewidth;
} ibuffer;
struct VertBuffer
{
ResourceId buf;
VkDeviceSize offs;
};
vector<VertBuffer> vbuffers;
} state;
} m_PartialReplayData;
bool IsPartialCmd(ResourceId cmdid) { return cmdid == m_PartialReplayData.partialParent; }
+1
View File
@@ -82,6 +82,7 @@ class VulkanReplay : public IReplayDriver
void SavePipelineState();
D3D11PipelineState GetD3D11PipelineState() { return m_D3D11PipelineState; }
GLPipelineState GetGLPipelineState() { return GLPipelineState(); }
VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); }
void FreeTargetResource(ResourceId id);