Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 82 additions & 4 deletions IGLU/imgui/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <IGLU/simple_renderer/Material.h>
#include <igl/ShaderCreator.h>

// D3D12 FXC precompiled shaders
#include "imgui_vs_d3d12_fxc.h"
#include "imgui_ps_d3d12_fxc.h"

namespace iglu::imgui {

/* internal renderer -- based on imgui_impl_metal.mm */
Expand Down Expand Up @@ -128,6 +132,51 @@ void main() {
})";
}

static const char* getD3D12VertexShaderSource() {
return R"(
cbuffer Uniforms : register(b0) {
float4x4 projectionMatrix;
};

struct VSInput {
float2 position : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};

struct PSInput {
float4 position : SV_Position;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};

PSInput main(VSInput input) {
PSInput output;
// Column-major multiplication to match the CPU-side matrix format
// In HLSL: mul(vector, matrix) treats matrix as column-major
output.position = mul(float4(input.position.xy, 0, 1), projectionMatrix);
output.color = input.color;
output.uv = input.uv;
return output;
})";
}

static const char* getD3D12FragmentShaderSource() {
return R"(
struct PSInput {
float4 position : SV_Position;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};

Texture2D tex : register(t0);
SamplerState uSampler : register(s0);

float4 main(PSInput input) : SV_Target {
return input.color * tex.Sample(uSampler, input.uv);
})";
}

