Skip to content

Commit

Permalink
Capture exe with renderdoc and pass --vulkan_renderdoc_capture_all.
Browse files Browse the repository at this point in the history
  • Loading branch information
benvanik committed Feb 21, 2016
1 parent fed6679 commit 8bf5eba
Show file tree
Hide file tree
Showing 8 changed files with 630 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/xenia/gpu/vulkan/vulkan_command_processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
IndexBufferInfo* index_buffer_info) {
auto& regs = *register_file_;

// TODO(benvanik): move to CP or to host (trace dump, etc).
if (FLAGS_vulkan_renderdoc_capture_all && device_->is_renderdoc_attached()) {
device_->BeginRenderDocFrameCapture();
}

#if FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu");
#endif // FINE_GRAINED_DRAW_SCOPES
Expand Down Expand Up @@ -313,6 +318,11 @@ bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
}
vkDestroyFence(*device_, fence, nullptr);

// TODO(benvanik): move to CP or to host (trace dump, etc).
if (FLAGS_vulkan_renderdoc_capture_all && device_->is_renderdoc_attached()) {
device_->EndRenderDocFrameCapture();
}

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions src/xenia/gpu/vulkan/vulkan_gpu_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
*/

#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"

DEFINE_bool(vulkan_renderdoc_capture_all, false,
"Capture everything with RenderDoc.");
2 changes: 2 additions & 0 deletions src/xenia/gpu/vulkan/vulkan_gpu_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@

#define FINE_GRAINED_DRAW_SCOPES 1

DECLARE_bool(vulkan_renderdoc_capture_all);

#endif // XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
27 changes: 27 additions & 0 deletions src/xenia/ui/vulkan/vulkan_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
#include <mutex>
#include <string>

#include "third_party/renderdoc/renderdoc_app.h"

#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_immediate_drawer.h"
#include "xenia/ui/vulkan/vulkan_instance.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/ui/window.h"

Expand Down Expand Up @@ -212,6 +215,30 @@ void VulkanDevice::ReleaseQueue(VkQueue queue) {
free_queues_.push_back(queue);
}

bool VulkanDevice::is_renderdoc_attached() const {
return instance_->is_renderdoc_attached();
}

void VulkanDevice::BeginRenderDocFrameCapture() {
auto api = reinterpret_cast<RENDERDOC_API_1_0_1*>(instance_->renderdoc_api());
if (!api) {
return;
}
assert_true(api->IsFrameCapturing() == 0);

api->StartFrameCapture(nullptr, nullptr);
}

void VulkanDevice::EndRenderDocFrameCapture() {
auto api = reinterpret_cast<RENDERDOC_API_1_0_1*>(instance_->renderdoc_api());
if (!api) {
return;
}
assert_true(api->IsFrameCapturing() == 1);

api->EndFrameCapture(nullptr, nullptr);
}

VkDeviceMemory VulkanDevice::AllocateMemory(
const VkMemoryRequirements& requirements, VkFlags required_properties) {
// Search memory types to find one matching our requirements and our
Expand Down
9 changes: 9 additions & 0 deletions src/xenia/ui/vulkan/vulkan_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ class VulkanDevice {
// This method is thread safe.
void ReleaseQueue(VkQueue queue);

// True if RenderDoc is attached and available for use.
bool is_renderdoc_attached() const;
// Begins capturing the current frame in RenderDoc, if it is attached.
// Must be paired with EndRenderDocCapture. Multiple frames cannot be
// captured at the same time.
void BeginRenderDocFrameCapture();
// Ends a capture.
void EndRenderDocFrameCapture();

// Allocates memory of the given size matching the required properties.
VkDeviceMemory AllocateMemory(
const VkMemoryRequirements& requirements,
Expand Down
44 changes: 44 additions & 0 deletions src/xenia/ui/vulkan/vulkan_instance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <mutex>
#include <string>

#include "third_party/renderdoc/renderdoc_app.h"

#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
Expand Down Expand Up @@ -58,6 +60,9 @@ bool VulkanInstance::Initialize(Window* any_target_window) {
auto version = Version::Parse(VK_API_VERSION);
XELOGVK("Initializing Vulkan %s...", version.pretty_string.c_str());

// Hook into renderdoc, if it's available.
EnableRenderDoc();

// Get all of the global layers and extensions provided by the system.
if (!QueryGlobals()) {
XELOGE("Failed to query instance globals");
Expand All @@ -81,6 +86,45 @@ bool VulkanInstance::Initialize(Window* any_target_window) {
return true;
}

bool VulkanInstance::EnableRenderDoc() {
// RenderDoc injects itself into our process, so we should be able to get it.
pRENDERDOC_GetAPI get_api = nullptr;
#if XE_PLATFORM_WIN32
auto module_handle = GetModuleHandle(L"renderdoc.dll");
if (!module_handle) {
XELOGI("RenderDoc support requested but it is not attached");
return false;
}
get_api = reinterpret_cast<pRENDERDOC_GetAPI>(
GetProcAddress(module_handle, "RENDERDOC_GetAPI"));
#else
// TODO(benvanik): dlsym/etc - abstracted in base/.
#endif // XE_PLATFORM_32
if (!get_api) {
XELOGI("RenderDoc support requested but it is not attached");
return false;
}

// Request all API function pointers.
if (!get_api(eRENDERDOC_API_Version_1_0_1,
reinterpret_cast<void**>(&renderdoc_api_))) {
XELOGE("RenderDoc found but was unable to get API - version mismatch?");
return false;
}
auto api = reinterpret_cast<RENDERDOC_API_1_0_1*>(renderdoc_api_);

// Query version.
int major;
int minor;
int patch;
api->GetAPIVersion(&major, &minor, &patch);
XELOGI("RenderDoc attached; %d.%d.%d", major, minor, patch);

is_renderdoc_attached_ = true;

return true;
}

bool VulkanInstance::QueryGlobals() {
// Scan global layers and accumulate properties.
// We do this in a loop so that we can allocate the required amount of
Expand Down
11 changes: 11 additions & 0 deletions src/xenia/ui/vulkan/vulkan_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,15 @@ class VulkanInstance {
return available_devices_;
}

// True if RenderDoc is attached and available for use.
bool is_renderdoc_attached() const { return is_renderdoc_attached_; }
// RenderDoc API handle, if attached.
void* renderdoc_api() const { return renderdoc_api_; }

private:
// Attempts to enable RenderDoc via the API, if it is attached.
bool EnableRenderDoc();

// Queries the system to find global extensions and layers.
bool QueryGlobals();

Expand Down Expand Up @@ -86,6 +94,9 @@ class VulkanInstance {
std::vector<DeviceInfo> available_devices_;

VkDebugReportCallbackEXT dbg_report_callback_ = nullptr;

void* renderdoc_api_ = nullptr;
bool is_renderdoc_attached_ = false;
};

} // namespace vulkan
Expand Down
Loading

0 comments on commit 8bf5eba

Please sign in to comment.