Skip to content

Commit f67e320

Browse files
Added SHADER_COMPILE_FLAG_HLSL_TO_SPIRV_VIA_GLSL flag (API256008)
1 parent 5e1f642 commit f67e320

File tree

6 files changed

+35
-8
lines changed

6 files changed

+35
-8
lines changed

Graphics/GraphicsEngine/interface/APIInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
/// \file
3131
/// Diligent API information
3232

33-
#define DILIGENT_API_VERSION 256007
33+
#define DILIGENT_API_VERSION 256008
3434

3535
#include "../../../Primitives/interface/BasicTypes.h"
3636

Graphics/GraphicsEngine/interface/Shader.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,29 @@ DILIGENT_TYPED_ENUM(SHADER_COMPILE_FLAGS, Uint32)
369369
/// they are laid out in memory row-by-row.
370370
SHADER_COMPILE_FLAG_PACK_MATRIX_ROW_MAJOR = 1u << 3u,
371371

372-
SHADER_COMPILE_FLAG_LAST = SHADER_COMPILE_FLAG_PACK_MATRIX_ROW_MAJOR
372+
/// Convert HLSL to GLSL when compiling HLSL shaders to SPIRV.
373+
///
374+
/// \remarks HLSL shaders can be compiled to SPIRV directly using either DXC or glslang.
375+
/// While glslang supports most HLSL 5.1 features, some Vulkan-specific functionality
376+
/// is missing. Notably, glslang does not support UAV texture format annotations
377+
/// (see https://github.com/KhronosGroup/glslang/issues/3790), for example:
378+
///
379+
/// [[vk::image_format("rgba8")]] RWTexture2D<float4> g_rwTexture;
380+
///
381+
/// This flag provides a workaround by converting HLSL to GLSL before compiling it
382+
/// to SPIRV. The converter supports specially formatted comments to specify UAV
383+
/// texture formats:
384+
///
385+
/// RWTexture2D<float4 /*format = rgba8*/> g_rwTexture;
386+
///
387+
/// Another use case for this flag is to leverage GLSL-specific keywords in HLSL
388+
/// shaders, such as `gl_DrawID` for multi-draw or manually setting `gl_PointSize`.
389+
///
390+
/// \note This flag only takes effect when compiling HLSL to SPIRV with glslang.
391+
/// Since DXC does not support GLSL, this flag is ignored when SHADER_COMPILER_DXC is used.
392+
SHADER_COMPILE_FLAG_HLSL_TO_SPIRV_VIA_GLSL = 1u << 4u,
393+
394+
SHADER_COMPILE_FLAG_LAST = SHADER_COMPILE_FLAG_HLSL_TO_SPIRV_VIA_GLSL
373395
};
374396
DEFINE_FLAG_ENUM_OPERATORS(SHADER_COMPILE_FLAGS);
375397

Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -73,7 +73,7 @@ class D3DIncludeImpl : public ID3DInclude
7373
return E_FAIL;
7474
}
7575

76-
auto pFileData = DataBlobImpl::Create();
76+
RefCntAutoPtr<DataBlobImpl> pFileData = DataBlobImpl::Create();
7777
pSourceStream->ReadBlob(pFileData);
7878
*ppData = pFileData->GetDataPtr();
7979
*pBytes = StaticCast<UINT>(pFileData->GetSize());
@@ -115,7 +115,7 @@ HRESULT CompileShader(const char* Source,
115115
// dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3;
116116
#endif
117117

118-
static_assert(SHADER_COMPILE_FLAG_LAST == 1u << 3u, "Did you add a new shader compile flag? You may need to handle it here.");
118+
static_assert(SHADER_COMPILE_FLAG_LAST == 1u << 4u, "Did you add a new shader compile flag? You may need to handle it here.");
119119
if (ShaderCI.CompileFlags & SHADER_COMPILE_FLAG_ENABLE_UNBOUNDED_ARRAYS)
120120
dwShaderFlags |= D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES;
121121

@@ -177,7 +177,7 @@ RefCntAutoPtr<IDataBlob> CompileD3DBytecode(const ShaderCreateInfo& ShaderCI,
177177
CComPtr<ID3DBlob> CompilerOutput;
178178
CComPtr<ID3DBlob> pShaderByteCode;
179179

180-
auto hr = CompileShader(HLSLSource.c_str(), HLSLSource.length(), ShaderCI, Profile.c_str(), &pShaderByteCode, &CompilerOutput);
180+
HRESULT hr = CompileShader(HLSLSource.c_str(), HLSLSource.length(), ShaderCI, Profile.c_str(), &pShaderByteCode, &CompilerOutput);
181181
HandleHLSLCompilerResult(SUCCEEDED(hr), CompilerOutput.p, HLSLSource, ShaderCI.Desc.Name, ppCompilerOutput);
182182
return DataBlobImpl::Create(pShaderByteCode->GetBufferSize(), pShaderByteCode->GetBufferPointer());
183183
}

Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ std::vector<uint32_t> CompileShaderGLSLang(const ShaderCreateInfo& Shade
9898
#if DILIGENT_NO_GLSLANG
9999
LOG_ERROR_AND_THROW("Diligent engine was not linked with glslang, use DXC or precompiled SPIRV bytecode.");
100100
#else
101-
if (ShaderCI.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL)
101+
if (ShaderCI.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL && (ShaderCI.CompileFlags & SHADER_COMPILE_FLAG_HLSL_TO_SPIRV_VIA_GLSL) == 0)
102102
{
103103
SPIRV = GLSLangUtils::HLSLtoSPIRV(ShaderCI, GLSLangUtils::SpirvVersion::Vk100, VulkanDefine, VkShaderCI.ppCompilerOutput);
104104
}

Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -458,10 +458,12 @@ void DeviceMemoryBarrier()
458458
// returns with no other effect.
459459
memoryBarrierImage();
460460

461+
#ifndef VULKAN
461462
// OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of
462463
// all accesses resulting from the use of ATOMIC COUNTERS and then returns
463464
// with no other effect.
464465
memoryBarrierAtomicCounter();
466+
#endif
465467
}
466468

467469
// MSDN: DeviceMemoryBarrierWithGroupSync() blocks execution of
@@ -502,10 +504,12 @@ void AllMemoryBarrier()
502504
// returns with no other effect.
503505
memoryBarrierImage();
504506

507+
#ifndef VULKAN
505508
// OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of
506509
// all accesses resulting from the use of ATOMIC COUNTERS and then returns
507510
// with no other effect.
508511
memoryBarrierAtomicCounter();
512+
#endif
509513

510514
// groupMemoryBarrier waits on the completion of all memory accesses performed
511515
// by an invocation of a compute shader relative to the same access performed by

ReleaseHistory.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Current progress
22

3+
* Added `SHADER_COMPILE_FLAG_HLSL_TO_SPIRV_VIA_GLSL` flag (API256008)
34
* Added `IRenderDevice::CreateDeferredContext()` method (API256007)
45
* Added `HostImageCopy` member to `DeviceFeaturesVk` struct (API256006)
56
* Added `IRenderDeviceVk::GetDeviceFeaturesVk()` method (API256005)

0 commit comments

Comments
 (0)