static std::unique_ptr<igl::IShaderStages> getShaderStagesForBackend(igl::IDevice& device) {
igl::Result result;
switch (device.getBackendType()) {
Expand All @@ -145,6 +194,19 @@ static std::unique_ptr<igl::IShaderStages> getShaderStagesForBackend(igl::IDevic
&result);
break;
}
case igl::BackendType::D3D12: {
return igl::ShaderStagesCreator::fromModuleBinaryInput(device,
_tmp_imgui_vs_fxc_cso,
_tmp_imgui_vs_fxc_cso_len,
"main",
"Shader Module: imgui::vertex (D3D12)",
_tmp_imgui_ps_fxc_cso,
_tmp_imgui_ps_fxc_cso_len,
"main",
"Shader Module: imgui::fragment (D3D12)",
&result);
break;
}
// @fb-only
// @fb-only
// @fb-only
Expand Down Expand Up @@ -296,7 +358,10 @@ Session::Renderer::Renderer(igl::IDevice& device) {
material_->blendMode = iglu::material::BlendMode::Translucent();

// @fb-only
if (device.getBackendType() != igl::BackendType::Vulkan) {
// D3D12 and Vulkan use direct slot binding, OpenGL/Metal use named binding
const bool usesDirectBinding = (device.getBackendType() == igl::BackendType::Vulkan ||
device.getBackendType() == igl::BackendType::D3D12);
if (!usesDirectBinding) {
material_->shaderUniforms().setTexture("texture", fontTexture_.get(), linearSampler_);
}
}
Expand Down Expand Up @@ -329,7 +394,14 @@ void Session::Renderer::renderDrawData(igl::IDevice& device,
// framebuffer coordinates)
const int fbWidth = (int)(drawData->DisplaySize.x * drawData->FramebufferScale.x);
const int fbHeight = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y);

IGL_LOG_INFO("ImGui renderDrawData: DisplaySize=(%.1f,%.1f), FramebufferScale=(%.1f,%.1f), fb=(%d,%d), CmdLists=%d, TotalVtx=%d, TotalIdx=%d\n",
drawData->DisplaySize.x, drawData->DisplaySize.y,
drawData->FramebufferScale.x, drawData->FramebufferScale.y,
fbWidth, fbHeight, drawData->CmdListsCount, drawData->TotalVtxCount, drawData->TotalIdxCount);

if (fbWidth <= 0 || fbHeight <= 0 || drawData->CmdListsCount == 0) {
IGL_LOG_INFO("ImGui renderDrawData: Early return (invalid dimensions or no command lists)\n");
return;
}

Expand All @@ -355,7 +427,10 @@ void Session::Renderer::renderDrawData(igl::IDevice& device,
orthoProjection.columns[1] = float4{0.0f, 2.0f / (t - b), 0.0f, 0.0f};
orthoProjection.columns[2] = float4{0.0f, 0.0f, -1.0f, 0.0f};
orthoProjection.columns[3] = float4{(r + l) / (l - r), (t + b) / (b - t), 0.0f, 1.0f};
if (device.getBackendType() != igl::BackendType::Vulkan) {
// D3D12 and Vulkan use direct slot binding, OpenGL/Metal use named binding
const bool usesDirectBinding = (device.getBackendType() == igl::BackendType::Vulkan ||
device.getBackendType() == igl::BackendType::D3D12);
if (!usesDirectBinding) {
material_->shaderUniforms().setFloat4x4(igl::genNameHandle("projectionMatrix"),
orthoProjection);
}
Expand All @@ -371,6 +446,8 @@ void Session::Renderer::renderDrawData(igl::IDevice& device,

const bool isOpenGL = device.getBackendType() == igl::BackendType::OpenGL;
const bool isVulkan = device.getBackendType() == igl::BackendType::Vulkan;
const bool isD3D12 = device.getBackendType() == igl::BackendType::D3D12;
const bool usesDirectBinding = isVulkan || isD3D12;

ImTextureID lastBoundTextureId = nullptr;

Expand Down Expand Up @@ -413,7 +490,8 @@ void Session::Renderer::renderDrawData(igl::IDevice& device,
if (cmd.TextureId != lastBoundTextureId) {
lastBoundTextureId = cmd.TextureId;
auto* tex = reinterpret_cast<igl::ITexture*>(cmd.TextureId);
if (isVulkan) {
if (usesDirectBinding) {
// D3D12 and Vulkan use direct slot binding
// @fb-only
// Add Vulkan support for texture reflection info in ShaderUniforms so we don't need to
// bind the texture directly
Expand All @@ -431,7 +509,7 @@ void Session::Renderer::renderDrawData(igl::IDevice& device,
drawableData.drawable->draw(device,
cmdEncoder,
renderPipelineDesc_,
isVulkan ? sizeof(orthoProjection) : 0,
usesDirectBinding ? sizeof(orthoProjection) : 0,
&orthoProjection);
}
}
Expand Down
25 changes: 25 additions & 0 deletions IGLU/imgui/compile_shaders.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@echo off
REM Compile D3D12 ImGui shaders

set FXC="C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\fxc.exe"

echo Compiling vertex shader...
%FXC% /T vs_5_0 /E main /Fo imgui_vs_d3d12_fxc.cso imgui_vs_d3d12.hlsl
if %ERRORLEVEL% NEQ 0 (
echo Vertex shader compilation failed!
exit /b 1
)

echo Compiling pixel shader...
%FXC% /T ps_5_0 /E main /Fo imgui_ps_d3d12_fxc.cso imgui_ps_d3d12.hlsl
if %ERRORLEVEL% NEQ 0 (
echo Pixel shader compilation failed!
exit /b 1
)

echo Converting to C header files...
python -c "import sys; data = open('imgui_vs_d3d12_fxc.cso', 'rb').read(); print('unsigned char _tmp_imgui_vs_fxc_cso[] = {'); print(', '.join(f'0x{b:02x}' for b in data)); print('};'); print(f'unsigned int _tmp_imgui_vs_fxc_cso_len = {len(data)};')" > imgui_vs_d3d12_fxc.h

python -c "import sys; data = open('imgui_ps_d3d12_fxc.cso', 'rb').read(); print('unsigned char _tmp_imgui_ps_fxc_cso[] = {'); print(', '.join(f'0x{b:02x}' for b in data)); print('};'); print(f'unsigned int _tmp_imgui_ps_fxc_cso_len = {len(data)};')" > imgui_ps_d3d12_fxc.h

echo Done!
57 changes: 57 additions & 0 deletions IGLU/imgui/compile_shaders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Compile D3D12 ImGui shaders"""

import os
import subprocess
import sys

FXC = r"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\fxc.exe"

def compile_shader(shader_file, profile, output_cso):
"""Compile HLSL shader to CSO"""
print(f"Compiling {shader_file}...")
cmd = [FXC, "/T", profile, "/E", "main", "/Fo", output_cso, shader_file]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"ERROR: {result.stderr}")
return False
print(f" SUCCESS: {output_cso}")
return True

def cso_to_header(cso_file, header_file, var_name):
"""Convert CSO binary to C header"""
print(f"Converting {cso_file} to {header_file}...")
with open(cso_file, 'rb') as f:
data = f.read()

with open(header_file, 'w') as f:
f.write(f"unsigned char {var_name}[] = {{\n")
for i in range(0, len(data), 12):
chunk = data[i:i+12]
hex_bytes = ', '.join(f'0x{b:02x}' for b in chunk)
f.write(f" {hex_bytes},\n")
f.write("};\n")
f.write(f"unsigned int {var_name}_len = {len(data)};\n")

print(f" SUCCESS: {header_file} ({len(data)} bytes)")

def main():
os.chdir(os.path.dirname(os.path.abspath(__file__)))

# Compile vertex shader
if not compile_shader("imgui_vs_d3d12.hlsl", "vs_5_0", "imgui_vs_d3d12_fxc.cso"):
return 1

# Compile pixel shader
if not compile_shader("imgui_ps_d3d12.hlsl", "ps_5_0", "imgui_ps_d3d12_fxc.cso"):
return 1

# Convert to headers
cso_to_header("imgui_vs_d3d12_fxc.cso", "imgui_vs_d3d12_fxc.h", "_tmp_imgui_vs_fxc_cso")
cso_to_header("imgui_ps_d3d12_fxc.cso", "imgui_ps_d3d12_fxc.h", "_tmp_imgui_ps_fxc_cso")

print("\nAll shaders compiled successfully!")
return 0

if __name__ == "__main__":
sys.exit(main())
12 changes: 12 additions & 0 deletions IGLU/imgui/imgui_ps_d3d12.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
struct PSInput {
float4 position : SV_Position;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};

Texture2D tex : register(t0);
SamplerState uSampler : register(s0);

float4 main(PSInput input) : SV_Target {
return input.color * tex.Sample(uSampler, input.uv);
}
Binary file added IGLU/imgui/imgui_ps_d3d12_fxc.cso
Binary file not shown.
3 changes: 3 additions & 0 deletions IGLU/imgui/imgui_ps_d3d12_fxc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
unsigned char _tmp_imgui_ps_fxc_cso[] = {
0x44, 0x58, 0x42, 0x43, 0xc7, 0x1a, 0xe2, 0x1a, 0x98, 0xf2, 0xe6, 0x19, 0xb5, 0xee, 0x27, 0x5c, 0x23, 0xba, 0x44, 0xe8, 0x01, 0x00, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x75, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x74, 0x65, 0x78, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2e, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0xa0, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x8b, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned int _tmp_imgui_ps_fxc_cso_len = 732;
23 changes: 23 additions & 0 deletions IGLU/imgui/imgui_vs_d3d12.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cbuffer PushConstants : register(b2) {
float4x4 projectionMatrix;
};

struct VSInput {
float2 position : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};

struct PSInput {
float4 position : SV_Position;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};

PSInput main(VSInput input) {
PSInput output;
output.position = mul(projectionMatrix, float4(input.position.xy, 0, 1));
output.color = input.color;
output.uv = input.uv;
return output;
}
Binary file added IGLU/imgui/imgui_vs_d3d12_fxc.cso
Binary file not shown.
Loading
Loading