Add demo tests for annotations

This commit is contained in:
baldurk
2026-01-28 14:42:11 +00:00
parent 352b88b344
commit 965d1c9568
15 changed files with 1235 additions and 0 deletions
+2
View File
@@ -101,6 +101,7 @@ set(VULKAN_SRC
vk/vk_test.cpp
vk/vk_test.h
vk/vk_adv_cbuffer_zoo.cpp
vk/vk_annotations.cpp
vk/vk_blend.cpp
vk/vk_buffer_truncation.cpp
vk/vk_cbuffer_zoo.cpp
@@ -174,6 +175,7 @@ set(OPENGL_SRC
3rdparty/glad/glad.c
gl/gl_test.cpp
gl/gl_test.h
gl/gl_annotations.cpp
gl/gl_buffer_resizing.cpp
gl/gl_buffer_spam.cpp
gl/gl_buffer_truncation.cpp
+191
View File
@@ -0,0 +1,191 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2023-2026 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.
******************************************************************************/
#include "d3d11_test.h"
RD_TEST(D3D11_Annotations, D3D11GraphicsTest)
{
static constexpr const char *Description = "Test annotations via the D3D11 API.";
int main()
{
// initialise, create window, create device, etc
if(!Init())
return 3;
ID3D11Texture2DPtr img = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, 4, 4).RTV();
ID3D11RenderTargetViewPtr imgRTV = MakeRTV(img);
SetDebugName(img, "Annotated Image");
SetDebugName(DefaultTriVB, "Vertex Buffer");
// cache the device pointer we pass in
void *d = dev;
if(rdoc)
{
rdoc->SetObjectAnnotation(d, img, "basic.bool", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
rdoc->SetObjectAnnotation(d, img, "basic.int32", eRENDERDOC_Int32, 0, RDAnnotationHelper(-3));
rdoc->SetObjectAnnotation(d, img, "basic.int64", eRENDERDOC_Int64, 0,
RDAnnotationHelper(-3000000000000LL));
rdoc->SetObjectAnnotation(d, img, "basic.uint32", eRENDERDOC_UInt32, 0, RDAnnotationHelper(3));
rdoc->SetObjectAnnotation(d, img, "basic.uint64", eRENDERDOC_UInt64, 0,
RDAnnotationHelper(3000000000000LL));
rdoc->SetObjectAnnotation(d, img, "basic.float", eRENDERDOC_Float, 0,
RDAnnotationHelper(3.25f));
rdoc->SetObjectAnnotation(d, img, "basic.double", eRENDERDOC_Double, 0,
RDAnnotationHelper(3.25000000001));
rdoc->SetObjectAnnotation(d, img, "basic.string", eRENDERDOC_String, 0,
RDAnnotationHelper("Hello, World!"));
RENDERDOC_AnnotationValue val;
val.apiObject = (void *)DefaultTriVB;
rdoc->SetObjectAnnotation(d, img, "basic.object", eRENDERDOC_APIObject, 0, &val);
rdoc->SetObjectAnnotation(d, img, "basic.object.__offset", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(64));
rdoc->SetObjectAnnotation(d, img, "basic.object.__size", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(32));
rdoc->SetObjectAnnotation(d, img, "basic.object.__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float4 vertex_data;"));
rdoc->SetObjectAnnotation(d, DefaultTriVB, "__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float3 pos;\n"
"float4 col;\n"
"float2 uv;\n"));
val = {};
val.vector.float32[0] = 1.1f;
val.vector.float32[1] = 2.2f;
val.vector.float32[2] = 3.3f;
val.vector.float32[3] = 4.4f; // should be ignored
rdoc->SetObjectAnnotation(d, img, "basic.vec3", eRENDERDOC_Float, 3, &val);
rdoc->SetObjectAnnotation(d, img, "deep.nested.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-4));
rdoc->SetObjectAnnotation(d, img, "deep.nested.path.to.annotation2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-5));
rdoc->SetObjectAnnotation(d, img, "deep.alternate.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-6));
// deleted paths should not stay around
rdoc->SetObjectAnnotation(d, img, "deleteme", eRENDERDOC_Int32, 0, RDAnnotationHelper(-7));
rdoc->SetObjectAnnotation(d, img, "deleteme", eRENDERDOC_Empty, 0, NULL);
rdoc->SetObjectAnnotation(d, img, "path.deleted.by.parent", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-8));
rdoc->SetObjectAnnotation(d, img, "path.deleted.by.parent2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-9));
// this will delete all children. `path` will still exist, but will be empty
rdoc->SetObjectAnnotation(d, img, "path.deleted", eRENDERDOC_Empty, 0, NULL);
}
while(Running())
{
if(rdoc)
{
// queue annotations don't exist in D3D11, but we set these to share the same test code.
// we specify the immediate context here specifically. Later we'll use NULL (which is equivalent on D3D11)
if(curFrame == 2)
rdoc->SetCommandAnnotation(d, ctx, "queue.too_old", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, ctx, "queue.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, ctx, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(9999));
rdoc->SetCommandAnnotation(d, ctx, "command.inherited", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1234));
rdoc->SetCommandAnnotation(d, ctx, "command.deleted", eRENDERDOC_Int32, 0,
RDAnnotationHelper(50));
}
setMarker("Start");
if(rdoc)
{
rdoc->SetCommandAnnotation(d, NULL, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(2000));
rdoc->SetCommandAnnotation(d, NULL, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-3333));
rdoc->SetCommandAnnotation(d, NULL, "command.new", eRENDERDOC_Int32, 0,
RDAnnotationHelper(3333));
rdoc->SetCommandAnnotation(d, NULL, "command.deleted", eRENDERDOC_Empty, 0, NULL);
}
setMarker("Initial");
ClearRenderTargetView(bbRTV, {0.2f, 0.2f, 0.2f, 1.0f});
ClearRenderTargetView(imgRTV, {0.2f, 0.2f, 0.2f, 1.0f});
if(rdoc)
rdoc->SetCommandAnnotation(d, NULL, "command.new", eRENDERDOC_Float, 0,
RDAnnotationHelper(1.75f));
IASetVertexBuffer(DefaultTriVB, sizeof(DefaultA2V), 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->IASetInputLayout(defaultLayout);
ctx->VSSetShader(DefaultTriVS, NULL, 0);
ctx->PSSetShader(DefaultTriPS, NULL, 0);
RSSetViewport({0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f});
ctx->OMSetRenderTargets(1, &bbRTV.GetInterfacePtr(), NULL);
setMarker("Pre-Draw");
// deleting a value is fine if it's re-added before the next event
if(rdoc)
{
rdoc->SetCommandAnnotation(d, NULL, "new.value", eRENDERDOC_Empty, 0, NULL);
rdoc->SetCommandAnnotation(d, NULL, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(4000));
}
setMarker("Draw 1");
ctx->Draw(3, 0);
RSSetViewport({0.0f, 0.0f, (float)screenWidth / 2.0f, (float)screenHeight / 2.0f, 0.0f, 1.0f});
setMarker("Draw 2");
ctx->Draw(3, 0);
Present();
}
return 0;
}
};
REGISTER_TEST();
+205
View File
@@ -0,0 +1,205 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2023-2026 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.
******************************************************************************/
#include "d3d12_test.h"
RD_TEST(D3D12_Annotations, D3D12GraphicsTest)
{
static constexpr const char *Description = "Test annotations via the D3D12 API.";
int main()
{
// initialise, create window, create device, etc
if(!Init())
return 3;
ID3D12ResourcePtr img = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, 4, 4)
.RTV()
.InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET);
img->SetName(L"Annotated Image");
DefaultTriVB->SetName(L"Vertex Buffer");
// cache the device pointer we pass in
void *d = dev;
if(rdoc)
{
rdoc->SetObjectAnnotation(d, img, "basic.bool", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
rdoc->SetObjectAnnotation(d, img, "basic.int32", eRENDERDOC_Int32, 0, RDAnnotationHelper(-3));
rdoc->SetObjectAnnotation(d, img, "basic.int64", eRENDERDOC_Int64, 0,
RDAnnotationHelper(-3000000000000LL));
rdoc->SetObjectAnnotation(d, img, "basic.uint32", eRENDERDOC_UInt32, 0, RDAnnotationHelper(3));
rdoc->SetObjectAnnotation(d, img, "basic.uint64", eRENDERDOC_UInt64, 0,
RDAnnotationHelper(3000000000000LL));
rdoc->SetObjectAnnotation(d, img, "basic.float", eRENDERDOC_Float, 0,
RDAnnotationHelper(3.25f));
rdoc->SetObjectAnnotation(d, img, "basic.double", eRENDERDOC_Double, 0,
RDAnnotationHelper(3.25000000001));
rdoc->SetObjectAnnotation(d, img, "basic.string", eRENDERDOC_String, 0,
RDAnnotationHelper("Hello, World!"));
RENDERDOC_AnnotationValue val;
val.apiObject = (void *)DefaultTriVB;
rdoc->SetObjectAnnotation(d, img, "basic.object", eRENDERDOC_APIObject, 0, &val);
rdoc->SetObjectAnnotation(d, img, "basic.object.__offset", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(64));
rdoc->SetObjectAnnotation(d, img, "basic.object.__size", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(32));
rdoc->SetObjectAnnotation(d, img, "basic.object.__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float4 vertex_data;"));
rdoc->SetObjectAnnotation(d, DefaultTriVB, "__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float3 pos;\n"
"float4 col;\n"
"float2 uv;\n"));
val = {};
val.vector.float32[0] = 1.1f;
val.vector.float32[1] = 2.2f;
val.vector.float32[2] = 3.3f;
val.vector.float32[3] = 4.4f; // should be ignored
rdoc->SetObjectAnnotation(d, img, "basic.vec3", eRENDERDOC_Float, 3, &val);
rdoc->SetObjectAnnotation(d, img, "deep.nested.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-4));
rdoc->SetObjectAnnotation(d, img, "deep.nested.path.to.annotation2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-5));
rdoc->SetObjectAnnotation(d, img, "deep.alternate.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-6));
// deleted paths should not stay around
rdoc->SetObjectAnnotation(d, img, "deleteme", eRENDERDOC_Int32, 0, RDAnnotationHelper(-7));
rdoc->SetObjectAnnotation(d, img, "deleteme", eRENDERDOC_Empty, 0, NULL);
rdoc->SetObjectAnnotation(d, img, "path.deleted.by.parent", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-8));
rdoc->SetObjectAnnotation(d, img, "path.deleted.by.parent2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-9));
// this will delete all children. `path` will still exist, but will be empty
rdoc->SetObjectAnnotation(d, img, "path.deleted", eRENDERDOC_Empty, 0, NULL);
}
while(Running())
{
if(rdoc)
{
// queue annotations are only included when in the captured frame
if(curFrame == 2)
rdoc->SetCommandAnnotation(d, queue, "queue.too_old", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, queue, "queue.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, queue, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(9999));
rdoc->SetCommandAnnotation(d, queue, "command.inherited", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1234));
rdoc->SetCommandAnnotation(d, queue, "command.deleted", eRENDERDOC_Int32, 0,
RDAnnotationHelper(50));
}
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
Reset(cmd);
setMarker(cmd, "Start");
if(rdoc)
{
rdoc->SetCommandAnnotation(d, cmd, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(2000));
rdoc->SetCommandAnnotation(d, cmd, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-3333));
rdoc->SetCommandAnnotation(d, cmd, "command.new", eRENDERDOC_Int32, 0,
RDAnnotationHelper(3333));
rdoc->SetCommandAnnotation(d, cmd, "command.deleted", eRENDERDOC_Empty, 0, NULL);
}
setMarker(cmd, "Initial");
D3D12_CPU_DESCRIPTOR_HANDLE rtv =
MakeRTV(img).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateCPU(0);
ClearRenderTargetView(cmd, rtv, {0.2f, 0.2f, 0.2f, 1.0f});
ID3D12ResourcePtr bb = StartUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
ClearRenderTargetView(cmd, BBRTV, {0.2f, 0.2f, 0.2f, 1.0f});
if(rdoc)
rdoc->SetCommandAnnotation(d, cmd, "command.new", eRENDERDOC_Float, 0,
RDAnnotationHelper(1.75f));
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
IASetVertexBuffer(cmd, DefaultTriVB, sizeof(DefaultA2V), 0);
cmd->SetPipelineState(DefaultTriPSO);
cmd->SetGraphicsRootSignature(DefaultTriSig);
SetMainWindowViewScissor(cmd);
OMSetRenderTargets(cmd, {BBRTV}, {});
setMarker(cmd, "Pre-Draw");
// deleting a value is fine if it's re-added before the next event
if(rdoc)
{
rdoc->SetCommandAnnotation(d, cmd, "new.value", eRENDERDOC_Empty, 0, NULL);
rdoc->SetCommandAnnotation(d, cmd, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(4000));
}
setMarker(cmd, "Draw 1");
cmd->DrawInstanced(3, 1, 0, 0);
RSSetViewport(
cmd, {0.0f, 0.0f, (float)screenWidth / 2.0f, (float)screenHeight / 2.0f, 0.0f, 1.0f});
setMarker(cmd, "Draw 2");
cmd->DrawInstanced(3, 1, 0, 0);
FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmd->Close();
SubmitAndPresent({cmd});
}
return 0;
}
};
REGISTER_TEST();
+4
View File
@@ -135,6 +135,7 @@
</ClCompile>
<ClCompile Include="d3d11\d3d11_1_many_uavs.cpp" />
<ClCompile Include="d3d11\d3d11_amd_shader_extensions.cpp" />
<ClCompile Include="d3d11\d3d11_annotations.cpp" />
<ClCompile Include="d3d11\d3d11_array_interpolator.cpp" />
<ClCompile Include="d3d11\d3d11_binding_hazards.cpp" />
<ClCompile Include="d3d11\d3d11_buffer_truncation.cpp" />
@@ -192,6 +193,7 @@
<ClCompile Include="d3d11\d3d11_video_textures.cpp" />
<ClCompile Include="d3d11\d3d11_workgroup_zoo.cpp" />
<ClCompile Include="d3d12\d3d12_amd_shader_extensions.cpp" />
<ClCompile Include="d3d12\d3d12_annotations.cpp" />
<ClCompile Include="d3d12\d3d12_blend.cpp" />
<ClCompile Include="d3d12\d3d12_buffer_truncation.cpp" />
<ClCompile Include="d3d12\d3d12_cbuffer_zoo.cpp" />
@@ -252,6 +254,7 @@
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="3rdparty\glad\glad_wgl.c" />
<ClCompile Include="gl\gl_annotations.cpp" />
<ClCompile Include="gl\gl_buffer_resizing.cpp" />
<ClCompile Include="gl\gl_buffer_spam.cpp" />
<ClCompile Include="gl\gl_buffer_truncation.cpp" />
@@ -315,6 +318,7 @@
<ClCompile Include="main.cpp" />
<ClCompile Include="test_common.cpp" />
<ClCompile Include="texture_zoo.cpp" />
<ClCompile Include="vk\vk_annotations.cpp" />
<ClCompile Include="vk\vk_blend.cpp" />
<ClCompile Include="vk\vk_descriptor_buffer.cpp" />
<ClCompile Include="vk\vk_compute_only.cpp" />
+12
View File
@@ -742,6 +742,18 @@
<ClCompile Include="gl\gl_shader_debug_zoo.cpp">
<Filter>OpenGL\demos</Filter>
</ClCompile>
<ClCompile Include="vk\vk_annotations.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
<ClCompile Include="gl\gl_annotations.cpp">
<Filter>OpenGL\demos</Filter>
</ClCompile>
<ClCompile Include="d3d12\d3d12_annotations.cpp">
<Filter>D3D12\demos</Filter>
</ClCompile>
<ClCompile Include="d3d11\d3d11_annotations.cpp">
<Filter>D3D11\demos</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
+189
View File
@@ -0,0 +1,189 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2023-2026 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.
******************************************************************************/
#include "gl_test.h"
RD_TEST(GL_Annotations, OpenGLGraphicsTest)
{
static constexpr const char *Description = "Test annotations via the OpenGL API.";
int main()
{
// initialise, create window, create context, etc
if(!Init())
return 3;
GLuint tex = MakeTexture();
glBindTexture(GL_TEXTURE_2D, tex);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 4);
glObjectLabel(GL_TEXTURE, tex, -1, "Annotated Image");
glObjectLabel(GL_BUFFER, DefaultTriVB, -1, "Vertex Buffer");
// cache the device pointer we pass in
void *d = mainContext;
if(rdoc)
{
// GL needs a helper struct to specify the type and handle together
RDGLObjectHelper img(GL_TEXTURE, tex);
RDGLObjectHelper buf(GL_BUFFER, DefaultTriVB);
rdoc->SetObjectAnnotation(d, img, "basic.bool", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
rdoc->SetObjectAnnotation(d, img, "basic.int32", eRENDERDOC_Int32, 0, RDAnnotationHelper(-3));
rdoc->SetObjectAnnotation(d, img, "basic.int64", eRENDERDOC_Int64, 0,
RDAnnotationHelper(-3000000000000LL));
rdoc->SetObjectAnnotation(d, img, "basic.uint32", eRENDERDOC_UInt32, 0, RDAnnotationHelper(3));
rdoc->SetObjectAnnotation(d, img, "basic.uint64", eRENDERDOC_UInt64, 0,
RDAnnotationHelper(3000000000000LL));
rdoc->SetObjectAnnotation(d, img, "basic.float", eRENDERDOC_Float, 0,
RDAnnotationHelper(3.25f));
rdoc->SetObjectAnnotation(d, img, "basic.double", eRENDERDOC_Double, 0,
RDAnnotationHelper(3.25000000001));
rdoc->SetObjectAnnotation(d, img, "basic.string", eRENDERDOC_String, 0,
RDAnnotationHelper("Hello, World!"));
RENDERDOC_AnnotationValue val;
val.apiObject = (void *)(RENDERDOC_GLResourceReference *)buf;
rdoc->SetObjectAnnotation(d, img, "basic.object", eRENDERDOC_APIObject, 0, &val);
rdoc->SetObjectAnnotation(d, img, "basic.object.__offset", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(64));
rdoc->SetObjectAnnotation(d, img, "basic.object.__size", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(32));
rdoc->SetObjectAnnotation(d, img, "basic.object.__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float4 vertex_data;"));
rdoc->SetObjectAnnotation(d, buf, "__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float3 pos;\n"
"float4 col;\n"
"float2 uv;\n"));
val = {};
val.vector.float32[0] = 1.1f;
val.vector.float32[1] = 2.2f;
val.vector.float32[2] = 3.3f;
val.vector.float32[3] = 4.4f; // should be ignored
rdoc->SetObjectAnnotation(d, img, "basic.vec3", eRENDERDOC_Float, 3, &val);
rdoc->SetObjectAnnotation(d, img, "deep.nested.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-4));
rdoc->SetObjectAnnotation(d, img, "deep.nested.path.to.annotation2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-5));
rdoc->SetObjectAnnotation(d, img, "deep.alternate.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-6));
// deleted paths should not stay around
rdoc->SetObjectAnnotation(d, img, "deleteme", eRENDERDOC_Int32, 0, RDAnnotationHelper(-7));
rdoc->SetObjectAnnotation(d, img, "deleteme", eRENDERDOC_Empty, 0, NULL);
rdoc->SetObjectAnnotation(d, img, "path.deleted.by.parent", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-8));
rdoc->SetObjectAnnotation(d, img, "path.deleted.by.parent2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-9));
// this will delete all children. `path` will still exist, but will be empty
rdoc->SetObjectAnnotation(d, img, "path.deleted", eRENDERDOC_Empty, 0, NULL);
}
while(Running())
{
if(rdoc)
{
// queue annotations don't exist in GL, but we set these to share the same test code.
if(curFrame == 2)
rdoc->SetCommandAnnotation(d, NULL, "queue.too_old", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, NULL, "queue.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, NULL, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(9999));
rdoc->SetCommandAnnotation(d, NULL, "command.inherited", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1234));
rdoc->SetCommandAnnotation(d, NULL, "command.deleted", eRENDERDOC_Int32, 0,
RDAnnotationHelper(50));
}
setMarker("Start");
if(rdoc)
{
rdoc->SetCommandAnnotation(d, NULL, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(2000));
rdoc->SetCommandAnnotation(d, NULL, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-3333));
rdoc->SetCommandAnnotation(d, NULL, "command.new", eRENDERDOC_Int32, 0,
RDAnnotationHelper(3333));
rdoc->SetCommandAnnotation(d, NULL, "command.deleted", eRENDERDOC_Empty, 0, NULL);
}
setMarker("Initial");
glClearBufferfv(GL_COLOR, 0, DefaultClearCol);
glBindTexture(GL_TEXTURE_2D, tex);
if(rdoc)
rdoc->SetCommandAnnotation(d, NULL, "command.new", eRENDERDOC_Float, 0,
RDAnnotationHelper(1.75f));
glBindVertexArray(DefaultTriVAO);
glUseProgram(DefaultTriProgram);
glViewport(0, 0, GLsizei(screenWidth), GLsizei(screenHeight));
setMarker("Pre-Draw");
// deleting a value is fine if it's re-added before the next event
if(rdoc)
{
rdoc->SetCommandAnnotation(d, NULL, "new.value", eRENDERDOC_Empty, 0, NULL);
rdoc->SetCommandAnnotation(d, NULL, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(4000));
}
setMarker("Draw 1");
glDrawArrays(GL_TRIANGLES, 0, 3);
glViewport(0, 0, GLsizei(screenWidth) / 2, GLsizei(screenHeight) / 2);
setMarker("Draw 2");
glDrawArrays(GL_TRIANGLES, 0, 3);
Present();
}
return 0;
}
};
REGISTER_TEST();
+2
View File
@@ -390,6 +390,8 @@ int main(int argc, char **argv)
{
std::vector<TestMetadata> &tests = test_list();
LoadLibraryA("P:/renderdoc/x64/development/renderdoc.dll");
std::sort(tests.begin(), tests.end());
if(argc >= 2 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") || !strcmp(argv[1], "-?") ||
+239
View File
@@ -0,0 +1,239 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2023-2026 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.
******************************************************************************/
#include "vk_test.h"
RD_TEST(VK_Annotations, VulkanGraphicsTest)
{
static constexpr const char *Description = "Test annotations via the vulkan API.";
int main()
{
// initialise, create window, create context, etc
if(!Init())
return 3;
// these tags provide the layer a way (for dispatchable objects at least) to identify
// dispatchable objects that may be wrapped by the loader
VkDebugUtilsObjectTagInfoEXT tag = {
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT,
NULL,
VK_OBJECT_TYPE_INSTANCE,
(uint64_t)instance,
RENDERDOC_APIObjectAnnotationHelper,
sizeof(instance),
instance,
};
vkSetDebugUtilsObjectTagEXT(device, &tag);
tag.objectHandle = (uint64_t)phys;
tag.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
tag.pTag = phys;
vkSetDebugUtilsObjectTagEXT(device, &tag);
tag.objectHandle = (uint64_t)device;
tag.objectType = VK_OBJECT_TYPE_DEVICE;
tag.pTag = device;
vkSetDebugUtilsObjectTagEXT(device, &tag);
AllocatedImage img(this,
vkh::ImageCreateInfo(4, 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
VK_IMAGE_USAGE_TRANSFER_DST_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
setName(img.image, "Annotated Image");
setName(DefaultTriVB.buffer, "Vertex Buffer");
// cache the device pointer we pass in
void *d = RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance);
if(rdoc)
{
rdoc->SetObjectAnnotation(d, img.image, "basic.bool", eRENDERDOC_Bool, 0,
RDAnnotationHelper(true));
rdoc->SetObjectAnnotation(d, img.image, "basic.int32", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-3));
rdoc->SetObjectAnnotation(d, img.image, "basic.int64", eRENDERDOC_Int64, 0,
RDAnnotationHelper(-3000000000000LL));
rdoc->SetObjectAnnotation(d, img.image, "basic.uint32", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(3));
rdoc->SetObjectAnnotation(d, img.image, "basic.uint64", eRENDERDOC_UInt64, 0,
RDAnnotationHelper(3000000000000LL));
rdoc->SetObjectAnnotation(d, img.image, "basic.float", eRENDERDOC_Float, 0,
RDAnnotationHelper(3.25f));
rdoc->SetObjectAnnotation(d, img.image, "basic.double", eRENDERDOC_Double, 0,
RDAnnotationHelper(3.25000000001));
rdoc->SetObjectAnnotation(d, img.image, "basic.string", eRENDERDOC_String, 0,
RDAnnotationHelper("Hello, World!"));
RENDERDOC_AnnotationValue val;
val.apiObject = (void *)DefaultTriVB.buffer;
rdoc->SetObjectAnnotation(d, img.image, "basic.object", eRENDERDOC_APIObject, 0, &val);
rdoc->SetObjectAnnotation(d, img.image, "basic.object.__offset", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(64));
rdoc->SetObjectAnnotation(d, img.image, "basic.object.__size", eRENDERDOC_UInt32, 0,
RDAnnotationHelper(32));
rdoc->SetObjectAnnotation(d, img.image, "basic.object.__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float4 vertex_data;"));
rdoc->SetObjectAnnotation(d, DefaultTriVB.buffer, "__rd_format", eRENDERDOC_String, 0,
RDAnnotationHelper("float3 pos;\n"
"float4 col;\n"
"float2 uv;\n"));
val = {};
val.vector.float32[0] = 1.1f;
val.vector.float32[1] = 2.2f;
val.vector.float32[2] = 3.3f;
val.vector.float32[3] = 4.4f; // should be ignored
rdoc->SetObjectAnnotation(d, img.image, "basic.vec3", eRENDERDOC_Float, 3, &val);
rdoc->SetObjectAnnotation(d, img.image, "deep.nested.path.to.annotation", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-4));
rdoc->SetObjectAnnotation(d, img.image, "deep.nested.path.to.annotation2", eRENDERDOC_Int32,
0, RDAnnotationHelper(-5));
rdoc->SetObjectAnnotation(d, img.image, "deep.alternate.path.to.annotation", eRENDERDOC_Int32,
0, RDAnnotationHelper(-6));
// deleted paths should not stay around
rdoc->SetObjectAnnotation(d, img.image, "deleteme", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-7));
rdoc->SetObjectAnnotation(d, img.image, "deleteme", eRENDERDOC_Empty, 0, NULL);
rdoc->SetObjectAnnotation(d, img.image, "path.deleted.by.parent", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-8));
rdoc->SetObjectAnnotation(d, img.image, "path.deleted.by.parent2", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-9));
// this will delete all children. `path` will still exist, but will be empty
rdoc->SetObjectAnnotation(d, img.image, "path.deleted", eRENDERDOC_Empty, 0, NULL);
}
while(Running())
{
if(rdoc)
{
// queue annotations are only included when in the captured frame
if(curFrame == 2)
rdoc->SetCommandAnnotation(d, queue, "queue.too_old", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, queue, "queue.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1000));
rdoc->SetCommandAnnotation(d, queue, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(9999));
rdoc->SetCommandAnnotation(d, queue, "command.inherited", eRENDERDOC_Int32, 0,
RDAnnotationHelper(1234));
rdoc->SetCommandAnnotation(d, queue, "command.deleted", eRENDERDOC_Int32, 0,
RDAnnotationHelper(50));
}
VkCommandBuffer cmd = GetCommandBuffer();
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
setMarker(cmd, "Start");
if(rdoc)
{
rdoc->SetCommandAnnotation(d, cmd, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(2000));
rdoc->SetCommandAnnotation(d, cmd, "command.overwritten", eRENDERDOC_Int32, 0,
RDAnnotationHelper(-3333));
rdoc->SetCommandAnnotation(d, cmd, "command.new", eRENDERDOC_Int32, 0,
RDAnnotationHelper(3333));
rdoc->SetCommandAnnotation(d, cmd, "command.deleted", eRENDERDOC_Empty, 0, NULL);
}
setMarker(cmd, "Initial");
VkImage swapimg = StartUsingBackbuffer(cmd);
vkh::cmdClearImage(cmd, swapimg, vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f));
vkh::cmdPipelineBarrier(cmd, {
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL, img.image),
});
vkCmdClearColorImage(cmd, img.image, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(cmd, mainWindow->beginRP(), VK_SUBPASS_CONTENTS_INLINE);
if(rdoc)
rdoc->SetCommandAnnotation(d, cmd, "command.new", eRENDERDOC_Float, 0,
RDAnnotationHelper(1.75f));
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, DefaultTriPipe);
mainWindow->setViewScissor(cmd);
vkh::cmdBindVertexBuffers(cmd, {DefaultTriVB.buffer});
setMarker(cmd, "Pre-Draw");
// deleting a value is fine if it's re-added before the next event
if(rdoc)
{
rdoc->SetCommandAnnotation(d, cmd, "new.value", eRENDERDOC_Empty, 0, NULL);
rdoc->SetCommandAnnotation(d, cmd, "new.value", eRENDERDOC_Int32, 0,
RDAnnotationHelper(4000));
}
setMarker(cmd, "Draw 1");
vkCmdDraw(cmd, 3, 1, 0, 0);
VkViewport view = mainWindow->viewport;
view.width /= 2;
view.height /= 2;
vkCmdSetViewport(cmd, 0, 1, &view);
setMarker(cmd, "Draw 2");
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdEndRenderPass(cmd);
FinishUsingBackbuffer(cmd);
vkEndCommandBuffer(cmd);
SubmitAndPresent({cmd});
}
return 0;
}
};
REGISTER_TEST();
+94
View File
@@ -76,8 +76,45 @@ RD_TEST(VK_Simple_Triangle, VulkanGraphicsTest)
VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1, 1, VK_SAMPLE_COUNT_4_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkDebugUtilsObjectTagInfoEXT tag = {
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT,
NULL,
VK_OBJECT_TYPE_INSTANCE,
(uint64_t)instance,
RENDERDOC_APIObjectAnnotationHelper,
sizeof(instance),
instance,
};
vkSetDebugUtilsObjectTagEXT(device, &tag);
tag.objectHandle = (uint64_t)phys;
tag.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
tag.pTag = phys;
vkSetDebugUtilsObjectTagEXT(device, &tag);
RENDERDOC_AnnotationValue val;
rdoc->SetObjectAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), instance,
"someInstData", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
rdoc->SetObjectAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), phys, "physData",
eRENDERDOC_String, 0, RDAnnotationHelper("my physical device ha ha"));
rdoc->SetObjectAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), offimg.image,
"cool.secretInfo", eRENDERDOC_Float, 0, RDAnnotationHelper(3.14f));
val.apiObject = offimgMS.image;
rdoc->SetObjectAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), offimg.image,
"cool.otherimage", eRENDERDOC_APIObject, 0, &val);
while(Running())
{
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), queue,
"global.coolQueue", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
int counter = 1;
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), queue,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
VkCommandBuffer cmd = GetCommandBuffer();
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
@@ -85,20 +122,45 @@ RD_TEST(VK_Simple_Triangle, VulkanGraphicsTest)
VkImage swapimg =
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.coolCommand", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"draw.isClear", eRENDERDOC_Bool, 0, RDAnnotationHelper(true));
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"draw.clearingswap", eRENDERDOC_Float, 0, RDAnnotationHelper(1.1f));
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"draw.notclearing", eRENDERDOC_APIObject, 0, &val);
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
vkh::ImageSubresourceRange());
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd, "draw",
eRENDERDOC_Empty, 0, NULL);
vkh::cmdPipelineBarrier(
cmd, {
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL, offimg.image),
});
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkCmdClearColorImage(cmd, offimg.image, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
vkh::ImageSubresourceRange());
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkh::cmdPipelineBarrier(
cmd, {
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
@@ -109,20 +171,52 @@ RD_TEST(VK_Simple_Triangle, VulkanGraphicsTest)
vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
vkh::ImageSubresourceRange());
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"renderpass.type", eRENDERDOC_String, 0,
RDAnnotationHelper("boring"));
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
VK_SUBPASS_CONTENTS_INLINE);
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkCmdDraw(cmd, 3, 1, 0, 0);
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkCmdEndRenderPass(cmd);
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
rdoc->SetCommandAnnotation(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), cmd,
"global.counter", eRENDERDOC_Int32, 0,
RDAnnotationHelper(counter++));
vkEndCommandBuffer(cmd);
Submit(0, 1, {cmd});
+1
View File
@@ -13,3 +13,4 @@ from .shared.Subgroup_Zoo import *
from .shared.Pixel_History import *
from .shared.Workgroup_Zoo import *
from .shared.Groupshared import *
from .shared.Annotations import *
+252
View File
@@ -0,0 +1,252 @@
import renderdoc as rd
import rdtest
# Not a direct test, re-used by API-specific tests
class Annotations(rdtest.TestCase):
internal = True
def check_resource_annotations(self):
annot = lambda x: annots.FindChildByKeyPath(x)
with rdtest.log.auto_section('Resource annotations'):
res = self.get_resource_by_name('Annotated Image')
annots = res.annotations
self.check(annots is not None)
self.check_eq(annot("basic.bool").type.basetype, rd.SDBasic.Boolean)
self.check_eq(annot("basic.bool").AsBool(), True)
self.check_eq(annot("basic.int32").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("basic.int32").type.byteSize, 4)
self.check_eq(annot("basic.int32").AsInt(), -3)
self.check_eq(annot("basic.int64").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("basic.int64").type.byteSize, 8)
self.check_eq(annot("basic.int64").AsInt(), -3000000000000)
self.check_eq(annot("basic.uint32").type.basetype, rd.SDBasic.UnsignedInteger)
self.check_eq(annot("basic.uint32").type.byteSize, 4)
self.check_eq(annot("basic.uint32").AsInt(), 3)
self.check_eq(annot("basic.uint64").type.basetype, rd.SDBasic.UnsignedInteger)
self.check_eq(annot("basic.uint64").type.byteSize, 8)
self.check_eq(annot("basic.uint64").AsInt(), 3000000000000)
self.check_eq(annot("basic.float").type.basetype, rd.SDBasic.Float)
self.check_eq(annot("basic.float").type.byteSize, 4)
self.check_eq(annot("basic.float").AsFloat(), 3.25)
self.check_eq(annot("basic.double").type.basetype, rd.SDBasic.Float)
self.check_eq(annot("basic.double").type.byteSize, 8)
self.check(rdtest.value_compare(annot("basic.double").AsFloat(), 3.25000000001))
self.check_eq(annot("basic.string").type.basetype, rd.SDBasic.String)
self.check_eq(annot("basic.string").AsString(), "Hello, World!")
self.check_eq(annot("basic.object").type.basetype, rd.SDBasic.Resource)
obj = self.get_resource(annot("basic.object").AsResourceId())
self.check_eq(obj.name, "Vertex Buffer")
self.check_eq(annot("basic.object.__offset").AsInt(), 64)
self.check_eq(annot("basic.object.__size").AsInt(), 32)
self.check(rdtest.value_compare(annot("basic.vec3.x").AsFloat(), 1.1))
self.check(rdtest.value_compare(annot("basic.vec3.y").AsFloat(), 2.2))
self.check(rdtest.value_compare(annot("basic.vec3.z").AsFloat(), 3.3))
self.check_eq(annot("deep.nested.path.to.annotation").AsInt(), -4)
self.check_eq(annot("deep.nested.path.to.annotation2").AsInt(), -5)
self.check_eq(annot("deep.alternate.path.to.annotation").AsInt(), -6)
self.check(annot("deleteme") is None)
self.check(annot("path.deleted.by.parent") is None)
self.check(annot("path.deleted.by.parent2") is None)
self.check(annot("path.deleted") is None)
def check_command_annotations(self, cmd_buffers: bool):
annot = lambda x: annots.FindChildByKeyPath(x)
with rdtest.log.auto_section('Event annotations'):
action = self.find_action("Start")
rdtest.log.print(f"Checking {action.customName}")
annots = action.events[-1].annotations
self.check(annots is not None)
# Should not have this annotation, it happened prior to the capture
self.check(annot("queue.too_old") is None)
# normal value set on the queue
self.check_eq(annot("queue.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("queue.value").AsInt(), 1000)
# this will later be overwritten by the commands, but for now has the queue value
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), 9999)
# this is inherited by the commands even as other siblings are modified
self.check_eq(annot("command.inherited").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.inherited").AsInt(), 1234)
# this will be deleted
self.check_eq(annot("command.deleted").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.deleted").AsInt(), 50)
action = self.find_action("Initial")
rdtest.log.print(f"Checking {action.customName}")
annots = action.events[-1].annotations
self.check(annots is not None)
# normal value set on the queue
self.check_eq(annot("queue.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("queue.value").AsInt(), 1000)
# this has the overwritten value now
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), -3333)
# this is inherited by the commands even as other siblings are modified
self.check_eq(annot("command.inherited").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.inherited").AsInt(), 1234)
# this has now been deleted
self.check(annot("command.deleted") is None)
# this is a new command-local value
self.check_eq(annot("command.new").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.new").AsInt(), 3333)
# this is a new command-local value
self.check_eq(annot("new.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("new.value").AsInt(), 2000)
action = self.find_action("Pre-Draw")
rdtest.log.print(f"Checking {action.customName}")
annots = action.events[-1].annotations
self.check(annots is not None)
# normal value set on the queue
self.check_eq(annot("queue.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("queue.value").AsInt(), 1000)
# this has the overwritten value now
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), -3333)
# this is inherited by the commands even as other siblings are modified
self.check_eq(annot("command.inherited").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.inherited").AsInt(), 1234)
# this has now been deleted
self.check(annot("command.deleted") is None)
# this is a command-local value, which has changed type
self.check_eq(annot("command.new").type.basetype, rd.SDBasic.Float)
self.check_eq(annot("command.new").AsFloat(), 1.75)
# this value has't changed
self.check_eq(annot("new.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("new.value").AsInt(), 2000)
predraw_id = action.eventId
action = self.find_action("Draw 1")
rdtest.log.print(f"Checking {action.customName}")
annots = action.events[-1].annotations
self.check(annots is not None)
# should be no events between these
self.check_eq(predraw_id + 1, action.eventId)
# this value was deleted and re-added, so it should be present as the new value
self.check_eq(annot("new.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("new.value").AsInt(), 4000)
# normal value set on the queue
self.check_eq(annot("queue.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("queue.value").AsInt(), 1000)
# this has the overwritten value now
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), -3333)
# this is inherited by the commands even as other siblings are modified
self.check_eq(annot("command.inherited").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.inherited").AsInt(), 1234)
# this has now been deleted
self.check(annot("command.deleted") is None)
# this is a command-local value, which has changed type
self.check_eq(annot("command.new").type.basetype, rd.SDBasic.Float)
self.check_eq(annot("command.new").AsFloat(), 1.75)
self.check_eq(annot("new.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("new.value").AsInt(), 4000)
action = self.find_action("Draw 2")
rdtest.log.print(f"Checking {action.customName}")
annots = action.events[-1].annotations
self.check(annots is not None)
# all of the values should still be present
self.check_eq(annot("queue.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("queue.value").AsInt(), 1000)
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), -3333)
self.check_eq(annot("command.inherited").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.inherited").AsInt(), 1234)
self.check(annot("command.deleted") is None)
self.check_eq(annot("command.new").type.basetype, rd.SDBasic.Float)
self.check_eq(annot("command.new").AsFloat(), 1.75)
self.check_eq(annot("new.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("new.value").AsInt(), 4000)
action = self.get_last_action()
rdtest.log.print(f"Checking {action.customName}")
annots = action.events[-1].annotations
self.check(annots is not None)
# normal value set on the queue
self.check_eq(annot("queue.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("queue.value").AsInt(), 1000)
self.check_eq(annot("command.inherited").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.inherited").AsInt(), 1234)
# if we have real command buffers, the annotations revert back to where they were on queues
if cmd_buffers:
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), 9999)
self.check_eq(annot("command.deleted").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.deleted").AsInt(), 50)
self.check(annot("command.new") is None)
self.check(annot("new.value") is None)
# otherwise they will be the same as on the command buffer
else:
self.check_eq(annot("command.overwritten").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("command.overwritten").AsInt(), -3333)
self.check(annot("command.deleted") is None)
self.check_eq(annot("command.new").type.basetype, rd.SDBasic.Float)
self.check_eq(annot("command.new").AsFloat(), 1.75)
self.check_eq(annot("new.value").type.basetype, rd.SDBasic.SignedInteger)
self.check_eq(annot("new.value").AsInt(), 4000)
@@ -0,0 +1,11 @@
import renderdoc as rd
import rdtest
class D3D11_Annotations(rdtest.Annotations):
demos_test_name = 'D3D11_Annotations'
internal = False
def check_capture(self):
super().check_resource_annotations()
super().check_command_annotations(False)
@@ -0,0 +1,11 @@
import renderdoc as rd
import rdtest
class D3D12_Annotations(rdtest.Annotations):
demos_test_name = 'D3D12_Annotations'
internal = False
def check_capture(self):
super().check_resource_annotations()
super().check_command_annotations(True)
+11
View File
@@ -0,0 +1,11 @@
import renderdoc as rd
import rdtest
class GL_Annotations(rdtest.Annotations):
demos_test_name = 'GL_Annotations'
internal = False
def check_capture(self):
super().check_resource_annotations()
super().check_command_annotations(False)
+11
View File
@@ -0,0 +1,11 @@
import renderdoc as rd
import rdtest
class VK_Annotations(rdtest.Annotations):
demos_test_name = 'VK_Annotations'
internal = False
def check_capture(self):
super().check_resource_annotations()
super().check_command_annotations(True)