Skip to content
Vadim Slyusarev edited this page Aug 12, 2019 · 5 revisions

Optick API

OPTICK_EVENT();

Basic scoped performance counter. Use this counter 99% of the time.
It automatically extracts the name of the current function.

void Function()
{ 
	OPTICK_EVENT();
	...
}

You could also pass an optional name for this macro to override the name - OPTICK_EVENT("ScopeName");.
Useful for marking multiple scopes within one function.

OPTICK_CATEGORY("UpdateLogic", Optick::Category::GameLogic);

Scoped performance counter with dedicated category.
Categories always go with predefined set of colors.
Use categories for high-level overview of the code.

OPTICK_THREAD("ThreadName");

A macro for declaring a new thread.
Required for collecting events from the current thread.

void WorkerThread(Engine* engine)
{
	OPTICK_THREAD("WorkerThread")
        ...
}

OPTICK_TAG("ModelName", m_Name);

A macro for attaching any custom data to the current scope.
Supported types: float, int32_t, uint32_t, uint64_t, float[3], const char*. Tags

OPTICK_TAG("PlayerName", name[index]);
OPTICK_TAG("Health", 100);
OPTICK_TAG("Score", 0x80000000u);
OPTICK_TAG("Height(cm)", 176.3f);
OPTICK_TAG("Address", (uint64)*this);
OPTICK_TAG("Position", 123.0f, 456.0f, 789.0f);

OPTICK_SET_STATE_CHANGED_CALLBACK(CALLBACK_FUNCTION);

A macro for subscribing on state change event.
Useful for attaching screenshots or any custom files and data to the capture.

#if USE_OPTICK
bool OnOptickStateChanged(Optick::State::Type state)
{
	if (state == Optick::State::STOP_CAPTURE)
	{
		// Starting to save screenshot
		g_TakingScreenshot = true;
	}

	if (state == Optick::State::DUMP_CAPTURE)
	{
		// Wait for screenshot to be ready
		// Returning false from this function will force Optick to retry again the next frame
		if (g_TakingScreenshot)
			return false;

		// Attach screenshot
		Optick::AttachFile(Optick::File::OPTICK_IMAGE, "Screenshot.bmp", g_ScreenshotRequest.c_str());
		
		// Attach text file
		const char* textFile = "You could attach custom text files!";
		Optick::AttachFile(Optick::File::OPTICK_TEXT, "Test.txt", (uint8_t*)textFile, (uint32_t)strlen(textFile));
		
		// Attaching some custom data
		Optick::AttachSummary("Build", __DATE__ " " __TIME__);
	}
	return true;
}
OPTICK_SET_STATE_CHANGED_CALLBACK(OnOptickStateChanged);
#endif

OPTICK_SET_MEMORY_ALLOCATOR(ALLOCATE_FUNCTION, DEALLOCATE_FUNCTION);

A macro for overriding defauult memory allocator.
Example:

OPTICK_SET_MEMORY_ALLOCATOR(
	[](size_t size) -> void* { return operator new(size); }, 
	[](void* p) { operator delete(p); }, 
	[]() { /* Do some TLS initialization here if needed */ }
);

OPTICK_SHUTDOWN();

Releases all the internal memory.

GPU API

OPTICK_GPU_INIT_D3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS);

Initializes DirectX12 GPU Profiler. Allocates a heap for 8192 timestamp queries.
Check WindowsD3D12 Sample for more details.

ID3D12Device* pDevice = m_device.Get();
ID3D12CommandQueue* pCommandQueue = m_commandQueue.Get();
OPTICK_GPU_INIT_D3D12(pDevice, &pCommandQueue, 1);

OPTICK_GPU_INIT_VULKAN(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS);

Initializes Vulkan GPU Profiler. Allocates a heap for 8192 timestamp queries.
Check WindowsVulkan Sample for more details.

OPTICK_GPU_INIT_VULKAN(&device, &physicalDevice, &queue, &vulkanDevice->queueFamilyIndices.graphics, 1);

OPTICK_GPU_CONTEXT(COMMAND_LIST);

Scoped macro for declaring current command list/buffer.

OPTICK_GPU_CONTEXT(pShadowCommandList);
OPTICK_GPU_EVENT("DrawShadows");
for (int j = 0; j < _countof(SampleAssets::Draws); ++j)
{
	OPTICK_GPU_EVENT("DrawIndexedInstanced");
        ...
}

OPTICK_GPU_EVENT(NAME);

Scoped GPU event.

OPTICK_GPU_EVENT("DrawShadows");

OPTICK_GPU_FLIP(SWAP_CHAIN);

This macro should be called just before present.

{
	OPTICK_GPU_FLIP(m_swapChain.Get());
	OPTICK_CATEGORY("Present", Optick::Category::Wait);
	ThrowIfFailed(m_swapChain->Present(1, 0));
}

OPTICK_APP(APP_NAME);

A macro for profiling general purpose application: exporters, tests, converters, etc.

int main()
{
        // Generate an Optick capture for the current scope (whole program)
        // Saves capture to the currnet working dir: e.g. ConsoleApp(2019-08-11.23-45-17).opt
        OPTICK_APP("ConsoleApp"); 
	...
        return 0;
}

Automation

OPTICK_START_CAPTURE();

Start a new Optick capture.

OPTICK_STOP_CAPTURE();

Stop an active Optick capture.

OPTICK_SAVE_CAPTURE();

Save an active Optick capture.
Note:

  • By default OPTICK_SAVE_CAPTURE(); generates a capture in current working directory: e.g. "capture(2019-08-11.23-45-17).opt"
  • You could override the name of the capture by passing name of the capture with extension: OPTICK_SAVE_CAPTURE("capture.opt");
  • You could pass folder name OPTICK_SAVE_CAPTURE("d:/captures/game"); to generate a capture in this folder: e.g. "d:/captures/game(2019-08-11.23-45-17).opt"
bool g_ProfileStartup = true;

int main() {
        if (g_ProfileStartup) {
             OPTICK_START_CAPTURE();
        }

        init();

        if (g_ProfileStartup) {
             OPTICK_STOP_CAPTURE();
             // Wait for any dependencies here if needed (e.g. screenshot)
             ...
             // Save capture to the current working directory: e.g. "capture(2019-08-11.23-45-17).opt"
             OPTICK_SAVE_CAPTURE();
        }

        while (true) {
             OPTICK_FRAME("MainThread");
             Update();
        }
}
Clone this wiki locally