Implement mesh rendering (wireframe and solid)

This commit is contained in:
baldurk
2015-11-13 19:56:02 +01:00
parent 5fdc74d34b
commit 879df25850
4 changed files with 565 additions and 7 deletions
+352 -3
View File
@@ -24,6 +24,7 @@
#include "vk_debug.h"
#include "vk_core.h"
#include "maths/matrix.h"
#include "stb/stb_truetype.h"
@@ -88,6 +89,16 @@ struct stringdata
uint32_t str[256][4];
};
struct meshuniforms
{
Matrix4f mvp;
Matrix4f invProj;
Vec4f color;
uint32_t displayFormat;
uint32_t homogenousInput;
Vec2f pointSpriteSize;
};
void VulkanDebugManager::GPUBuffer::Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, uint32_t ringSize, uint32_t flags)
{
const VkLayerDispatchTable *vt = ObjDisp(dev);
@@ -296,6 +307,12 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
RDCASSERT(vkr == VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(dev), m_GenericDescSetLayout);
// identical layout
vkr = vt->CreateDescriptorSetLayout(Unwrap(dev), &descsetLayoutInfo, &m_MeshDescSetLayout);
RDCASSERT(vkr == VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(dev), m_MeshDescSetLayout);
}
{
@@ -366,6 +383,13 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
GetResourceManager()->WrapResource(Unwrap(dev), m_GenericPipeLayout);
pipeLayoutInfo.pSetLayouts = UnwrapPtr(m_MeshDescSetLayout);
vkr = vt->CreatePipelineLayout(Unwrap(dev), &pipeLayoutInfo, &m_MeshPipeLayout);
RDCASSERT(vkr == VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(dev), m_MeshPipeLayout);
VkDescriptorTypeCount descPoolTypes[] = {
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1024, },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1024, },
@@ -374,7 +398,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
VkDescriptorPoolCreateInfo descpoolInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, NULL,
VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 3+ARRAY_COUNT(m_TexDisplayDescSet),
VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 4+ARRAY_COUNT(m_TexDisplayDescSet),
ARRAY_COUNT(descPoolTypes), &descPoolTypes[0],
};
@@ -409,6 +433,12 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
RDCASSERT(vkr == VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(dev), m_GenericDescSet);
vkr = vt->AllocDescriptorSets(Unwrap(dev), Unwrap(m_DescriptorPool), VK_DESCRIPTOR_SET_USAGE_STATIC, 1,
UnwrapPtr(m_MeshDescSetLayout), &m_MeshDescSet);
RDCASSERT(vkr == VK_SUCCESS);
GetResourceManager()->WrapResource(Unwrap(dev), m_MeshDescSet);
m_GenericUBO.Create(driver, dev, 128, 10, 0);
RDCCOMPILE_ASSERT(sizeof(genericuniforms) <= 128, "outline strip VBO size");
@@ -1008,7 +1038,9 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
m_PickPixelReadbackBuffer.Create(driver, dev, sizeof(float)*4, 1, GPUBuffer::eGPUBufferReadback);
}
VkDescriptorInfo desc[6];
m_MeshUBO.Create(driver, dev, sizeof(meshuniforms), 16, 0);
VkDescriptorInfo desc[7];
RDCEraseEl(desc);
// checkerboard
@@ -1027,6 +1059,9 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
// generic
m_GenericUBO.FillDescriptor(desc[5]);
// mesh
m_MeshUBO.FillDescriptor(desc[6]);
VkWriteDescriptorSet writeSet[] = {
{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
@@ -1052,6 +1087,10 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
Unwrap(m_GenericDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &desc[5]
},
{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
Unwrap(m_MeshDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &desc[6]
},
};
vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
@@ -1070,6 +1109,17 @@ VulkanDebugManager::~VulkanDebugManager()
// pool here won't remove the descriptor sets, so we need to free our own
// tracking data (not the API objects) for descriptor sets.
for(auto it=m_CachedMeshPipelines.begin(); it != m_CachedMeshPipelines.end(); ++it)
{
for(uint32_t i=0; i < eShade_Count; i++)
{
if(it->second.pipes[i] == VK_NULL_HANDLE) continue;
vt->DestroyPipeline(Unwrap(dev), Unwrap(it->second.pipes[i]));
GetResourceManager()->ReleaseWrappedResource(it->second.pipes[i]);
}
}
for(size_t i=0; i < ARRAY_COUNT(m_MeshModules); i++)
{
vt->DestroyShader(Unwrap(dev), Unwrap(m_MeshShaders[i]));
@@ -1082,6 +1132,7 @@ VulkanDebugManager::~VulkanDebugManager()
GetResourceManager()->ReleaseWrappedResource(m_CheckerboardDescSet);
GetResourceManager()->ReleaseWrappedResource(m_GenericDescSet);
GetResourceManager()->ReleaseWrappedResource(m_TextDescSet);
GetResourceManager()->ReleaseWrappedResource(m_MeshDescSet);
for(size_t i=0; i < ARRAY_COUNT(m_TexDisplayDescSet); i++)
GetResourceManager()->ReleaseWrappedResource(m_TexDisplayDescSet[i]);
@@ -1226,7 +1277,21 @@ VulkanDebugManager::~VulkanDebugManager()
vt->FreeMemory(Unwrap(dev), Unwrap(m_TextAtlasMem));
GetResourceManager()->ReleaseWrappedResource(m_TextAtlasMem);
}
if(m_MeshDescSetLayout != VK_NULL_HANDLE)
{
vt->DestroyDescriptorSetLayout(Unwrap(dev), Unwrap(m_MeshDescSetLayout));
GetResourceManager()->ReleaseWrappedResource(m_MeshDescSetLayout);
}
if(m_MeshPipeLayout != VK_NULL_HANDLE)
{
vt->DestroyPipelineLayout(Unwrap(dev), Unwrap(m_MeshPipeLayout));
GetResourceManager()->ReleaseWrappedResource(m_MeshPipeLayout);
}
m_MeshUBO.Destroy(vt, dev);
if(m_GenericDescSetLayout != VK_NULL_HANDLE)
{
vt->DestroyDescriptorSetLayout(Unwrap(dev), Unwrap(m_GenericDescSetLayout));
@@ -1881,3 +1946,287 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
return GetResID(m_OverlayImage);
}
MeshDisplayPipelines VulkanDebugManager::CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary)
{
// generate a key to look up the map
uint64_t key = 0;
uint64_t bit = 0;
if(primary.idxByteWidth == 4) key |= 1ULL << bit;
bit++;
RDCASSERT((uint32_t)primary.topo < 64);
key |= ((uint32_t)primary.topo & 0x3f) << bit;
bit += 6;
ResourceFormat fmt;
fmt.special = primary.specialFormat != eSpecial_Unknown;
fmt.specialFormat = primary.specialFormat;
fmt.compByteWidth = primary.compByteWidth;
fmt.compCount = primary.compCount;
fmt.compType = primary.compType;
VkFormat primaryFmt = MakeVkFormat(fmt);
fmt.special = secondary.specialFormat != eSpecial_Unknown;
fmt.specialFormat = secondary.specialFormat;
fmt.compByteWidth = secondary.compByteWidth;
fmt.compCount = secondary.compCount;
fmt.compType = secondary.compType;
VkFormat secondaryFmt = secondary.buf == ResourceId() ? VK_FORMAT_UNDEFINED : MakeVkFormat(fmt);
RDCCOMPILE_ASSERT(VK_FORMAT_NUM <= 255, "Mesh pipeline cache key needs an extra bit for format");
key |= ((uint32_t)primaryFmt & 0xff) << bit;
bit += 8;
key |= ((uint32_t)secondaryFmt & 0xff) << bit;
bit += 8;
RDCASSERT(primary.stride <= 0xffff);
key |= ((uint32_t)primary.stride & 0xffff) << bit;
bit += 16;
if(secondary.buf != ResourceId())
{
RDCASSERT(secondary.stride <= 0xffff);
key |= ((uint32_t)secondary.stride & 0xffff) << bit;
}
bit += 16;
MeshDisplayPipelines &cache = m_CachedMeshPipelines[key];
if(cache.pipes[eShade_None] != VK_NULL_HANDLE)
return cache;
const VkLayerDispatchTable *vt = ObjDisp(m_Device);
VkResult vkr = VK_SUCCESS;
// should we try and evict old pipelines from the cache here?
// or just keep them forever
VkVertexInputBindingDescription binds[] = {
// primary
{
0,
primary.stride,
VK_VERTEX_INPUT_STEP_RATE_VERTEX
},
// secondary
{
1,
secondary.stride,
VK_VERTEX_INPUT_STEP_RATE_VERTEX
}
};
RDCASSERT(primaryFmt != VK_FORMAT_UNDEFINED);
VkVertexInputAttributeDescription vertAttrs[] = {
// primary
{
0,
0,
primaryFmt,
0,
},
// secondary
{
1,
0,
primaryFmt,
0,
},
};
VkPipelineVertexInputStateCreateInfo vi = {
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, NULL,
1, binds,
2, vertAttrs,
};
VkPipelineShaderStageCreateInfo stages[3] = {
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, VK_SHADER_STAGE_MAX_ENUM, VK_NULL_HANDLE, NULL },
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, VK_SHADER_STAGE_MAX_ENUM, VK_NULL_HANDLE, NULL },
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, VK_SHADER_STAGE_MAX_ENUM, VK_NULL_HANDLE, NULL },
};
VkPipelineInputAssemblyStateCreateInfo ia = {
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL,
primary.topo >= eTopology_PatchList ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : MakeVkPrimitiveTopology(primary.topo), false,
};
VkRect2D scissor = { { 0, 0 }, { 4096, 4096 } };
VkPipelineViewportStateCreateInfo vp = {
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL,
1, NULL,
1, &scissor
};
VkPipelineRasterStateCreateInfo rs = {
VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO, NULL,
true, false, VK_FILL_MODE_SOLID, VK_CULL_MODE_NONE, VK_FRONT_FACE_CW,
false, 0.0f, 0.0f, 0.0f, 1.0f,
};
VkPipelineMultisampleStateCreateInfo msaa = {
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, NULL,
1, false, 0.0f, NULL,
};
VkPipelineDepthStencilStateCreateInfo ds = {
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, NULL,
true, true, VK_COMPARE_OP_LESS, false, false,
{ VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0 },
{ VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0 },
0.0f, 1.0f,
};
VkPipelineColorBlendAttachmentState attState = {
false,
VK_BLEND_ONE, VK_BLEND_ZERO, VK_BLEND_OP_ADD,
VK_BLEND_ONE, VK_BLEND_ZERO, VK_BLEND_OP_ADD,
0xf,
};
VkPipelineColorBlendStateCreateInfo cb = {
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, NULL,
false, false, false, VK_LOGIC_OP_NOOP,
1, &attState,
{ 1.0f, 1.0f, 1.0f, 1.0f }
};
VkDynamicState dynstates[] = { VK_DYNAMIC_STATE_VIEWPORT };
VkPipelineDynamicStateCreateInfo dyn = {
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, NULL,
ARRAY_COUNT(dynstates), dynstates,
};
VkRenderPass rp; // compatible render pass
{
VkAttachmentDescription attDesc[] = {
{
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, NULL,
VK_FORMAT_R8G8B8A8_UNORM, 1,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
},
{
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION, NULL,
VK_FORMAT_D32_SFLOAT, 1,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
},
};
VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
VkSubpassDescription sub = {
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION, NULL,
VK_PIPELINE_BIND_POINT_GRAPHICS, 0,
0, NULL, // inputs
1, &attRef, // color
NULL, // resolve
{ 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }, // depth-stencil
0, NULL, // preserve
};
VkRenderPassCreateInfo rpinfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL,
2, attDesc,
1, &sub,
0, NULL, // dependencies
};
vt->CreateRenderPass(Unwrap(m_Device), &rpinfo, &rp);
}
VkGraphicsPipelineCreateInfo pipeInfo = {
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, NULL,
2, stages,
&vi,
&ia,
NULL, // tess
&vp,
&rs,
&msaa,
&ds,
&cb,
&dyn,
0, // flags
Unwrap(m_MeshPipeLayout),
rp,
0, // sub pass
VK_NULL_HANDLE, // base pipeline handle
0, // base pipeline index
};
// wireframe pipeline
stages[0].shader = Unwrap(m_MeshShaders[0]);
stages[0].stage = VK_SHADER_STAGE_VERTEX;
stages[1].shader = Unwrap(m_MeshShaders[2]);
stages[1].stage = VK_SHADER_STAGE_FRAGMENT;
rs.fillMode = VK_FILL_MODE_WIREFRAME;
rs.lineWidth = 1.0f;
ds.depthTestEnable = false;
vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, &cache.pipes[eShade_None]);
RDCASSERT(vkr == VK_SUCCESS);
// solid shading pipeline
rs.fillMode = VK_FILL_MODE_SOLID;
ds.depthTestEnable = true;
vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, &cache.pipes[eShade_Solid]);
RDCASSERT(vkr == VK_SUCCESS);
if(secondary.buf != ResourceId())
{
// pull secondary information from second vertex buffer
vertAttrs[1].binding = 1;
vertAttrs[1].format = secondaryFmt;
RDCASSERT(secondaryFmt != VK_FORMAT_UNDEFINED);
vi.bindingCount = 2;
vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, &cache.pipes[eShade_Secondary]);
RDCASSERT(vkr == VK_SUCCESS);
}
// seems to not be working at the moment, just make a solid-shaded pipeline
vertAttrs[1].binding = 0;
vi.bindingCount = 1;
#if 1
vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, &cache.pipes[eShade_Lit]);
RDCASSERT(vkr == VK_SUCCESS);
#else
// flat lit pipeline, needs geometry shader to calculate face normals
stages[0].shader = Unwrap(m_MeshShaders[0]);
stages[0].stage = VK_SHADER_STAGE_VERTEX;
stages[1].shader = Unwrap(m_MeshShaders[1]);
stages[1].stage = VK_SHADER_STAGE_GEOMETRY;
stages[2].shader = Unwrap(m_MeshShaders[2]);
stages[2].stage = VK_SHADER_STAGE_FRAGMENT;
vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, &cache.pipes[eShade_Lit]);
RDCASSERT(vkr == VK_SUCCESS);
#endif
for(uint32_t i=0; i < eShade_Count; i++)
if(cache.pipes[i] != VK_NULL_HANDLE)
GetResourceManager()->WrapResource(Unwrap(m_Device), cache.pipes[i]);
vt->DestroyRenderPass(Unwrap(m_Device), rp);
return cache;
}
+15 -1
View File
@@ -38,6 +38,11 @@ struct TextPrintState
int32_t w, h;
};
struct MeshDisplayPipelines
{
VkPipeline pipes[eShade_Count];
};
class VulkanResourceManager;
class VulkanDebugManager
@@ -137,9 +142,16 @@ class VulkanDebugManager
VkRenderPass m_OverlayNoDepthRP;
VkExtent2D m_OverlayDim;
VkDeviceSize m_OverlayMemSize;
VkDescriptorSetLayout m_MeshDescSetLayout;
VkPipelineLayout m_MeshPipeLayout;
VkDescriptorSet m_MeshDescSet;
GPUBuffer m_MeshUBO;
VkShader m_MeshShaders[3];
VkShaderModule m_MeshModules[3];
MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary);
private:
void InitDebugData();
void ShutdownDebugData();
@@ -149,12 +161,14 @@ class VulkanDebugManager
void PatchFixedColShader(VkShaderModule &mod, VkShader &shad, float col[4]);
void RenderTextInternal(const TextPrintState &textstate, float x, float y, const char *text);
void MakeGraphicsPipelineInfo( VkGraphicsPipelineCreateInfo &pipeCreateInfo, ResourceId pipeline );
void MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &pipeCreateInfo, ResourceId pipeline);
static const int FONT_TEX_WIDTH = 256;
static const int FONT_TEX_HEIGHT = 128;
float m_FontCharAspect;
float m_FontCharSize;
map<uint64_t, MeshDisplayPipelines> m_CachedMeshPipelines;
WrappedVulkan *m_pDriver;
VulkanResourceManager *m_ResourceManager;
+197 -2
View File
@@ -26,6 +26,9 @@
#include "vk_core.h"
#include "vk_debug.h"
#include "vk_resources.h"
#include "maths/matrix.h"
#include "maths/camera.h"
#include "maths/formatpacking.h"
#include "serialise/string_utils.h"
@@ -62,6 +65,21 @@ struct genericuniforms
Vec4f Color;
};
struct meshuniforms
{
Matrix4f mvp;
Matrix4f invProj;
Vec4f color;
uint32_t displayFormat;
uint32_t homogenousInput;
Vec2f pointSpriteSize;
};
#define MESHDISPLAY_SOLID 0x1
#define MESHDISPLAY_FACELIT 0x2
#define MESHDISPLAY_SECONDARY 0x3
#define MESHDISPLAY_SECONDARY_ALPHA 0x4
VulkanReplay::OutputWindow::OutputWindow() : wnd(NULL_WND_HANDLE), width(0), height(0),
dsimg(VK_NULL_HANDLE), dsmem(VK_NULL_HANDLE)
{
@@ -1217,10 +1235,187 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay o
{
return GetDebugManager()->RenderOverlay(texid, overlay, frameID, eventID, passEvents);
}
void VulkanReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshFormat> &secondaryDraws, MeshDisplay cfg)
{
VULKANNOTIMP("RenderMesh");
if(cfg.position.buf == ResourceId())
return;
auto it = m_OutputWindows.find(m_ActiveWinID);
if(m_ActiveWinID == 0 || it == m_OutputWindows.end())
return;
OutputWindow &outw = it->second;
VkDevice dev = m_pDriver->GetDev();
VkCmdBuffer cmd = m_pDriver->GetNextCmd();
const VkLayerDispatchTable *vt = ObjDisp(dev);
VkResult vkr = VK_SUCCESS;
VkCmdBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, NULL, VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT };
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
VkClearValue clearval = {0};
VkRenderPassBeginInfo rpbegin = {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL,
Unwrap(outw.rpdepth), Unwrap(outw.fbdepth),
{ { 0, 0, }, { m_DebugWidth, m_DebugHeight } },
1, &clearval,
};
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE);
VkViewport viewport = { 0.0f, 0.0f, (float)m_DebugWidth, (float)m_DebugHeight, 0.0f, 1.0f };
vt->CmdSetViewport(Unwrap(cmd), 1, &viewport);
Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(m_DebugWidth)/float(m_DebugHeight));
Matrix4f InvProj = projMat.Inverse();
Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity();
Matrix4f ModelViewProj = projMat.Mul(camMat);
Matrix4f guessProjInv;
if(cfg.position.unproject)
{
// 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(cfg.ortho)
{
guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane);
}
guessProjInv = guessProj.Inverse();
ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv));
}
RDCASSERT(secondaryDraws.empty());
MeshDisplayPipelines cache = GetDebugManager()->CacheMeshDisplayPipelines(cfg.position, cfg.second);
if(cfg.position.buf != ResourceId())
{
VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle<VkBuffer>(cfg.position.buf);
VkDeviceSize offs = cfg.position.offset;
vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(vb), &offs);
}
if(cfg.second.buf != ResourceId())
{
VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle<VkBuffer>(cfg.second.buf);
VkDeviceSize offs = cfg.second.offset;
vt->CmdBindVertexBuffers(Unwrap(cmd), 1, 1, UnwrapPtr(vb), &offs);
}
// can't support secondary shading without a buffer - no pipeline will have been created
if(cfg.solidShadeMode == eShade_Secondary && cfg.second.buf == ResourceId())
cfg.solidShadeMode = eShade_None;
// solid render
if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList)
{
VkPipeline pipe = cache.pipes[cfg.solidShadeMode];
uint32_t uboOffs = 0;
meshuniforms *data = (meshuniforms *)GetDebugManager()->m_MeshUBO.Map(vt, dev, &uboOffs);
if(cfg.solidShadeMode == eShade_Lit)
data->invProj = projMat.Inverse();
data->mvp = ModelViewProj;
data->color = Vec4f(0.8f, 0.8f, 0.0f, 1.0f);
data->homogenousInput = cfg.position.unproject;
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
data->displayFormat = (uint32_t)cfg.solidShadeMode;
if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha)
data->displayFormat = MESHDISPLAY_SECONDARY_ALPHA;
GetDebugManager()->m_MeshUBO.Unmap(vt, dev);
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout),
0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs);
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
if(cfg.position.idxByteWidth)
{
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
if(cfg.position.idxByteWidth == 4)
idxtype = VK_INDEX_TYPE_UINT32;
if(cfg.position.idxbuf != ResourceId())
{
VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle<VkBuffer>(cfg.position.idxbuf);
vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), cfg.position.idxoffs, idxtype);
}
vt->CmdDrawIndexed(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0, 0);
}
else
{
vt->CmdDraw(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0);
}
}
// wireframe render
if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || cfg.position.topo >= eTopology_PatchList)
{
Vec4f wireCol = Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
if(!secondaryDraws.empty())
{
wireCol.x = cfg.currentMeshColour.x;
wireCol.y = cfg.currentMeshColour.y;
wireCol.z = cfg.currentMeshColour.z;
}
uint32_t uboOffs = 0;
meshuniforms *data = (meshuniforms *)GetDebugManager()->m_MeshUBO.Map(vt, dev, &uboOffs);
data->mvp = ModelViewProj;
data->color = wireCol;
data->displayFormat = (uint32_t)eShade_Solid;
data->homogenousInput = cfg.position.unproject;
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
GetDebugManager()->m_MeshUBO.Unmap(vt, dev);
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout),
0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs);
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[eShade_None]));
if(cfg.position.idxByteWidth)
{
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
if(cfg.position.idxByteWidth == 4)
idxtype = VK_INDEX_TYPE_UINT32;
if(cfg.position.idxbuf != ResourceId())
{
VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle<VkBuffer>(cfg.position.idxbuf);
vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), cfg.position.idxoffs, idxtype);
}
vt->CmdDrawIndexed(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0, 0);
}
else
{
vt->CmdDraw(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0);
}
}
vt->CmdEndRenderPass(Unwrap(cmd));
vkr = vt->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
}
bool VulkanReplay::CheckResizeOutputWindow(uint64_t id)
+1 -1
View File
@@ -2177,7 +2177,7 @@ namespace renderdocui.Windows
private void render_Paint(object sender, PaintEventArgs e)
{
if (m_Core.CurVulkanPipelineState != null || m_Output == null || m_Core.Renderer == null)
if (m_Output == null || m_Core.Renderer == null)
{
e.Graphics.Clear(Color.Black);
return;