mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-14 02:31:12 +00:00
Start tracking current state
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user