Skip to content

Commit

Permalink
Continue vertex viewer
Browse files Browse the repository at this point in the history
- Add arcball cam control
- Add solid triangle shading
- Do first groundwork for vertex shader debugging
- Also cleanup workstack todos
  • Loading branch information
nyorain committed May 16, 2023
1 parent 5fd7d8c commit 0c6abcd
Show file tree
Hide file tree
Showing 14 changed files with 554 additions and 131 deletions.
37 changes: 37 additions & 0 deletions docs/own/done.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
- [x] Clean up DeviceHandle (?)
- [~] In some handles we don't need the DeviceHandle::dev pointer, e.g. imageView etc.
Remove it?
{Hm, we might need it in imageView, e.g. when the image was destroyed.
And it does not hurt. Disregarding that idea}
- [x] Instead use DeviceHandle<ObjectType>, allowing to remove objectType from Handle
In its destructor, pass the objectType to the destruction notification
{NOTE: fixed in a different way, objectType no longer stored in handle}
- [x] full commandbuffer/record timings.
- [x] for this we need proper prefix-matching support in CommandHook. WIP
- [x] integration test: depend on meson subproject for mock driver
And don't hardcode my own env path
- [x] also make sure we don't need the layer to be installed
but use the latest built version.
pass build path in via meson config header file?
- [x] add manual meson dependencies from integration test to used layer
and mock driver
- [x] Clean up Handle (?)
- [x] remove objectType from Handle
- [~] could remove 'name' from Handle, instead use HashMap in device?
not sure if this is a good idea though. Probably not for now.
our main usecase after all is application debugging where we
expect most handles to have a name -> embedding in object makes sense.
{NOPE, we don't want this atm}
- [x] write a simple test just creating an instance and device with
vil and the validation layer. And check that we can execute that on
CI as well
- [x] got the null mock driver to work.
- [x] rename main branch to main
- [x] rework gui device locking. We should be able to execute draw/uploadDraw
without holding a lock THE WHOLE TIME. Only lock it where it's really
needed
- [x] descriptorSet should not derive from DeviceHandle, does not need refRecords
- [x] Maybe rename DeviceHandle to RecordReferenced or something?
- split up notifyDestruction functionality in DeviceObserved or something,
many classes (like Fence, CommandPool etc) don't need refRecords I guess
{This was completely reworked, refRecords got killed}
- [x] fix command viewer update when nothing is selected
- [x] fix resource viewer when switching handle types
currently does not select the right handle then (e.g.
Expand Down
3 changes: 3 additions & 0 deletions docs/own/ideas.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ be possible or useful in the end.
don't hook anything. Instead just insert our own command buffers
(before and after) into the submission stream where we write out timestamps

- (low prio) add also full batch (e.g. vkQueueSubmit/vkQueueBindSparse) timings?
Would require custom cb recording on our side

- When clicking on a flag, extension name or something, link to vulkan api spec
regarding that item? Not sure how easy to do.
Also e.g. for enabled extensions, features, etc.
Expand Down
2 changes: 1 addition & 1 deletion docs/own/serialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class CompletedHookSerializer {
std::vector<Buffer*> buffers;
std::vector<ImageView*> imageViews;
std::vector<BufferView*> bufferViews;
std::vector<DescriptorLayout*> dsLayouts;
std::vector<DescriptorSetLayout*> dsLayouts;
std::vector<PipelineLayout*> pipeLayouts;
std::vector<GraphicsPipeline*> gfxPipes;
std::vector<ComputePipeline*> computePipes;
Expand Down
97 changes: 42 additions & 55 deletions docs/own/workstack.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,52 @@
- [x] Add imgui list clipper to tables and show *whole* captured data again
- [ ] figure out upside-down issue with iro. Flip y based on used viewport?
I guess other games just flip the viewport, that's why they did not need it
{partially solved}
- [ ] add "y-up-mode" to options. Can be any of the 3-axis-plus-directions
by default for vertex input: y-up is y-up (although many models have z-up)
default for vertex output: y-down is y-up (except when viewport is negative,
then y-up is y-up).
- [x] Make vertices selectable
- [ ] Draw selected vertex
- [ ] Allow to select specific vertex (either input or output) in debugger
- [ ] Make vertices selectable. I.e. via mouse click in debugger
- [ ] Draw selected vertex via point
- [x] Allow to select specific vertex (either input or output) in debugger
- [ ] Allow to choose display style
- [ ] solid (single-colored or shaded) vs wireframe
- [x] solid (single-colored or shaded) vs wireframe
- [x] add simple triangle-normal-based lighting (sh9 based or something)
- [ ] color using another input.
- [x] allow not clearing background of canvas, draw on blurred ui directly?
looks kinda neat as well. Should probably be checkbox
- [ ] allow to render wireframe *and* shaded view.
- [ ] some more shading options? Allow to select a hdri and roughness?
- [ ] allow to modify canvas size. I.e. make vertically resizeable
- [ ] Explicitly allow to modify what is used as position input?
- [ ] (low prio) Explicitly allow to modify what is used as position input?
- [ ] Fix Recenter for top-level AccelStruct view
- [ ] Allow to explicitly toggle between perspective and non-perspective projection?
- [ ] make perspective heuristic more robust, caused issues in past.
- [ ] Add arcball camera controls (allow both or allow to toggle via ui)
- [x] Add arcball camera controls (allow both or allow to toggle via ui)
- [ ] later: Make vertex list properly page-able, allow to see *everything*
without random size restrictions
- [ ] For this to properly work with vertex input, we might need an indirect
copy (based on indirect draw command and indices.
See node 1749
- [ ] For this to properly work with xfb (vertex output), we potentially
need to implement draw-call splitting. Which will be a pain in the ass.
- Allow to open where left off?
Would require some serialization of frames/commands/resources.
Also, would have to completely rework matching to work with those loaded up
resources/commands :/ We could *never* compare for equality.
But we probably explicitly want that in some cases, normally. So matching
would need additional options.
- Add vertex shaders to shader debugger
- [ ] copy vertex buffers in that case in updateHooks
- [ ] set up vertex inputs from vertex buffers
Also set up stuff like VertexIndex, InstanceIndex etc.
All the builtin inputs
- [ ] handle special vertex shader variables
- [ ] important optimization: only copy the resources statically accessed by shader
- Really hard-match on vertexCount/indexCount for draw commands?
See e.g. debug drawing in iro, adding control points to a spline will
currently unselect the draw command. Not expected behavior.
Maybe just match with *really* high weight.
- [ ] shader debugger: add dropdown for all embdeeded sources.
- [ ] implement sync tracking
- [ ] and fix full sync
Expand All @@ -55,7 +71,27 @@
- [ ] investigate 255-overflow-like bug in shader debugger when
resizing
- [ ] fix bad vk::name impls. E.g. for DescriptorSetLayout, the stages
- [ ] Add "Jump to End/Begin" buttons in begin/end commands.
only show them in brokenLabel display mode?
- [ ] figure out why integration test crashes on CI.
execute with valgrind?
meson test --wrapper 'valgrind --leak-check=full --error-exitcode=1' --print-errorlogs
-> no idea. Crash inside the vulkan loader that i can't reproduce locally
Maybe just execute on windows? seems to work there.
- [ ] document what to do when descriptors are not available when
clicking new record in UI. Implement prototype for
always-ds-cow-on-submission? Should probably be toggleable.
- [ ] clean up special descriptorSet handling in handles.cpp
- [ ] write integration test for creating ds, updating it with imageView, destroying
imageView and then using ds in submission (might need partially_bound
or something I guess)
- [ ] Don't always alloc/free in LinAllocator.
Enable our global memory block cache thingy?

low prio:
- [ ] cleanup imageToBuffer implementation
{NOTE: a lot better already, mainly just missing the blit implementation.
low prio now. See copy.cpp `enum class CopyMethod`}
- [x] for most formats (that we can read on cpu) we probably just
want CmdCopyImageToBuffer
- [ ] some formats can't be easily read on cpu. We want support on the
Expand All @@ -71,59 +107,10 @@
(e.g. rgba8unorm, rgba16Sfloat, rgba32Sflot, r32Uint etc)
(3) if nothing else works, fall back to our old terrible
copy to vec4[]-storage buffer solution?
- [x] full commandbuffer/record timings.
- [x] for this we need proper prefix-matching support in CommandHook. WIP
- [ ] also full batch timings?
- [ ] Add "Jump to End/Begin" buttons in begin/end commands.
only show them in brokenLabel display mode?
- [x] integration test: depend on meson subproject for mock driver
And don't hardcode my own env path
- [x] also make sure we don't need the layer to be installed
but use the latest built version.
pass build path in via meson config header file?
- [x] add manual meson dependencies from integration test to used layer
and mock driver
- [ ] figure out why integration test crashes on CI.
execute with valgrind?
meson test --wrapper 'valgrind --leak-check=full --error-exitcode=1' --print-errorlogs
-> no idea. Crash inside the vulkan loader that i can't reproduce locally
Maybe just execute on windows? seems to work there.
- [ ] document what to do when descriptors are not available when
clicking new record in UI. Implement prototype for
always-ds-cow-on-submission? Should probably be toggleable.
- [ ] clean up special descriptorSet handling in handles.cpp
- rework gui device locking. We should be able to execute draw/uploadDraw
without holding a lock THE WHOLE TIME. Only lock it where it's really
needed
- [x] got the null mock driver to work.
[x] Now write a simple test just creating an instance and device with
vil and the validation layer. And check that we can execute that on
CI as well
- [ ] write test for creating ds, updating it with imageView, destroying
imageView and then using ds in submission (might need partially_bound
or something I guess)
- [x] rename main branch to main
- [ ] Don't always alloc/free in LinAllocator.
Enable our global memory block cache thingy?

- look into found doom performance hotpaths
- Improve QueuePresent timing
- analyze other issues, tracy file on D:
- Clean up Handle (?)
- remove objectType from Handle
- could remove 'name' from Handle, instead use HashMap in device?
not sure if this is a good idea though. Probably not for now.
our main usecase after all is application debugging where we
expect most handles to have a name -> embedding in object makes sense.
- Clean up DeviceHandle (?)
- In many handles we don't need the 'dev' pointer, e.g. descriptorSet,
imageView etc. Remove it?
- Instead use DeviceHandle<ObjectType>, allowing to remove objectType from Handle
In its destructor, pass the objectType to the destruction notification
- descriptorSet should not derive from DeviceHandle, does not need refRecords
- Maybe rename DeviceHandle to RecordReferenced or something?
- split up notifyDestruction functionality in DeviceObserved or something,
many classes (like Fence, CommandPool etc) don't need refRecords I guess
- check if we can get the null vulkan driver running and execute tests
- just create images/buffers with various parameters and record submissions,
recording every command at least once.
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ pch = []
if not with_win32 or not with_tracy
# TODO: fix. We want to use pch unless we are frequently editing shaders
# See https://github.com/mesonbuild/meson/issues/10882
pch = 'src/pch.hpp'
# pch = 'src/pch.hpp'
endif

lib_spvm = static_library(
Expand Down
8 changes: 8 additions & 0 deletions src/command/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ struct DrawCmdBase : StateCmdBase {
void displayGrahpicsState(Gui& gui, bool indices) const;
Matcher doMatch(const DrawCmdBase& cmd, bool indexed) const;

virtual bool isIndexed() const = 0;

const DescriptorState& boundDescriptors() const override { return state; }
const Pipeline* boundPipe() const override { return state.pipe; }
const PushConstantData& boundPushConstants() const override { return pushConstants; }
Expand All @@ -408,6 +410,7 @@ struct DrawCmd final : DrawCmdBase {
void record(const Device&, VkCommandBuffer, u32) const override;
Matcher match(const Command&) const override;
void visit(CommandVisitor& v) const override { doVisit(v, *this); }
bool isIndexed() const override { return false; }
};

struct DrawIndirectCmd final : DrawCmdBase {
Expand All @@ -427,6 +430,7 @@ struct DrawIndirectCmd final : DrawCmdBase {
void record(const Device&, VkCommandBuffer, u32) const override;
Matcher match(const Command&) const override;
void visit(CommandVisitor& v) const override { doVisit(v, *this); }
bool isIndexed() const override { return indexed; }
};

struct DrawIndexedCmd final : DrawCmdBase {
Expand All @@ -444,6 +448,7 @@ struct DrawIndexedCmd final : DrawCmdBase {
void record(const Device&, VkCommandBuffer, u32) const override;
Matcher match(const Command&) const override;
void visit(CommandVisitor& v) const override { doVisit(v, *this); }
bool isIndexed() const override { return true; }
};

struct DrawIndirectCountCmd final : DrawCmdBase {
Expand All @@ -465,6 +470,7 @@ struct DrawIndirectCountCmd final : DrawCmdBase {
void record(const Device&, VkCommandBuffer, u32) const override;
Matcher match(const Command&) const override;
void visit(CommandVisitor& v) const override { doVisit(v, *this); }
bool isIndexed() const override { return indexed; }
};

struct DrawMultiCmd final : DrawCmdBase {
Expand All @@ -481,6 +487,7 @@ struct DrawMultiCmd final : DrawCmdBase {
void record(const Device&, VkCommandBuffer, u32) const override;
Matcher match(const Command&) const override;
void visit(CommandVisitor& v) const override { doVisit(v, *this); }
bool isIndexed() const override { return false; }
};

struct DrawMultiIndexedCmd final : DrawCmdBase {
Expand All @@ -498,6 +505,7 @@ struct DrawMultiIndexedCmd final : DrawCmdBase {
void record(const Device&, VkCommandBuffer, u32) const override;
Matcher match(const Command&) const override;
void visit(CommandVisitor& v) const override { doVisit(v, *this); }
bool isIndexed() const override { return true; }
};

struct BindVertexBuffersCmd final : Command {
Expand Down
1 change: 1 addition & 0 deletions src/data/frustum.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ layout(push_constant, row_major) uniform PCR {
layout(offset = 64) float near;
layout(offset = 68) float far;
layout(offset = 72) uint useW;
// NOTE: offset = 76 already used by fragment shader.
} pcr;

void main() {
Expand Down
62 changes: 61 additions & 1 deletion src/data/vertices.frag
Original file line number Diff line number Diff line change
@@ -1,7 +1,67 @@
#version 450 core

layout(location = 0) in vec3 inPos;
layout(location = 0) out vec4 outFragColor;

layout(push_constant, row_major) uniform PCR {
layout(offset = 76) bool shade;
} pcr;

// 9-band spherical harmonics
float sh0(vec3 nrm) { return 0.282095; }
float sh1(vec3 nrm) { return 0.488603 * nrm.y; }
float sh2(vec3 nrm) { return 0.488603 * nrm.z; }
float sh3(vec3 nrm) { return 0.488603 * nrm.x; }
float sh4(vec3 nrm) { return 1.092548 * nrm.x * nrm.y; }
float sh5(vec3 nrm) { return 1.092548 * nrm.y * nrm.z; }
float sh6(vec3 nrm) { return 0.315392 * (3.0 * nrm.z * nrm.z - 1.0); }
float sh7(vec3 nrm) { return 1.092548 * nrm.x * nrm.z; }
float sh8(vec3 nrm) { return 0.546274 * (nrm.x * nrm.x - nrm.y * nrm.y); }

vec3 evalSH(vec3 nrm, vec3 coeffs[9]) {
return coeffs[0] * sh0(nrm) +
coeffs[1] * sh1(nrm) +
coeffs[2] * sh2(nrm) +
coeffs[3] * sh3(nrm) +
coeffs[4] * sh4(nrm) +
coeffs[5] * sh5(nrm) +
coeffs[6] * sh6(nrm) +
coeffs[7] * sh7(nrm) +
coeffs[8] * sh8(nrm);
}

// tried to maximize lighting differences, looks terrible :)
// vec3 shCoeffs[9] = {
// vec3(1.0),
// vec3(1.0, 0.3, 0.3),
// vec3(0.3, 1.0, 0.3),
// vec3(0.3, 0.3, 1.0),
// vec3(1.0, 0.3, 1.0),
// vec3(0.3, 1.0, 1.0),
// vec3(1.0, 1.0, 0.3),
// vec3(1.0, 1.0, 1.0),
// vec3(0.0, 0.0, 0.0)
// };

// taken from convolved sunset atmosphere in iro
vec3 shCoeffs[9] = {
vec3(1.0),
vec3(0.257, 0.315, 0.448),
vec3(-0.123, -0.073, -0.0322),
vec3(-0.538, -0.319, -0.141),
vec3(-0.0652, -0.0425, -0.0243),
vec3(-0.0149, -0.00975, -0.00559),
vec3(-0.0703, -0.0313, -0.0103),
vec3(0.0937, 0.0606, 0.0321),
vec3(0.265, 0.195, 0.114),
};

void main() {
outFragColor = vec4(1.0);
if(pcr.shade) {
vec3 n = -normalize(cross(dFdx(inPos), dFdy(inPos)));
vec3 col = max(evalSH(n, shCoeffs), vec3(0.0));
outFragColor = vec4(col, 1.0);
} else {
outFragColor = vec4(1.0);
}
}
4 changes: 4 additions & 0 deletions src/data/vertices.vert
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#version 450 core

layout(location = 0) in vec4 inPos;
layout(location = 0) out vec3 outPos;

// layout(set = 0, binding = 0, row_major) uniform CamUbo {
layout(push_constant, row_major) uniform PCR {
layout(offset = 0) mat4 viewProjMtx;
layout(offset = 64) bool useW;
layout(offset = 68) float scale;
layout(offset = 72) bool flipY;
// NOTE: offset = 76 already used by fragment shader.
} pcr;

void main() {
Expand All @@ -16,6 +18,8 @@ void main() {
pos.y *= -1;
}
pos *= pcr.scale;
outPos = pos;

gl_Position = pcr.viewProjMtx * vec4(pos, 1.0);
}

Loading

0 comments on commit 0c6abcd

Please sign in to comment.