From 5f7fd914619f9e429ae6d5a140e211691e382e15 Mon Sep 17 00:00:00 2001 From: dzhdan Date: Thu, 29 Aug 2024 13:58:48 +0800 Subject: [PATCH] v1.143: HIGHLIGHTS: - NRI: added shading rate support (aka VRS) for all GAPIs, including D3D11 - bug fixes and improvements BREAKING_CHANGES: - "DEPTH_STENCIL" in "Layout" and "Access" renamed to "DEPTH_STENCIL_ATTACHMENT" to emphasize the stage DETAILS: - D3D11/D3D12/VK/Validation: added shading rate support - D3D11: fixed 0 values potentially sneaking into internally used "m_SubresourceInfo" - D3D11: fixed "ForcedSampleCount" usage - D3D11/D3D12: improved NVAPI usage and fixed some bugs - VK: hooked up "VK_EXT_image_sliced_view_of_3d" - VK: implemented read-only depth and/or stencil - VK: 3D textures get created with "VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT" flag for flexibility and compatibility - Validation: reduced code entropy - added ".clang-format-ignore" - updated docs --- .clang-format-ignore | 1 + Include/Extensions/NRIMeshShader.h | 1 + Include/Extensions/NRIRayTracing.h | 10 +- Include/NRI.h | 36 +- Include/NRICompatibility.hlsli | 3 + Include/NRIDescs.h | 115 +++- Resources/Version.h | 2 +- Source/D3D11/BufferD3D11.cpp | 4 +- Source/D3D11/CommandBufferD3D11.cpp | 51 +- Source/D3D11/CommandBufferD3D11.h | 2 + Source/D3D11/CommandBufferD3D11.hpp | 4 + Source/D3D11/CommandBufferEmuD3D11.cpp | 12 + Source/D3D11/CommandBufferEmuD3D11.h | 1 + Source/D3D11/CommandBufferEmuD3D11.hpp | 5 + Source/D3D11/DescriptorD3D11.cpp | 338 ++++++----- Source/D3D11/DescriptorD3D11.h | 10 +- Source/D3D11/DeviceD3D11.cpp | 23 +- Source/D3D11/DeviceD3D11.h | 2 +- Source/D3D11/FenceD3D11.cpp | 10 +- Source/D3D11/PipelineD3D11.cpp | 11 +- Source/D3D11/PipelineLayoutD3D11.cpp | 11 +- Source/D3D11/SharedD3D11.h | 2 + Source/D3D11/SwapChainD3D11.cpp | 4 +- Source/D3D12/CommandBufferD3D12.cpp | 47 +- Source/D3D12/CommandBufferD3D12.h | 1 + Source/D3D12/CommandBufferD3D12.hpp | 4 + Source/D3D12/DescriptorD3D12.cpp | 6 +- Source/D3D12/DeviceD3D12.cpp | 12 +- Source/D3D12/FenceD3D12.cpp | 8 +- Source/D3D12/SharedD3D12.cpp | 377 ++++++------ Source/D3D12/SharedD3D12.h | 2 + Source/D3D12/SwapChainD3D12.cpp | 4 +- Source/D3D12/TextureD3D12.cpp | 3 +- Source/Shared/D3DExt.hpp | 30 +- Source/Shared/DeviceBase.h | 1 + Source/Shared/SharedExternal.h | 10 +- Source/VK/CommandBufferVK.cpp | 33 +- Source/VK/CommandBufferVK.h | 1 + Source/VK/CommandBufferVK.hpp | 4 + Source/VK/CommandQueueVK.cpp | 4 +- Source/VK/ConversionVK.h | 564 ++++++++++-------- Source/VK/DescriptorVK.cpp | 201 ++++--- Source/VK/DescriptorVK.h | 2 + Source/VK/DeviceVK.cpp | 34 +- Source/VK/DeviceVK.h | 19 +- Source/VK/DispatchTable.h | 3 + Source/VK/FenceVK.cpp | 2 +- Source/VK/PipelineVK.cpp | 10 +- .../Validation/AccelerationStructureVal.cpp | 4 +- Source/Validation/BufferVal.cpp | 6 +- Source/Validation/CommandBufferVal.cpp | 241 ++++---- Source/Validation/CommandBufferVal.h | 1 + Source/Validation/CommandBufferVal.hpp | 4 + Source/Validation/CommandQueueVal.cpp | 46 +- Source/Validation/DescriptorPoolVal.cpp | 10 +- Source/Validation/DescriptorSetVal.cpp | 42 +- Source/Validation/DescriptorVal.cpp | 5 +- Source/Validation/DescriptorVal.h | 3 +- Source/Validation/DeviceVal.cpp | 327 +++++----- Source/Validation/DeviceVal.h | 6 +- Source/Validation/DeviceVal.hpp | 8 +- Source/Validation/SharedVal.h | 17 +- 62 files changed, 1605 insertions(+), 1155 deletions(-) create mode 100644 .clang-format-ignore diff --git a/.clang-format-ignore b/.clang-format-ignore new file mode 100644 index 00000000..95828ab5 --- /dev/null +++ b/.clang-format-ignore @@ -0,0 +1 @@ +External/* \ No newline at end of file diff --git a/Include/Extensions/NRIMeshShader.h b/Include/Extensions/NRIMeshShader.h index 0fdd34ee..086fc341 100644 --- a/Include/Extensions/NRIMeshShader.h +++ b/Include/Extensions/NRIMeshShader.h @@ -13,6 +13,7 @@ NRI_STRUCT(DrawMeshTasksDesc) NRI_STRUCT(MeshShaderInterface) { + // Draw void (NRI_CALL *CmdDrawMeshTasks)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(DrawMeshTasksDesc) drawMeshTasksDesc); void (NRI_CALL *CmdDrawMeshTasksIndirect)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Buffer) buffer, uint64_t offset, uint32_t drawNum, uint32_t stride); // buffer contains "DrawMeshTasksDesc" commands }; diff --git a/Include/Extensions/NRIRayTracing.h b/Include/Extensions/NRIRayTracing.h index 72e2fc21..c6fe5313 100644 --- a/Include/Extensions/NRIRayTracing.h +++ b/Include/Extensions/NRIRayTracing.h @@ -217,7 +217,7 @@ NRI_STRUCT(RayTracingInterface) // Shader table NRI_NAME(Result) (NRI_CALL *WriteShaderGroupIdentifiers)(const NRI_NAME_REF(Pipeline) pipeline, uint32_t baseShaderGroupIndex, uint32_t shaderGroupNum, void* buffer); // TODO: add stride - // Command buffer + // Compute void (NRI_CALL *CmdBuildTopLevelAccelerationStructure)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint32_t instanceNum, const NRI_NAME_REF(Buffer) buffer, uint64_t bufferOffset, NRI_NAME(AccelerationStructureBuildBits) flags, NRI_NAME_REF(AccelerationStructure) dst, NRI_NAME_REF(Buffer) scratch, uint64_t scratchOffset); void (NRI_CALL *CmdBuildBottomLevelAccelerationStructure)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint32_t geometryObjectNum, const NRI_NAME(GeometryObject)* geometryObjects, @@ -227,13 +227,13 @@ NRI_STRUCT(RayTracingInterface) void (NRI_CALL *CmdUpdateBottomLevelAccelerationStructure)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint32_t geometryObjectNum, const NRI_NAME(GeometryObject)* geometryObjects, NRI_NAME(AccelerationStructureBuildBits) flags, NRI_NAME_REF(AccelerationStructure) dst, NRI_NAME_REF(AccelerationStructure) src, NRI_NAME_REF(Buffer) scratch, uint64_t scratchOffset); - void (NRI_CALL *CmdCopyAccelerationStructure)(NRI_NAME_REF(CommandBuffer) commandBuffer, NRI_NAME_REF(AccelerationStructure) dst, NRI_NAME_REF(AccelerationStructure) src, NRI_NAME(CopyMode) copyMode); - void (NRI_CALL *CmdWriteAccelerationStructureSize)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(AccelerationStructure)* const* accelerationStructures, uint32_t accelerationStructureNum, - NRI_NAME_REF(QueryPool) queryPool, uint32_t queryPoolOffset); - void (NRI_CALL *CmdDispatchRays)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(DispatchRaysDesc) dispatchRaysDesc); void (NRI_CALL *CmdDispatchRaysIndirect)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Buffer) buffer, uint64_t offset); // buffer contains "DispatchRaysIndirectDesc" commands + // Copy + void (NRI_CALL *CmdCopyAccelerationStructure)(NRI_NAME_REF(CommandBuffer) commandBuffer, NRI_NAME_REF(AccelerationStructure) dst, NRI_NAME_REF(AccelerationStructure) src, NRI_NAME(CopyMode) copyMode); + void (NRI_CALL *CmdWriteAccelerationStructureSize)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(AccelerationStructure)* const* accelerationStructures, uint32_t accelerationStructureNum, NRI_NAME_REF(QueryPool) queryPool, uint32_t queryPoolOffset); + // Debug name void (NRI_CALL *SetAccelerationStructureDebugName)(NRI_NAME_REF(AccelerationStructure) accelerationStructure, const char* name); diff --git a/Include/NRI.h b/Include/NRI.h index 040cf6d9..5e9e7c10 100644 --- a/Include/NRI.h +++ b/Include/NRI.h @@ -25,8 +25,8 @@ Non-goals: #include #define NRI_VERSION_MAJOR 1 -#define NRI_VERSION_MINOR 142 -#define NRI_VERSION_DATE "26 August 2024" +#define NRI_VERSION_MINOR 143 +#define NRI_VERSION_DATE "29 August 2024" #ifdef _WIN32 #define NRI_CALL __fastcall @@ -116,12 +116,23 @@ NRI_STRUCT(CoreInterface) void (NRI_CALL *CmdSetPipeline)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Pipeline) pipeline); void (NRI_CALL *CmdSetConstants)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint32_t pushConstantIndex, const void* data, uint32_t size); - // Barrier (can be used inside "Graphics" with limited functionality) + // Barrier void (NRI_CALL *CmdBarrier)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(BarrierGroupDesc) barrierGroupDesc); - // Mandatory state, if enabled (can be set only once) - // Interacts with PSL enabled pipelines. Affects any depth-stencil operations, including clear and copy + // Input assembly + void (NRI_CALL *CmdSetIndexBuffer)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Buffer) buffer, uint64_t offset, NRI_NAME(IndexType) indexType); + void (NRI_CALL *CmdSetVertexBuffers)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint32_t baseSlot, uint32_t bufferNum, const NRI_NAME(Buffer)* const* buffers, const uint64_t* offsets); + + // Mandatory state for "Graphics" + void (NRI_CALL *CmdSetViewports)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(Viewport)* viewports, uint32_t viewportNum); + void (NRI_CALL *CmdSetScissors)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(Rect)* rects, uint32_t rectNum); + + // Mandatory state for "Graphics", if enabled in the pipeline (since this state is global in D3D11/D3D12 better treat it as global) + void (NRI_CALL *CmdSetStencilReference)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint8_t frontRef, uint8_t backRef); // "backRef" requires "isIndependentFrontAndBackStencilReferenceAndMasksSupported" + void (NRI_CALL *CmdSetDepthBounds)(NRI_NAME_REF(CommandBuffer) commandBuffer, float boundsMin, float boundsMax); + void (NRI_CALL *CmdSetBlendConstants)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Color32f) color); void (NRI_CALL *CmdSetSamplePositions)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(SamplePosition)* positions, NRI_NAME(Sample_t) positionNum, NRI_NAME(Sample_t) sampleNum); + void (NRI_CALL *CmdSetShadingRate)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(ShadingRateDesc) shadingRateDesc); // Graphics void (NRI_CALL *CmdBeginRendering)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(AttachmentsDesc) attachmentsDesc); @@ -129,19 +140,6 @@ NRI_STRUCT(CoreInterface) // Fast clear void (NRI_CALL *CmdClearAttachments)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(ClearDesc)* clearDescs, uint32_t clearDescNum, const NRI_NAME(Rect)* rects, uint32_t rectNum); - // Mandatory state (can be set only once) - void (NRI_CALL *CmdSetViewports)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(Viewport)* viewports, uint32_t viewportNum); - void (NRI_CALL *CmdSetScissors)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME(Rect)* rects, uint32_t rectNum); - - // Mandatory state, if enabled (can be set only once) - void (NRI_CALL *CmdSetStencilReference)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint8_t frontRef, uint8_t backRef); // "backRef" requires "isIndependentFrontAndBackStencilReferenceAndMasksSupported" - void (NRI_CALL *CmdSetDepthBounds)(NRI_NAME_REF(CommandBuffer) commandBuffer, float boundsMin, float boundsMax); - void (NRI_CALL *CmdSetBlendConstants)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Color32f) color); - - // Input assembly - void (NRI_CALL *CmdSetIndexBuffer)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(Buffer) buffer, uint64_t offset, NRI_NAME(IndexType) indexType); - void (NRI_CALL *CmdSetVertexBuffers)(NRI_NAME_REF(CommandBuffer) commandBuffer, uint32_t baseSlot, uint32_t bufferNum, const NRI_NAME(Buffer)* const* buffers, const uint64_t* offsets); - // Draw void (NRI_CALL *CmdDraw)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(DrawDesc) drawDesc); void (NRI_CALL *CmdDrawIndexed)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(DrawIndexedDesc) drawIndexedDesc); @@ -166,7 +164,7 @@ NRI_STRUCT(CoreInterface) void (NRI_CALL *CmdUploadBufferToTexture)(NRI_NAME_REF(CommandBuffer) commandBuffer, NRI_NAME_REF(Texture) dstTexture, const NRI_NAME_REF(TextureRegionDesc) dstRegionDesc, const NRI_NAME_REF(Buffer) srcBuffer, const NRI_NAME_REF(TextureDataLayoutDesc) srcDataLayoutDesc); void (NRI_CALL *CmdReadbackTextureToBuffer)(NRI_NAME_REF(CommandBuffer) commandBuffer, NRI_NAME_REF(Buffer) dstBuffer, NRI_NAME_REF(TextureDataLayoutDesc) dstDataLayoutDesc, const NRI_NAME_REF(Texture) srcTexture, const NRI_NAME_REF(TextureRegionDesc) srcRegionDesc); - // Clear storage (slow clear) + // Clear storage (potentially slow clear) void (NRI_CALL *CmdClearStorageBuffer)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(ClearStorageBufferDesc) clearDesc); void (NRI_CALL *CmdClearStorageTexture)(NRI_NAME_REF(CommandBuffer) commandBuffer, const NRI_NAME_REF(ClearStorageTextureDesc) clearDesc); diff --git a/Include/NRICompatibility.hlsli b/Include/NRICompatibility.hlsli index c0368994..fdcd18f5 100644 --- a/Include/NRICompatibility.hlsli +++ b/Include/NRICompatibility.hlsli @@ -115,6 +115,9 @@ Draw parameters: NRI_BUFFER_WRITE(buffer, cmdIndex * 7, 5, baseVertex); \ NRI_BUFFER_WRITE(buffer, cmdIndex * 7, 6, baseInstance) +// Shading rate +#define NRI_SHADING_RATE(xLogSize, yLogSize) ((xLogSize << 2) | yLogSize) + // SPIRV #ifdef NRI_SPIRV #define NRI_RESOURCE(resourceType, name, regName, bindingIndex, setIndex) \ diff --git a/Include/NRIDescs.h b/Include/NRIDescs.h index 5eac31c6..3c3201c1 100644 --- a/Include/NRIDescs.h +++ b/Include/NRIDescs.h @@ -86,7 +86,7 @@ NRI_ENUM // Plain: 8 bits per channel R8_UNORM, // + + + - + - + + + - R8_SNORM, // + + + - + - + + + - - R8_UINT, // + + + - - - + + + - + R8_UINT, // + + + - - - + + + - // SHADING_RATE compatible R8_SINT, // + + + - - - + + + - RG8_UNORM, // + + + - + - + + + - @@ -381,6 +381,7 @@ NRI_ENUM SHADER_RESOURCE_STORAGE_2D_ARRAY, COLOR_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT, + SHADING_RATE_ATTACHMENT, MAX_NUM ); @@ -432,7 +433,8 @@ NRI_ENUM_BITS SHADER_RESOURCE = NRI_SET_BIT(0), SHADER_RESOURCE_STORAGE = NRI_SET_BIT(1), COLOR_ATTACHMENT = NRI_SET_BIT(2), - DEPTH_STENCIL_ATTACHMENT = NRI_SET_BIT(3) + DEPTH_STENCIL_ATTACHMENT = NRI_SET_BIT(3), + SHADING_RATE_ATTACHMENT = NRI_SET_BIT(4) ); NRI_ENUM_BITS @@ -454,6 +456,7 @@ NRI_ENUM_BITS ( ResourceViewBits, uint8_t, + NONE = 0, READONLY_DEPTH = NRI_SET_BIT(0), READONLY_STENCIL = NRI_SET_BIT(1) ); @@ -513,7 +516,6 @@ NRI_STRUCT(Texture3DViewDesc) NRI_NAME(Mip_t) mipNum; NRI_NAME(Dim_t) sliceOffset; NRI_NAME(Dim_t) sliceNum; - NRI_NAME(ResourceViewBits) flags; }; NRI_STRUCT(BufferViewDesc) @@ -718,6 +720,34 @@ NRI_ENUM MAX_NUM ); +NRI_ENUM +( + ShadingRate, uint8_t, + + _1x1, + _1x2, + _2x1, + _2x2, + _2x4, + _4x2, + _4x4, + + MAX_NUM +); + +NRI_ENUM +( + ShadingRateCombiner, uint8_t, + + REPLACE, + KEEP, + MIN, + MAX, + SUM, + + MAX_NUM +); + NRI_STRUCT(RasterizationDesc) { uint32_t viewportNum; @@ -728,8 +758,15 @@ NRI_STRUCT(RasterizationDesc) NRI_NAME(CullMode) cullMode; bool frontCounterClockwise; bool depthClamp; - bool antialiasedLines; // Requires "isLineSmoothingSupported" - bool conservativeRasterization; // Requires "conservativeRasterTier > 0" + + // Requires "isLineSmoothingSupported" + bool antialiasedLines; + + // Requires "conservativeRasterTier > 0" + bool conservativeRasterization; + + // Requires "is[Pipeline/Primitive/Attachment]ShadingRateSupported", expects "CmdSetShadingRate" and optionally "AttachmentsDesc::shadingRate" + bool shadingRate; }; NRI_STRUCT(MultisampleDesc) @@ -737,7 +774,16 @@ NRI_STRUCT(MultisampleDesc) uint32_t sampleMask; NRI_NAME(Sample_t) sampleNum; bool alphaToCoverage; - bool programmableSampleLocations; // Requires "isProgrammableSampleLocationsSupported" + + // Requires "isProgrammableSampleLocationsSupported", expects "CmdSetSamplePositions" + bool programmableSampleLocations; +}; + +NRI_STRUCT(ShadingRateDesc) +{ + NRI_NAME(ShadingRate) shadingRate; + NRI_NAME(ShadingRateCombiner) primitiveCombiner; + NRI_NAME(ShadingRateCombiner) attachmentCombiner; }; #pragma endregion @@ -749,11 +795,11 @@ NRI_STRUCT(MultisampleDesc) NRI_ENUM ( + // Requires "isLogicOpSupported" LogicFunc, uint8_t, NONE, - // Requires "isLogicOpSupported" // S - source color 0 // D - destination color @@ -940,13 +986,17 @@ NRI_STRUCT(DepthAttachmentDesc) { NRI_NAME(CompareFunc) compareFunc; bool write; - bool boundsTest; // Requires "isDepthBoundsTestSupported", expects "CmdSetDepthBounds" + + // Requires "isDepthBoundsTestSupported", expects "CmdSetDepthBounds" + bool boundsTest; }; NRI_STRUCT(StencilAttachmentDesc) { NRI_NAME(StencilDesc) front; - NRI_NAME(StencilDesc) back; // "back.writeMask" requires "isIndependentFrontAndBackStencilReferenceAndMasksSupported" + + // Requires "isIndependentFrontAndBackStencilReferenceAndMasksSupported" for "back.writeMask" + NRI_NAME(StencilDesc) back; }; NRI_STRUCT(OutputMergerDesc) @@ -962,6 +1012,7 @@ NRI_STRUCT(OutputMergerDesc) NRI_STRUCT(AttachmentsDesc) { NRI_OPTIONAL const NRI_NAME(Descriptor)* depthStencil; + NRI_OPTIONAL const NRI_NAME(Descriptor)* shadingRate; const NRI_NAME(Descriptor)* const* colors; uint32_t colorNum; }; @@ -999,11 +1050,10 @@ NRI_ENUM NRI_ENUM ( + // Requires "isTextureFilterMinMaxSupported" FilterExt, uint8_t, NONE, - - // Requires "isTextureFilterMinMaxSupported" MIN, MAX, @@ -1091,36 +1141,37 @@ NRI_ENUM UNKNOWN, COLOR_ATTACHMENT, - DEPTH_STENCIL, - DEPTH_STENCIL_READONLY, + DEPTH_STENCIL_ATTACHMENT, + DEPTH_STENCIL_READONLY, // attachment or shader resource SHADER_RESOURCE, SHADER_RESOURCE_STORAGE, COPY_SOURCE, COPY_DESTINATION, PRESENT, + SHADING_RATE_ATTACHMENT, MAX_NUM ); NRI_ENUM_BITS ( - AccessBits, uint16_t, // Compatible "StageBits" (including ALL): - - UNKNOWN = 0, - INDEX_BUFFER = NRI_SET_BIT(0), // INDEX_INPUT - VERTEX_BUFFER = NRI_SET_BIT(1), // VERTEX_SHADER - CONSTANT_BUFFER = NRI_SET_BIT(2), // GRAPHICS_SHADERS, COMPUTE_SHADER, RAY_TRACING_SHADERS - SHADER_RESOURCE = NRI_SET_BIT(3), // GRAPHICS_SHADERS, COMPUTE_SHADER, RAY_TRACING_SHADERS - SHADER_RESOURCE_STORAGE = NRI_SET_BIT(4), // GRAPHICS_SHADERS, COMPUTE_SHADER, RAY_TRACING_SHADERS, CLEAR_STORAGE - ARGUMENT_BUFFER = NRI_SET_BIT(5), // INDIRECT - COLOR_ATTACHMENT = NRI_SET_BIT(6), // COLOR_ATTACHMENT - DEPTH_STENCIL_WRITE = NRI_SET_BIT(7), // DEPTH_STENCIL_ATTACHMENT - DEPTH_STENCIL_READ = NRI_SET_BIT(8), // DEPTH_STENCIL_ATTACHMENT - COPY_SOURCE = NRI_SET_BIT(9), // COPY - COPY_DESTINATION = NRI_SET_BIT(10), // COPY - ACCELERATION_STRUCTURE_READ = NRI_SET_BIT(11), // COMPUTE_SHADER, RAY_TRACING_SHADERS, ACCELERATION_STRUCTURE - ACCELERATION_STRUCTURE_WRITE = NRI_SET_BIT(12), // COMPUTE_SHADER, RAY_TRACING_SHADERS, ACCELERATION_STRUCTURE - SHADING_RATE = NRI_SET_BIT(13) // FRAGMENT_SHADER // TODO: WIP + AccessBits, uint16_t, // Compatible "StageBits" (including ALL): + + UNKNOWN = 0, + INDEX_BUFFER = NRI_SET_BIT(0), // INDEX_INPUT + VERTEX_BUFFER = NRI_SET_BIT(1), // VERTEX_SHADER + CONSTANT_BUFFER = NRI_SET_BIT(2), // GRAPHICS_SHADERS, COMPUTE_SHADER, RAY_TRACING_SHADERS + SHADER_RESOURCE = NRI_SET_BIT(3), // GRAPHICS_SHADERS, COMPUTE_SHADER, RAY_TRACING_SHADERS + SHADER_RESOURCE_STORAGE = NRI_SET_BIT(4), // GRAPHICS_SHADERS, COMPUTE_SHADER, RAY_TRACING_SHADERS, CLEAR_STORAGE + ARGUMENT_BUFFER = NRI_SET_BIT(5), // INDIRECT + COLOR_ATTACHMENT = NRI_SET_BIT(6), // COLOR_ATTACHMENT + DEPTH_STENCIL_ATTACHMENT_WRITE = NRI_SET_BIT(7), // DEPTH_STENCIL_ATTACHMENT + DEPTH_STENCIL_ATTACHMENT_READ = NRI_SET_BIT(8), // DEPTH_STENCIL_ATTACHMENT + COPY_SOURCE = NRI_SET_BIT(9), // COPY + COPY_DESTINATION = NRI_SET_BIT(10), // COPY + ACCELERATION_STRUCTURE_READ = NRI_SET_BIT(11), // COMPUTE_SHADER, RAY_TRACING_SHADERS, ACCELERATION_STRUCTURE + ACCELERATION_STRUCTURE_WRITE = NRI_SET_BIT(12), // COMPUTE_SHADER, RAY_TRACING_SHADERS, ACCELERATION_STRUCTURE + SHADING_RATE_ATTACHMENT = NRI_SET_BIT(13) // FRAGMENT_SHADER ); NRI_STRUCT(AccessStage) @@ -1566,6 +1617,7 @@ NRI_STRUCT(DeviceDesc) uint32_t combinedClipAndCullDistanceMaxNum; uint8_t conservativeRasterTier; uint8_t programmableSampleLocationsTier; + uint8_t shadingRateAttachmentTileSize; // Features uint32_t isComputeQueueSupported : 1; @@ -1582,6 +1634,9 @@ NRI_STRUCT(DeviceDesc) uint32_t isMeshShaderPipelineStatsSupported : 1; uint32_t isEnchancedBarrierSupported : 1; // aka - can "Layout" be ignored? uint32_t isMemoryTier2Supported : 1; // a memory object can support resources from all 3 categories (buffers, attachments, all other textures) + uint32_t isPipelineShadingRateSupported : 1; + uint32_t isPrimitiveShadingRateSupported : 1; + uint32_t isAttachmentShadingRateSupported : 1; // Shader features uint32_t isShaderNativeI16Supported : 1; diff --git a/Resources/Version.h b/Resources/Version.h index 50c93e17..0a56a5d8 100644 --- a/Resources/Version.h +++ b/Resources/Version.h @@ -4,7 +4,7 @@ #define STR(x) STR_HELPER(x) #define VERSION_MAJOR 1 -#define VERSION_MINOR 142 +#define VERSION_MINOR 143 #define VERSION_BUILD 0 #define VERSION_REVISION 0 diff --git a/Source/D3D11/BufferD3D11.cpp b/Source/D3D11/BufferD3D11.cpp index fe209500..e13adf80 100644 --- a/Source/D3D11/BufferD3D11.cpp +++ b/Source/D3D11/BufferD3D11.cpp @@ -126,7 +126,7 @@ void* BufferD3D11::Map(uint64_t offset) { D3D11_MAPPED_SUBRESOURCE mappedData = {}; HRESULT hr = m_Device.GetImmediateContext()->Map(m_Buffer, 0, map, 0, &mappedData); if (FAILED(hr)) { - REPORT_ERROR(&m_Device, "ID3D11DeviceContext::Map() - FAILED!"); + REPORT_ERROR(&m_Device, "ID3D11DeviceContext::Map() failed!"); return nullptr; } @@ -144,7 +144,7 @@ void* BufferD3D11::Map(uint64_t offset) { hr = m_Device.GetImmediateContext()->Map(*m_ReadbackTexture, 0, D3D11_MAP_READ, 0, &srcData); if (FAILED(hr)) { m_Device.GetImmediateContext()->Unmap(m_Buffer, 0); - REPORT_ERROR(&m_Device, "ID3D11DeviceContext::Map() - FAILED!"); + REPORT_ERROR(&m_Device, "ID3D11DeviceContext::Map() failed!"); return nullptr; } diff --git a/Source/D3D11/CommandBufferD3D11.cpp b/Source/D3D11/CommandBufferD3D11.cpp index e2ba8f56..9aea17ab 100644 --- a/Source/D3D11/CommandBufferD3D11.cpp +++ b/Source/D3D11/CommandBufferD3D11.cpp @@ -11,6 +11,8 @@ #include "QueryPoolD3D11.h" #include "TextureD3D11.h" +#include "NRICompatibility.hlsli" + using namespace nri; static constexpr uint64_t s_nullOffsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {0}; @@ -163,6 +165,10 @@ void CommandBufferD3D11::SetBlendConstants(const Color32f& color) { m_BlendFactor = color; } +void CommandBufferD3D11::SetShadingRate(const ShadingRateDesc& shadingRateDesc) { + MaybeUnused(shadingRateDesc); // doesn't exist in D3D11 +} + void CommandBufferD3D11::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { if (!rects || !rectNum) { for (uint32_t i = 0; i < clearDescNum; i++) { @@ -233,14 +239,15 @@ void CommandBufferD3D11::ClearStorageTexture(const ClearStorageTextureDesc& clea } void CommandBufferD3D11::BeginRendering(const AttachmentsDesc& attachmentsDesc) { + // Render targets m_RenderTargetNum = attachmentsDesc.colors ? attachmentsDesc.colorNum : 0; - uint32_t i = 0; + size_t i = 0; for (; i < m_RenderTargetNum; i++) { const DescriptorD3D11& descriptor = *(DescriptorD3D11*)attachmentsDesc.colors[i]; m_RenderTargets[i] = descriptor; } - for (; i < (uint32_t)m_RenderTargets.size(); i++) + for (; i < m_RenderTargets.size(); i++) m_RenderTargets[i] = nullptr; if (attachmentsDesc.depthStencil) { @@ -250,6 +257,46 @@ void CommandBufferD3D11::BeginRendering(const AttachmentsDesc& attachmentsDesc) m_DepthStencil = nullptr; m_DeferredContext->OMSetRenderTargets(m_RenderTargetNum, m_RenderTargets.data(), m_DepthStencil); + + // Shading rate +#if NRI_USE_EXT_LIBS + if (m_Device.GetExt()->HasNVAPI()) { + ID3D11NvShadingRateResourceView* shadingRateImage = nullptr; + if (attachmentsDesc.shadingRate) { + const DescriptorD3D11& descriptor = *(DescriptorD3D11*)attachmentsDesc.shadingRate; + shadingRateImage = descriptor; + + // Program shading rate lookup table + if (!m_IsShadingRateLookupTableSet) { + std::array shadingRates = {}; + for (i = 0; i < shadingRates.size(); i++) { + shadingRates[i].enableVariablePixelShadingRate = true; + + for (size_t j = 0; j < GetCountOf(shadingRates[i].shadingRateTable); j++) + shadingRates[i].shadingRateTable[j] = NV_PIXEL_X1_PER_RASTER_PIXEL; // be on the safe side, avoid culling + + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(0, 0)] = NV_PIXEL_X1_PER_RASTER_PIXEL; + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(0, 1)] = NV_PIXEL_X1_PER_1X2_RASTER_PIXELS; + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(1, 0)] = NV_PIXEL_X1_PER_2X1_RASTER_PIXELS; + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(1, 1)] = NV_PIXEL_X1_PER_2X2_RASTER_PIXELS; + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(1, 2)] = NV_PIXEL_X1_PER_2X4_RASTER_PIXELS; + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(2, 1)] = NV_PIXEL_X1_PER_4X2_RASTER_PIXELS; + shadingRates[i].shadingRateTable[NRI_SHADING_RATE(2, 2)] = NV_PIXEL_X1_PER_4X4_RASTER_PIXELS; + } + + NV_D3D11_VIEWPORTS_SHADING_RATE_DESC shadingRateDesc = {NV_D3D11_VIEWPORTS_SHADING_RATE_DESC_VER}; + shadingRateDesc.numViewports = (uint32_t)shadingRates.size(); + shadingRateDesc.pViewports = shadingRates.data(); + + REPORT_ERROR_ON_BAD_STATUS(&m_Device, NvAPI_D3D11_RSSetViewportsPixelShadingRates(m_DeferredContext, &shadingRateDesc)); + + m_IsShadingRateLookupTableSet = true; + } + } + + REPORT_ERROR_ON_BAD_STATUS(&m_Device, NvAPI_D3D11_RSSetShadingRateResourceView(m_DeferredContext, shadingRateImage)); + } +#endif } void CommandBufferD3D11::SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets) { diff --git a/Source/D3D11/CommandBufferD3D11.h b/Source/D3D11/CommandBufferD3D11.h index 6be7267d..91ae10d3 100644 --- a/Source/D3D11/CommandBufferD3D11.h +++ b/Source/D3D11/CommandBufferD3D11.h @@ -48,6 +48,7 @@ struct CommandBufferD3D11 final : public CommandBufferHelper { void SetStencilReference(uint8_t frontRef, uint8_t backRef); void SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum); void SetBlendConstants(const Color32f& color); + void SetShadingRate(const ShadingRateDesc& shadingRateDesc); void ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum); void ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc); void ClearStorageTexture(const ClearStorageTextureDesc& clearDesc); @@ -98,6 +99,7 @@ struct CommandBufferD3D11 final : public CommandBufferHelper { float m_DepthBounds[2] = {0.0f, 1.0f}; uint8_t m_StencilRef = 0; uint8_t m_Version = 0; + bool m_IsShadingRateLookupTableSet = false; }; } // namespace nri diff --git a/Source/D3D11/CommandBufferD3D11.hpp b/Source/D3D11/CommandBufferD3D11.hpp index 7c152a8b..6059d6a7 100644 --- a/Source/D3D11/CommandBufferD3D11.hpp +++ b/Source/D3D11/CommandBufferD3D11.hpp @@ -71,6 +71,10 @@ static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Co ((CommandBufferD3D11&)commandBuffer).SetBlendConstants(color); } +static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { + ((CommandBufferD3D11&)commandBuffer).SetShadingRate(shadingRateDesc); +} + static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { ((CommandBufferD3D11&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); } diff --git a/Source/D3D11/CommandBufferEmuD3D11.cpp b/Source/D3D11/CommandBufferEmuD3D11.cpp index 38ae576e..58d443b5 100644 --- a/Source/D3D11/CommandBufferEmuD3D11.cpp +++ b/Source/D3D11/CommandBufferEmuD3D11.cpp @@ -19,6 +19,7 @@ enum OpCode : uint32_t { SET_STENCIL_REFERENCE, SET_SAMPLE_POSITIONS, SET_BLEND_CONSTANTS, + SET_SHADING_RATE, CLEAR_ATTACHMENTS, CLEAR_STORAGE_BUFFER, CLEAR_STORAGE_TEXTURE, @@ -177,6 +178,12 @@ void CommandBufferEmuD3D11::Submit() { commandBuffer.SetBlendConstants(color); } break; + case SET_SHADING_RATE: { + ShadingRateDesc shadingRateDesc = {}; + Read(m_PushBuffer, i, shadingRateDesc); + + commandBuffer.SetShadingRate(shadingRateDesc); + } break; case CLEAR_ATTACHMENTS: { ClearDesc* clearDescs; uint32_t clearDescNum; @@ -520,6 +527,11 @@ inline void CommandBufferEmuD3D11::SetBlendConstants(const Color32f& color) { Push(m_PushBuffer, color); } +inline void CommandBufferEmuD3D11::SetShadingRate(const ShadingRateDesc& shadingRateDesc) { + Push(m_PushBuffer, SET_SHADING_RATE); + Push(m_PushBuffer, shadingRateDesc); +} + inline void CommandBufferEmuD3D11::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { Push(m_PushBuffer, CLEAR_ATTACHMENTS); Push(m_PushBuffer, clearDescs, clearDescNum); diff --git a/Source/D3D11/CommandBufferEmuD3D11.h b/Source/D3D11/CommandBufferEmuD3D11.h index decfda69..cc06a0fb 100644 --- a/Source/D3D11/CommandBufferEmuD3D11.h +++ b/Source/D3D11/CommandBufferEmuD3D11.h @@ -45,6 +45,7 @@ struct CommandBufferEmuD3D11 final : public CommandBufferHelper { void SetStencilReference(uint8_t frontRef, uint8_t backRef); void SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum); void SetBlendConstants(const Color32f& color); + void SetShadingRate(const ShadingRateDesc& shadingRateDesc); void ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum); void ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc); void ClearStorageTexture(const ClearStorageTextureDesc& clearDesc); diff --git a/Source/D3D11/CommandBufferEmuD3D11.hpp b/Source/D3D11/CommandBufferEmuD3D11.hpp index acfe51e4..de4b424e 100644 --- a/Source/D3D11/CommandBufferEmuD3D11.hpp +++ b/Source/D3D11/CommandBufferEmuD3D11.hpp @@ -71,6 +71,10 @@ static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Co ((CommandBufferEmuD3D11&)commandBuffer).SetBlendConstants(color); } +static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { + ((CommandBufferEmuD3D11&)commandBuffer).SetShadingRate(shadingRateDesc); +} + static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { ((CommandBufferEmuD3D11&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); } @@ -185,6 +189,7 @@ void Core_CommandBufferEmu_PartiallyFillFunctionTable(CoreInterface& table) { table.CmdSetStencilReference = ::CmdSetStencilReference; table.CmdSetSamplePositions = ::CmdSetSamplePositions; table.CmdSetBlendConstants = ::CmdSetBlendConstants; + table.CmdSetShadingRate = ::CmdSetShadingRate; table.CmdSetIndexBuffer = ::CmdSetIndexBuffer; table.CmdSetVertexBuffers = ::CmdSetVertexBuffers; table.CmdDraw = ::CmdDraw; diff --git a/Source/D3D11/DescriptorD3D11.cpp b/Source/D3D11/DescriptorD3D11.cpp index 516c7d23..60132992 100644 --- a/Source/D3D11/DescriptorD3D11.cpp +++ b/Source/D3D11/DescriptorD3D11.cpp @@ -62,78 +62,77 @@ Result DescriptorD3D11::Create(const Texture1DViewDesc& textureViewDesc) { HRESULT hr = E_INVALIDARG; switch (textureViewDesc.viewType) { case Texture1DViewType::SHADER_RESOURCE_1D: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; - srv.Texture1D.MostDetailedMip = textureViewDesc.mipOffset; - srv.Texture1D.MipLevels = remainingMips; - srv.Format = format; + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + desc.Texture1D.MostDetailedMip = textureViewDesc.mipOffset; + desc.Texture1D.MipLevels = remainingMips; + desc.Format = format; - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; } break; case Texture1DViewType::SHADER_RESOURCE_1D_ARRAY: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - srv.Texture1DArray.MostDetailedMip = textureViewDesc.mipOffset; - srv.Texture1DArray.MipLevels = remainingMips; - srv.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; - srv.Texture1DArray.ArraySize = remainingLayers; - srv.Format = format; + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + desc.Texture1DArray.MostDetailedMip = textureViewDesc.mipOffset; + desc.Texture1DArray.MipLevels = remainingMips; + desc.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture1DArray.ArraySize = remainingLayers; + desc.Format = format; - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; } break; case Texture1DViewType::SHADER_RESOURCE_STORAGE_1D: { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav = {}; - uav.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D; - uav.Texture1D.MipSlice = textureViewDesc.mipOffset; - uav.Format = format; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D; + desc.Texture1D.MipSlice = textureViewDesc.mipOffset; + desc.Format = format; - hr = m_Device->CreateUnorderedAccessView(texture, &uav, (ID3D11UnorderedAccessView**)&m_Descriptor); + hr = m_Device->CreateUnorderedAccessView(texture, &desc, (ID3D11UnorderedAccessView**)&m_Descriptor); m_Type = DescriptorTypeDX11::STORAGE; } break; case Texture1DViewType::SHADER_RESOURCE_STORAGE_1D_ARRAY: { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav = {}; - uav.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY; - uav.Texture1DArray.MipSlice = textureViewDesc.mipOffset; - uav.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; - uav.Texture1DArray.ArraySize = remainingLayers; - uav.Format = format; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY; + desc.Texture1DArray.MipSlice = textureViewDesc.mipOffset; + desc.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture1DArray.ArraySize = remainingLayers; + desc.Format = format; - hr = m_Device->CreateUnorderedAccessView(texture, &uav, (ID3D11UnorderedAccessView**)&m_Descriptor); + hr = m_Device->CreateUnorderedAccessView(texture, &desc, (ID3D11UnorderedAccessView**)&m_Descriptor); m_Type = DescriptorTypeDX11::STORAGE; } break; case Texture1DViewType::COLOR_ATTACHMENT: { - D3D11_RENDER_TARGET_VIEW_DESC rtv = {}; - rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; - rtv.Texture1DArray.MipSlice = textureViewDesc.mipOffset; - rtv.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; - rtv.Texture1DArray.ArraySize = remainingLayers; - rtv.Format = format; + D3D11_RENDER_TARGET_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; + desc.Texture1DArray.MipSlice = textureViewDesc.mipOffset; + desc.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture1DArray.ArraySize = remainingLayers; + desc.Format = format; - hr = m_Device->CreateRenderTargetView(texture, &rtv, (ID3D11RenderTargetView**)&m_Descriptor); + hr = m_Device->CreateRenderTargetView(texture, &desc, (ID3D11RenderTargetView**)&m_Descriptor); m_Type = DescriptorTypeDX11::NO_SHADER_VISIBLE; } break; case Texture1DViewType::DEPTH_STENCIL_ATTACHMENT: { - D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {}; - dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; - dsv.Texture1DArray.MipSlice = textureViewDesc.mipOffset; - dsv.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; - dsv.Texture1DArray.ArraySize = remainingLayers; - dsv.Format = format; + D3D11_DEPTH_STENCIL_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; + desc.Texture1DArray.MipSlice = textureViewDesc.mipOffset; + desc.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture1DArray.ArraySize = remainingLayers; + desc.Format = format; if (textureViewDesc.flags & ResourceViewBits::READONLY_DEPTH) - dsv.Flags |= D3D11_DSV_READ_ONLY_DEPTH; - + desc.Flags |= D3D11_DSV_READ_ONLY_DEPTH; if (textureViewDesc.flags & ResourceViewBits::READONLY_STENCIL) - dsv.Flags |= D3D11_DSV_READ_ONLY_STENCIL; + desc.Flags |= D3D11_DSV_READ_ONLY_STENCIL; - hr = m_Device->CreateDepthStencilView(texture, &dsv, (ID3D11DepthStencilView**)&m_Descriptor); + hr = m_Device->CreateDepthStencilView(texture, &desc, (ID3D11DepthStencilView**)&m_Descriptor); m_Type = DescriptorTypeDX11::NO_SHADER_VISIBLE; } break; @@ -143,7 +142,7 @@ Result DescriptorD3D11::Create(const Texture1DViewDesc& textureViewDesc) { const FormatProps& formatProps = GetFormatProps(textureViewDesc.format); m_IsIntegerFormat = formatProps.isInteger; - m_SubresourceInfo.Initialize(textureViewDesc.texture, textureViewDesc.mipOffset, textureViewDesc.mipNum, textureViewDesc.layerOffset, textureViewDesc.layerNum); + m_SubresourceInfo.Initialize(textureViewDesc.texture, textureViewDesc.mipOffset, remainingMips, textureViewDesc.layerOffset, remainingLayers); return Result::SUCCESS; } @@ -159,134 +158,167 @@ Result DescriptorD3D11::Create(const Texture2DViewDesc& textureViewDesc) { HRESULT hr = E_INVALIDARG; switch (textureViewDesc.viewType) { case Texture2DViewType::SHADER_RESOURCE_2D: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; if (textureDesc.sampleNum > 1) - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; else { - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srv.Texture2D.MostDetailedMip = textureViewDesc.mipOffset; - srv.Texture2D.MipLevels = remainingMips; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MostDetailedMip = textureViewDesc.mipOffset; + desc.Texture2D.MipLevels = remainingMips; } - srv.Format = GetShaderFormatForDepth(format); + desc.Format = GetShaderFormatForDepth(format); - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; - } break; + + break; + } case Texture2DViewType::SHADER_RESOURCE_2D_ARRAY: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; if (textureDesc.sampleNum > 1) { - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - srv.Texture2DMSArray.FirstArraySlice = textureViewDesc.layerOffset; - srv.Texture2DMSArray.ArraySize = remainingLayers; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + desc.Texture2DMSArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DMSArray.ArraySize = remainingLayers; } else { - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srv.Texture2DArray.MostDetailedMip = textureViewDesc.mipOffset; - srv.Texture2DArray.MipLevels = remainingMips; - srv.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; - srv.Texture2DArray.ArraySize = remainingLayers; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.MostDetailedMip = textureViewDesc.mipOffset; + desc.Texture2DArray.MipLevels = remainingMips; + desc.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DArray.ArraySize = remainingLayers; } - srv.Format = GetShaderFormatForDepth(format); + desc.Format = GetShaderFormatForDepth(format); - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; - } break; + + break; + } case Texture2DViewType::SHADER_RESOURCE_CUBE: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srv.TextureCube.MostDetailedMip = textureViewDesc.mipOffset; - srv.TextureCube.MipLevels = remainingMips; - srv.Format = GetShaderFormatForDepth(format); + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + desc.TextureCube.MostDetailedMip = textureViewDesc.mipOffset; + desc.TextureCube.MipLevels = remainingMips; + desc.Format = GetShaderFormatForDepth(format); - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; - } break; + + break; + } case Texture2DViewType::SHADER_RESOURCE_CUBE_ARRAY: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; - srv.TextureCubeArray.MostDetailedMip = textureViewDesc.mipOffset; - srv.TextureCubeArray.MipLevels = remainingMips; - srv.TextureCubeArray.First2DArrayFace = textureViewDesc.layerOffset; - srv.TextureCubeArray.NumCubes = textureViewDesc.layerNum / 6; - srv.Format = GetShaderFormatForDepth(format); + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + desc.TextureCubeArray.MostDetailedMip = textureViewDesc.mipOffset; + desc.TextureCubeArray.MipLevels = remainingMips; + desc.TextureCubeArray.First2DArrayFace = textureViewDesc.layerOffset; + desc.TextureCubeArray.NumCubes = textureViewDesc.layerNum / 6; + desc.Format = GetShaderFormatForDepth(format); - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; - } break; + + break; + } case Texture2DViewType::SHADER_RESOURCE_STORAGE_2D: { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav = {}; - uav.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; - uav.Texture2D.MipSlice = textureViewDesc.mipOffset; - uav.Format = format; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = textureViewDesc.mipOffset; + desc.Format = format; - hr = m_Device->CreateUnorderedAccessView(texture, &uav, (ID3D11UnorderedAccessView**)&m_Descriptor); + hr = m_Device->CreateUnorderedAccessView(texture, &desc, (ID3D11UnorderedAccessView**)&m_Descriptor); m_Type = DescriptorTypeDX11::STORAGE; - } break; + + break; + } case Texture2DViewType::SHADER_RESOURCE_STORAGE_2D_ARRAY: { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav = {}; - uav.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; - uav.Texture2DArray.MipSlice = textureViewDesc.mipOffset; - uav.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; - uav.Texture2DArray.ArraySize = remainingLayers; - uav.Format = format; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.MipSlice = textureViewDesc.mipOffset; + desc.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DArray.ArraySize = remainingLayers; + desc.Format = format; - hr = m_Device->CreateUnorderedAccessView(texture, &uav, (ID3D11UnorderedAccessView**)&m_Descriptor); + hr = m_Device->CreateUnorderedAccessView(texture, &desc, (ID3D11UnorderedAccessView**)&m_Descriptor); m_Type = DescriptorTypeDX11::STORAGE; - } break; + + break; + } case Texture2DViewType::COLOR_ATTACHMENT: { - D3D11_RENDER_TARGET_VIEW_DESC rtv = {}; + D3D11_RENDER_TARGET_VIEW_DESC desc = {}; if (textureDesc.sampleNum > 1) { - rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - rtv.Texture2DMSArray.FirstArraySlice = textureViewDesc.layerOffset; - rtv.Texture2DMSArray.ArraySize = remainingLayers; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + desc.Texture2DMSArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DMSArray.ArraySize = remainingLayers; } else { - rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtv.Texture2DArray.MipSlice = textureViewDesc.mipOffset; - rtv.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; - rtv.Texture2DArray.ArraySize = remainingLayers; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.MipSlice = textureViewDesc.mipOffset; + desc.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DArray.ArraySize = remainingLayers; } - rtv.Format = format; + desc.Format = format; - hr = m_Device->CreateRenderTargetView(texture, &rtv, (ID3D11RenderTargetView**)&m_Descriptor); + hr = m_Device->CreateRenderTargetView(texture, &desc, (ID3D11RenderTargetView**)&m_Descriptor); m_Type = DescriptorTypeDX11::NO_SHADER_VISIBLE; - } break; + + break; + } case Texture2DViewType::DEPTH_STENCIL_ATTACHMENT: { - D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {}; + D3D11_DEPTH_STENCIL_VIEW_DESC desc = {}; if (textureDesc.sampleNum > 1) { - dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; - dsv.Texture2DMSArray.FirstArraySlice = textureViewDesc.layerOffset; - dsv.Texture2DMSArray.ArraySize = remainingLayers; + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + desc.Texture2DMSArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DMSArray.ArraySize = remainingLayers; } else { - dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsv.Texture2DArray.MipSlice = textureViewDesc.mipOffset; - dsv.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; - dsv.Texture2DArray.ArraySize = remainingLayers; + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.MipSlice = textureViewDesc.mipOffset; + desc.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; + desc.Texture2DArray.ArraySize = remainingLayers; } - dsv.Format = format; + desc.Format = format; if (textureViewDesc.flags & ResourceViewBits::READONLY_DEPTH) - dsv.Flags |= D3D11_DSV_READ_ONLY_DEPTH; - + desc.Flags |= D3D11_DSV_READ_ONLY_DEPTH; if (textureViewDesc.flags & ResourceViewBits::READONLY_STENCIL) - dsv.Flags |= D3D11_DSV_READ_ONLY_STENCIL; + desc.Flags |= D3D11_DSV_READ_ONLY_STENCIL; - hr = m_Device->CreateDepthStencilView(texture, &dsv, (ID3D11DepthStencilView**)&m_Descriptor); + hr = m_Device->CreateDepthStencilView(texture, &desc, (ID3D11DepthStencilView**)&m_Descriptor); m_Type = DescriptorTypeDX11::NO_SHADER_VISIBLE; - } break; + + break; + } + case Texture2DViewType::SHADING_RATE_ATTACHMENT: { +#if NRI_USE_EXT_LIBS + if (m_Device.GetExt()->HasNVAPI()) { + NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC desc = {NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_VER}; + desc.Format = format; + desc.ViewDimension = NV_SRRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = 0; + + NvAPI_Status status = NvAPI_D3D11_CreateShadingRateResourceView(m_Device.GetNativeObject(), texture, &desc, (ID3D11NvShadingRateResourceView**)&m_Descriptor); + if (status == NVAPI_OK) + hr = S_OK; + + m_Type = DescriptorTypeDX11::NO_SHADER_VISIBLE; + } +#endif + + break; + } }; RETURN_ON_BAD_HRESULT(&m_Device, hr, "ID3D11Device::CreateXxxView()"); const FormatProps& formatProps = GetFormatProps(textureViewDesc.format); m_IsIntegerFormat = formatProps.isInteger; - m_SubresourceInfo.Initialize(textureViewDesc.texture, textureViewDesc.mipOffset, textureViewDesc.mipNum, textureViewDesc.layerOffset, textureViewDesc.layerNum); + m_SubresourceInfo.Initialize(textureViewDesc.texture, textureViewDesc.mipOffset, remainingMips, textureViewDesc.layerOffset, remainingLayers); return Result::SUCCESS; } @@ -301,37 +333,37 @@ Result DescriptorD3D11::Create(const Texture3DViewDesc& textureViewDesc) { HRESULT hr = E_INVALIDARG; switch (textureViewDesc.viewType) { case Texture3DViewType::SHADER_RESOURCE_3D: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; - srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - srv.Texture3D.MostDetailedMip = textureViewDesc.mipOffset; - srv.Texture3D.MipLevels = remainingMips; - srv.Format = format; + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + desc.Texture3D.MostDetailedMip = textureViewDesc.mipOffset; + desc.Texture3D.MipLevels = remainingMips; + desc.Format = format; - hr = m_Device->CreateShaderResourceView(texture, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(texture, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; } break; case Texture3DViewType::SHADER_RESOURCE_STORAGE_3D: { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav = {}; - uav.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; - uav.Texture3D.MipSlice = textureViewDesc.mipOffset; - uav.Texture3D.FirstWSlice = textureViewDesc.sliceOffset; - uav.Texture3D.WSize = textureViewDesc.sliceNum; - uav.Format = format; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + desc.Texture3D.MipSlice = textureViewDesc.mipOffset; + desc.Texture3D.FirstWSlice = textureViewDesc.sliceOffset; + desc.Texture3D.WSize = textureViewDesc.sliceNum; + desc.Format = format; - hr = m_Device->CreateUnorderedAccessView(texture, &uav, (ID3D11UnorderedAccessView**)&m_Descriptor); + hr = m_Device->CreateUnorderedAccessView(texture, &desc, (ID3D11UnorderedAccessView**)&m_Descriptor); m_Type = DescriptorTypeDX11::STORAGE; } break; case Texture3DViewType::COLOR_ATTACHMENT: { - D3D11_RENDER_TARGET_VIEW_DESC rtv = {}; - rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtv.Texture3D.MipSlice = textureViewDesc.mipOffset; - rtv.Texture3D.FirstWSlice = textureViewDesc.sliceOffset; - rtv.Texture3D.WSize = textureViewDesc.sliceNum; - rtv.Format = format; + D3D11_RENDER_TARGET_VIEW_DESC desc = {}; + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + desc.Texture3D.MipSlice = textureViewDesc.mipOffset; + desc.Texture3D.FirstWSlice = textureViewDesc.sliceOffset; + desc.Texture3D.WSize = textureViewDesc.sliceNum; + desc.Format = format; - hr = m_Device->CreateRenderTargetView(texture, &rtv, (ID3D11RenderTargetView**)&m_Descriptor); + hr = m_Device->CreateRenderTargetView(texture, &desc, (ID3D11RenderTargetView**)&m_Descriptor); m_Type = DescriptorTypeDX11::NO_SHADER_VISIBLE; } break; @@ -341,7 +373,7 @@ Result DescriptorD3D11::Create(const Texture3DViewDesc& textureViewDesc) { const FormatProps& formatProps = GetFormatProps(textureViewDesc.format); m_IsIntegerFormat = formatProps.isInteger; - m_SubresourceInfo.Initialize(textureViewDesc.texture, textureViewDesc.mipOffset, textureViewDesc.mipNum, textureViewDesc.sliceOffset, textureViewDesc.sliceNum); + m_SubresourceInfo.Initialize(textureViewDesc.texture, textureViewDesc.mipOffset, remainingMips, textureViewDesc.sliceOffset, textureViewDesc.sliceNum); return Result::SUCCESS; } @@ -374,24 +406,24 @@ Result DescriptorD3D11::Create(const BufferViewDesc& bufferViewDesc) { m_Type = DescriptorTypeDX11::CONSTANT; } break; case BufferViewType::SHADER_RESOURCE: { - D3D11_SHADER_RESOURCE_VIEW_DESC srv = {}; - srv.Format = format; - srv.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srv.Buffer.FirstElement = m_ElementOffset; - srv.Buffer.NumElements = m_ElementNum; + D3D11_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.Format = format; + desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + desc.Buffer.FirstElement = m_ElementOffset; + desc.Buffer.NumElements = m_ElementNum; - hr = m_Device->CreateShaderResourceView(buffer, &srv, (ID3D11ShaderResourceView**)&m_Descriptor); + hr = m_Device->CreateShaderResourceView(buffer, &desc, (ID3D11ShaderResourceView**)&m_Descriptor); m_Type = DescriptorTypeDX11::RESOURCE; } break; case BufferViewType::SHADER_RESOURCE_STORAGE: { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav = {}; - uav.Format = format; - uav.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - uav.Buffer.FirstElement = m_ElementOffset; - uav.Buffer.NumElements = m_ElementNum; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.Format = format; + desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + desc.Buffer.FirstElement = m_ElementOffset; + desc.Buffer.NumElements = m_ElementNum; - hr = m_Device->CreateUnorderedAccessView(buffer, &uav, (ID3D11UnorderedAccessView**)&m_Descriptor); + hr = m_Device->CreateUnorderedAccessView(buffer, &desc, (ID3D11UnorderedAccessView**)&m_Descriptor); m_Type = DescriptorTypeDX11::STORAGE; } break; diff --git a/Source/D3D11/DescriptorD3D11.h b/Source/D3D11/DescriptorD3D11.h index ff3fa035..8d30682d 100644 --- a/Source/D3D11/DescriptorD3D11.h +++ b/Source/D3D11/DescriptorD3D11.h @@ -18,10 +18,6 @@ struct DescriptorD3D11 { return m_Device; } - inline operator void*() const { - return (void*)m_Descriptor.GetInterface(); - } - inline operator ID3D11View*() const { return (ID3D11View*)m_Descriptor.GetInterface(); } @@ -38,6 +34,12 @@ struct DescriptorD3D11 { return (ID3D11UnorderedAccessView*)m_Descriptor.GetInterface(); } +#if NRI_USE_EXT_LIBS + inline operator ID3D11NvShadingRateResourceView*() const { + return (ID3D11NvShadingRateResourceView*)m_Descriptor.GetInterface(); + } +#endif + inline uint32_t GetElementOffset() const { return m_ElementOffset; } diff --git a/Source/D3D11/DeviceD3D11.cpp b/Source/D3D11/DeviceD3D11.cpp index c206a746..e0de2a8b 100644 --- a/Source/D3D11/DeviceD3D11.cpp +++ b/Source/D3D11/DeviceD3D11.cpp @@ -178,7 +178,7 @@ Result DeviceD3D11::Create(const DeviceCreationDesc& deviceCreationDesc, ID3D11D result = m_Ext.m_AGS.CreateDeviceD3D11(m_Ext.m_AGSContext, &deviceCreationParams, &extensionsParams, &agsParams); } - RETURN_ON_FAILURE(this, result == AGS_SUCCESS, Result::FAILURE, "agsDriverExtensionsDX11_CreateDevice() failed: %d", (int32_t)result); + RETURN_ON_FAILURE(this, result == AGS_SUCCESS, Result::FAILURE, "agsDriverExtensionsDX11_CreateDevice() returned %d", (int32_t)result); deviceTemp = (ID3D11DeviceBest*)agsParams.pDevice; isDepthBoundsTestSupported = agsParams.extensionsSupported.depthBoundsDeferredContexts; @@ -196,9 +196,9 @@ Result DeviceD3D11::Create(const DeviceCreationDesc& deviceCreationDesc, ID3D11D #if NRI_USE_EXT_LIBS if (m_Ext.HasNVAPI()) { - NvAPI_D3D_RegisterDevice(m_Device); - NvAPI_D3D11_SetNvShaderExtnSlot(m_Device, shaderExtRegister); - NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_UINT64_ATOMIC, &isShaderAtomicsI64Supported); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D_RegisterDevice(deviceTemp)); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D11_SetNvShaderExtnSlot(deviceTemp, shaderExtRegister)); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(deviceTemp, NV_EXTN_OP_UINT64_ATOMIC, &isShaderAtomicsI64Supported)); isDepthBoundsTestSupported = true; } } @@ -411,12 +411,21 @@ void DeviceD3D11::FillDesc() { bool isShaderAtomicsF16Supported = false; bool isShaderAtomicsF32Supported = false; #if NRI_USE_EXT_LIBS - NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP16_ATOMIC, &isShaderAtomicsF16Supported); - NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP32_ATOMIC, &isShaderAtomicsF32Supported); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP16_ATOMIC, &isShaderAtomicsF16Supported)); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP32_ATOMIC, &isShaderAtomicsF32Supported)); NV_D3D11_FEATURE_DATA_RASTERIZER_SUPPORT rasterizerFeatures = {}; - NvAPI_D3D11_CheckFeatureSupport(m_Device, NV_D3D11_FEATURE_RASTERIZER, &rasterizerFeatures, sizeof(rasterizerFeatures)); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D11_CheckFeatureSupport(m_Device, NV_D3D11_FEATURE_RASTERIZER, &rasterizerFeatures, sizeof(rasterizerFeatures))); + + NV_D3D1x_GRAPHICS_CAPS caps = {}; + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D1x_GetGraphicsCapabilities(m_Device, NV_D3D1x_GRAPHICS_CAPS_VER, &caps)); + m_Desc.programmableSampleLocationsTier = rasterizerFeatures.ProgrammableSamplePositions ? 2 : 0; + + m_Desc.isPipelineShadingRateSupported = false; + m_Desc.isPrimitiveShadingRateSupported = false; + m_Desc.isAttachmentShadingRateSupported = caps.bVariablePixelRateShadingSupported; + m_Desc.shadingRateAttachmentTileSize = NV_VARIABLE_PIXEL_SHADING_TILE_WIDTH; #endif // TODO: report fake COMPUTE and COPY queues support since multi-queue supporting code is NOP. Can it hurt? diff --git a/Source/D3D11/DeviceD3D11.h b/Source/D3D11/DeviceD3D11.h index dc1e6ff4..282d8c2b 100644 --- a/Source/D3D11/DeviceD3D11.h +++ b/Source/D3D11/DeviceD3D11.h @@ -14,7 +14,7 @@ struct DeviceD3D11 final : public DeviceBase { ~DeviceD3D11(); inline ID3D11DeviceBest* GetNativeObject() const { - return m_Device; + return m_Device.GetInterface(); } inline ID3D11DeviceBest* operator->() const { diff --git a/Source/D3D11/FenceD3D11.cpp b/Source/D3D11/FenceD3D11.cpp index aad8817a..2a9dd8ff 100644 --- a/Source/D3D11/FenceD3D11.cpp +++ b/Source/D3D11/FenceD3D11.cpp @@ -38,7 +38,7 @@ inline uint64_t FenceD3D11::GetFenceValue() const { void FenceD3D11::QueueSignal(uint64_t value) { if (m_Fence) { HRESULT hr = m_Device.GetImmediateContext()->Signal(m_Fence, value); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "D3D11DeviceContext4::Signal() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "D3D11DeviceContext4::Signal() failed!"); } else { m_Device.GetImmediateContext()->End(m_Query); m_Value = value; @@ -48,7 +48,7 @@ void FenceD3D11::QueueSignal(uint64_t value) { void FenceD3D11::QueueWait(uint64_t value) { if (m_Fence) { HRESULT hr = m_Device.GetImmediateContext()->Wait(m_Fence, value); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "D3D11DeviceContext4::Wait() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "D3D11DeviceContext4::Wait() failed!"); } } @@ -59,17 +59,17 @@ inline void FenceD3D11::Wait(uint64_t value) { ; } else if (m_Fence->GetCompletedValue() < value) { HRESULT hr = m_Fence->SetEventOnCompletion(value, m_Event); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12Fence::SetEventOnCompletion() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12Fence::SetEventOnCompletion() failed!"); uint32_t result = WaitForSingleObjectEx(m_Event, TIMEOUT_FENCE, TRUE); - RETURN_ON_FAILURE(&m_Device, result == WAIT_OBJECT_0, ReturnVoid(), "WaitForSingleObjectEx() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, result == WAIT_OBJECT_0, ReturnVoid(), "WaitForSingleObjectEx() failed!"); } } else { HRESULT hr = S_FALSE; while (hr == S_FALSE) hr = m_Device.GetImmediateContext()->GetData(m_Query, nullptr, 0, 0); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "D3D11DeviceContext::GetData() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "D3D11DeviceContext::GetData() failed!"); } } diff --git a/Source/D3D11/PipelineD3D11.cpp b/Source/D3D11/PipelineD3D11.cpp index a64ead48..9f9c82f3 100644 --- a/Source/D3D11/PipelineD3D11.cpp +++ b/Source/D3D11/PipelineD3D11.cpp @@ -103,7 +103,7 @@ Result PipelineD3D11::Create(const GraphicsPipelineDesc& pipelineDesc) { rasterizerDesc.AntialiasedLineEnable = r.antialiasedLines; rasterizerDesc.MultisampleEnable = sampleNum > 1 ? TRUE : FALSE; // D3D11_RASTERIZER_DESC1 - rasterizerDesc.ForcedSampleCount = sampleNum; + rasterizerDesc.ForcedSampleCount = sampleNum > 1 ? sampleNum : 0; // D3D11_RASTERIZER_DESC2 rasterizerDesc.ConservativeRaster = r.conservativeRasterization ? D3D11_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF; @@ -123,7 +123,7 @@ Result PipelineD3D11::Create(const GraphicsPipelineDesc& pipelineDesc) { // Ex memcpy(&m_RasterizerDesc, &rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); #if NRI_USE_EXT_LIBS - m_RasterizerDesc.ForcedSampleCount = sampleNum; + m_RasterizerDesc.ForcedSampleCount = sampleNum > 1 ? sampleNum : 0; m_RasterizerDesc.ProgrammableSamplePositionsEnable = true; m_RasterizerDesc.SampleCount = sampleNum; m_RasterizerDesc.ConservativeRasterEnable = r.conservativeRasterization; @@ -239,11 +239,8 @@ void PipelineD3D11::ChangeSamplePositions(ID3D11DeviceContextBest* deferredConte m_RasterizerDesc.SamplePositionsY[j] = samplePositionState.positions[j].y + 8; } - if (m_Device.GetExt()->HasNVAPI()) { - NvAPI_Status result = NvAPI_D3D11_CreateRasterizerState(m_Device.GetNativeObject(), &m_RasterizerDesc, (ID3D11RasterizerState**)&newState.ptr); - if (result != NVAPI_OK) - REPORT_ERROR(&m_Device, "NvAPI_D3D11_CreateRasterizerState() - FAILED!"); - } + if (m_Device.GetExt()->HasNVAPI()) + REPORT_ERROR_ON_BAD_STATUS(&m_Device, NvAPI_D3D11_CreateRasterizerState(m_Device.GetNativeObject(), &m_RasterizerDesc, (ID3D11RasterizerState**)&newState.ptr)); if (newState.ptr) m_RasterizerStates.push_back(newState); diff --git a/Source/D3D11/PipelineLayoutD3D11.cpp b/Source/D3D11/PipelineLayoutD3D11.cpp index e7086a2b..96a707a7 100644 --- a/Source/D3D11/PipelineLayoutD3D11.cpp +++ b/Source/D3D11/PipelineLayoutD3D11.cpp @@ -194,13 +194,10 @@ void PipelineLayoutD3D11::BindDescriptorSetImpl(BindingState& currentBindingStat constantFirst[i] = offset; constantNum[i] = descriptor->GetElementNum(); - } else if (bindingRange.descriptorType == DescriptorTypeDX11::STORAGE) { - currentBindingState.TrackSubresource_UnbindIfNeeded_PostponeGraphicsStorageBinding( - deferredContext, descriptor->GetSubresourceInfo(), *descriptor, bindingRange.baseSlot + i, isGraphics, true); - } else if (bindingRange.descriptorType == DescriptorTypeDX11::RESOURCE) { - currentBindingState.TrackSubresource_UnbindIfNeeded_PostponeGraphicsStorageBinding( - deferredContext, descriptor->GetSubresourceInfo(), *descriptor, bindingRange.baseSlot + i, isGraphics, false); - } + } else if (bindingRange.descriptorType == DescriptorTypeDX11::STORAGE) + currentBindingState.TrackSubresource_UnbindIfNeeded_PostponeGraphicsStorageBinding(deferredContext, descriptor->GetSubresourceInfo(), *descriptor, bindingRange.baseSlot + i, isGraphics, true); + else if (bindingRange.descriptorType == DescriptorTypeDX11::RESOURCE) + currentBindingState.TrackSubresource_UnbindIfNeeded_PostponeGraphicsStorageBinding(deferredContext, descriptor->GetSubresourceInfo(), *descriptor, bindingRange.baseSlot + i, isGraphics, false); } else { descriptors[i] = nullptr; constantFirst[i] = 0; diff --git a/Source/D3D11/SharedD3D11.h b/Source/D3D11/SharedD3D11.h index dc72c46f..f024e024 100644 --- a/Source/D3D11/SharedD3D11.h +++ b/Source/D3D11/SharedD3D11.h @@ -160,6 +160,7 @@ struct SamplePositionsState { inline void Reset() { memset(&positions, 0, sizeof(positions)); + positionNum = 0; positionHash = 0; } @@ -168,6 +169,7 @@ struct SamplePositionsState { const uint32_t size = sizeof(SamplePosition) * samplePositionNum; memcpy(&positions, samplePositions, size); + positionHash = ComputeHash(samplePositions, size); positionNum = samplePositionNum; } diff --git a/Source/D3D11/SwapChainD3D11.cpp b/Source/D3D11/SwapChainD3D11.cpp index 4f55fe05..d555aa27 100644 --- a/Source/D3D11/SwapChainD3D11.cpp +++ b/Source/D3D11/SwapChainD3D11.cpp @@ -109,7 +109,7 @@ Result SwapChainD3D11::Create(const SwapChainDesc& swapChainDesc) { hr = m_SwapChain->SetColorSpace1(colorSpace); if (FAILED(hr)) - REPORT_WARNING(&m_Device, "IDXGISwapChain3::SetColorSpace1() - FAILED!"); + REPORT_WARNING(&m_Device, "IDXGISwapChain3::SetColorSpace1() failed!"); } else REPORT_ERROR(&m_Device, "IDXGISwapChain3::SetColorSpace1() is not supported by the OS!"); @@ -118,7 +118,7 @@ Result SwapChainD3D11::Create(const SwapChainDesc& swapChainDesc) { DXGI_RGBA color = {0.0f, 0.0f, 0.0f, 1.0f}; hr = m_SwapChain->SetBackgroundColor(&color); if (FAILED(hr)) - REPORT_WARNING(&m_Device, "IDXGISwapChain1::SetBackgroundColor() - FAILED!"); + REPORT_WARNING(&m_Device, "IDXGISwapChain1::SetBackgroundColor() failed!"); } // Maximum frame latency diff --git a/Source/D3D12/CommandBufferD3D12.cpp b/Source/D3D12/CommandBufferD3D12.cpp index 0465834f..009aa4d2 100644 --- a/Source/D3D12/CommandBufferD3D12.cpp +++ b/Source/D3D12/CommandBufferD3D12.cpp @@ -118,10 +118,10 @@ static inline D3D12_BARRIER_ACCESS GetBarrierAccessFlags(AccessBits accessBits) if (accessBits & AccessBits::COLOR_ATTACHMENT) flags |= D3D12_BARRIER_ACCESS_RENDER_TARGET; - if (accessBits & AccessBits::DEPTH_STENCIL_WRITE) + if (accessBits & AccessBits::DEPTH_STENCIL_ATTACHMENT_WRITE) flags |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE; - if (accessBits & AccessBits::DEPTH_STENCIL_READ) + if (accessBits & AccessBits::DEPTH_STENCIL_ATTACHMENT_READ) flags |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_READ; if (accessBits & AccessBits::COPY_SOURCE) @@ -136,22 +136,23 @@ static inline D3D12_BARRIER_ACCESS GetBarrierAccessFlags(AccessBits accessBits) if (accessBits & AccessBits::ACCELERATION_STRUCTURE_WRITE) flags |= D3D12_BARRIER_ACCESS_RAYTRACING_ACCELERATION_STRUCTURE_WRITE; - if (accessBits & AccessBits::SHADING_RATE) + if (accessBits & AccessBits::SHADING_RATE_ATTACHMENT) flags |= D3D12_BARRIER_ACCESS_SHADING_RATE_SOURCE; return flags; } -constexpr std::array LAYOUTS = { +constexpr std::array LAYOUTS = { D3D12_BARRIER_LAYOUT_UNDEFINED, // UNKNOWN D3D12_BARRIER_LAYOUT_RENDER_TARGET, // COLOR_ATTACHMENT - D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // DEPTH_STENCIL + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // DEPTH_STENCIL_ATTACHMENT D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ, // DEPTH_STENCIL_READONLY D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // SHADER_RESOURCE D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS, // SHADER_RESOURCE_STORAGE D3D12_BARRIER_LAYOUT_COPY_SOURCE, // COPY_SOURCE D3D12_BARRIER_LAYOUT_COPY_DEST, // COPY_DESTINATION D3D12_BARRIER_LAYOUT_PRESENT, // PRESENT + D3D12_BARRIER_LAYOUT_SHADING_RATE_SOURCE, // SHADING_RATE_ATTACHMENT }; static inline D3D12_BARRIER_LAYOUT GetBarrierLayout(Layout layout) { @@ -164,32 +165,46 @@ static inline D3D12_RESOURCE_STATES GetResourceStates(AccessBits accessMask, D3D if (accessMask & (AccessBits::CONSTANT_BUFFER | AccessBits::VERTEX_BUFFER)) resourceStates |= D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; + if (accessMask & AccessBits::INDEX_BUFFER) resourceStates |= D3D12_RESOURCE_STATE_INDEX_BUFFER; + if (accessMask & AccessBits::ARGUMENT_BUFFER) resourceStates |= D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT; + if (accessMask & AccessBits::SHADER_RESOURCE_STORAGE) resourceStates |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + if (accessMask & AccessBits::COLOR_ATTACHMENT) resourceStates |= D3D12_RESOURCE_STATE_RENDER_TARGET; - if (accessMask & AccessBits::DEPTH_STENCIL_READ) + + if (accessMask & AccessBits::DEPTH_STENCIL_ATTACHMENT_READ) resourceStates |= D3D12_RESOURCE_STATE_DEPTH_READ; - if (accessMask & AccessBits::DEPTH_STENCIL_WRITE) + + if (accessMask & AccessBits::DEPTH_STENCIL_ATTACHMENT_WRITE) resourceStates |= D3D12_RESOURCE_STATE_DEPTH_WRITE; + if (accessMask & AccessBits::COPY_SOURCE) resourceStates |= D3D12_RESOURCE_STATE_COPY_SOURCE; + if (accessMask & AccessBits::COPY_DESTINATION) resourceStates |= D3D12_RESOURCE_STATE_COPY_DEST; + if (accessMask & AccessBits::SHADER_RESOURCE) { resourceStates |= D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; if (commandListType == D3D12_COMMAND_LIST_TYPE_DIRECT) resourceStates |= D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; } + if (accessMask & AccessBits::ACCELERATION_STRUCTURE_READ) resourceStates |= D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE; + if (accessMask & AccessBits::ACCELERATION_STRUCTURE_WRITE) resourceStates |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + if (accessMask & AccessBits::SHADING_RATE_ATTACHMENT) + resourceStates |= D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE; + return resourceStates; } @@ -305,6 +320,16 @@ inline void CommandBufferD3D12::SetBlendConstants(const Color32f& color) { m_GraphicsCommandList->OMSetBlendFactor(&color.x); } +inline void CommandBufferD3D12::SetShadingRate(const ShadingRateDesc& shadingRateDesc) { + D3D12_SHADING_RATE shadingRate = GetShadingRate(shadingRateDesc.shadingRate); + D3D12_SHADING_RATE_COMBINER shadingRateCombiners[2] = { + GetShadingRateCombiner(shadingRateDesc.primitiveCombiner), + GetShadingRateCombiner(shadingRateDesc.attachmentCombiner), + }; + + m_GraphicsCommandList->RSSetShadingRate(shadingRate, shadingRateCombiners); +} + inline void CommandBufferD3D12::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { D3D12_RECT* rectsD3D12 = StackAlloc(D3D12_RECT, rectNum); ConvertRects(rectsD3D12, rects, rectNum); @@ -355,6 +380,7 @@ inline void CommandBufferD3D12::ClearStorageTexture(const ClearStorageTextureDes } inline void CommandBufferD3D12::BeginRendering(const AttachmentsDesc& attachmentsDesc) { + // Render targets m_RenderTargetNum = attachmentsDesc.colors ? attachmentsDesc.colorNum : 0; uint32_t i = 0; @@ -372,6 +398,13 @@ inline void CommandBufferD3D12::BeginRendering(const AttachmentsDesc& attachment m_DepthStencil.ptr = NULL; m_GraphicsCommandList->OMSetRenderTargets(m_RenderTargetNum, m_RenderTargets.data(), FALSE, m_DepthStencil.ptr ? &m_DepthStencil : nullptr); + + // Shading rate + ID3D12Resource* shadingRateImage = nullptr; + if (attachmentsDesc.shadingRate) + shadingRateImage = *(DescriptorD3D12*)attachmentsDesc.shadingRate; + + m_GraphicsCommandList->RSSetShadingRateImage(shadingRateImage); } inline void CommandBufferD3D12::SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets) { diff --git a/Source/D3D12/CommandBufferD3D12.h b/Source/D3D12/CommandBufferD3D12.h index 9de986c0..1e21b9e2 100644 --- a/Source/D3D12/CommandBufferD3D12.h +++ b/Source/D3D12/CommandBufferD3D12.h @@ -59,6 +59,7 @@ struct CommandBufferD3D12 { void SetStencilReference(uint8_t frontRef, uint8_t backRef); void SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum); void SetBlendConstants(const Color32f& color); + void SetShadingRate(const ShadingRateDesc& shadingRateDesc); void ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum); void ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc); void ClearStorageTexture(const ClearStorageTextureDesc& clearDesc); diff --git a/Source/D3D12/CommandBufferD3D12.hpp b/Source/D3D12/CommandBufferD3D12.hpp index 891e374f..fab7e5ee 100644 --- a/Source/D3D12/CommandBufferD3D12.hpp +++ b/Source/D3D12/CommandBufferD3D12.hpp @@ -71,6 +71,10 @@ static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Co ((CommandBufferD3D12&)commandBuffer).SetBlendConstants(color); } +static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { + ((CommandBufferD3D12&)commandBuffer).SetShadingRate(shadingRateDesc); +} + static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { ((CommandBufferD3D12&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); } diff --git a/Source/D3D12/DescriptorD3D12.cpp b/Source/D3D12/DescriptorD3D12.cpp index e579151d..5bddf4a7 100644 --- a/Source/D3D12/DescriptorD3D12.cpp +++ b/Source/D3D12/DescriptorD3D12.cpp @@ -89,7 +89,6 @@ Result DescriptorD3D12::Create(const Texture1DViewDesc& textureViewDesc) { D3D12_DEPTH_STENCIL_VIEW_DESC desc = {}; desc.Format = format; desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE1DARRAY; - desc.Flags = D3D12_DSV_FLAG_NONE; desc.Texture1DArray.MipSlice = textureViewDesc.mipOffset; desc.Texture1DArray.FirstArraySlice = textureViewDesc.layerOffset; desc.Texture1DArray.ArraySize = remainingLayers; @@ -207,7 +206,6 @@ Result DescriptorD3D12::Create(const Texture2DViewDesc& textureViewDesc) { case Texture2DViewType::DEPTH_STENCIL_ATTACHMENT: { D3D12_DEPTH_STENCIL_VIEW_DESC desc = {}; desc.Format = format; - desc.Flags = D3D12_DSV_FLAG_NONE; desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; desc.Texture2DArray.MipSlice = textureViewDesc.mipOffset; desc.Texture2DArray.FirstArraySlice = textureViewDesc.layerOffset; @@ -220,6 +218,10 @@ Result DescriptorD3D12::Create(const Texture2DViewDesc& textureViewDesc) { return CreateDepthStencilView(texture, desc); } + case Texture2DViewType::SHADING_RATE_ATTACHMENT: { + m_Resource = texture; // a resource view is not needed + return Result::SUCCESS; + } } return Result::FAILURE; diff --git a/Source/D3D12/DeviceD3D12.cpp b/Source/D3D12/DeviceD3D12.cpp index 406c8c04..9ffe30ca 100644 --- a/Source/D3D12/DeviceD3D12.cpp +++ b/Source/D3D12/DeviceD3D12.cpp @@ -216,8 +216,8 @@ Result DeviceD3D12::Create(const DeviceCreationDesc& deviceCreationDesc, const D #if NRI_USE_EXT_LIBS if (m_Ext.HasNVAPI()) { - NvAPI_D3D12_SetNvShaderExtnSlotSpace(m_Device, shaderExtRegister, deviceCreationDesc.shaderExtSpace); - NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_UINT64_ATOMIC, &isShaderAtomicsI64Supported); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D12_SetNvShaderExtnSlotSpace(deviceTemp, shaderExtRegister, deviceCreationDesc.shaderExtSpace)); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(deviceTemp, NV_EXTN_OP_UINT64_ATOMIC, &isShaderAtomicsI64Supported)); } } @@ -324,6 +324,10 @@ void DeviceD3D12::FillDesc(const DeviceCreationDesc& deviceCreationDesc) { hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &options6, sizeof(options6)); if (FAILED(hr)) REPORT_WARNING(this, "ID3D12Device::CheckFeatureSupport(options6) failed, result = 0x%08X!", hr); + m_Desc.isPipelineShadingRateSupported = options6.VariableShadingRateTier >= D3D12_VARIABLE_SHADING_RATE_TIER_1; + m_Desc.isPrimitiveShadingRateSupported = options6.VariableShadingRateTier >= D3D12_VARIABLE_SHADING_RATE_TIER_2; + m_Desc.isAttachmentShadingRateSupported = options6.VariableShadingRateTier >= D3D12_VARIABLE_SHADING_RATE_TIER_2; + m_Desc.shadingRateAttachmentTileSize = (uint8_t)options6.ShadingRateImageTileSize; D3D12_FEATURE_DATA_D3D12_OPTIONS7 options7 = {}; hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options7, sizeof(options7)); @@ -585,8 +589,8 @@ void DeviceD3D12::FillDesc(const DeviceCreationDesc& deviceCreationDesc) { bool isShaderAtomicsF16Supported = false; bool isShaderAtomicsF32Supported = false; #if NRI_USE_EXT_LIBS - NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP16_ATOMIC, &isShaderAtomicsF16Supported); - NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP32_ATOMIC, &isShaderAtomicsF32Supported); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP16_ATOMIC, &isShaderAtomicsF16Supported)); + REPORT_ERROR_ON_BAD_STATUS(this, NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(m_Device, NV_EXTN_OP_FP32_ATOMIC, &isShaderAtomicsF32Supported)); #endif m_Desc.isShaderAtomicsF16Supported = isShaderAtomicsF16Supported; diff --git a/Source/D3D12/FenceD3D12.cpp b/Source/D3D12/FenceD3D12.cpp index 5a774206..4524dfc4 100644 --- a/Source/D3D12/FenceD3D12.cpp +++ b/Source/D3D12/FenceD3D12.cpp @@ -25,12 +25,12 @@ inline uint64_t FenceD3D12::GetFenceValue() const { void FenceD3D12::QueueSignal(CommandQueueD3D12& commandQueue, uint64_t value) { HRESULT hr = ((ID3D12CommandQueue*)commandQueue)->Signal(m_Fence, value); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12CommandQueue::Signal() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12CommandQueue::Signal() failed!"); } void FenceD3D12::QueueWait(CommandQueueD3D12& commandQueue, uint64_t value) { HRESULT hr = ((ID3D12CommandQueue*)commandQueue)->Wait(m_Fence, value); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12CommandQueue::Wait() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12CommandQueue::Wait() failed!"); } inline void FenceD3D12::Wait(uint64_t value) { @@ -39,10 +39,10 @@ inline void FenceD3D12::Wait(uint64_t value) { ; } else if (m_Fence->GetCompletedValue() < value) { HRESULT hr = m_Fence->SetEventOnCompletion(value, m_Event); - RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12Fence::SetEventOnCompletion() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, hr == S_OK, ReturnVoid(), "ID3D12Fence::SetEventOnCompletion() failed!"); uint32_t result = WaitForSingleObjectEx(m_Event, TIMEOUT_FENCE, TRUE); - RETURN_ON_FAILURE(&m_Device, result == WAIT_OBJECT_0, ReturnVoid(), "WaitForSingleObjectEx() - FAILED!"); + RETURN_ON_FAILURE(&m_Device, result == WAIT_OBJECT_0, ReturnVoid(), "WaitForSingleObjectEx() failed!"); } } diff --git a/Source/D3D12/SharedD3D12.cpp b/Source/D3D12/SharedD3D12.cpp index afa54ac0..863e6cff 100644 --- a/Source/D3D12/SharedD3D12.cpp +++ b/Source/D3D12/SharedD3D12.cpp @@ -6,62 +6,25 @@ using namespace nri; -D3D12_COMMAND_LIST_TYPE nri::GetCommandListType(CommandQueueType commandQueueType) { - switch (commandQueueType) { - case CommandQueueType::GRAPHICS: - return D3D12_COMMAND_LIST_TYPE_DIRECT; - case CommandQueueType::COMPUTE: - return D3D12_COMMAND_LIST_TYPE_COMPUTE; - case CommandQueueType::COPY: - case CommandQueueType::HIGH_PRIORITY_COPY: - return D3D12_COMMAND_LIST_TYPE_COPY; - default: - CHECK(false, "Wrong value"); - return D3D12_COMMAND_LIST_TYPE_DIRECT; - } -} - -D3D12_HEAP_FLAGS nri::GetHeapFlags(MemoryType memoryType) { - return (D3D12_HEAP_FLAGS)(memoryType & 0xffff); -} - -D3D12_RESOURCE_FLAGS nri::GetBufferFlags(BufferUsageBits bufferUsageMask) { - D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE; - - if (bufferUsageMask & (BufferUsageBits::SHADER_RESOURCE_STORAGE | BufferUsageBits::RAY_TRACING_BUFFER)) - flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - - return flags; +constexpr std::array COMMAND_LIST_TYPES = { + D3D12_COMMAND_LIST_TYPE_DIRECT, // GRAPHICS, + D3D12_COMMAND_LIST_TYPE_COMPUTE, // COMPUTE, + D3D12_COMMAND_LIST_TYPE_COPY, // COPY, + D3D12_COMMAND_LIST_TYPE_COPY, // HIGH_PRIORITY_COPY, }; -D3D12_RESOURCE_FLAGS nri::GetTextureFlags(TextureUsageBits textureUsageMask) { - D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE; - - if (textureUsageMask & TextureUsageBits::SHADER_RESOURCE_STORAGE) - flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - - if (textureUsageMask & TextureUsageBits::COLOR_ATTACHMENT) - flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - - if (textureUsageMask & TextureUsageBits::DEPTH_STENCIL_ATTACHMENT) { - flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; - - if (!(textureUsageMask & TextureUsageBits::SHADER_RESOURCE)) - flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - } +D3D12_COMMAND_LIST_TYPE nri::GetCommandListType(CommandQueueType commandQueueType) { + return COMMAND_LIST_TYPES[(size_t)commandQueueType]; +} - return flags; +constexpr std::array RESOURCE_DIMENSIONS = { + D3D12_RESOURCE_DIMENSION_TEXTURE1D, // TEXTURE_1D, + D3D12_RESOURCE_DIMENSION_TEXTURE2D, // TEXTURE_2D, + D3D12_RESOURCE_DIMENSION_TEXTURE3D, // TEXTURE_3D, }; D3D12_RESOURCE_DIMENSION nri::GetResourceDimension(TextureType textureType) { - if (textureType == TextureType::TEXTURE_1D) - return D3D12_RESOURCE_DIMENSION_TEXTURE1D; - else if (textureType == TextureType::TEXTURE_2D) - return D3D12_RESOURCE_DIMENSION_TEXTURE2D; - else if (textureType == TextureType::TEXTURE_3D) - return D3D12_RESOURCE_DIMENSION_TEXTURE3D; - - return D3D12_RESOURCE_DIMENSION_UNKNOWN; + return RESOURCE_DIMENSIONS[(size_t)textureType]; } constexpr std::array DESCRIPTOR_RANGE_TYPES = { @@ -77,40 +40,7 @@ constexpr std::array PRIMITIVE_TOPOLOGY_TYPES = { @@ -127,7 +57,7 @@ constexpr std::array }; D3D12_PRIMITIVE_TOPOLOGY_TYPE nri::GetPrimitiveTopologyType(Topology topology) { - return PRIMITIVE_TOPOLOGY_TYPES[(uint32_t)topology]; + return PRIMITIVE_TOPOLOGY_TYPES[(size_t)topology]; } constexpr std::array PRIMITIVE_TOPOLOGIES = { @@ -146,7 +76,7 @@ D3D_PRIMITIVE_TOPOLOGY nri::GetPrimitiveTopology(Topology topology, uint8_t tess if (topology == Topology::PATCH_LIST) return (D3D_PRIMITIVE_TOPOLOGY)((uint8_t)D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ + tessControlPointNum); else - return PRIMITIVE_TOPOLOGIES[(uint32_t)topology]; + return PRIMITIVE_TOPOLOGIES[(size_t)topology]; } constexpr std::array FILL_MODES = { @@ -155,7 +85,7 @@ constexpr std::array FILL_MODES = }; D3D12_FILL_MODE nri::GetFillMode(FillMode fillMode) { - return FILL_MODES[(uint32_t)fillMode]; + return FILL_MODES[(size_t)fillMode]; } constexpr std::array CULL_MODES = { @@ -165,11 +95,7 @@ constexpr std::array CULL_MODES = }; D3D12_CULL_MODE nri::GetCullMode(CullMode cullMode) { - return CULL_MODES[(uint32_t)cullMode]; -} - -UINT8 nri::GetRenderTargetWriteMask(ColorWriteBits colorWriteMask) { - return colorWriteMask & ColorWriteBits::RGBA; + return CULL_MODES[(size_t)cullMode]; } constexpr std::array COMPARISON_FUNCS = { @@ -189,7 +115,7 @@ constexpr std::array COMP }; D3D12_COMPARISON_FUNC nri::GetComparisonFunc(CompareFunc compareFunc) { - return COMPARISON_FUNCS[(uint32_t)compareFunc]; + return COMPARISON_FUNCS[(size_t)compareFunc]; } constexpr std::array STENCIL_OPS = { @@ -204,7 +130,7 @@ constexpr std::array STENCIL_O }; D3D12_STENCIL_OP nri::GetStencilOp(StencilFunc stencilFunc) { - return STENCIL_OPS[(uint32_t)stencilFunc]; + return STENCIL_OPS[(size_t)stencilFunc]; } constexpr std::array LOGIC_OPS = { @@ -227,7 +153,7 @@ constexpr std::array LOGIC_OPS = { }; D3D12_LOGIC_OP nri::GetLogicOp(LogicFunc logicFunc) { - return LOGIC_OPS[(uint32_t)logicFunc]; + return LOGIC_OPS[(size_t)logicFunc]; } constexpr std::array BLENDS = { @@ -259,7 +185,7 @@ constexpr std::array BLENDS = { }; D3D12_BLEND nri::GetBlend(BlendFactor blendFactor) { - return BLENDS[(uint32_t)blendFactor]; + return BLENDS[(size_t)blendFactor]; } constexpr std::array BLEND_OPS = { @@ -271,7 +197,7 @@ constexpr std::array BLEND_OPS = { }; D3D12_BLEND_OP nri::GetBlendOp(BlendFunc blendFunc) { - return BLEND_OPS[(uint32_t)blendFunc]; + return BLEND_OPS[(size_t)blendFunc]; } constexpr std::array TEXTURE_ADDRESS_MODES = { @@ -282,7 +208,69 @@ constexpr std::array }; D3D12_TEXTURE_ADDRESS_MODE nri::GetAddressMode(AddressMode addressMode) { - return TEXTURE_ADDRESS_MODES[(uint32_t)addressMode]; + return TEXTURE_ADDRESS_MODES[(size_t)addressMode]; +} + +constexpr std::array HEAP_TYPES = { + D3D12_HEAP_TYPE_DEFAULT, // DEVICE +#ifdef NRI_USE_AGILITY_SDK + D3D12_HEAP_TYPE_GPU_UPLOAD, // DEVICE_UPLOAD (Prerequisite: D3D12_FEATURE_D3D12_OPTIONS16) +#else + D3D12_HEAP_TYPE_UPLOAD, // DEVICE_UPLOAD (silent fallback to HOST_UPLOAD) +#endif + D3D12_HEAP_TYPE_UPLOAD, // HOST_UPLOAD + D3D12_HEAP_TYPE_READBACK, // HOST_READBACK +}; + +D3D12_HEAP_TYPE nri::GetHeapType(MemoryLocation memoryLocation) { + return HEAP_TYPES[(size_t)memoryLocation]; +} + +constexpr std::array SHADING_RATES = { + D3D12_SHADING_RATE_1X1, // _1x1, + D3D12_SHADING_RATE_1X2, // _1x2, + D3D12_SHADING_RATE_2X1, // _2x1, + D3D12_SHADING_RATE_2X2, // _2x2, + D3D12_SHADING_RATE_2X4, // _2x4, + D3D12_SHADING_RATE_4X2, // _4x2, + D3D12_SHADING_RATE_4X4, // _4x4, +}; + +D3D12_SHADING_RATE nri::GetShadingRate(ShadingRate shadingRate) { + return SHADING_RATES[(size_t)shadingRate]; +} + +constexpr std::array SHADING_RATE_COMBINERS = { + D3D12_SHADING_RATE_COMBINER_OVERRIDE, // REPLACE, + D3D12_SHADING_RATE_COMBINER_PASSTHROUGH, // KEEP, + D3D12_SHADING_RATE_COMBINER_MIN, // MIN, + D3D12_SHADING_RATE_COMBINER_MAX, // MAX, + D3D12_SHADING_RATE_COMBINER_SUM, // SUM, +}; + +D3D12_SHADING_RATE_COMBINER nri::GetShadingRateCombiner(ShadingRateCombiner shadingRateCombiner) { + return SHADING_RATE_COMBINERS[(size_t)shadingRateCombiner]; +} + +UINT8 nri::GetRenderTargetWriteMask(ColorWriteBits colorWriteMask) { + return colorWriteMask & ColorWriteBits::RGBA; +} + +D3D12_DESCRIPTOR_HEAP_TYPE nri::GetDescriptorHeapType(DescriptorType descriptorType) { + return descriptorType == DescriptorType::SAMPLER ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; +} + +D3D12_HEAP_FLAGS nri::GetHeapFlags(MemoryType memoryType) { + return (D3D12_HEAP_FLAGS)(memoryType & 0xffff); +} + +D3D12_RESOURCE_FLAGS nri::GetBufferFlags(BufferUsageBits bufferUsageMask) { + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE; + + if (bufferUsageMask & (BufferUsageBits::SHADER_RESOURCE_STORAGE | BufferUsageBits::RAY_TRACING_BUFFER)) + flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + return flags; } D3D12_FILTER nri::GetFilterIsotropic(Filter mip, Filter magnification, Filter minification, FilterExt filterExt, bool useComparison) { @@ -310,6 +298,116 @@ D3D12_FILTER nri::GetFilterAnisotropic(FilterExt filterExt, bool useComparison) return useComparison ? D3D12_FILTER_COMPARISON_ANISOTROPIC : D3D12_FILTER_ANISOTROPIC; } +D3D12_SHADER_VISIBILITY nri::GetShaderVisibility(StageBits shaderStages) { + if (shaderStages == StageBits::ALL || shaderStages == StageBits::COMPUTE_SHADER || (shaderStages & StageBits::RAY_TRACING_SHADERS) != 0) + return D3D12_SHADER_VISIBILITY_ALL; + + if (shaderStages == StageBits::VERTEX_SHADER) + return D3D12_SHADER_VISIBILITY_VERTEX; + + if (shaderStages == StageBits::TESS_CONTROL_SHADER) + return D3D12_SHADER_VISIBILITY_HULL; + + if (shaderStages == StageBits::TESS_EVALUATION_SHADER) + return D3D12_SHADER_VISIBILITY_DOMAIN; + + if (shaderStages == StageBits::GEOMETRY_SHADER) + return D3D12_SHADER_VISIBILITY_GEOMETRY; + + if (shaderStages == StageBits::FRAGMENT_SHADER) + return D3D12_SHADER_VISIBILITY_PIXEL; + + if (shaderStages == StageBits::MESH_CONTROL_SHADER) + return D3D12_SHADER_VISIBILITY_AMPLIFICATION; + + if (shaderStages == StageBits::MESH_EVALUATION_SHADER) + return D3D12_SHADER_VISIBILITY_MESH; + + // Should be unreachable + return D3D12_SHADER_VISIBILITY_ALL; +} + +D3D12_RESOURCE_FLAGS nri::GetTextureFlags(TextureUsageBits textureUsageMask) { + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE; + + if (textureUsageMask & TextureUsageBits::SHADER_RESOURCE_STORAGE) + flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + if (textureUsageMask & TextureUsageBits::COLOR_ATTACHMENT) + flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + + if (textureUsageMask & TextureUsageBits::DEPTH_STENCIL_ATTACHMENT) { + flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + + if (!(textureUsageMask & TextureUsageBits::SHADER_RESOURCE)) + flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; + } + + return flags; +} + +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE nri::GetAccelerationStructureType(AccelerationStructureType accelerationStructureType) { + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL == (uint32_t)AccelerationStructureType::TOP_LEVEL, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL == (uint32_t)AccelerationStructureType::BOTTOM_LEVEL, "Enum mismatch"); + + return (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE)accelerationStructureType; +} + +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS nri::GetAccelerationStructureBuildFlags(AccelerationStructureBuildBits accelerationStructureBuildFlags) { + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE == (uint32_t)AccelerationStructureBuildBits::ALLOW_UPDATE, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION == (uint32_t)AccelerationStructureBuildBits::ALLOW_COMPACTION, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_TRACE, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_BUILD, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY == (uint32_t)AccelerationStructureBuildBits::MINIMIZE_MEMORY, "Enum mismatch"); + + return (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS)accelerationStructureBuildFlags; +} + +D3D12_RAYTRACING_GEOMETRY_TYPE GetGeometryType(GeometryType geometryType) { + static_assert(D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES == (uint32_t)GeometryType::TRIANGLES, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS == (uint32_t)GeometryType::AABBS, "Enum mismatch"); + + return (D3D12_RAYTRACING_GEOMETRY_TYPE)geometryType; +} + +D3D12_RAYTRACING_GEOMETRY_FLAGS GetGeometryFlags(BottomLevelGeometryBits geometryFlagMask) { + static_assert(D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE == (uint32_t)BottomLevelGeometryBits::OPAQUE_GEOMETRY, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION == (uint32_t)BottomLevelGeometryBits::NO_DUPLICATE_ANY_HIT_INVOCATION, "Enum mismatch"); + + return (D3D12_RAYTRACING_GEOMETRY_FLAGS)geometryFlagMask; +} + +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE nri::GetCopyMode(CopyMode copyMode) { + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE == (uint32_t)CopyMode::CLONE, "Enum mismatch"); + static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT == (uint32_t)CopyMode::COMPACT, "Enum mismatch"); + + return (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE)copyMode; +} + +void nri::ConvertGeometryDescs(D3D12_RAYTRACING_GEOMETRY_DESC* geometryDescs, const GeometryObject* geometryObjects, uint32_t geometryObjectNum) { + for (uint32_t i = 0; i < geometryObjectNum; i++) { + geometryDescs[i].Type = GetGeometryType(geometryObjects[i].type); + geometryDescs[i].Flags = GetGeometryFlags(geometryObjects[i].flags); + + if (geometryDescs[i].Type == D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES) { + const Triangles& triangles = geometryObjects[i].geometry.triangles; + geometryDescs[i].Triangles.Transform3x4 = triangles.transformBuffer ? ((BufferD3D12*)triangles.transformBuffer)->GetPointerGPU() + triangles.transformOffset : 0; + geometryDescs[i].Triangles.IndexFormat = triangles.indexType == IndexType::UINT16 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + geometryDescs[i].Triangles.VertexFormat = GetDxgiFormat(triangles.vertexFormat).typed; + geometryDescs[i].Triangles.IndexCount = triangles.indexNum; + geometryDescs[i].Triangles.VertexCount = triangles.vertexNum; + geometryDescs[i].Triangles.IndexBuffer = triangles.indexBuffer ? ((BufferD3D12*)triangles.indexBuffer)->GetPointerGPU() + triangles.indexOffset : 0; + geometryDescs[i].Triangles.VertexBuffer.StartAddress = ((BufferD3D12*)triangles.vertexBuffer)->GetPointerGPU() + triangles.vertexOffset; + geometryDescs[i].Triangles.VertexBuffer.StrideInBytes = triangles.vertexStride; + } else if (geometryDescs[i].Type == D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS) { + const AABBs& aabbs = geometryObjects[i].geometry.aabbs; + geometryDescs[i].AABBs.AABBCount = aabbs.boxNum; + geometryDescs[i].AABBs.AABBs.StartAddress = ((BufferD3D12*)aabbs.buffer)->GetPointerGPU() + aabbs.offset; + geometryDescs[i].AABBs.AABBs.StrideInBytes = aabbs.stride; + } + } +} + void nri::ConvertRects(D3D12_RECT* rectsD3D12, const Rect* rects, uint32_t rectNum) { for (uint32_t i = 0; i < rectNum; i++) { rectsD3D12[i].left = rects[i].x; @@ -413,86 +511,3 @@ bool nri::GetBufferDesc(const BufferD3D12Desc& bufferD3D12Desc, BufferDesc& buff return true; } - -constexpr std::array HEAP_TYPES = { - D3D12_HEAP_TYPE_DEFAULT, // DEVICE -#ifdef NRI_USE_AGILITY_SDK - D3D12_HEAP_TYPE_GPU_UPLOAD, // DEVICE_UPLOAD (Prerequisite: D3D12_FEATURE_D3D12_OPTIONS16) -#else - D3D12_HEAP_TYPE_UPLOAD, // DEVICE_UPLOAD (silent fallback to HOST_UPLOAD) -#endif - D3D12_HEAP_TYPE_UPLOAD, // HOST_UPLOAD - D3D12_HEAP_TYPE_READBACK, // HOST_READBACK -}; - -D3D12_HEAP_TYPE nri::GetHeapType(MemoryLocation memoryLocation) { - return HEAP_TYPES[(size_t)memoryLocation]; -} - -D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE nri::GetAccelerationStructureType(AccelerationStructureType accelerationStructureType) { - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL == (uint32_t)AccelerationStructureType::TOP_LEVEL, "Unsupported AccelerationStructureType."); - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL == (uint32_t)AccelerationStructureType::BOTTOM_LEVEL, "Unsupported AccelerationStructureType."); - - return (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE)accelerationStructureType; -} - -D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS nri::GetAccelerationStructureBuildFlags(AccelerationStructureBuildBits accelerationStructureBuildFlags) { - static_assert( - D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE == (uint32_t)AccelerationStructureBuildBits::ALLOW_UPDATE, "Unsupported AccelerationStructureBuildBits."); - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION == (uint32_t)AccelerationStructureBuildBits::ALLOW_COMPACTION, - "Unsupported AccelerationStructureBuildBits."); - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_TRACE, - "Unsupported AccelerationStructureBuildBits."); - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_BUILD, - "Unsupported AccelerationStructureBuildBits."); - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY == (uint32_t)AccelerationStructureBuildBits::MINIMIZE_MEMORY, - "Unsupported AccelerationStructureBuildBits."); - - return (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS)accelerationStructureBuildFlags; -} - -D3D12_RAYTRACING_GEOMETRY_TYPE GetGeometryType(GeometryType geometryType) { - static_assert(D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES == (uint32_t)GeometryType::TRIANGLES, "Unsupported GeometryType."); - static_assert(D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS == (uint32_t)GeometryType::AABBS, "Unsupported GeometryType."); - - return (D3D12_RAYTRACING_GEOMETRY_TYPE)geometryType; -} - -D3D12_RAYTRACING_GEOMETRY_FLAGS GetGeometryFlags(BottomLevelGeometryBits geometryFlagMask) { - static_assert(D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE == (uint32_t)BottomLevelGeometryBits::OPAQUE_GEOMETRY, "Unsupported GeometryFlagMask."); - static_assert( - D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION == (uint32_t)BottomLevelGeometryBits::NO_DUPLICATE_ANY_HIT_INVOCATION, "Unsupported GeometryFlagMask."); - - return (D3D12_RAYTRACING_GEOMETRY_FLAGS)geometryFlagMask; -} - -void nri::ConvertGeometryDescs(D3D12_RAYTRACING_GEOMETRY_DESC* geometryDescs, const GeometryObject* geometryObjects, uint32_t geometryObjectNum) { - for (uint32_t i = 0; i < geometryObjectNum; i++) { - geometryDescs[i].Type = GetGeometryType(geometryObjects[i].type); - geometryDescs[i].Flags = GetGeometryFlags(geometryObjects[i].flags); - - if (geometryDescs[i].Type == D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES) { - const Triangles& triangles = geometryObjects[i].geometry.triangles; - geometryDescs[i].Triangles.Transform3x4 = triangles.transformBuffer ? ((BufferD3D12*)triangles.transformBuffer)->GetPointerGPU() + triangles.transformOffset : 0; - geometryDescs[i].Triangles.IndexFormat = triangles.indexType == IndexType::UINT16 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; - geometryDescs[i].Triangles.VertexFormat = GetDxgiFormat(triangles.vertexFormat).typed; - geometryDescs[i].Triangles.IndexCount = triangles.indexNum; - geometryDescs[i].Triangles.VertexCount = triangles.vertexNum; - geometryDescs[i].Triangles.IndexBuffer = triangles.indexBuffer ? ((BufferD3D12*)triangles.indexBuffer)->GetPointerGPU() + triangles.indexOffset : 0; - geometryDescs[i].Triangles.VertexBuffer.StartAddress = ((BufferD3D12*)triangles.vertexBuffer)->GetPointerGPU() + triangles.vertexOffset; - geometryDescs[i].Triangles.VertexBuffer.StrideInBytes = triangles.vertexStride; - } else if (geometryDescs[i].Type == D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS) { - const AABBs& aabbs = geometryObjects[i].geometry.aabbs; - geometryDescs[i].AABBs.AABBCount = aabbs.boxNum; - geometryDescs[i].AABBs.AABBs.StartAddress = ((BufferD3D12*)aabbs.buffer)->GetPointerGPU() + aabbs.offset; - geometryDescs[i].AABBs.AABBs.StrideInBytes = aabbs.stride; - } - } -} - -D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE nri::GetCopyMode(CopyMode copyMode) { - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE == (uint32_t)CopyMode::CLONE, "Unsupported CopyMode."); - static_assert(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT == (uint32_t)CopyMode::COMPACT, "Unsupported CopyMode."); - - return (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE)copyMode; -} diff --git a/Source/D3D12/SharedD3D12.h b/Source/D3D12/SharedD3D12.h index 3966cb49..c8de1b9e 100644 --- a/Source/D3D12/SharedD3D12.h +++ b/Source/D3D12/SharedD3D12.h @@ -82,6 +82,8 @@ D3D12_BLEND_OP GetBlendOp(BlendFunc blendFunc); D3D12_SHADER_VISIBILITY GetShaderVisibility(StageBits shaderStage); D3D12_DESCRIPTOR_RANGE_TYPE GetDescriptorRangesType(DescriptorType descriptorType); D3D12_RESOURCE_DIMENSION GetResourceDimension(TextureType textureType); +D3D12_SHADING_RATE GetShadingRate(ShadingRate shadingRate); +D3D12_SHADING_RATE_COMBINER GetShadingRateCombiner(ShadingRateCombiner shadingRateCombiner); } // namespace nri #if NRI_USE_EXT_LIBS diff --git a/Source/D3D12/SwapChainD3D12.cpp b/Source/D3D12/SwapChainD3D12.cpp index 0ed267af..84287b1d 100644 --- a/Source/D3D12/SwapChainD3D12.cpp +++ b/Source/D3D12/SwapChainD3D12.cpp @@ -112,7 +112,7 @@ Result SwapChainD3D12::Create(const SwapChainDesc& swapChainDesc) { hr = m_SwapChain->SetColorSpace1(colorSpace); if (FAILED(hr)) - REPORT_WARNING(&m_Device, "IDXGISwapChain3::SetColorSpace1() - FAILED!"); + REPORT_WARNING(&m_Device, "IDXGISwapChain3::SetColorSpace1() failed!"); } else REPORT_ERROR(&m_Device, "IDXGISwapChain3::SetColorSpace1() is not supported by the OS!"); @@ -121,7 +121,7 @@ Result SwapChainD3D12::Create(const SwapChainDesc& swapChainDesc) { DXGI_RGBA color = {0.0f, 0.0f, 0.0f, 1.0f}; hr = m_SwapChain->SetBackgroundColor(&color); if (FAILED(hr)) - REPORT_WARNING(&m_Device, "IDXGISwapChain1::SetBackgroundColor() - FAILED!"); + REPORT_WARNING(&m_Device, "IDXGISwapChain1::SetBackgroundColor() failed!"); } // Maximum frame latency diff --git a/Source/D3D12/TextureD3D12.cpp b/Source/D3D12/TextureD3D12.cpp index 28088f08..80d7d911 100644 --- a/Source/D3D12/TextureD3D12.cpp +++ b/Source/D3D12/TextureD3D12.cpp @@ -9,6 +9,7 @@ using namespace nri; void nri::GetResourceDesc(D3D12_RESOURCE_DESC* desc, const TextureDesc& textureDesc) { uint16_t blockWidth = (uint16_t)GetFormatProps(textureDesc.format).blockWidth; + const DxgiFormat& dxgiFormat = GetDxgiFormat(textureDesc.format); desc->Dimension = GetResourceDimension(textureDesc.type); desc->Alignment = textureDesc.sampleNum > 1 ? 0 : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; @@ -16,7 +17,7 @@ void nri::GetResourceDesc(D3D12_RESOURCE_DESC* desc, const TextureDesc& textureD desc->Height = Align(textureDesc.height, blockWidth); desc->DepthOrArraySize = textureDesc.type == TextureType::TEXTURE_3D ? textureDesc.depth : textureDesc.layerNum; desc->MipLevels = textureDesc.mipNum; - desc->Format = GetDxgiFormat(textureDesc.format).typeless; + desc->Format = (textureDesc.usageMask & nri::TextureUsageBits::SHADING_RATE_ATTACHMENT) ? dxgiFormat.typed : dxgiFormat.typeless; desc->SampleDesc.Count = textureDesc.sampleNum; desc->Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; desc->Flags = GetTextureFlags(textureDesc.usageMask); diff --git a/Source/Shared/D3DExt.hpp b/Source/Shared/D3DExt.hpp index 42e40d0e..ca979825 100644 --- a/Source/Shared/D3DExt.hpp +++ b/Source/Shared/D3DExt.hpp @@ -98,33 +98,33 @@ void Ext::InitializeAMDExt(const nri::DeviceBase* deviceBase, AGSContext* agsCon void Ext::BeginUAVOverlap(ID3D11DeviceContext* deviceContext) const { if (m_IsNvAPIAvailable) { const NvAPI_Status res = NvAPI_D3D11_BeginUAVOverlap(deviceContext); - RETURN_ON_FAILURE(m_DeviceBase, res == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_BeginUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_BeginUAVOverlap() failed!"); } else if (m_AGSContext) { const AGSReturnCode res = m_AGS.BeginUAVOverlap(m_AGSContext, deviceContext); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_BeginUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_BeginUAVOverlap() failed!"); } } void Ext::EndUAVOverlap(ID3D11DeviceContext* deviceContext) const { if (m_IsNvAPIAvailable) { const NvAPI_Status status = NvAPI_D3D11_EndUAVOverlap(deviceContext); - RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_EndUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_EndUAVOverlap() failed!"); } else if (m_AGSContext) { const AGSReturnCode res = m_AGS.EndUAVOverlap(m_AGSContext, deviceContext); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_EndUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_EndUAVOverlap() failed!"); } } void Ext::WaitForDrain(ID3D11DeviceContext* deviceContext, uint32_t flags) const { if (m_IsNvAPIAvailable) { const NvAPI_Status res = NvAPI_D3D11_BeginUAVOverlapEx(deviceContext, flags); - RETURN_ON_FAILURE(m_DeviceBase, res == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_BeginUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_BeginUAVOverlap() failed!"); } else if (m_AGSContext) { // TODO: verify that this code actually works on AMD! const AGSReturnCode res1 = m_AGS.EndUAVOverlap(m_AGSContext, deviceContext); - RETURN_ON_FAILURE(m_DeviceBase, res1 == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_EndUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res1 == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_EndUAVOverlap() failed!"); const AGSReturnCode res2 = m_AGS.BeginUAVOverlap(m_AGSContext, deviceContext); - RETURN_ON_FAILURE(m_DeviceBase, res2 == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_BeginUAVOverlap() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res2 == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_BeginUAVOverlap() failed!"); } } @@ -133,10 +133,10 @@ void Ext::SetDepthBounds(ID3D11DeviceContext* deviceContext, float minBound, flo if (m_IsNvAPIAvailable) { const NvAPI_Status status = NvAPI_D3D11_SetDepthBoundsTest(deviceContext, isEnabled, minBound, maxBound); - RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_SetDepthBoundsTest() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_SetDepthBoundsTest() failed!"); } else if (m_AGSContext) { const AGSReturnCode res = m_AGS.SetDepthBounds(m_AGSContext, deviceContext, isEnabled, minBound, maxBound); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_SetDepthBounds() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_SetDepthBounds() failed!"); } } @@ -145,15 +145,15 @@ void Ext::DrawIndirect( if (countBuffer) { if (m_AGSContext) { const AGSReturnCode res = m_AGS.DrawIndirectCount(m_AGSContext, deviceContext, countBuffer, countBufferOffset, buffer, (uint32_t)offset, stride); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect() failed!"); } } else { if (m_IsNvAPIAvailable && drawNum > 1) { const NvAPI_Status status = NvAPI_D3D11_MultiDrawInstancedIndirect(deviceContext, drawNum, buffer, (uint32_t)offset, stride); - RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_MultiDrawInstancedIndirect() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_MultiDrawInstancedIndirect() failed!"); } else if (m_AGSContext && drawNum > 1) { const AGSReturnCode res = m_AGS.DrawIndirect(m_AGSContext, deviceContext, drawNum, buffer, (uint32_t)offset, stride); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawInstancedIndirect() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawInstancedIndirect() failed!"); } else { for (uint32_t i = 0; i < drawNum; i++) { deviceContext->DrawInstancedIndirect(buffer, (uint32_t)offset); @@ -168,15 +168,15 @@ void Ext::DrawIndexedIndirect( if (countBuffer) { if (m_AGSContext) { const AGSReturnCode res = m_AGS.DrawIndexedIndirectCount(m_AGSContext, deviceContext, countBuffer, countBufferOffset, buffer, (uint32_t)offset, stride); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect() failed!"); } } else { if (m_IsNvAPIAvailable && drawNum > 1) { const NvAPI_Status status = NvAPI_D3D11_MultiDrawIndexedInstancedIndirect(deviceContext, drawNum, buffer, (uint32_t)offset, stride); - RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_MultiDrawIndexedInstancedIndirect() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, status == NVAPI_OK, ReturnVoid(), "NvAPI_D3D11_MultiDrawIndexedInstancedIndirect() failed!"); } else if (m_AGSContext && drawNum > 1) { const AGSReturnCode res = m_AGS.DrawIndexedIndirect(m_AGSContext, deviceContext, drawNum, buffer, (uint32_t)offset, stride); - RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirect() - FAILED!"); + RETURN_ON_FAILURE(m_DeviceBase, res == AGS_SUCCESS, ReturnVoid(), "agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirect() failed!"); } else { for (uint32_t i = 0; i < drawNum; i++) { deviceContext->DrawIndexedInstancedIndirect(buffer, (uint32_t)offset); diff --git a/Source/Shared/DeviceBase.h b/Source/Shared/DeviceBase.h index 1d45b57b..86cdafb9 100644 --- a/Source/Shared/DeviceBase.h +++ b/Source/Shared/DeviceBase.h @@ -156,6 +156,7 @@ struct DeviceBase { table.CmdSetStencilReference = ::CmdSetStencilReference; \ table.CmdSetSamplePositions = ::CmdSetSamplePositions; \ table.CmdSetBlendConstants = ::CmdSetBlendConstants; \ + table.CmdSetShadingRate = ::CmdSetShadingRate; \ table.CmdSetIndexBuffer = ::CmdSetIndexBuffer; \ table.CmdSetVertexBuffers = ::CmdSetVertexBuffers; \ table.CmdDraw = ::CmdDraw; \ diff --git a/Source/Shared/SharedExternal.h b/Source/Shared/SharedExternal.h index c7a6fe40..a39d67bb 100644 --- a/Source/Shared/SharedExternal.h +++ b/Source/Shared/SharedExternal.h @@ -99,18 +99,22 @@ typedef uint32_t DXGI_FORMAT; #define NRI_STRINGIFY_(token) #token #define NRI_STRINGIFY(token) NRI_STRINGIFY_(token) -#define RETURN_ON_BAD_HRESULT(deviceBase, hr, msg) \ +#define RETURN_ON_BAD_HRESULT(deviceBase, hr, format) \ if (FAILED(hr)) { \ - (deviceBase)->ReportMessage(nri::Message::TYPE_ERROR, __FILE__, __LINE__, msg " failed, result = 0x%08X!", hr); \ + (deviceBase)->ReportMessage(nri::Message::TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__ ": " format " failed, result = 0x%08X!", hr); \ return GetResultFromHRESULT(hr); \ } #define RETURN_ON_FAILURE(deviceBase, condition, returnCode, format, ...) \ if (!(condition)) { \ - (deviceBase)->ReportMessage(nri::Message::TYPE_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__); \ + (deviceBase)->ReportMessage(nri::Message::TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__ ": " format, ##__VA_ARGS__); \ return returnCode; \ } +#define REPORT_ERROR_ON_BAD_STATUS(deviceBase, expression) \ + if ((expression) != 0) \ + (deviceBase)->ReportMessage(nri::Message::TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__ ": " NRI_STRINGIFY(expression) " failed!") + #define CHECK(condition, message) assert((condition) && message) #define SET_D3D_DEBUG_OBJECT_NAME(obj, name) \ diff --git a/Source/VK/CommandBufferVK.cpp b/Source/VK/CommandBufferVK.cpp index 4ad3b50c..52778973 100644 --- a/Source/VK/CommandBufferVK.cpp +++ b/Source/VK/CommandBufferVK.cpp @@ -146,6 +146,17 @@ inline void CommandBufferVK::SetBlendConstants(const Color32f& color) { vk.CmdSetBlendConstants(m_Handle, &color.x); } +inline void CommandBufferVK::SetShadingRate(const ShadingRateDesc& shadingRateDesc) { + VkExtent2D shadingRate = GetShadingRate(shadingRateDesc.shadingRate); + VkFragmentShadingRateCombinerOpKHR combiners[2] = { + GetShadingRateCombiner(shadingRateDesc.primitiveCombiner), + GetShadingRateCombiner(shadingRateDesc.attachmentCombiner), + }; + + const auto& vk = m_Device.GetDispatchTable(); + vk.CmdSetFragmentShadingRateKHR(m_Handle, &shadingRate, combiners); +} + inline void CommandBufferVK::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { VkClearAttachment* attachments = StackAlloc(VkClearAttachment, clearDescNum); @@ -224,6 +235,7 @@ inline void CommandBufferVK::BeginRendering(const AttachmentsDesc& attachmentsDe m_RenderWidth = deviceDesc.attachmentMaxDim; m_RenderHeight = deviceDesc.attachmentMaxDim; + // Color VkRenderingAttachmentInfo* colors = StackAlloc(VkRenderingAttachmentInfo, attachmentsDesc.colorNum); for (uint32_t i = 0; i < attachmentsDesc.colorNum; i++) { const DescriptorVK& descriptor = *(DescriptorVK*)attachmentsDesc.colors[i]; @@ -248,6 +260,7 @@ inline void CommandBufferVK::BeginRendering(const AttachmentsDesc& attachmentsDe m_RenderHeight = std::min(m_RenderHeight, h); } + // Depth-stencil VkRenderingAttachmentInfo depthStencil = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; bool hasStencil = false; if (attachmentsDesc.depthStencil) { @@ -273,6 +286,17 @@ inline void CommandBufferVK::BeginRendering(const AttachmentsDesc& attachmentsDe hasStencil = HasStencil(descriptor.GetTexture().GetDesc().format); } + // Shading rate + VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRate = {VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR}; + if (attachmentsDesc.shadingRate) { + uint32_t tileSize = m_Device.GetDesc().shadingRateAttachmentTileSize; + const DescriptorVK& descriptor = *(DescriptorVK*)attachmentsDesc.shadingRate; + + shadingRate.imageView = descriptor.GetImageView(); + shadingRate.imageLayout = descriptor.GetImageLayout(); + shadingRate.shadingRateAttachmentTexelSize = {tileSize, tileSize}; + } + // TODO: matches D3D behavior? bool hasAttachment = attachmentsDesc.depthStencil || attachmentsDesc.colors; if (!hasAttachment) { @@ -291,6 +315,9 @@ inline void CommandBufferVK::BeginRendering(const AttachmentsDesc& attachmentsDe renderingInfo.pDepthAttachment = attachmentsDesc.depthStencil ? &depthStencil : nullptr; renderingInfo.pStencilAttachment = hasStencil ? &depthStencil : nullptr; + if (attachmentsDesc.shadingRate) + renderingInfo.pNext = &shadingRate; + const auto& vk = m_Device.GetDispatchTable(); vk.CmdBeginRendering(m_Handle, &renderingInfo); } @@ -537,10 +564,10 @@ static inline VkAccessFlags2 GetAccessFlags(AccessBits accessBits) { if (accessBits & AccessBits::COLOR_ATTACHMENT) flags |= VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - if (accessBits & AccessBits::DEPTH_STENCIL_WRITE) + if (accessBits & AccessBits::DEPTH_STENCIL_ATTACHMENT_WRITE) flags |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - if (accessBits & AccessBits::DEPTH_STENCIL_READ) + if (accessBits & AccessBits::DEPTH_STENCIL_ATTACHMENT_READ) flags |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT; if (accessBits & AccessBits::COPY_SOURCE) @@ -555,7 +582,7 @@ static inline VkAccessFlags2 GetAccessFlags(AccessBits accessBits) { if (accessBits & AccessBits::ACCELERATION_STRUCTURE_WRITE) flags |= VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; - if (accessBits & AccessBits::SHADING_RATE) + if (accessBits & AccessBits::SHADING_RATE_ATTACHMENT) flags |= VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR; return flags; diff --git a/Source/VK/CommandBufferVK.h b/Source/VK/CommandBufferVK.h index 9bbfbe3a..803aa5f1 100644 --- a/Source/VK/CommandBufferVK.h +++ b/Source/VK/CommandBufferVK.h @@ -50,6 +50,7 @@ struct CommandBufferVK { void SetStencilReference(uint8_t frontRef, uint8_t backRef); void SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum); void SetBlendConstants(const Color32f& color); + void SetShadingRate(const ShadingRateDesc& shadingRateDesc); void ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum); void SetIndexBuffer(const Buffer& buffer, uint64_t offset, IndexType indexType); void SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets); diff --git a/Source/VK/CommandBufferVK.hpp b/Source/VK/CommandBufferVK.hpp index 04c3bff0..35306581 100644 --- a/Source/VK/CommandBufferVK.hpp +++ b/Source/VK/CommandBufferVK.hpp @@ -71,6 +71,10 @@ static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Co ((CommandBufferVK&)commandBuffer).SetBlendConstants(color); } +static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { + ((CommandBufferVK&)commandBuffer).SetShadingRate(shadingRateDesc); +} + static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { ((CommandBufferVK&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); } diff --git a/Source/VK/CommandQueueVK.cpp b/Source/VK/CommandQueueVK.cpp index 857061eb..4c13f820 100644 --- a/Source/VK/CommandQueueVK.cpp +++ b/Source/VK/CommandQueueVK.cpp @@ -67,7 +67,7 @@ inline void CommandQueueVK::Submit(const QueueSubmitDesc& queueSubmitDesc, const const auto& vk = m_Device.GetDispatchTable(); VkResult result = vk.QueueSubmit2(m_Handle, 1, &submitInfo, VK_NULL_HANDLE); - RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, ReturnVoid(), "Submit: vkQueueSubmit returned %d", (int32_t)result); + RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, ReturnVoid(), "vkQueueSubmit returned %d", (int32_t)result); } inline Result CommandQueueVK::UploadData( @@ -82,7 +82,7 @@ inline Result CommandQueueVK::WaitForIdle() { const auto& vk = m_Device.GetDispatchTable(); VkResult result = vk.QueueWaitIdle(m_Handle); - RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "WaitForIdle: vkQueueWaitIdle returned %d", (int32_t)result); + RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkQueueWaitIdle returned %d", (int32_t)result); return Result::SUCCESS; } diff --git a/Source/VK/ConversionVK.h b/Source/VK/ConversionVK.h index 5c6e13f3..939a0208 100644 --- a/Source/VK/ConversionVK.h +++ b/Source/VK/ConversionVK.h @@ -4,22 +4,26 @@ namespace nri { -constexpr std::array INDEX_TYPE_TABLE = {VK_INDEX_TYPE_UINT16, VK_INDEX_TYPE_UINT32}; +constexpr std::array INDEX_TYPE_TABLE = { + VK_INDEX_TYPE_UINT16, // UINT16 + VK_INDEX_TYPE_UINT32, // UINT32 +}; constexpr VkIndexType GetIndexType(IndexType indexType) { return INDEX_TYPE_TABLE[(uint32_t)indexType]; } constexpr std::array LAYOUT_TABLE = { - VK_IMAGE_LAYOUT_UNDEFINED, // UNKNOWN - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // COLOR_ATTACHMENT - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // DEPTH_STENCIL - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, // DEPTH_STENCIL_READONLY - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE - VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE - IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // COPY_SOURCE - IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // COPY_DESTINATION - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // PRESENT + VK_IMAGE_LAYOUT_UNDEFINED, // UNKNOWN + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // COLOR_ATTACHMENT + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // DEPTH_STENCIL_ATTACHMENT + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, // DEPTH_STENCIL_READONLY + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE + VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE + IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // COPY_SOURCE + IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // COPY_DESTINATION + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // PRESENT + VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, // SHADING_RATE_ATTACHMENT }; constexpr VkImageLayout GetImageLayout(Layout layout) { @@ -42,143 +46,6 @@ constexpr VkDescriptorType GetDescriptorType(DescriptorType type) { return DESCRIPTOR_TYPES[(uint32_t)type]; } -constexpr VkPipelineStageFlags2 GetPipelineStageFlags(StageBits stageBits) { - // Check non-mask values first - if (stageBits == StageBits::ALL) - return VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - - if (stageBits == StageBits::NONE) - return VK_PIPELINE_STAGE_2_NONE; - - // Gather bits - VkPipelineStageFlags2 flags = 0; - - if (stageBits & StageBits::INDEX_INPUT) - flags |= VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT; - - if (stageBits & StageBits::VERTEX_SHADER) - flags |= VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT; - - if (stageBits & StageBits::TESS_CONTROL_SHADER) - flags |= VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT; - - if (stageBits & StageBits::TESS_EVALUATION_SHADER) - flags |= VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT; - - if (stageBits & StageBits::GEOMETRY_SHADER) - flags |= VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT; - - if (stageBits & StageBits::MESH_CONTROL_SHADER) - flags |= VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT; - - if (stageBits & StageBits::MESH_EVALUATION_SHADER) - flags |= VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT; - - if (stageBits & StageBits::FRAGMENT_SHADER) - flags |= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; - - if (stageBits & StageBits::DEPTH_STENCIL_ATTACHMENT) - flags |= VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT; - - if (stageBits & StageBits::COLOR_ATTACHMENT) - flags |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - - if (stageBits & StageBits::COMPUTE_SHADER) - flags |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; - - if (stageBits & StageBits::RAY_TRACING_SHADERS) - flags |= VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR; - - if (stageBits & StageBits::INDIRECT) - flags |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT; - - if (stageBits & (StageBits::COPY | StageBits::CLEAR_STORAGE)) - flags |= VK_PIPELINE_STAGE_2_TRANSFER_BIT; - - if (stageBits & StageBits::ACCELERATION_STRUCTURE) - flags |= VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR; - - return flags; -} - -constexpr VkShaderStageFlags GetShaderStageFlags(StageBits stage) { - // Check non-mask values first - if (stage == StageBits::ALL) - return VK_SHADER_STAGE_ALL; - - // Gather bits - VkShaderStageFlags stageFlags = 0; - - if (stage & StageBits::VERTEX_SHADER) - stageFlags |= VK_SHADER_STAGE_VERTEX_BIT; - - if (stage & StageBits::TESS_CONTROL_SHADER) - stageFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - - if (stage & StageBits::TESS_EVALUATION_SHADER) - stageFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - - if (stage & StageBits::GEOMETRY_SHADER) - stageFlags |= VK_SHADER_STAGE_GEOMETRY_BIT; - - if (stage & StageBits::FRAGMENT_SHADER) - stageFlags |= VK_SHADER_STAGE_FRAGMENT_BIT; - - if (stage & StageBits::COMPUTE_SHADER) - stageFlags |= VK_SHADER_STAGE_COMPUTE_BIT; - - if (stage & StageBits::RAYGEN_SHADER) - stageFlags |= VK_SHADER_STAGE_RAYGEN_BIT_KHR; - - if (stage & StageBits::MISS_SHADER) - stageFlags |= VK_SHADER_STAGE_MISS_BIT_KHR; - - if (stage & StageBits::INTERSECTION_SHADER) - stageFlags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR; - - if (stage & StageBits::CLOSEST_HIT_SHADER) - stageFlags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; - - if (stage & StageBits::ANY_HIT_SHADER) - stageFlags |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR; - - if (stage & StageBits::CALLABLE_SHADER) - stageFlags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; - - if (stage & StageBits::MESH_CONTROL_SHADER) - stageFlags |= VK_SHADER_STAGE_TASK_BIT_EXT; - - if (stage & StageBits::MESH_EVALUATION_SHADER) - stageFlags |= VK_SHADER_STAGE_MESH_BIT_EXT; - - return stageFlags; -} - -inline VkFormat GetVkFormat(Format format, bool demoteSrgb = false) { - if (demoteSrgb) { - const FormatProps& formatProps = GetFormatProps(format); - if (formatProps.isSrgb) - format = (Format)((uint32_t)format - 1); - } - - return (VkFormat)NRIFormatToVKFormat(format); -} - -inline bool HasStencil(Format format) { - switch (format) { - case nri::Format::D24_UNORM_S8_UINT: - return true; - case nri::Format::D32_SFLOAT_S8_UINT_X24: - return true; - case nri::Format::X24_G8_UINT: - return true; - case nri::Format::X32_G8_UINT_X24: - return true; - default: - return false; - } -} - constexpr std::array TOPOLOGIES = { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // POINT_LIST VK_PRIMITIVE_TOPOLOGY_LINE_LIST, // LINE_LIST @@ -307,37 +174,16 @@ constexpr VkBlendOp GetBlendOp(BlendFunc blendFunc) { return BLEND_OP[(uint32_t)blendFunc]; } -constexpr VkColorComponentFlags GetColorComponent(ColorWriteBits colorWriteMask) { - return VkColorComponentFlags(colorWriteMask & ColorWriteBits::RGBA); -} - -constexpr std::array IMAGE_TYPES = {VK_IMAGE_TYPE_1D, VK_IMAGE_TYPE_2D, VK_IMAGE_TYPE_3D}; +constexpr std::array IMAGE_TYPES = { + VK_IMAGE_TYPE_1D, // TEXTURE_1D + VK_IMAGE_TYPE_2D, // TEXTURE_2D + VK_IMAGE_TYPE_3D, // TEXTURE_3D +}; constexpr VkImageType GetImageType(TextureType type) { return IMAGE_TYPES[(uint32_t)type]; } -constexpr VkImageAspectFlags GetImageAspectFlags(Format format) { - switch (format) { - case Format::D16_UNORM: - case Format::D32_SFLOAT: - case Format::R24_UNORM_X8: - case Format::R32_SFLOAT_X8_X24: - return VK_IMAGE_ASPECT_DEPTH_BIT; - - case Format::D24_UNORM_S8_UINT: - case Format::D32_SFLOAT_S8_UINT_X24: - return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - - case Format::X32_G8_UINT_X24: - case Format::X24_G8_UINT: - return VK_IMAGE_ASPECT_STENCIL_BIT; - - default: - return VK_IMAGE_ASPECT_COLOR_BIT; - } -} - constexpr std::array FILTER = { VK_FILTER_NEAREST, // NEAREST VK_FILTER_LINEAR, // LINEAR @@ -376,6 +222,10 @@ constexpr std::array IMAG VK_IMAGE_VIEW_TYPE_1D, // DEPTH_STENCIL_ATTACHMENT }; +constexpr VkImageViewType GetImageViewType(Texture1DViewType type) { + return IMAGE_VIEW_TYPE_1D[(uint32_t)type]; +} + constexpr std::array IMAGE_VIEW_TYPE_2D = { VK_IMAGE_VIEW_TYPE_2D, // SHADER_RESOURCE_2D, VK_IMAGE_VIEW_TYPE_2D_ARRAY, // SHADER_RESOURCE_2D_ARRAY, @@ -385,22 +235,19 @@ constexpr std::array IMAG VK_IMAGE_VIEW_TYPE_2D_ARRAY, // SHADER_RESOURCE_STORAGE_2D_ARRAY, VK_IMAGE_VIEW_TYPE_2D, // COLOR_ATTACHMENT, VK_IMAGE_VIEW_TYPE_2D, // DEPTH_STENCIL_ATTACHMENT + VK_IMAGE_VIEW_TYPE_2D, // SHADING_RATE_ATTACHMENT }; +constexpr VkImageViewType GetImageViewType(Texture2DViewType type) { + return IMAGE_VIEW_TYPE_2D[(uint32_t)type]; +} + constexpr std::array IMAGE_VIEW_TYPE_3D = { VK_IMAGE_VIEW_TYPE_3D, // SHADER_RESOURCE_3D, VK_IMAGE_VIEW_TYPE_3D, // SHADER_RESOURCE_STORAGE_3D, VK_IMAGE_VIEW_TYPE_3D, // COLOR_ATTACHMENT }; -constexpr VkImageViewType GetImageViewType(Texture1DViewType type) { - return IMAGE_VIEW_TYPE_1D[(uint32_t)type]; -} - -constexpr VkImageViewType GetImageViewType(Texture2DViewType type) { - return IMAGE_VIEW_TYPE_2D[(uint32_t)type]; -} - constexpr VkImageViewType GetImageViewType(Texture3DViewType type) { return IMAGE_VIEW_TYPE_3D[(uint32_t)type]; } @@ -414,31 +261,32 @@ constexpr std::array IM VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // DEPTH_STENCIL_ATTACHMENT }; +constexpr VkImageUsageFlags GetImageViewUsage(Texture1DViewType type) { + return IMAGE_VIEW_USAGE_1D[(uint32_t)type]; +} + constexpr std::array IMAGE_VIEW_USAGE_2D = { - VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_2D, - VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_2D_ARRAY, - VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_CUBE, - VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_CUBE_ARRAY, - VK_IMAGE_USAGE_STORAGE_BIT, // SHADER_RESOURCE_STORAGE_2D, - VK_IMAGE_USAGE_STORAGE_BIT, // SHADER_RESOURCE_STORAGE_2D_ARRAY, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // COLOR_ATTACHMENT, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // DEPTH_STENCIL_ATTACHMENT + VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_2D, + VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_2D_ARRAY, + VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_CUBE, + VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_CUBE_ARRAY, + VK_IMAGE_USAGE_STORAGE_BIT, // SHADER_RESOURCE_STORAGE_2D, + VK_IMAGE_USAGE_STORAGE_BIT, // SHADER_RESOURCE_STORAGE_2D_ARRAY, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // COLOR_ATTACHMENT, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // DEPTH_STENCIL_ATTACHMENT + VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, // SHADING_RATE_ATTACHMENT }; +constexpr VkImageUsageFlags GetImageViewUsage(Texture2DViewType type) { + return IMAGE_VIEW_USAGE_2D[(uint32_t)type]; +} + constexpr std::array IMAGE_VIEW_USAGE_3D = { VK_IMAGE_USAGE_SAMPLED_BIT, // SHADER_RESOURCE_3D, VK_IMAGE_USAGE_STORAGE_BIT, // SHADER_RESOURCE_STORAGE_3D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // COLOR_ATTACHMENT }; -constexpr VkImageUsageFlags GetImageViewUsage(Texture1DViewType type) { - return IMAGE_VIEW_USAGE_1D[(uint32_t)type]; -} - -constexpr VkImageUsageFlags GetImageViewUsage(Texture2DViewType type) { - return IMAGE_VIEW_USAGE_2D[(uint32_t)type]; -} - constexpr VkImageUsageFlags GetImageViewUsage(Texture3DViewType type) { return IMAGE_VIEW_USAGE_3D[(uint32_t)type]; } @@ -452,72 +300,70 @@ constexpr std::array IMAGE_ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // DEPTH_STENCIL_ATTACHMENT }; +constexpr VkImageLayout GetImageLayoutForView(Texture1DViewType type, ResourceViewBits flags) { + if (type == Texture1DViewType::DEPTH_STENCIL_ATTACHMENT && flags != ResourceViewBits::NONE) { + if (flags == (ResourceViewBits::READONLY_DEPTH | ResourceViewBits::READONLY_STENCIL)) + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + else if (flags == ResourceViewBits::READONLY_DEPTH) + return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + else if (flags == ResourceViewBits::READONLY_STENCIL) + return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR; + else + CHECK(false, "Bad flags"); + } + + return IMAGE_LAYOUT_1D[(uint32_t)type]; +} + constexpr std::array IMAGE_LAYOUT_2D = { - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_2D, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_2D_ARRAY, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_CUBE, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_CUBE_ARRAY, - VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE_2D, - VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE_2D_ARRAY, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // COLOR_ATTACHMENT, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // DEPTH_STENCIL_ATTACHMENT + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_2D, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_2D_ARRAY, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_CUBE, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_CUBE_ARRAY, + VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE_2D, + VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE_2D_ARRAY, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // COLOR_ATTACHMENT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // DEPTH_STENCIL_ATTACHMENT + VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, // SHADING_RATE_ATTACHMENT }; +constexpr VkImageLayout GetImageLayoutForView(Texture2DViewType type, ResourceViewBits flags) { + if (type == Texture2DViewType::DEPTH_STENCIL_ATTACHMENT && flags != ResourceViewBits::NONE) { + if (flags == (ResourceViewBits::READONLY_DEPTH | ResourceViewBits::READONLY_STENCIL)) + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + else if (flags == ResourceViewBits::READONLY_DEPTH) + return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + else if (flags == ResourceViewBits::READONLY_STENCIL) + return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR; + else + CHECK(false, "Bad flags"); + } + + return IMAGE_LAYOUT_2D[(uint32_t)type]; +} + constexpr std::array IMAGE_LAYOUT_3D = { VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // SHADER_RESOURCE_3D, VK_IMAGE_LAYOUT_GENERAL, // SHADER_RESOURCE_STORAGE_3D, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // COLOR_ATTACHMENT }; -constexpr VkImageLayout GetImageLayoutForView(Texture1DViewType type) { - return IMAGE_LAYOUT_1D[(uint32_t)type]; -} - -constexpr VkImageLayout GetImageLayoutForView(Texture2DViewType type) { - return IMAGE_LAYOUT_2D[(uint32_t)type]; -} - constexpr VkImageLayout GetImageLayoutForView(Texture3DViewType type) { return IMAGE_LAYOUT_3D[(uint32_t)type]; } -constexpr VkAccelerationStructureTypeKHR GetAccelerationStructureType(AccelerationStructureType type) { - static_assert(VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR == (uint32_t)AccelerationStructureType::TOP_LEVEL, "Enum mismatch."); - static_assert(VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR == (uint32_t)AccelerationStructureType::BOTTOM_LEVEL, "Enum mismatch."); - return (VkAccelerationStructureTypeKHR)type; -} - -constexpr VkBuildAccelerationStructureFlagsKHR GetAccelerationStructureBuildFlags(AccelerationStructureBuildBits flags) { - static_assert(VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::ALLOW_UPDATE, "Enum mismatch."); - static_assert(VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::ALLOW_COMPACTION, "Enum mismatch."); - static_assert(VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_TRACE, "Enum mismatch."); - static_assert(VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_BUILD, "Enum mismatch."); - static_assert(VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::MINIMIZE_MEMORY, "Enum mismatch."); - return (VkBuildAccelerationStructureFlagsKHR)flags; -} - -constexpr VkGeometryFlagsKHR GetGeometryFlags(BottomLevelGeometryBits geometryFlags) { - static_assert(VK_GEOMETRY_OPAQUE_BIT_KHR == (uint32_t)BottomLevelGeometryBits::OPAQUE_GEOMETRY, "Enum mismatch."); - static_assert(VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR == (uint32_t)BottomLevelGeometryBits::NO_DUPLICATE_ANY_HIT_INVOCATION, "Enum mismatch."); - return (VkGeometryFlagsKHR)geometryFlags; -} - -constexpr VkGeometryTypeKHR GetGeometryType(GeometryType geometryType) { - static_assert(VK_GEOMETRY_TYPE_TRIANGLES_KHR == (uint32_t)GeometryType::TRIANGLES, "Enum mismatch."); - static_assert(VK_GEOMETRY_TYPE_AABBS_KHR == (uint32_t)GeometryType::AABBS, "Enum mismatch."); - return (VkGeometryTypeKHR)geometryType; -} +constexpr std::array SHADING_RATE_COMBINER = { + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR, // REPLACE, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, // KEEP, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, // MIN, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, // MAX, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, // SUM, // TODO: SUM vs MUL? +}; -constexpr VkCopyAccelerationStructureModeKHR GetCopyMode(CopyMode copyMode) { - static_assert(VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR == (uint32_t)CopyMode::CLONE, "Enum mismatch."); - static_assert(VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR == (uint32_t)CopyMode::COMPACT, "Enum mismatch."); - return (VkCopyAccelerationStructureModeKHR)copyMode; +constexpr VkFragmentShadingRateCombinerOpKHR GetShadingRateCombiner(ShadingRateCombiner combiner) { + return SHADING_RATE_COMBINER[(uint32_t)combiner]; } -void ConvertGeometryObjectSizesVK(VkAccelerationStructureGeometryKHR* destObjects, uint32_t* primitiveNums, const GeometryObject* sourceObjects, uint32_t objectNum); -void ConvertGeometryObjectsVK( - VkAccelerationStructureGeometryKHR* destObjects, VkAccelerationStructureBuildRangeInfoKHR* ranges, const GeometryObject* sourceObjects, uint32_t objectNum); - constexpr std::array TEXTURE_TYPE_TABLE = { TextureType::TEXTURE_1D, // VK_IMAGE_TYPE_1D TextureType::TEXTURE_2D, // VK_IMAGE_TYPE_2D @@ -531,6 +377,154 @@ constexpr TextureType GetTextureType(VkImageType type) { return TextureType::MAX_NUM; } +constexpr VkPipelineStageFlags2 GetPipelineStageFlags(StageBits stageBits) { + // Check non-mask values first + if (stageBits == StageBits::ALL) + return VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + + if (stageBits == StageBits::NONE) + return VK_PIPELINE_STAGE_2_NONE; + + // Gather bits + VkPipelineStageFlags2 flags = 0; + + if (stageBits & StageBits::INDEX_INPUT) + flags |= VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT; + + if (stageBits & StageBits::VERTEX_SHADER) + flags |= VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT; + + if (stageBits & StageBits::TESS_CONTROL_SHADER) + flags |= VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT; + + if (stageBits & StageBits::TESS_EVALUATION_SHADER) + flags |= VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT; + + if (stageBits & StageBits::GEOMETRY_SHADER) + flags |= VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT; + + if (stageBits & StageBits::MESH_CONTROL_SHADER) + flags |= VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT; + + if (stageBits & StageBits::MESH_EVALUATION_SHADER) + flags |= VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT; + + if (stageBits & StageBits::FRAGMENT_SHADER) + flags |= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; + + if (stageBits & StageBits::DEPTH_STENCIL_ATTACHMENT) + flags |= VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT; + + if (stageBits & StageBits::COLOR_ATTACHMENT) + flags |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + + if (stageBits & StageBits::COMPUTE_SHADER) + flags |= VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT; + + if (stageBits & StageBits::RAY_TRACING_SHADERS) + flags |= VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR; + + if (stageBits & StageBits::INDIRECT) + flags |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT; + + if (stageBits & (StageBits::COPY | StageBits::CLEAR_STORAGE)) + flags |= VK_PIPELINE_STAGE_2_TRANSFER_BIT; + + if (stageBits & StageBits::ACCELERATION_STRUCTURE) + flags |= VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR; + + return flags; +} + +constexpr VkShaderStageFlags GetShaderStageFlags(StageBits stage) { + // Check non-mask values first + if (stage == StageBits::ALL) + return VK_SHADER_STAGE_ALL; + + // Gather bits + VkShaderStageFlags stageFlags = 0; + + if (stage & StageBits::VERTEX_SHADER) + stageFlags |= VK_SHADER_STAGE_VERTEX_BIT; + + if (stage & StageBits::TESS_CONTROL_SHADER) + stageFlags |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + + if (stage & StageBits::TESS_EVALUATION_SHADER) + stageFlags |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + + if (stage & StageBits::GEOMETRY_SHADER) + stageFlags |= VK_SHADER_STAGE_GEOMETRY_BIT; + + if (stage & StageBits::FRAGMENT_SHADER) + stageFlags |= VK_SHADER_STAGE_FRAGMENT_BIT; + + if (stage & StageBits::COMPUTE_SHADER) + stageFlags |= VK_SHADER_STAGE_COMPUTE_BIT; + + if (stage & StageBits::RAYGEN_SHADER) + stageFlags |= VK_SHADER_STAGE_RAYGEN_BIT_KHR; + + if (stage & StageBits::MISS_SHADER) + stageFlags |= VK_SHADER_STAGE_MISS_BIT_KHR; + + if (stage & StageBits::INTERSECTION_SHADER) + stageFlags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR; + + if (stage & StageBits::CLOSEST_HIT_SHADER) + stageFlags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; + + if (stage & StageBits::ANY_HIT_SHADER) + stageFlags |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR; + + if (stage & StageBits::CALLABLE_SHADER) + stageFlags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; + + if (stage & StageBits::MESH_CONTROL_SHADER) + stageFlags |= VK_SHADER_STAGE_TASK_BIT_EXT; + + if (stage & StageBits::MESH_EVALUATION_SHADER) + stageFlags |= VK_SHADER_STAGE_MESH_BIT_EXT; + + return stageFlags; +} + +constexpr VkImageAspectFlags GetImageAspectFlags(Format format) { + switch (format) { + case Format::D16_UNORM: + case Format::D32_SFLOAT: + case Format::R24_UNORM_X8: + case Format::R32_SFLOAT_X8_X24: + return VK_IMAGE_ASPECT_DEPTH_BIT; + + case Format::D24_UNORM_S8_UINT: + case Format::D32_SFLOAT_S8_UINT_X24: + return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + + case Format::X32_G8_UINT_X24: + case Format::X24_G8_UINT: + return VK_IMAGE_ASPECT_STENCIL_BIT; + + default: + return VK_IMAGE_ASPECT_COLOR_BIT; + } +} + +constexpr bool HasStencil(Format format) { + switch (format) { + case nri::Format::D24_UNORM_S8_UINT: + return true; + case nri::Format::D32_SFLOAT_S8_UINT_X24: + return true; + case nri::Format::X24_G8_UINT: + return true; + case nri::Format::X32_G8_UINT_X24: + return true; + default: + return false; + } +} + constexpr Result GetReturnCode(VkResult result) { switch (result) { case VK_SUCCESS: @@ -578,4 +572,80 @@ constexpr Result GetReturnCode(VkResult result) { } } +constexpr VkColorComponentFlags GetColorComponent(ColorWriteBits colorWriteMask) { + return VkColorComponentFlags(colorWriteMask & ColorWriteBits::RGBA); +} + +constexpr VkAccelerationStructureTypeKHR GetAccelerationStructureType(AccelerationStructureType type) { + static_assert(VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR == (uint32_t)AccelerationStructureType::TOP_LEVEL, "Enum mismatch"); + static_assert(VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR == (uint32_t)AccelerationStructureType::BOTTOM_LEVEL, "Enum mismatch"); + + return (VkAccelerationStructureTypeKHR)type; +} + +constexpr VkBuildAccelerationStructureFlagsKHR GetAccelerationStructureBuildFlags(AccelerationStructureBuildBits flags) { + static_assert(VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::ALLOW_UPDATE, "Enum mismatch"); + static_assert(VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::ALLOW_COMPACTION, "Enum mismatch"); + static_assert(VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_TRACE, "Enum mismatch"); + static_assert(VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::PREFER_FAST_BUILD, "Enum mismatch"); + static_assert(VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR == (uint32_t)AccelerationStructureBuildBits::MINIMIZE_MEMORY, "Enum mismatch"); + + return (VkBuildAccelerationStructureFlagsKHR)flags; +} + +constexpr VkGeometryFlagsKHR GetGeometryFlags(BottomLevelGeometryBits geometryFlags) { + static_assert(VK_GEOMETRY_OPAQUE_BIT_KHR == (uint32_t)BottomLevelGeometryBits::OPAQUE_GEOMETRY, "Enum mismatch"); + static_assert(VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR == (uint32_t)BottomLevelGeometryBits::NO_DUPLICATE_ANY_HIT_INVOCATION, "Enum mismatch"); + + return (VkGeometryFlagsKHR)geometryFlags; +} + +constexpr VkGeometryTypeKHR GetGeometryType(GeometryType geometryType) { + static_assert(VK_GEOMETRY_TYPE_TRIANGLES_KHR == (uint32_t)GeometryType::TRIANGLES, "Enum mismatch"); + static_assert(VK_GEOMETRY_TYPE_AABBS_KHR == (uint32_t)GeometryType::AABBS, "Enum mismatch"); + + return (VkGeometryTypeKHR)geometryType; +} + +constexpr VkCopyAccelerationStructureModeKHR GetCopyMode(CopyMode copyMode) { + static_assert(VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR == (uint32_t)CopyMode::CLONE, "Enum mismatch"); + static_assert(VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR == (uint32_t)CopyMode::COMPACT, "Enum mismatch"); + + return (VkCopyAccelerationStructureModeKHR)copyMode; +} + +inline VkFormat GetVkFormat(Format format, bool demoteSrgb = false) { + if (demoteSrgb) { + const FormatProps& formatProps = GetFormatProps(format); + if (formatProps.isSrgb) + format = (Format)((uint32_t)format - 1); + } + + return (VkFormat)NRIFormatToVKFormat(format); +} + +inline VkExtent2D GetShadingRate(ShadingRate shadingRate) { + switch (shadingRate) { + case ShadingRate::_1x1: + return {1, 1}; + case ShadingRate::_1x2: + return {1, 2}; + case ShadingRate::_2x1: + return {2, 1}; + case ShadingRate::_2x2: + return {2, 2}; + case ShadingRate::_2x4: + return {2, 4}; + case ShadingRate::_4x2: + return {4, 2}; + case ShadingRate::_4x4: + return {4, 4}; + } + + return {}; +} + +void ConvertGeometryObjectSizesVK(VkAccelerationStructureGeometryKHR* destObjects, uint32_t* primitiveNums, const GeometryObject* sourceObjects, uint32_t objectNum); +void ConvertGeometryObjectsVK(VkAccelerationStructureGeometryKHR* destObjects, VkAccelerationStructureBuildRangeInfoKHR* ranges, const GeometryObject* sourceObjects, uint32_t objectNum); + } // namespace nri \ No newline at end of file diff --git a/Source/VK/DescriptorVK.cpp b/Source/VK/DescriptorVK.cpp index 74cf873d..2f5d3894 100644 --- a/Source/VK/DescriptorVK.cpp +++ b/Source/VK/DescriptorVK.cpp @@ -31,74 +31,98 @@ DescriptorVK::~DescriptorVK() { } template -void FillTextureDesc(const T& textureViewDesc, DescriptorTextureDesc& descriptorTextureDesc) { +Result DescriptorVK::CreateTextureView(const T& textureViewDesc) { const TextureVK& texture = *(const TextureVK*)textureViewDesc.texture; const TextureDesc& textureDesc = texture.GetDesc(); - const Mip_t remainingMips = textureDesc.mipNum - textureViewDesc.mipOffset; - const Dim_t remainingLayers = textureDesc.layerNum - descriptorTextureDesc.layerOffset; - - descriptorTextureDesc.texture = &texture; - descriptorTextureDesc.layout = ::GetImageLayoutForView(textureViewDesc.viewType); - descriptorTextureDesc.aspectFlags = ::GetImageAspectFlags(textureViewDesc.format); - descriptorTextureDesc.layerOffset = textureViewDesc.layerOffset; - descriptorTextureDesc.layerNum = (textureViewDesc.layerNum == REMAINING_LAYERS) ? remainingLayers : textureViewDesc.layerNum; - descriptorTextureDesc.mipOffset = textureViewDesc.mipOffset; - descriptorTextureDesc.mipNum = (textureViewDesc.mipNum == REMAINING_MIPS) ? remainingMips : textureViewDesc.mipNum; -} + Mip_t remainingMips = textureDesc.mipNum - textureViewDesc.mipOffset; + Dim_t remainingLayers = textureDesc.layerNum - textureViewDesc.layerOffset; + + VkImageViewUsageCreateInfo usageInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO}; + usageInfo.usage = GetImageViewUsage(textureViewDesc.viewType); + + VkImageSubresourceRange subresource = { + GetImageAspectFlags(textureViewDesc.format), + textureViewDesc.mipOffset, + textureViewDesc.mipNum == REMAINING_MIPS ? remainingMips : textureViewDesc.mipNum, + textureViewDesc.layerOffset, + textureViewDesc.layerNum == REMAINING_LAYERS ? remainingLayers : textureViewDesc.layerNum, + }; + + VkImageViewCreateInfo createInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + createInfo.pNext = &usageInfo; + createInfo.viewType = GetImageViewType(textureViewDesc.viewType); + createInfo.format = GetVkFormat(textureViewDesc.format); + createInfo.subresourceRange = subresource; + createInfo.image = texture.GetHandle(); -template <> -void FillTextureDesc(const Texture3DViewDesc& textureViewDesc, DescriptorTextureDesc& descriptorTextureDesc) { - const TextureVK& texture = *(const TextureVK*)textureViewDesc.texture; - const TextureDesc& textureDesc = texture.GetDesc(); - const Mip_t remainingMips = textureDesc.mipNum - textureViewDesc.mipOffset; - - descriptorTextureDesc.texture = &texture; - descriptorTextureDesc.layout = ::GetImageLayoutForView(textureViewDesc.viewType); - descriptorTextureDesc.aspectFlags = ::GetImageAspectFlags(textureViewDesc.format); - descriptorTextureDesc.layerOffset = 0; - descriptorTextureDesc.layerNum = 1; - descriptorTextureDesc.mipOffset = textureViewDesc.mipOffset; - descriptorTextureDesc.mipNum = (textureViewDesc.mipNum == REMAINING_MIPS) ? remainingMips : textureViewDesc.mipNum; -} + const auto& vk = m_Device.GetDispatchTable(); + VkResult result = vk.CreateImageView(m_Device, &createInfo, m_Device.GetAllocationCallbacks(), &m_ImageView); + RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkCreateImageView returned %d", (int32_t)result); -template -void FillImageSubresourceRange(const T& textureViewDesc, VkImageSubresourceRange& subresourceRange) { - subresourceRange = {::GetImageAspectFlags(textureViewDesc.format), textureViewDesc.mipOffset, - (textureViewDesc.mipNum == REMAINING_MIPS) ? VK_REMAINING_MIP_LEVELS : textureViewDesc.mipNum, textureViewDesc.layerOffset, - (textureViewDesc.layerNum == REMAINING_LAYERS) ? VK_REMAINING_ARRAY_LAYERS : textureViewDesc.layerNum}; -} + m_Type = DescriptorTypeVK::IMAGE_VIEW; + m_Format = createInfo.format; + m_TextureDesc.handle = texture.GetHandle(); + m_TextureDesc.texture = &texture; + m_TextureDesc.layout = GetImageLayoutForView(textureViewDesc.viewType, textureViewDesc.flags); + m_TextureDesc.aspectFlags = GetImageAspectFlags(textureViewDesc.format); + m_TextureDesc.layerOffset = textureViewDesc.layerOffset; + m_TextureDesc.layerNum = (Dim_t)subresource.layerCount; + m_TextureDesc.sliceOffset = 0; + m_TextureDesc.sliceNum = 1; + m_TextureDesc.mipOffset = textureViewDesc.mipOffset; + m_TextureDesc.mipNum = (Mip_t)subresource.levelCount; -template <> -void FillImageSubresourceRange(const Texture3DViewDesc& textureViewDesc, VkImageSubresourceRange& subresourceRange) { - subresourceRange = {::GetImageAspectFlags(textureViewDesc.format), textureViewDesc.mipOffset, - (textureViewDesc.mipNum == REMAINING_MIPS) ? VK_REMAINING_MIP_LEVELS : textureViewDesc.mipNum, 0, 1}; + return Result::SUCCESS; } -template -Result DescriptorVK::CreateTextureView(const T& textureViewDesc) { +template <> +Result DescriptorVK::CreateTextureView(const Texture3DViewDesc& textureViewDesc) { const TextureVK& texture = *(const TextureVK*)textureViewDesc.texture; + const TextureDesc& textureDesc = texture.GetDesc(); + Mip_t remainingMips = textureDesc.mipNum - textureViewDesc.mipOffset; + Dim_t remainingLayers = textureDesc.layerNum - textureViewDesc.sliceOffset; + + VkImageViewSlicedCreateInfoEXT slicesInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_SLICED_CREATE_INFO_EXT}; + slicesInfo.sliceOffset = textureViewDesc.sliceOffset; + slicesInfo.sliceCount = textureViewDesc.sliceNum == REMAINING_LAYERS ? remainingLayers : textureViewDesc.sliceNum; + + VkImageViewUsageCreateInfo usageInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO}; + usageInfo.usage = GetImageViewUsage(textureViewDesc.viewType); + + if (m_Device.m_IsImageSlicedViewSupported) + usageInfo.pNext = &slicesInfo; + + VkImageSubresourceRange subresource = { + GetImageAspectFlags(textureViewDesc.format), + textureViewDesc.mipOffset, + textureViewDesc.mipNum == REMAINING_MIPS ? remainingMips : textureViewDesc.mipNum, + 0, + 1, + }; + + VkImageViewCreateInfo createInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; + createInfo.pNext = &usageInfo; + createInfo.viewType = GetImageViewType(textureViewDesc.viewType); + createInfo.format = GetVkFormat(textureViewDesc.format); + createInfo.subresourceRange = subresource; + createInfo.image = texture.GetHandle(); - VkImageViewUsageCreateInfo imageViewUsageCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO}; - imageViewUsageCreateInfo.usage = GetImageViewUsage(textureViewDesc.viewType); + const auto& vk = m_Device.GetDispatchTable(); + VkResult result = vk.CreateImageView(m_Device, &createInfo, m_Device.GetAllocationCallbacks(), &m_ImageView); + RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkCreateImageView returned %d", (int32_t)result); m_Type = DescriptorTypeVK::IMAGE_VIEW; - m_Format = ::GetVkFormat(textureViewDesc.format); - ::FillTextureDesc(textureViewDesc, m_TextureDesc); + m_Format = createInfo.format; m_TextureDesc.handle = texture.GetHandle(); - - VkImageSubresourceRange subresource = {}; - ::FillImageSubresourceRange(textureViewDesc, subresource); - - VkImageViewCreateInfo imageViewCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; - imageViewCreateInfo.pNext = &imageViewUsageCreateInfo; - imageViewCreateInfo.viewType = GetImageViewType(textureViewDesc.viewType); - imageViewCreateInfo.format = m_Format; - imageViewCreateInfo.subresourceRange = subresource; - imageViewCreateInfo.image = texture.GetHandle(); - - const auto& vk = m_Device.GetDispatchTable(); - VkResult result = vk.CreateImageView(m_Device, &imageViewCreateInfo, m_Device.GetAllocationCallbacks(), &m_ImageView); - RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkCreateImageView returned %d", (int32_t)result); + m_TextureDesc.texture = &texture; + m_TextureDesc.layout = GetImageLayoutForView(textureViewDesc.viewType); + m_TextureDesc.aspectFlags = GetImageAspectFlags(textureViewDesc.format); + m_TextureDesc.layerOffset = 0; + m_TextureDesc.layerNum = 1; + m_TextureDesc.sliceOffset = textureViewDesc.sliceOffset; + m_TextureDesc.sliceNum = (Dim_t)slicesInfo.sliceCount; + m_TextureDesc.mipOffset = textureViewDesc.mipOffset; + m_TextureDesc.mipNum = (Mip_t)subresource.levelCount; return Result::SUCCESS; } @@ -115,51 +139,68 @@ Result DescriptorVK::Create(const BufferViewDesc& bufferViewDesc) { if (bufferViewDesc.format == Format::UNKNOWN) return Result::SUCCESS; - VkBufferViewCreateInfo info = { - VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, nullptr, (VkBufferViewCreateFlags)0, buffer.GetHandle(), m_Format, bufferViewDesc.offset, m_BufferDesc.size}; + VkBufferViewCreateInfo createInfo = {VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + createInfo.flags = (VkBufferViewCreateFlags)0; + createInfo.buffer = buffer.GetHandle(); + createInfo.format = m_Format; + createInfo.offset = bufferViewDesc.offset; + createInfo.range = m_BufferDesc.size; const auto& vk = m_Device.GetDispatchTable(); - VkResult result = vk.CreateBufferView(m_Device, &info, m_Device.GetAllocationCallbacks(), &m_BufferView); + VkResult result = vk.CreateBufferView(m_Device, &createInfo, m_Device.GetAllocationCallbacks(), &m_BufferView); RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkCreateBufferView returned %d", (int32_t)result); return Result::SUCCESS; } -Result DescriptorVK::Create(const Texture1DViewDesc& textureViewDesc) { - return CreateTextureView(textureViewDesc); -} - -Result DescriptorVK::Create(const Texture2DViewDesc& textureViewDesc) { - return CreateTextureView(textureViewDesc); -} - -Result DescriptorVK::Create(const Texture3DViewDesc& textureViewDesc) { - return CreateTextureView(textureViewDesc); -} - Result DescriptorVK::Create(const SamplerDesc& samplerDesc) { - m_Type = DescriptorTypeVK::SAMPLER; - - const VkSamplerCreateInfo samplerInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, nullptr, (VkSamplerCreateFlags)0, GetFilter(samplerDesc.filters.mag), - GetFilter(samplerDesc.filters.min), GetSamplerMipmapMode(samplerDesc.filters.mip), GetSamplerAddressMode(samplerDesc.addressModes.u), - GetSamplerAddressMode(samplerDesc.addressModes.v), GetSamplerAddressMode(samplerDesc.addressModes.w), samplerDesc.mipBias, VkBool32(samplerDesc.anisotropy > 1.0f), - (float)samplerDesc.anisotropy, VkBool32(samplerDesc.compareFunc != CompareFunc::NONE), GetCompareOp(samplerDesc.compareFunc), samplerDesc.mipMin, samplerDesc.mipMax, - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, false}; + VkSamplerCreateInfo info = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; + info.pNext = nullptr; + info.flags = (VkSamplerCreateFlags)0; + info.magFilter = GetFilter(samplerDesc.filters.mag); + info.minFilter = GetFilter(samplerDesc.filters.min); + info.mipmapMode = GetSamplerMipmapMode(samplerDesc.filters.mip); + info.addressModeU = GetSamplerAddressMode(samplerDesc.addressModes.u); + info.addressModeV = GetSamplerAddressMode(samplerDesc.addressModes.v); + info.addressModeW = GetSamplerAddressMode(samplerDesc.addressModes.w); + info.mipLodBias = samplerDesc.mipBias; + info.anisotropyEnable = VkBool32(samplerDesc.anisotropy > 1.0f); + info.maxAnisotropy = (float)samplerDesc.anisotropy; + info.compareEnable = VkBool32(samplerDesc.compareFunc != CompareFunc::NONE); + info.compareOp = GetCompareOp(samplerDesc.compareFunc); + info.minLod = samplerDesc.mipMin; + info.maxLod = samplerDesc.mipMax; + info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + info.unnormalizedCoordinates = false; const auto& vk = m_Device.GetDispatchTable(); - VkResult result = vk.CreateSampler(m_Device, &samplerInfo, m_Device.GetAllocationCallbacks(), &m_Sampler); + VkResult result = vk.CreateSampler(m_Device, &info, m_Device.GetAllocationCallbacks(), &m_Sampler); RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkCreateSampler returned %d", (int32_t)result); + m_Type = DescriptorTypeVK::SAMPLER; + return Result::SUCCESS; } Result DescriptorVK::Create(VkAccelerationStructureKHR accelerationStructure) { - m_Type = DescriptorTypeVK::ACCELERATION_STRUCTURE; m_AccelerationStructure = accelerationStructure; + m_Type = DescriptorTypeVK::ACCELERATION_STRUCTURE; return Result::SUCCESS; } +Result DescriptorVK::Create(const Texture1DViewDesc& textureViewDesc) { + return CreateTextureView(textureViewDesc); +} + +Result DescriptorVK::Create(const Texture2DViewDesc& textureViewDesc) { + return CreateTextureView(textureViewDesc); +} + +Result DescriptorVK::Create(const Texture3DViewDesc& textureViewDesc) { + return CreateTextureView(textureViewDesc); +} + //================================================================================================================ // NRI //================================================================================================================ diff --git a/Source/VK/DescriptorVK.h b/Source/VK/DescriptorVK.h index 9ca96df8..bd7772bb 100644 --- a/Source/VK/DescriptorVK.h +++ b/Source/VK/DescriptorVK.h @@ -28,6 +28,8 @@ struct DescriptorTextureDesc { VkImageAspectFlags aspectFlags; Dim_t layerOffset; Dim_t layerNum; + Dim_t sliceOffset; + Dim_t sliceNum; Mip_t mipOffset; Mip_t mipNum; }; diff --git a/Source/VK/DeviceVK.cpp b/Source/VK/DeviceVK.cpp index c6829288..3e51f6a5 100644 --- a/Source/VK/DeviceVK.cpp +++ b/Source/VK/DeviceVK.cpp @@ -78,6 +78,9 @@ constexpr VkImageUsageFlags GetImageUsageFlags(TextureUsageBits textureUsageBits if (textureUsageBits & TextureUsageBits::DEPTH_STENCIL_ATTACHMENT) flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + if (textureUsageBits & TextureUsageBits::SHADING_RATE_ATTACHMENT) + flags |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; + return flags; } @@ -305,6 +308,9 @@ void DeviceVK::ProcessDeviceExtensions(Vector& desiredDeviceExts, b if (IsExtensionSupported(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, supportedExts)) desiredDeviceExts.push_back(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME); + if (IsExtensionSupported(VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME, supportedExts)) + desiredDeviceExts.push_back(VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME); + // Optional if (IsExtensionSupported(VK_NV_LOW_LATENCY_2_EXTENSION_NAME, supportedExts)) desiredDeviceExts.push_back(VK_NV_LOW_LATENCY_2_EXTENSION_NAME); @@ -604,6 +610,11 @@ Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc, const Devi APPEND_EXT(memoryPriorityFeatures); } + VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT slicedViewFeatures = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT}; + if (IsExtensionSupported(VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME, desiredDeviceExts)) { + APPEND_EXT(slicedViewFeatures); + } + if (IsExtensionSupported(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, desiredDeviceExts)) m_IsMemoryBudgetSupported = true; @@ -699,6 +710,11 @@ Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc, const Devi APPEND_EXT(sampleLocationsProps); } + VkPhysicalDeviceFragmentShadingRatePropertiesKHR shadingRateProps = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR}; + if (IsExtensionSupported(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, desiredDeviceExts)) { + APPEND_EXT(shadingRateProps); + } + VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingProps = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR}; if (IsExtensionSupported(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, desiredDeviceExts)) { APPEND_EXT(rayTracingProps); @@ -723,9 +739,10 @@ Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc, const Devi m_IsDeviceAddressSupported = features12.bufferDeviceAddress; m_IsSwapChainMutableFormatSupported = IsExtensionSupported(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, desiredDeviceExts); m_IsPresentIdSupported = presentIdFeatures.presentId; - m_IsPresentWaitSupported = m_IsPresentIdSupported && presentWaitFeatures.presentWait; + m_IsPresentWaitSupported = m_IsPresentIdSupported != 0 && presentWaitFeatures.presentWait != 0; m_IsMemoryPrioritySupported = memoryPriorityFeatures.memoryPriority; - m_IsLowLatencySupported = m_IsPresentIdSupported && IsExtensionSupported(VK_NV_LOW_LATENCY_2_EXTENSION_NAME, desiredDeviceExts); + m_IsLowLatencySupported = m_IsPresentIdSupported != 0 && IsExtensionSupported(VK_NV_LOW_LATENCY_2_EXTENSION_NAME, desiredDeviceExts); + m_IsImageSlicedViewSupported = slicedViewFeatures.imageSlicedViewOf3D != 0; // Fill desc const VkPhysicalDeviceLimits& limits = props.properties.limits; @@ -867,6 +884,11 @@ Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc, const Devi if (sampleLocationsProps.sampleLocationSampleCounts) m_Desc.programmableSampleLocationsTier = sampleLocationsProps.variableSampleLocations ? 2 : 1; // TODO: best guess + m_Desc.isPipelineShadingRateSupported = shadingRateFeatures.pipelineFragmentShadingRate != 0; + m_Desc.isPrimitiveShadingRateSupported = shadingRateFeatures.primitiveFragmentShadingRate != 0; + m_Desc.isAttachmentShadingRateSupported = shadingRateFeatures.attachmentFragmentShadingRate != 0; + m_Desc.shadingRateAttachmentTileSize = (uint8_t)shadingRateProps.minFragmentShadingRateAttachmentTexelSize.width; + m_Desc.isComputeQueueSupported = m_QueueFamilyIndices[(uint32_t)CommandQueueType::COMPUTE] != INVALID_FAMILY_INDEX; m_Desc.isCopyQueueSupported = m_QueueFamilyIndices[(uint32_t)CommandQueueType::COPY] != INVALID_FAMILY_INDEX; @@ -923,8 +945,10 @@ void DeviceVK::FillCreateInfo(const TextureDesc& textureDesc, VkImageCreateInfo& flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; // allow cube maps if (textureDesc.type == nri::TextureType::TEXTURE_3D) flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; // allow 3D demotion to a set of layers // TODO: hook up "VK_EXT_image_2d_view_of_3d"? - if (m_Desc.programmableSampleLocationsTier && textureDesc.format >= Format::D16_UNORM) + if (m_Desc.programmableSampleLocationsTier && formatProps.isDepth) flags |= VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT; + if (textureDesc.depth > 1) + flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; // should be already set info.flags = flags; @@ -1600,6 +1624,10 @@ Result DeviceVK::ResolveDispatchTable(const Vector& desiredDeviceEx // IMPORTANT: {} is mandatory here! + if (IsExtensionSupported(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, desiredDeviceExts)) { + GET_DEVICE_PROC(CmdSetFragmentShadingRateKHR); + } + if (IsExtensionSupported(VK_KHR_SWAPCHAIN_EXTENSION_NAME, desiredDeviceExts)) { GET_DEVICE_PROC(AcquireNextImageKHR); GET_DEVICE_PROC(QueuePresentKHR); diff --git a/Source/VK/DeviceVK.h b/Source/VK/DeviceVK.h index 97c5ff3e..0aba396c 100644 --- a/Source/VK/DeviceVK.h +++ b/Source/VK/DeviceVK.h @@ -118,15 +118,16 @@ struct DeviceVK final : public DeviceBase { Result ResolveDispatchTable(const Vector& desiredDeviceExts); public: - bool m_IsDescriptorIndexingSupported = false; - bool m_IsDeviceAddressSupported = false; - bool m_IsSwapChainMutableFormatSupported = false; - bool m_IsPresentIdSupported = false; - bool m_IsPresentWaitSupported = false; - bool m_IsLowLatencySupported = false; - bool m_IsMemoryPrioritySupported = false; - bool m_IsMemoryBudgetSupported = false; - bool m_IsMaintenance5Supported = false; + uint32_t m_IsDescriptorIndexingSupported : 1; + uint32_t m_IsDeviceAddressSupported : 1; + uint32_t m_IsSwapChainMutableFormatSupported : 1; + uint32_t m_IsPresentIdSupported : 1; + uint32_t m_IsPresentWaitSupported : 1; + uint32_t m_IsLowLatencySupported : 1; + uint32_t m_IsMemoryPrioritySupported : 1; + uint32_t m_IsMemoryBudgetSupported : 1; + uint32_t m_IsMaintenance5Supported : 1; + uint32_t m_IsImageSlicedViewSupported : 1; private: VkPhysicalDevice m_PhysicalDevice = nullptr; diff --git a/Source/VK/DispatchTable.h b/Source/VK/DispatchTable.h index ae114616..8d44b6b1 100644 --- a/Source/VK/DispatchTable.h +++ b/Source/VK/DispatchTable.h @@ -143,6 +143,9 @@ struct DispatchTable { VULKAN_FUNCTION(CmdEndRendering); VULKAN_FUNCTION(EndCommandBuffer); + // VK_KHR_fragment_shading_rate + VULKAN_FUNCTION(CmdSetFragmentShadingRateKHR); + // VK_KHR_swapchain VULKAN_FUNCTION(AcquireNextImageKHR); VULKAN_FUNCTION(QueuePresentKHR); diff --git a/Source/VK/FenceVK.cpp b/Source/VK/FenceVK.cpp index 4a9dc52c..710e63ed 100644 --- a/Source/VK/FenceVK.cpp +++ b/Source/VK/FenceVK.cpp @@ -23,7 +23,7 @@ Result FenceVK::Create(uint64_t initialValue) { const auto& vk = m_Device.GetDispatchTable(); VkResult result = vk.CreateSemaphore((VkDevice)m_Device, &semaphoreCreateInfo, m_Device.GetAllocationCallbacks(), &m_Handle); - RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vk.CreateSemaphore returned %d", (int32_t)result); + RETURN_ON_FAILURE(&m_Device, result == VK_SUCCESS, GetReturnCode(result), "vkCreateSemaphore returned %d", (int32_t)result); return Result::SUCCESS; } diff --git a/Source/VK/PipelineVK.cpp b/Source/VK/PipelineVK.cpp index 1e313328..62703f8c 100644 --- a/Source/VK/PipelineVK.cpp +++ b/Source/VK/PipelineVK.cpp @@ -187,7 +187,7 @@ Result PipelineVK::Create(const GraphicsPipelineDesc& graphicsPipelineDesc) { colorFormats[i] = GetVkFormat(om.color[i].format); VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO}; - // pipelineRenderingCreateInfo.viewMask; // TODO + // pipelineRenderingCreateInfo.viewMask; // TODO: add multi-view support pipelineRenderingCreateInfo.colorAttachmentCount = om.colorNum; pipelineRenderingCreateInfo.pColorAttachmentFormats = colorFormats; pipelineRenderingCreateInfo.depthAttachmentFormat = GetVkFormat(om.depthStencilFormat); @@ -206,18 +206,24 @@ Result PipelineVK::Create(const GraphicsPipelineDesc& graphicsPipelineDesc) { dynamicStates[dynamicStateNum++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT; if (isConstantColorReferenced) dynamicStates[dynamicStateNum++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + if (r.shadingRate) + dynamicStates[dynamicStateNum++] = VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR; VkPipelineDynamicStateCreateInfo dynamicState = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO}; dynamicState.dynamicStateCount = dynamicStateNum; dynamicState.pDynamicStates = dynamicStates.data(); // Create + VkPipelineCreateFlags flags = 0; + if (r.shadingRate) + flags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; + const PipelineLayoutVK& pipelineLayoutVK = *(const PipelineLayoutVK*)graphicsPipelineDesc.pipelineLayout; const VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &pipelineRenderingCreateInfo, - (VkPipelineCreateFlags)0, + flags, graphicsPipelineDesc.shaderNum, stages, &vertexInputState, diff --git a/Source/Validation/AccelerationStructureVal.cpp b/Source/Validation/AccelerationStructureVal.cpp index e81f655d..ae13415a 100644 --- a/Source/Validation/AccelerationStructureVal.cpp +++ b/Source/Validation/AccelerationStructureVal.cpp @@ -26,13 +26,13 @@ uint64_t AccelerationStructureVal::GetBuildScratchBufferSize() const { } uint64_t AccelerationStructureVal::GetHandle() const { - RETURN_ON_FAILURE(&m_Device, IsBoundToMemory(), 0, "GetAccelerationStructureHandle: AccelerationStructure is not bound to memory"); + RETURN_ON_FAILURE(&m_Device, IsBoundToMemory(), 0, "AccelerationStructure is not bound to memory"); return GetRayTracingInterface().GetAccelerationStructureHandle(*GetImpl()); } uint64_t AccelerationStructureVal::GetNativeObject() const { - RETURN_ON_FAILURE(&m_Device, IsBoundToMemory(), 0, "GetAccelerationStructureNativeObject: AccelerationStructure is not bound to memory"); + RETURN_ON_FAILURE(&m_Device, IsBoundToMemory(), 0, "AccelerationStructure is not bound to memory"); return GetRayTracingInterface().GetAccelerationStructureNativeObject(*GetImpl()); } diff --git a/Source/Validation/BufferVal.cpp b/Source/Validation/BufferVal.cpp index d26731df..368f4731 100644 --- a/Source/Validation/BufferVal.cpp +++ b/Source/Validation/BufferVal.cpp @@ -20,8 +20,8 @@ void BufferVal::SetDebugName(const char* name) { } void* BufferVal::Map(uint64_t offset, uint64_t size) { - RETURN_ON_FAILURE(&m_Device, m_IsBoundToMemory, nullptr, "MapBuffer: the buffer is not bound to memory"); - RETURN_ON_FAILURE(&m_Device, !m_IsMapped, nullptr, "MapBuffer: the buffer is already mapped (D3D11 doesn't support nested calls)"); + RETURN_ON_FAILURE(&m_Device, m_IsBoundToMemory, nullptr, "the buffer is not bound to memory"); + RETURN_ON_FAILURE(&m_Device, !m_IsMapped, nullptr, "the buffer is already mapped (D3D11 doesn't support nested calls)"); m_IsMapped = true; @@ -29,7 +29,7 @@ void* BufferVal::Map(uint64_t offset, uint64_t size) { } void BufferVal::Unmap() { - RETURN_ON_FAILURE(&m_Device, m_IsMapped, ReturnVoid(), "UnmapBuffer: the buffer is not mapped"); + RETURN_ON_FAILURE(&m_Device, m_IsMapped, ReturnVoid(), "the buffer is not mapped"); m_IsMapped = false; diff --git a/Source/Validation/CommandBufferVal.cpp b/Source/Validation/CommandBufferVal.cpp index 9bb71fdf..f3666266 100644 --- a/Source/Validation/CommandBufferVal.cpp +++ b/Source/Validation/CommandBufferVal.cpp @@ -21,11 +21,11 @@ void ConvertGeometryObjectsVal(GeometryObject* destObjects, const GeometryObject static bool ValidateBufferBarrierDesc(const DeviceVal& device, uint32_t i, const BufferBarrierDesc& bufferBarrierDesc) { const BufferVal& bufferVal = *(const BufferVal*)bufferBarrierDesc.buffer; - RETURN_ON_FAILURE(&device, bufferBarrierDesc.buffer != nullptr, false, "CmdBarrier: 'bufferBarrierDesc.buffers[%u].buffer' is NULL", i); + RETURN_ON_FAILURE(&device, bufferBarrierDesc.buffer != nullptr, false, "'bufferBarrierDesc.buffers[%u].buffer' is NULL", i); RETURN_ON_FAILURE(&device, IsAccessMaskSupported(bufferVal.GetDesc().usageMask, bufferBarrierDesc.before.access), false, - "CmdBarrier: 'bufferBarrierDesc.buffers[%u].before' is not supported by the usage mask of the buffer ('%s')", i, bufferVal.GetDebugName()); + "'bufferBarrierDesc.buffers[%u].before' is not supported by the usage mask of the buffer ('%s')", i, bufferVal.GetDebugName()); RETURN_ON_FAILURE(&device, IsAccessMaskSupported(bufferVal.GetDesc().usageMask, bufferBarrierDesc.after.access), false, - "CmdBarrier: 'bufferBarrierDesc.buffers[%u].after' is not supported by the usage mask of the buffer ('%s')", i, bufferVal.GetDebugName()); + "'bufferBarrierDesc.buffers[%u].after' is not supported by the usage mask of the buffer ('%s')", i, bufferVal.GetDebugName()); return true; } @@ -33,15 +33,15 @@ static bool ValidateBufferBarrierDesc(const DeviceVal& device, uint32_t i, const static bool ValidateTextureBarrierDesc(const DeviceVal& device, uint32_t i, const TextureBarrierDesc& textureBarrierDesc) { const TextureVal& textureVal = *(const TextureVal*)textureBarrierDesc.texture; - RETURN_ON_FAILURE(&device, textureBarrierDesc.texture != nullptr, false, "CmdBarrier: 'bufferBarrierDesc.textures[%u].texture' is NULL", i); + RETURN_ON_FAILURE(&device, textureBarrierDesc.texture != nullptr, false, "'bufferBarrierDesc.textures[%u].texture' is NULL", i); RETURN_ON_FAILURE(&device, IsAccessMaskSupported(textureVal.GetDesc().usageMask, textureBarrierDesc.before.access), false, - "CmdBarrier: 'bufferBarrierDesc.textures[%u].before' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); + "'bufferBarrierDesc.textures[%u].before' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); RETURN_ON_FAILURE(&device, IsAccessMaskSupported(textureVal.GetDesc().usageMask, textureBarrierDesc.after.access), false, - "CmdBarrier: 'bufferBarrierDesc.textures[%u].after' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); + "'bufferBarrierDesc.textures[%u].after' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); RETURN_ON_FAILURE(&device, IsTextureLayoutSupported(textureVal.GetDesc().usageMask, textureBarrierDesc.before.layout), false, - "CmdBarrier: 'bufferBarrierDesc.textures[%u].prevLayout' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); + "'bufferBarrierDesc.textures[%u].prevLayout' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); RETURN_ON_FAILURE(&device, IsTextureLayoutSupported(textureVal.GetDesc().usageMask, textureBarrierDesc.after.layout), false, - "CmdBarrier: 'bufferBarrierDesc.textures[%u].nextLayout' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); + "'bufferBarrierDesc.textures[%u].nextLayout' is not supported by the usage mask of the texture ('%s')", i, textureVal.GetDebugName()); return true; } @@ -52,7 +52,7 @@ void CommandBufferVal::SetDebugName(const char* name) { } Result CommandBufferVal::Begin(const DescriptorPool* descriptorPool) { - RETURN_ON_FAILURE(&m_Device, !m_IsRecordingStarted, Result::FAILURE, "BeginCommandBuffer: already in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRecordingStarted, Result::FAILURE, "already in the recording state"); DescriptorPool* descriptorPoolImpl = NRI_GET_IMPL(DescriptorPool, descriptorPool); @@ -66,12 +66,12 @@ Result CommandBufferVal::Begin(const DescriptorPool* descriptorPool) { } Result CommandBufferVal::End() { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, Result::FAILURE, "EndCommandBuffer: not in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, Result::FAILURE, "not in the recording state"); if (m_AnnotationStack > 0) - REPORT_ERROR(&m_Device, "EndCommandBuffer: 'CmdBeginAnnotation' is called more times than 'CmdEndAnnotation'"); + REPORT_ERROR(&m_Device, "'CmdBeginAnnotation' is called more times than 'CmdEndAnnotation'"); else if (m_AnnotationStack < 0) - REPORT_ERROR(&m_Device, "EndCommandBuffer: 'CmdEndAnnotation' is called more times than 'CmdBeginAnnotation'"); + REPORT_ERROR(&m_Device, "'CmdEndAnnotation' is called more times than 'CmdBeginAnnotation'"); Result result = GetCoreInterface().EndCommandBuffer(*GetImpl()); @@ -82,64 +82,71 @@ Result CommandBufferVal::End() { } void CommandBufferVal::SetViewports(const Viewport* viewports, uint32_t viewportNum) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetViewports: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); if (viewportNum == 0) return; - RETURN_ON_FAILURE(&m_Device, viewports != nullptr, ReturnVoid(), "CmdSetViewports: 'viewports' is NULL"); + RETURN_ON_FAILURE(&m_Device, viewports != nullptr, ReturnVoid(), "'viewports' is NULL"); GetCoreInterface().CmdSetViewports(*GetImpl(), viewports, viewportNum); } void CommandBufferVal::SetScissors(const Rect* rects, uint32_t rectNum) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetScissors: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); if (rectNum == 0) return; - RETURN_ON_FAILURE(&m_Device, rects != nullptr, ReturnVoid(), "CmdSetScissors: 'rects' is NULL"); + RETURN_ON_FAILURE(&m_Device, rects != nullptr, ReturnVoid(), "'rects' is NULL"); GetCoreInterface().CmdSetScissors(*GetImpl(), rects, rectNum); } void CommandBufferVal::SetDepthBounds(float boundsMin, float boundsMax) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetDepthBounds: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_Device.GetDesc().isDepthBoundsTestSupported, ReturnVoid(), "CmdSetDepthBounds: DeviceDesc::isDepthBoundsTestSupported = false"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_Device.GetDesc().isDepthBoundsTestSupported, ReturnVoid(), "DeviceDesc::isDepthBoundsTestSupported = false"); GetCoreInterface().CmdSetDepthBounds(*GetImpl(), boundsMin, boundsMax); } void CommandBufferVal::SetStencilReference(uint8_t frontRef, uint8_t backRef) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetStencilReference: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); GetCoreInterface().CmdSetStencilReference(*GetImpl(), frontRef, backRef); } void CommandBufferVal::SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetSamplePositions: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_Device.GetDesc().programmableSampleLocationsTier != 0, ReturnVoid(), "CmdSetSamplePositions: DeviceDesc::isProgrammableSampleLocationsSupported = false"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_Device.GetDesc().programmableSampleLocationsTier != 0, ReturnVoid(), "DeviceDesc::isProgrammableSampleLocationsSupported = false"); GetCoreInterface().CmdSetSamplePositions(*GetImpl(), positions, positionNum, sampleNum); } void CommandBufferVal::SetBlendConstants(const Color32f& color) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "SetBlendConstants: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); GetCoreInterface().CmdSetBlendConstants(*GetImpl(), color); } +void CommandBufferVal::SetShadingRate(const ShadingRateDesc& shadingRateDesc) { + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_Device.GetDesc().isPipelineShadingRateSupported || m_Device.GetDesc().isPrimitiveShadingRateSupported, ReturnVoid(), "DeviceDesc::is[Pipeline/Primitive]ShadingRateSupported = false"); + + GetCoreInterface().CmdSetShadingRate(*GetImpl(), shadingRateDesc); +} + void CommandBufferVal::ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdClearAttachments: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "CmdClearAttachments: must be called inside 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); GetCoreInterface().CmdClearAttachments(*GetImpl(), clearDescs, clearDescNum, rects, rectNum); } void CommandBufferVal::ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdClearStorageBuffer: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdClearStorageBuffer: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, clearDesc.storageBuffer != nullptr, ReturnVoid(), "CmdClearStorageBuffer: 'clearDesc.storageBuffer' is NULL"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, clearDesc.storageBuffer != nullptr, ReturnVoid(), "'clearDesc.storageBuffer' is NULL"); auto clearDescImpl = clearDesc; clearDescImpl.storageBuffer = NRI_GET_IMPL(Descriptor, clearDesc.storageBuffer); @@ -148,9 +155,9 @@ void CommandBufferVal::ClearStorageBuffer(const ClearStorageBufferDesc& clearDes } void CommandBufferVal::ClearStorageTexture(const ClearStorageTextureDesc& clearDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdClearStorageTexture: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdClearStorageTexture: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, clearDesc.storageTexture != nullptr, ReturnVoid(), "CmdClearStorageTexture: 'clearDesc.storageTexture' is NULL"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, clearDesc.storageTexture != nullptr, ReturnVoid(), "'clearDesc.storageTexture' is NULL"); auto clearDescImpl = clearDesc; clearDescImpl.storageTexture = NRI_GET_IMPL(Descriptor, clearDesc.storageTexture); @@ -159,8 +166,8 @@ void CommandBufferVal::ClearStorageTexture(const ClearStorageTextureDesc& clearD } void CommandBufferVal::BeginRendering(const AttachmentsDesc& attachmentsDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdBeginRendering: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdBeginRendering: 'CmdBeginRendering' has been already called"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "'CmdBeginRendering' has been already called"); Descriptor** colors = StackAlloc(Descriptor*, attachmentsDesc.colorNum); for (uint32_t i = 0; i < attachmentsDesc.colorNum; i++) @@ -168,6 +175,7 @@ void CommandBufferVal::BeginRendering(const AttachmentsDesc& attachmentsDesc) { AttachmentsDesc attachmentsDescImpl = {}; attachmentsDescImpl.depthStencil = NRI_GET_IMPL(Descriptor, attachmentsDesc.depthStencil); + attachmentsDescImpl.shadingRate = NRI_GET_IMPL(Descriptor, attachmentsDesc.shadingRate); attachmentsDescImpl.colors = colors; attachmentsDescImpl.colorNum = attachmentsDesc.colorNum; @@ -177,8 +185,8 @@ void CommandBufferVal::BeginRendering(const AttachmentsDesc& attachmentsDesc) { } void CommandBufferVal::EndRendering() { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdEndRendering: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "CmdEndRendering: 'CmdBeginRendering' has not been called"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "'CmdBeginRendering' has not been called"); GetCoreInterface().CmdEndRendering(*GetImpl()); @@ -186,7 +194,7 @@ void CommandBufferVal::EndRendering() { } void CommandBufferVal::SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, const Buffer* const* buffers, const uint64_t* offsets) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetVertexBuffers: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); Buffer** buffersImpl = StackAlloc(Buffer*, bufferNum); for (uint32_t i = 0; i < bufferNum; i++) @@ -196,7 +204,7 @@ void CommandBufferVal::SetVertexBuffers(uint32_t baseSlot, uint32_t bufferNum, c } void CommandBufferVal::SetIndexBuffer(const Buffer& buffer, uint64_t offset, IndexType indexType) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetIndexBuffer: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); Buffer* bufferImpl = NRI_GET_IMPL(Buffer, &buffer); @@ -204,7 +212,7 @@ void CommandBufferVal::SetIndexBuffer(const Buffer& buffer, uint64_t offset, Ind } void CommandBufferVal::SetPipelineLayout(const PipelineLayout& pipelineLayout) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetPipelineLayout: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); PipelineLayout* pipelineLayoutImpl = NRI_GET_IMPL(PipelineLayout, &pipelineLayout); @@ -212,7 +220,7 @@ void CommandBufferVal::SetPipelineLayout(const PipelineLayout& pipelineLayout) { } void CommandBufferVal::SetPipeline(const Pipeline& pipeline) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetPipeline: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); Pipeline* pipelineImpl = NRI_GET_IMPL(Pipeline, &pipeline); @@ -220,7 +228,7 @@ void CommandBufferVal::SetPipeline(const Pipeline& pipeline) { } void CommandBufferVal::SetDescriptorPool(const DescriptorPool& descriptorPool) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetDescriptorPool: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); DescriptorPool* descriptorPoolImpl = NRI_GET_IMPL(DescriptorPool, &descriptorPool); @@ -228,7 +236,7 @@ void CommandBufferVal::SetDescriptorPool(const DescriptorPool& descriptorPool) { } void CommandBufferVal::SetDescriptorSet(uint32_t setIndexInPipelineLayout, const DescriptorSet& descriptorSet, const uint32_t* dynamicConstantBufferOffsets) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetDescriptorSet: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); DescriptorSet* descriptorSetImpl = NRI_GET_IMPL(DescriptorSet, &descriptorSet); @@ -236,30 +244,30 @@ void CommandBufferVal::SetDescriptorSet(uint32_t setIndexInPipelineLayout, const } void CommandBufferVal::SetConstants(uint32_t pushConstantIndex, const void* data, uint32_t size) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdSetConstants: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); GetCoreInterface().CmdSetConstants(*GetImpl(), pushConstantIndex, data, size); } void CommandBufferVal::Draw(const DrawDesc& drawDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDraw: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "CmdDraw: must be called inside 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); GetCoreInterface().CmdDraw(*GetImpl(), drawDesc); } void CommandBufferVal::DrawIndexed(const DrawIndexedDesc& drawIndexedDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDrawIndexed: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "CmdDrawIndexed: must be called inside 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); GetCoreInterface().CmdDrawIndexed(*GetImpl(), drawIndexedDesc); } void CommandBufferVal::DrawIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { const DeviceDesc& deviceDesc = m_Device.GetDesc(); - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDrawIndirect: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "CmdDrawIndirect: must be called inside 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, !countBuffer || deviceDesc.isDrawIndirectCountSupported, ReturnVoid(), "CmdDrawIndirect: 'countBuffer' is not supported"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, !countBuffer || deviceDesc.isDrawIndirectCountSupported, ReturnVoid(), "'countBuffer' is not supported"); Buffer* bufferImpl = NRI_GET_IMPL(Buffer, &buffer); Buffer* countBufferImpl = NRI_GET_IMPL(Buffer, countBuffer); @@ -269,9 +277,9 @@ void CommandBufferVal::DrawIndirect(const Buffer& buffer, uint64_t offset, uint3 void CommandBufferVal::DrawIndexedIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride, const Buffer* countBuffer, uint64_t countBufferOffset) { const DeviceDesc& deviceDesc = m_Device.GetDesc(); - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDrawIndexedIndirect: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "CmdDrawIndexedIndirect: must be called inside 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, !countBuffer || deviceDesc.isDrawIndirectCountSupported, ReturnVoid(), "CmdDrawIndexedIndirect: 'countBuffer' is not supported"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, !countBuffer || deviceDesc.isDrawIndirectCountSupported, ReturnVoid(), "'countBuffer' is not supported"); Buffer* bufferImpl = NRI_GET_IMPL(Buffer, &buffer); Buffer* countBufferImpl = NRI_GET_IMPL(Buffer, countBuffer); @@ -280,14 +288,14 @@ void CommandBufferVal::DrawIndexedIndirect(const Buffer& buffer, uint64_t offset } void CommandBufferVal::CopyBuffer(Buffer& dstBuffer, uint64_t dstOffset, const Buffer& srcBuffer, uint64_t srcOffset, uint64_t size) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdCopyBuffer: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); if (size == WHOLE_SIZE) { const BufferDesc& dstDesc = ((BufferVal&)dstBuffer).GetDesc(); const BufferDesc& srcDesc = ((BufferVal&)srcBuffer).GetDesc(); if (dstDesc.size != srcDesc.size) - REPORT_WARNING(&m_Device, "WHOLE_SIZE is used but 'dstBuffer' and 'srcBuffer' have diffenet sizes"); + REPORT_WARNING(&m_Device, "WHOLE_SIZE is used but 'dstBuffer' and 'srcBuffer' have different sizes"); } Buffer* dstBufferImpl = NRI_GET_IMPL(Buffer, &dstBuffer); @@ -297,10 +305,9 @@ void CommandBufferVal::CopyBuffer(Buffer& dstBuffer, uint64_t dstOffset, const B } void CommandBufferVal::CopyTexture(Texture& dstTexture, const TextureRegionDesc* dstRegionDesc, const Texture& srcTexture, const TextureRegionDesc* srcRegionDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdCopyTexture: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdCopyTexture: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, (dstRegionDesc == nullptr && srcRegionDesc == nullptr) || (dstRegionDesc != nullptr && srcRegionDesc != nullptr), ReturnVoid(), - "CmdCopyTexture: 'dstRegionDesc' and 'srcRegionDesc' must be valid pointers or both NULL"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, (!dstRegionDesc && !srcRegionDesc) || (dstRegionDesc && srcRegionDesc), ReturnVoid(), "'dstRegionDesc' and 'srcRegionDesc' must be valid pointers or both NULL"); Texture* dstTextureImpl = NRI_GET_IMPL(Texture, &dstTexture); Texture* srcTextureImpl = NRI_GET_IMPL(Texture, &srcTexture); @@ -309,8 +316,8 @@ void CommandBufferVal::CopyTexture(Texture& dstTexture, const TextureRegionDesc* } void CommandBufferVal::UploadBufferToTexture(Texture& dstTexture, const TextureRegionDesc& dstRegionDesc, const Buffer& srcBuffer, const TextureDataLayoutDesc& srcDataLayoutDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdUploadBufferToTexture: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdUploadBufferToTexture: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); Texture* dstTextureImpl = NRI_GET_IMPL(Texture, &dstTexture); Buffer* srcBufferImpl = NRI_GET_IMPL(Buffer, &srcBuffer); @@ -319,8 +326,8 @@ void CommandBufferVal::UploadBufferToTexture(Texture& dstTexture, const TextureR } void CommandBufferVal::ReadbackTextureToBuffer(Buffer& dstBuffer, TextureDataLayoutDesc& dstDataLayoutDesc, const Texture& srcTexture, const TextureRegionDesc& srcRegionDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdReadbackTextureToBuffer: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdReadbackTextureToBuffer: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); Buffer* dstBufferImpl = NRI_GET_IMPL(Buffer, &dstBuffer); Texture* srcTextureImpl = NRI_GET_IMPL(Texture, &srcTexture); @@ -329,26 +336,26 @@ void CommandBufferVal::ReadbackTextureToBuffer(Buffer& dstBuffer, TextureDataLay } void CommandBufferVal::Dispatch(const DispatchDesc& dispatchDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDispatch: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdDispatch: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); GetCoreInterface().CmdDispatch(*GetImpl(), dispatchDesc); } void CommandBufferVal::DispatchIndirect(const Buffer& buffer, uint64_t offset) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDispatchIndirect: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdDispatchIndirect: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); const BufferDesc& bufferDesc = ((BufferVal&)buffer).GetDesc(); - RETURN_ON_FAILURE(&m_Device, offset < bufferDesc.size, ReturnVoid(), "CmdDispatchIndirect: offset is greater than the buffer size"); + RETURN_ON_FAILURE(&m_Device, offset < bufferDesc.size, ReturnVoid(), "offset is greater than the buffer size"); Buffer* bufferImpl = NRI_GET_IMPL(Buffer, &buffer); GetCoreInterface().CmdDispatchIndirect(*GetImpl(), *bufferImpl, offset); } void CommandBufferVal::Barrier(const BarrierGroupDesc& barrierGroupDesc) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdBarrier: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdBarrier: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); for (uint32_t i = 0; i < barrierGroupDesc.bufferNum; i++) { if (!ValidateBufferBarrierDesc(m_Device, i, barrierGroupDesc.buffers[i])) @@ -380,11 +387,11 @@ void CommandBufferVal::Barrier(const BarrierGroupDesc& barrierGroupDesc) { void CommandBufferVal::BeginQuery(const QueryPool& queryPool, uint32_t offset) { const QueryPoolVal& queryPoolVal = (const QueryPoolVal&)queryPool; - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdBeginQuery: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, queryPoolVal.GetQueryType() != QueryType::TIMESTAMP, ReturnVoid(), "CmdBeginQuery: 'BeginQuery' is not supported for timestamp queries"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, queryPoolVal.GetQueryType() != QueryType::TIMESTAMP, ReturnVoid(), "'BeginQuery' is not supported for timestamp queries"); if (!queryPoolVal.IsImported()) { - RETURN_ON_FAILURE(&m_Device, offset < queryPoolVal.GetQueryNum(), ReturnVoid(), "CmdBeginQuery: 'offset = %u' is out of range", offset); + RETURN_ON_FAILURE(&m_Device, offset < queryPoolVal.GetQueryNum(), ReturnVoid(), "'offset = %u' is out of range", offset); ValidationCommandUseQuery& validationCommand = AllocateValidationCommand(); validationCommand.type = ValidationCommandType::BEGIN_QUERY; @@ -400,10 +407,10 @@ void CommandBufferVal::BeginQuery(const QueryPool& queryPool, uint32_t offset) { void CommandBufferVal::EndQuery(const QueryPool& queryPool, uint32_t offset) { const QueryPoolVal& queryPoolVal = (const QueryPoolVal&)queryPool; - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdEndQuery: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); if (!queryPoolVal.IsImported()) { - RETURN_ON_FAILURE(&m_Device, offset < queryPoolVal.GetQueryNum(), ReturnVoid(), "CmdEndQuery: 'offset = %u' is out of range", offset); + RETURN_ON_FAILURE(&m_Device, offset < queryPoolVal.GetQueryNum(), ReturnVoid(), "'offset = %u' is out of range", offset); ValidationCommandUseQuery& validationCommand = AllocateValidationCommand(); validationCommand.type = ValidationCommandType::END_QUERY; @@ -417,12 +424,12 @@ void CommandBufferVal::EndQuery(const QueryPool& queryPool, uint32_t offset) { } void CommandBufferVal::CopyQueries(const QueryPool& queryPool, uint32_t offset, uint32_t num, Buffer& dstBuffer, uint64_t dstOffset) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdCopyQueries: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdCopyQueries: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); const QueryPoolVal& queryPoolVal = (const QueryPoolVal&)queryPool; if (!queryPoolVal.IsImported()) - RETURN_ON_FAILURE(&m_Device, offset + num <= queryPoolVal.GetQueryNum(), ReturnVoid(), "CmdCopyQueries: 'offset + num = %u' is out of range", offset + num); + RETURN_ON_FAILURE(&m_Device, offset + num <= queryPoolVal.GetQueryNum(), ReturnVoid(), "'offset + num = %u' is out of range", offset + num); QueryPool* queryPoolImpl = NRI_GET_IMPL(QueryPool, &queryPool); Buffer* dstBufferImpl = NRI_GET_IMPL(Buffer, &dstBuffer); @@ -431,12 +438,12 @@ void CommandBufferVal::CopyQueries(const QueryPool& queryPool, uint32_t offset, } void CommandBufferVal::ResetQueries(const QueryPool& queryPool, uint32_t offset, uint32_t num) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdResetQueries: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdResetQueries: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); const QueryPoolVal& queryPoolVal = (const QueryPoolVal&)queryPool; if (!queryPoolVal.IsImported()) { - RETURN_ON_FAILURE(&m_Device, offset + num <= queryPoolVal.GetQueryNum(), ReturnVoid(), "CmdResetQueries: 'offset + num = %u' is out of range", offset + num); + RETURN_ON_FAILURE(&m_Device, offset + num <= queryPoolVal.GetQueryNum(), ReturnVoid(), "'offset + num = %u' is out of range", offset + num); ValidationCommandResetQuery& validationCommand = AllocateValidationCommand(); validationCommand.type = ValidationCommandType::RESET_QUERY; @@ -451,14 +458,14 @@ void CommandBufferVal::ResetQueries(const QueryPool& queryPool, uint32_t offset, } void CommandBufferVal::BeginAnnotation(const char* name) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdBeginAnnotation: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); m_AnnotationStack++; GetCoreInterface().CmdBeginAnnotation(*GetImpl(), name); } void CommandBufferVal::EndAnnotation() { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdEndAnnotation: the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); GetCoreInterface().CmdEndAnnotation(*GetImpl()); m_AnnotationStack--; @@ -466,14 +473,14 @@ void CommandBufferVal::EndAnnotation() { void CommandBufferVal::BuildTopLevelAccelerationStructure( uint32_t instanceNum, const Buffer& buffer, uint64_t bufferOffset, AccelerationStructureBuildBits flags, AccelerationStructure& dst, Buffer& scratch, uint64_t scratchOffset) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdBuildTopLevelAccelerationStructure: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdBuildTopLevelAccelerationStructure: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); BufferVal& bufferVal = (BufferVal&)buffer; BufferVal& scratchVal = (BufferVal&)scratch; - RETURN_ON_FAILURE(&m_Device, bufferOffset < bufferVal.GetDesc().size, ReturnVoid(), "CmdBuildTopLevelAccelerationStructure: 'bufferOffset = %llu' is out of bounds", bufferOffset); - RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "CmdBuildTopLevelAccelerationStructure: 'scratchOffset = %llu' is out of bounds", scratchOffset); + RETURN_ON_FAILURE(&m_Device, bufferOffset < bufferVal.GetDesc().size, ReturnVoid(), "'bufferOffset = %llu' is out of bounds", bufferOffset); + RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "'scratchOffset = %llu' is out of bounds", scratchOffset); AccelerationStructure& dstImpl = *NRI_GET_IMPL(AccelerationStructure, &dst); Buffer& scratchImpl = *NRI_GET_IMPL(Buffer, &scratch); @@ -486,10 +493,10 @@ void CommandBufferVal::BuildBottomLevelAccelerationStructure( uint32_t geometryObjectNum, const GeometryObject* geometryObjects, AccelerationStructureBuildBits flags, AccelerationStructure& dst, Buffer& scratch, uint64_t scratchOffset) { BufferVal& scratchVal = (BufferVal&)scratch; - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdBuildBottomLevelAccelerationStructure: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdBuildBottomLevelAccelerationStructure: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, geometryObjects != nullptr, ReturnVoid(), "CmdBuildBottomLevelAccelerationStructure: 'geometryObjects' is NULL"); - RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "CmdBuildBottomLevelAccelerationStructure: 'scratchOffset = %llu' is out of bounds", scratchOffset); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, geometryObjects != nullptr, ReturnVoid(), "'geometryObjects' is NULL"); + RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "'scratchOffset = %llu' is out of bounds", scratchOffset); AccelerationStructure& dstImpl = *NRI_GET_IMPL(AccelerationStructure, &dst); Buffer& scratchImpl = *NRI_GET_IMPL(Buffer, &scratch); @@ -502,14 +509,14 @@ void CommandBufferVal::BuildBottomLevelAccelerationStructure( void CommandBufferVal::UpdateTopLevelAccelerationStructure(uint32_t instanceNum, const Buffer& buffer, uint64_t bufferOffset, AccelerationStructureBuildBits flags, AccelerationStructure& dst, AccelerationStructure& src, Buffer& scratch, uint64_t scratchOffset) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdUpdateTopLevelAccelerationStructure: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdUpdateTopLevelAccelerationStructure: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); BufferVal& bufferVal = (BufferVal&)buffer; BufferVal& scratchVal = (BufferVal&)scratch; - RETURN_ON_FAILURE(&m_Device, bufferOffset < bufferVal.GetDesc().size, ReturnVoid(), "CmdUpdateTopLevelAccelerationStructure: 'bufferOffset = %llu' is out of bounds", bufferOffset); - RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "CmdUpdateTopLevelAccelerationStructure: 'scratchOffset = %llu' is out of bounds", scratchOffset); + RETURN_ON_FAILURE(&m_Device, bufferOffset < bufferVal.GetDesc().size, ReturnVoid(), "'bufferOffset = %llu' is out of bounds", bufferOffset); + RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "'scratchOffset = %llu' is out of bounds", scratchOffset); AccelerationStructure& dstImpl = *NRI_GET_IMPL(AccelerationStructure, &dst); AccelerationStructure& srcImpl = *NRI_GET_IMPL(AccelerationStructure, &src); @@ -521,13 +528,13 @@ void CommandBufferVal::UpdateTopLevelAccelerationStructure(uint32_t instanceNum, void CommandBufferVal::UpdateBottomLevelAccelerationStructure(uint32_t geometryObjectNum, const GeometryObject* geometryObjects, AccelerationStructureBuildBits flags, AccelerationStructure& dst, AccelerationStructure& src, Buffer& scratch, uint64_t scratchOffset) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdUpdateBottomLevelAccelerationStructure: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdUpdateBottomLevelAccelerationStructure: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, geometryObjects != nullptr, ReturnVoid(), "CmdUpdateBottomLevelAccelerationStructure: 'geometryObjects' is NULL"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, geometryObjects != nullptr, ReturnVoid(), "'geometryObjects' is NULL"); BufferVal& scratchVal = (BufferVal&)scratch; - RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "CmdUpdateBottomLevelAccelerationStructure: 'scratchOffset = %llu' is out of bounds", scratchOffset); + RETURN_ON_FAILURE(&m_Device, scratchOffset < scratchVal.GetDesc().size, ReturnVoid(), "'scratchOffset = %llu' is out of bounds", scratchOffset); AccelerationStructure& dstImpl = *NRI_GET_IMPL(AccelerationStructure, &dst); AccelerationStructure& srcImpl = *NRI_GET_IMPL(AccelerationStructure, &src); @@ -540,9 +547,9 @@ void CommandBufferVal::UpdateBottomLevelAccelerationStructure(uint32_t geometryO } void CommandBufferVal::CopyAccelerationStructure(AccelerationStructure& dst, AccelerationStructure& src, CopyMode copyMode) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdCopyAccelerationStructure: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdCopyAccelerationStructure: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, copyMode < CopyMode::MAX_NUM, ReturnVoid(), "CmdCopyAccelerationStructure: 'copyMode' is invalid"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, copyMode < CopyMode::MAX_NUM, ReturnVoid(), "'copyMode' is invalid"); AccelerationStructure& dstImpl = *NRI_GET_IMPL(AccelerationStructure, &dst); AccelerationStructure& srcImpl = *NRI_GET_IMPL(AccelerationStructure, &src); @@ -552,13 +559,13 @@ void CommandBufferVal::CopyAccelerationStructure(AccelerationStructure& dst, Acc void CommandBufferVal::WriteAccelerationStructureSize( const AccelerationStructure* const* accelerationStructures, uint32_t accelerationStructureNum, QueryPool& queryPool, uint32_t queryOffset) { - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdWriteAccelerationStructureSize: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdWriteAccelerationStructureSize: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, accelerationStructures != nullptr, ReturnVoid(), "CmdWriteAccelerationStructureSize: 'accelerationStructures' is NULL"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, accelerationStructures != nullptr, ReturnVoid(), "'accelerationStructures' is NULL"); AccelerationStructure** accelerationStructureArray = StackAlloc(AccelerationStructure*, accelerationStructureNum); for (uint32_t i = 0; i < accelerationStructureNum; i++) { - RETURN_ON_FAILURE(&m_Device, accelerationStructures[i] != nullptr, ReturnVoid(), "CmdWriteAccelerationStructureSize: 'accelerationStructures[%u]' is NULL", i); + RETURN_ON_FAILURE(&m_Device, accelerationStructures[i] != nullptr, ReturnVoid(), "'accelerationStructures[%u]' is NULL", i); accelerationStructureArray[i] = NRI_GET_IMPL(AccelerationStructure, accelerationStructures[i]); } @@ -570,14 +577,14 @@ void CommandBufferVal::WriteAccelerationStructureSize( void CommandBufferVal::DispatchRays(const DispatchRaysDesc& dispatchRaysDesc) { uint64_t align = m_Device.GetDesc().rayTracingShaderTableAlignment; - RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "CmdDispatchRays: the command buffer must be in the recording state"); - RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "CmdDispatchRays: must be called outside of 'CmdBeginRendering/CmdEndRendering'"); - RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.raygenShader.buffer != nullptr, ReturnVoid(), "CmdDispatchRays: 'dispatchRaysDesc.raygenShader.buffer' is NULL"); - RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.raygenShader.size != 0, ReturnVoid(), "CmdDispatchRays: 'dispatchRaysDesc.raygenShader.size' is 0"); - RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.raygenShader.offset % align == 0, ReturnVoid(), "CmdDispatchRays: 'dispatchRaysDesc.raygenShader.offset' is misaligned"); - RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.missShaders.offset % align == 0, ReturnVoid(), "CmdDispatchRays: 'dispatchRaysDesc.missShaders.offset' is misaligned"); - RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.hitShaderGroups.offset % align == 0, ReturnVoid(), "CmdDispatchRays: 'dispatchRaysDesc.hitShaderGroups.offset' is misaligned"); - RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.callableShaders.offset % align == 0, ReturnVoid(), "CmdDispatchRays: 'dispatchRaysDesc.callableShaders.offset' is misaligned"); + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, !m_IsRenderPass, ReturnVoid(), "must be called outside of 'CmdBeginRendering/CmdEndRendering'"); + RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.raygenShader.buffer != nullptr, ReturnVoid(), "'dispatchRaysDesc.raygenShader.buffer' is NULL"); + RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.raygenShader.size != 0, ReturnVoid(), "'dispatchRaysDesc.raygenShader.size' is 0"); + RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.raygenShader.offset % align == 0, ReturnVoid(), "'dispatchRaysDesc.raygenShader.offset' is misaligned"); + RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.missShaders.offset % align == 0, ReturnVoid(), "'dispatchRaysDesc.missShaders.offset' is misaligned"); + RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.hitShaderGroups.offset % align == 0, ReturnVoid(), "'dispatchRaysDesc.hitShaderGroups.offset' is misaligned"); + RETURN_ON_FAILURE(&m_Device, dispatchRaysDesc.callableShaders.offset % align == 0, ReturnVoid(), "'dispatchRaysDesc.callableShaders.offset' is misaligned"); auto dispatchRaysDescImpl = dispatchRaysDesc; dispatchRaysDescImpl.raygenShader.buffer = NRI_GET_IMPL(Buffer, dispatchRaysDesc.raygenShader.buffer); @@ -590,19 +597,25 @@ void CommandBufferVal::DispatchRays(const DispatchRaysDesc& dispatchRaysDesc) { void CommandBufferVal::DispatchRaysIndirect(const Buffer& buffer, uint64_t offset) { const BufferDesc& bufferDesc = ((BufferVal&)buffer).GetDesc(); - RETURN_ON_FAILURE(&m_Device, offset < bufferDesc.size, ReturnVoid(), "CmdDrawMeshTasksIndirect: offset is greater than the buffer size"); + RETURN_ON_FAILURE(&m_Device, offset < bufferDesc.size, ReturnVoid(), "offset is greater than the buffer size"); Buffer* bufferImpl = NRI_GET_IMPL(Buffer, &buffer); GetRayTracingInterface().CmdDispatchRaysIndirect(*GetImpl(), *bufferImpl, offset); } void CommandBufferVal::DrawMeshTasks(const DrawMeshTasksDesc& drawMeshTasksDesc) { + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); + GetMeshShaderInterface().CmdDrawMeshTasks(*GetImpl(), drawMeshTasksDesc); } void CommandBufferVal::DrawMeshTasksIndirect(const Buffer& buffer, uint64_t offset, uint32_t drawNum, uint32_t stride) { + RETURN_ON_FAILURE(&m_Device, m_IsRecordingStarted, ReturnVoid(), "the command buffer must be in the recording state"); + RETURN_ON_FAILURE(&m_Device, m_IsRenderPass, ReturnVoid(), "must be called inside 'CmdBeginRendering/CmdEndRendering'"); + const BufferDesc& bufferDesc = ((BufferVal&)buffer).GetDesc(); - RETURN_ON_FAILURE(&m_Device, offset < bufferDesc.size, ReturnVoid(), "CmdDrawMeshTasksIndirect: offset is greater than the buffer size"); + RETURN_ON_FAILURE(&m_Device, offset < bufferDesc.size, ReturnVoid(), "Cmdoffset is greater than the buffer size"); Buffer* bufferImpl = NRI_GET_IMPL(Buffer, &buffer); GetMeshShaderInterface().CmdDrawMeshTasksIndirect(*GetImpl(), *bufferImpl, offset, drawNum, stride); diff --git a/Source/Validation/CommandBufferVal.h b/Source/Validation/CommandBufferVal.h index 6d6c6a54..cbca8550 100644 --- a/Source/Validation/CommandBufferVal.h +++ b/Source/Validation/CommandBufferVal.h @@ -32,6 +32,7 @@ struct CommandBufferVal : public DeviceObjectVal { void SetStencilReference(uint8_t frontRef, uint8_t backRef); void SetSamplePositions(const SamplePosition* positions, Sample_t positionNum, Sample_t sampleNum); void SetBlendConstants(const Color32f& color); + void SetShadingRate(const ShadingRateDesc& shadingRateDesc); void ClearAttachments(const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum); void ClearStorageBuffer(const ClearStorageBufferDesc& clearDesc); void ClearStorageTexture(const ClearStorageTextureDesc& clearDesc); diff --git a/Source/Validation/CommandBufferVal.hpp b/Source/Validation/CommandBufferVal.hpp index 403c8ff9..c53d8219 100644 --- a/Source/Validation/CommandBufferVal.hpp +++ b/Source/Validation/CommandBufferVal.hpp @@ -71,6 +71,10 @@ static void NRI_CALL CmdSetBlendConstants(CommandBuffer& commandBuffer, const Co ((CommandBufferVal&)commandBuffer).SetBlendConstants(color); } +static void NRI_CALL CmdSetShadingRate(CommandBuffer& commandBuffer, const ShadingRateDesc& shadingRateDesc) { + ((CommandBufferVal&)commandBuffer).SetShadingRate(shadingRateDesc); +} + static void NRI_CALL CmdClearAttachments(CommandBuffer& commandBuffer, const ClearDesc* clearDescs, uint32_t clearDescNum, const Rect* rects, uint32_t rectNum) { ((CommandBufferVal&)commandBuffer).ClearAttachments(clearDescs, clearDescNum, rects, rectNum); } diff --git a/Source/Validation/CommandQueueVal.cpp b/Source/Validation/CommandQueueVal.cpp index 460c0653..4f84cb57 100644 --- a/Source/Validation/CommandQueueVal.cpp +++ b/Source/Validation/CommandQueueVal.cpp @@ -15,16 +15,16 @@ using namespace nri; static bool ValidateTextureUploadDesc(DeviceVal& device, uint32_t i, const TextureUploadDesc& textureUploadDesc) { if (!textureUploadDesc.subresources) { - REPORT_WARNING(&device, "UploadData: the number of subresources in 'textureUploadDescs[%u]' is 0 (nothing to upload)", i); + REPORT_WARNING(&device, "the number of subresources in 'textureUploadDescs[%u]' is 0 (nothing to upload)", i); return true; } const TextureVal& textureVal = *(TextureVal*)textureUploadDesc.texture; const TextureDesc& textureDesc = textureVal.GetDesc(); - RETURN_ON_FAILURE(&device, textureUploadDesc.texture != nullptr, false, "UploadData: 'textureUploadDescs[%u].texture' is NULL", i); - RETURN_ON_FAILURE(&device, textureUploadDesc.after.layout < Layout::MAX_NUM, false, "UploadData: 'textureUploadDescs[%u].nextLayout' is invalid", i); - RETURN_ON_FAILURE(&device, textureVal.IsBoundToMemory(), false, "UploadData: 'textureUploadDescs[%u].texture' is not bound to memory", i); + RETURN_ON_FAILURE(&device, textureUploadDesc.texture != nullptr, false, "'textureUploadDescs[%u].texture' is NULL", i); + RETURN_ON_FAILURE(&device, textureUploadDesc.after.layout < Layout::MAX_NUM, false, "'textureUploadDescs[%u].nextLayout' is invalid", i); + RETURN_ON_FAILURE(&device, textureVal.IsBoundToMemory(), false, "'textureUploadDescs[%u].texture' is not bound to memory", i); uint32_t subresourceNum = textureDesc.layerNum * textureDesc.mipNum; for (uint32_t j = 0; j < subresourceNum; j++) { @@ -35,9 +35,9 @@ static bool ValidateTextureUploadDesc(DeviceVal& device, uint32_t i, const Textu continue; } - RETURN_ON_FAILURE(&device, subresource.slices != nullptr, false, "UploadData: 'textureUploadDescs[%u].subresources[%u].slices' is invalid", i, j); - RETURN_ON_FAILURE(&device, subresource.rowPitch != 0, false, "UploadData: 'textureUploadDescs[%u].subresources[%u].rowPitch' is 0", i, j); - RETURN_ON_FAILURE(&device, subresource.slicePitch != 0, false, "UploadData: 'textureUploadDescs[%u].subresources[%u].slicePitch' is 0", i, j); + RETURN_ON_FAILURE(&device, subresource.slices != nullptr, false, "'textureUploadDescs[%u].subresources[%u].slices' is invalid", i, j); + RETURN_ON_FAILURE(&device, subresource.rowPitch != 0, false, "'textureUploadDescs[%u].subresources[%u].rowPitch' is 0", i, j); + RETURN_ON_FAILURE(&device, subresource.slicePitch != 0, false, "'textureUploadDescs[%u].subresources[%u].slicePitch' is 0", i, j); } return true; @@ -45,17 +45,17 @@ static bool ValidateTextureUploadDesc(DeviceVal& device, uint32_t i, const Textu static bool ValidateBufferUploadDesc(DeviceVal& device, uint32_t i, const BufferUploadDesc& bufferUploadDesc) { if (bufferUploadDesc.dataSize == 0) { - REPORT_WARNING(&device, "UploadData: 'bufferUploadDescs[%u].dataSize' is 0 (nothing to upload)", i); + REPORT_WARNING(&device, "'bufferUploadDescs[%u].dataSize' is 0 (nothing to upload)", i); return true; } const BufferVal& bufferVal = *(BufferVal*)bufferUploadDesc.buffer; const uint64_t rangeEnd = bufferUploadDesc.bufferOffset + bufferUploadDesc.dataSize; - RETURN_ON_FAILURE(&device, bufferUploadDesc.buffer != nullptr, false, "UploadData: 'bufferUploadDescs[%u].buffer' is invalid", i); - RETURN_ON_FAILURE(&device, bufferUploadDesc.data != nullptr, false, "UploadData: 'bufferUploadDescs[%u].data' is invalid", i); - RETURN_ON_FAILURE(&device, bufferVal.IsBoundToMemory(), false, "UploadData: 'bufferUploadDescs[%u].buffer' is not bound to memory", i); - RETURN_ON_FAILURE(&device, rangeEnd <= bufferVal.GetDesc().size, false, "UploadData: 'bufferUploadDescs[%u].bufferOffset + bufferUploadDescs[%u].dataSize' is out of bounds", i, i); + RETURN_ON_FAILURE(&device, bufferUploadDesc.buffer != nullptr, false, "'bufferUploadDescs[%u].buffer' is invalid", i); + RETURN_ON_FAILURE(&device, bufferUploadDesc.data != nullptr, false, "'bufferUploadDescs[%u].data' is invalid", i); + RETURN_ON_FAILURE(&device, bufferVal.IsBoundToMemory(), false, "'bufferUploadDescs[%u].buffer' is not bound to memory", i); + RETURN_ON_FAILURE(&device, rangeEnd <= bufferVal.GetDesc().size, false, "'bufferUploadDescs[%u].bufferOffset + bufferUploadDescs[%u].dataSize' is out of bounds", i, i); return true; } @@ -98,8 +98,8 @@ void CommandQueueVal::Submit(const QueueSubmitDesc& queueSubmitDesc, const SwapC Result CommandQueueVal::UploadData( const TextureUploadDesc* textureUploadDescs, uint32_t textureUploadDescNum, const BufferUploadDesc* bufferUploadDescs, uint32_t bufferUploadDescNum) { - RETURN_ON_FAILURE(&m_Device, textureUploadDescNum == 0 || textureUploadDescs != nullptr, Result::INVALID_ARGUMENT, "UploadData: 'textureUploadDescs' is NULL"); - RETURN_ON_FAILURE(&m_Device, bufferUploadDescNum == 0 || bufferUploadDescs != nullptr, Result::INVALID_ARGUMENT, "UploadData: 'bufferUploadDescs' is NULL"); + RETURN_ON_FAILURE(&m_Device, textureUploadDescNum == 0 || textureUploadDescs != nullptr, Result::INVALID_ARGUMENT, "'textureUploadDescs' is NULL"); + RETURN_ON_FAILURE(&m_Device, bufferUploadDescNum == 0 || bufferUploadDescs != nullptr, Result::INVALID_ARGUMENT, "'bufferUploadDescs' is NULL"); TextureUploadDesc* textureUploadDescsImpl = StackAlloc(TextureUploadDesc, textureUploadDescNum); @@ -144,37 +144,37 @@ const Command* ReadCommand(const uint8_t*& begin, const uint8_t* end) { void CommandQueueVal::ProcessValidationCommandBeginQuery(const uint8_t*& begin, const uint8_t* end) { const ValidationCommandUseQuery* command = ReadCommand(begin, end); - CHECK(command != nullptr, "ProcessValidationCommandBeginQuery() failed: can't parse command"); - CHECK(command->queryPool != nullptr, "ProcessValidationCommandBeginQuery() failed: query pool is invalid"); + CHECK(command != nullptr, "can't parse command"); + CHECK(command->queryPool != nullptr, "query pool is invalid"); QueryPoolVal& queryPool = *(QueryPoolVal*)command->queryPool; const bool used = queryPool.SetQueryState(command->queryPoolOffset, true); if (used) - REPORT_ERROR(&m_Device, "CmdBeginQuery: it must be reset before use. (QueryPool='%s', offset=%u)", queryPool.GetDebugName(), command->queryPoolOffset); + REPORT_ERROR(&m_Device, "it must be reset before use. (QueryPool='%s', offset=%u)", queryPool.GetDebugName(), command->queryPoolOffset); } void CommandQueueVal::ProcessValidationCommandEndQuery(const uint8_t*& begin, const uint8_t* end) { const ValidationCommandUseQuery* command = ReadCommand(begin, end); - CHECK(command != nullptr, "ProcessValidationCommandEndQuery() failed: can't parse command"); - CHECK(command->queryPool != nullptr, "ProcessValidationCommandEndQuery() failed: query pool is invalid"); + CHECK(command != nullptr, "can't parse command"); + CHECK(command->queryPool != nullptr, "query pool is invalid"); QueryPoolVal& queryPool = *(QueryPoolVal*)command->queryPool; const bool used = queryPool.SetQueryState(command->queryPoolOffset, true); if (queryPool.GetQueryType() == QueryType::TIMESTAMP) { if (used) - REPORT_ERROR(&m_Device, "CmdEndQuery: it must be reset before use. (QueryPool='%s', offset=%u)", queryPool.GetDebugName(), command->queryPoolOffset); + REPORT_ERROR(&m_Device, "it must be reset before use. (QueryPool='%s', offset=%u)", queryPool.GetDebugName(), command->queryPoolOffset); } else { if (!used) - REPORT_ERROR(&m_Device, "CmdEndQuery: it's not in active state. (QueryPool='%s', offset=%u)", queryPool.GetDebugName(), command->queryPoolOffset); + REPORT_ERROR(&m_Device, "it's not in active state. (QueryPool='%s', offset=%u)", queryPool.GetDebugName(), command->queryPoolOffset); } } void CommandQueueVal::ProcessValidationCommandResetQuery(const uint8_t*& begin, const uint8_t* end) { const ValidationCommandResetQuery* command = ReadCommand(begin, end); - CHECK(command != nullptr, "ProcessValidationCommandResetQuery() failed: can't parse command"); - CHECK(command->queryPool != nullptr, "ProcessValidationCommandResetQuery() failed: query pool is invalid"); + CHECK(command != nullptr, "can't parse command"); + CHECK(command->queryPool != nullptr, "query pool is invalid"); QueryPoolVal& queryPool = *(QueryPoolVal*)command->queryPool; queryPool.ResetQueries(command->queryPoolOffset, command->queryNum); diff --git a/Source/Validation/DescriptorPoolVal.cpp b/Source/Validation/DescriptorPoolVal.cpp index 62545ed2..7b6b724c 100644 --- a/Source/Validation/DescriptorPoolVal.cpp +++ b/Source/Validation/DescriptorPoolVal.cpp @@ -88,11 +88,11 @@ Result DescriptorPoolVal::AllocateDescriptorSets( const PipelineLayoutVal& pipelineLayoutVal = (const PipelineLayoutVal&)pipelineLayout; const PipelineLayoutDesc& pipelineLayoutDesc = pipelineLayoutVal.GetPipelineLayoutDesc(); - RETURN_ON_FAILURE(&m_Device, instanceNum != 0, Result::INVALID_ARGUMENT, "AllocateDescriptorSets: 'instanceNum' is 0"); - RETURN_ON_FAILURE(&m_Device, m_DescriptorSetsNum + instanceNum <= m_Desc.descriptorSetMaxNum, Result::INVALID_ARGUMENT, "AllocateDescriptorSets: the maximum number of descriptor sets exceeded"); + RETURN_ON_FAILURE(&m_Device, instanceNum != 0, Result::INVALID_ARGUMENT, "'instanceNum' is 0"); + RETURN_ON_FAILURE(&m_Device, m_DescriptorSetsNum + instanceNum <= m_Desc.descriptorSetMaxNum, Result::INVALID_ARGUMENT, "the maximum number of descriptor sets exceeded"); if (!m_SkipValidation) { - RETURN_ON_FAILURE(&m_Device, setIndexInPipelineLayout < pipelineLayoutDesc.descriptorSetNum, Result::INVALID_ARGUMENT, "AllocateDescriptorSets: 'setIndexInPipelineLayout' is invalid"); + RETURN_ON_FAILURE(&m_Device, setIndexInPipelineLayout < pipelineLayoutDesc.descriptorSetNum, Result::INVALID_ARGUMENT, "'setIndexInPipelineLayout' is invalid"); const DescriptorSetDesc& descriptorSetDesc = pipelineLayoutDesc.descriptorSets[setIndexInPipelineLayout]; @@ -100,13 +100,13 @@ Result DescriptorPoolVal::AllocateDescriptorSets( const DescriptorRangeDesc& rangeDesc = descriptorSetDesc.ranges[i]; bool enoughDescriptors = CheckDescriptorRange(rangeDesc, variableDescriptorNum); - RETURN_ON_FAILURE(&m_Device, enoughDescriptors, Result::INVALID_ARGUMENT, "AllocateDescriptorSets: the maximum number of descriptors exceeded ('%s')", + RETURN_ON_FAILURE(&m_Device, enoughDescriptors, Result::INVALID_ARGUMENT, "the maximum number of descriptors exceeded ('%s')", GetDescriptorTypeName(rangeDesc.descriptorType)); } bool enoughDescriptors = m_DynamicConstantBufferNum + descriptorSetDesc.dynamicConstantBufferNum <= m_Desc.dynamicConstantBufferMaxNum; - RETURN_ON_FAILURE(&m_Device, enoughDescriptors, Result::INVALID_ARGUMENT, "AllocateDescriptorSets: the maximum number of descriptors exceeded ('DYNAMIC_CONSTANT_BUFFER')"); + RETURN_ON_FAILURE(&m_Device, enoughDescriptors, Result::INVALID_ARGUMENT, "the maximum number of descriptors exceeded ('DYNAMIC_CONSTANT_BUFFER')"); } PipelineLayout* pipelineLayoutImpl = NRI_GET_IMPL(PipelineLayout, &pipelineLayout); diff --git a/Source/Validation/DescriptorSetVal.cpp b/Source/Validation/DescriptorSetVal.cpp index 82349e0b..e1287876 100644 --- a/Source/Validation/DescriptorSetVal.cpp +++ b/Source/Validation/DescriptorSetVal.cpp @@ -17,11 +17,11 @@ void DescriptorSetVal::UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t ran if (rangeNum == 0) return; - RETURN_ON_FAILURE(&m_Device, rangeUpdateDescs != nullptr, ReturnVoid(), "UpdateDescriptorRanges: 'rangeUpdateDescs' is NULL"); - RETURN_ON_FAILURE(&m_Device, rangeOffset < GetDesc().rangeNum, ReturnVoid(), "UpdateDescriptorRanges: 'rangeOffset' is out of bounds. (rangeOffset=%u, rangeNum=%u)", rangeOffset, GetDesc().rangeNum); + RETURN_ON_FAILURE(&m_Device, rangeUpdateDescs != nullptr, ReturnVoid(), "'rangeUpdateDescs' is NULL"); + RETURN_ON_FAILURE(&m_Device, rangeOffset < GetDesc().rangeNum, ReturnVoid(), "'rangeOffset' is out of bounds. (rangeOffset=%u, rangeNum=%u)", rangeOffset, GetDesc().rangeNum); RETURN_ON_FAILURE(&m_Device, rangeOffset + rangeNum <= GetDesc().rangeNum, ReturnVoid(), - "UpdateDescriptorRanges: 'rangeOffset' + 'rangeNum' is greater than the number of ranges. (rangeOffset=%u, rangeNum=%u, rangeNum=%u)", rangeOffset, rangeNum, + "'rangeOffset' + 'rangeNum' is greater than the number of ranges. (rangeOffset=%u, rangeNum=%u, rangeNum=%u)", rangeOffset, rangeNum, GetDesc().rangeNum); DescriptorRangeUpdateDesc* rangeUpdateDescsImpl = StackAlloc(DescriptorRangeUpdateDesc, rangeNum); @@ -29,15 +29,15 @@ void DescriptorSetVal::UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t ran const DescriptorRangeUpdateDesc& updateDesc = rangeUpdateDescs[i]; const DescriptorRangeDesc& rangeDesc = GetDesc().ranges[rangeOffset + i]; - RETURN_ON_FAILURE(&m_Device, updateDesc.descriptorNum != 0, ReturnVoid(), "UpdateDescriptorRanges: 'rangeUpdateDescs[%u].descriptorNum' is 0", i); - RETURN_ON_FAILURE(&m_Device, updateDesc.descriptors != nullptr, ReturnVoid(), "UpdateDescriptorRanges: 'rangeUpdateDescs[%u].descriptors' is NULL", i); + RETURN_ON_FAILURE(&m_Device, updateDesc.descriptorNum != 0, ReturnVoid(), "'rangeUpdateDescs[%u].descriptorNum' is 0", i); + RETURN_ON_FAILURE(&m_Device, updateDesc.descriptors != nullptr, ReturnVoid(), "'rangeUpdateDescs[%u].descriptors' is NULL", i); RETURN_ON_FAILURE(&m_Device, updateDesc.offsetInRange < rangeDesc.descriptorNum, ReturnVoid(), - "UpdateDescriptorRanges: 'rangeUpdateDescs[%u].offsetInRange' is greater than the number of descriptors (offsetInRange=%u, rangeDescriptorNum=%u, descriptorType=%s)", + "'rangeUpdateDescs[%u].offsetInRange' is greater than the number of descriptors (offsetInRange=%u, rangeDescriptorNum=%u, descriptorType=%s)", i, updateDesc.offsetInRange, rangeDesc.descriptorNum, GetDescriptorTypeName(rangeDesc.descriptorType)); RETURN_ON_FAILURE(&m_Device, updateDesc.offsetInRange + updateDesc.descriptorNum <= rangeDesc.descriptorNum, ReturnVoid(), - "UpdateDescriptorRanges: 'rangeUpdateDescs[%u].offsetInRange' + 'rangeUpdateDescs[%u].descriptorNum' is greater than the number of descriptors (offsetInRange=%u, " + "'rangeUpdateDescs[%u].offsetInRange' + 'rangeUpdateDescs[%u].descriptorNum' is greater than the number of descriptors (offsetInRange=%u, " "descriptorNum=%u, rangeDescriptorNum=%u, descriptorType=%s)", i, i, updateDesc.offsetInRange, updateDesc.descriptorNum, rangeDesc.descriptorNum, GetDescriptorTypeName(rangeDesc.descriptorType)); @@ -48,7 +48,7 @@ void DescriptorSetVal::UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t ran Descriptor** descriptors = (Descriptor**)dstDesc.descriptors; for (uint32_t j = 0; j < updateDesc.descriptorNum; j++) { - RETURN_ON_FAILURE(&m_Device, updateDesc.descriptors[j] != nullptr, ReturnVoid(), "UpdateDescriptorRanges: 'rangeUpdateDescs[%u].descriptors[%u]' is NULL", i, j); + RETURN_ON_FAILURE(&m_Device, updateDesc.descriptors[j] != nullptr, ReturnVoid(), "'rangeUpdateDescs[%u].descriptors[%u]' is NULL", i, j); descriptors[j] = NRI_GET_IMPL(Descriptor, updateDesc.descriptors[j]); } @@ -62,17 +62,17 @@ void DescriptorSetVal::UpdateDynamicConstantBuffers(uint32_t baseBuffer, uint32_ return; RETURN_ON_FAILURE(&m_Device, baseBuffer < GetDesc().dynamicConstantBufferNum, ReturnVoid(), - "UpdateDynamicConstantBuffers: 'baseBuffer' is invalid. (baseBuffer=%u, dynamicConstantBufferNum=%u)", baseBuffer, GetDesc().dynamicConstantBufferNum); + "'baseBuffer' is invalid. (baseBuffer=%u, dynamicConstantBufferNum=%u)", baseBuffer, GetDesc().dynamicConstantBufferNum); RETURN_ON_FAILURE(&m_Device, baseBuffer + bufferNum <= GetDesc().dynamicConstantBufferNum, ReturnVoid(), - "UpdateDynamicConstantBuffers: 'baseBuffer' + 'bufferNum' is greater than the number of buffers (baseBuffer=%u, bufferNum=%u, dynamicConstantBufferNum=%u)", baseBuffer, + "'baseBuffer' + 'bufferNum' is greater than the number of buffers (baseBuffer=%u, bufferNum=%u, dynamicConstantBufferNum=%u)", baseBuffer, bufferNum, GetDesc().dynamicConstantBufferNum); - RETURN_ON_FAILURE(&m_Device, descriptors != nullptr, ReturnVoid(), "UpdateDynamicConstantBuffers: 'descriptors' is NULL"); + RETURN_ON_FAILURE(&m_Device, descriptors != nullptr, ReturnVoid(), "'descriptors' is NULL"); Descriptor** descriptorsImpl = StackAlloc(Descriptor*, bufferNum); for (uint32_t i = 0; i < bufferNum; i++) { - RETURN_ON_FAILURE(&m_Device, descriptors[i] != nullptr, ReturnVoid(), "UpdateDynamicConstantBuffers: 'descriptors[%u]' is NULL", i); + RETURN_ON_FAILURE(&m_Device, descriptors[i] != nullptr, ReturnVoid(), "'descriptors[%u]' is NULL", i); descriptorsImpl[i] = NRI_GET_IMPL(Descriptor, descriptors[i]); } @@ -81,12 +81,12 @@ void DescriptorSetVal::UpdateDynamicConstantBuffers(uint32_t baseBuffer, uint32_ } void DescriptorSetVal::Copy(const DescriptorSetCopyDesc& descriptorSetCopyDesc) { - RETURN_ON_FAILURE(&m_Device, descriptorSetCopyDesc.srcDescriptorSet != nullptr, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.srcDescriptorSet' is NULL"); + RETURN_ON_FAILURE(&m_Device, descriptorSetCopyDesc.srcDescriptorSet != nullptr, ReturnVoid(), "'descriptorSetCopyDesc.srcDescriptorSet' is NULL"); DescriptorSetVal& srcDescriptorSetVal = *(DescriptorSetVal*)descriptorSetCopyDesc.srcDescriptorSet; const DescriptorSetDesc& srcDesc = srcDescriptorSetVal.GetDesc(); - RETURN_ON_FAILURE(&m_Device, descriptorSetCopyDesc.baseSrcRange < srcDesc.rangeNum, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.baseSrcRange' is invalid"); + RETURN_ON_FAILURE(&m_Device, descriptorSetCopyDesc.baseSrcRange < srcDesc.rangeNum, ReturnVoid(), "'descriptorSetCopyDesc.baseSrcRange' is invalid"); bool srcRangeValid = descriptorSetCopyDesc.baseSrcRange + descriptorSetCopyDesc.rangeNum < srcDesc.rangeNum; bool dstRangeValid = descriptorSetCopyDesc.baseDstRange + descriptorSetCopyDesc.rangeNum < GetDesc().rangeNum; @@ -95,13 +95,13 @@ void DescriptorSetVal::Copy(const DescriptorSetCopyDesc& descriptorSetCopyDesc) bool dstOffsetValid = descriptorSetCopyDesc.baseDstDynamicConstantBuffer < GetDesc().dynamicConstantBufferNum; bool dstDynamicConstantBufferValid = descriptorSetCopyDesc.baseDstDynamicConstantBuffer + descriptorSetCopyDesc.dynamicConstantBufferNum < GetDesc().dynamicConstantBufferNum; - RETURN_ON_FAILURE(&m_Device, srcRangeValid, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.rangeNum' is invalid"); - RETURN_ON_FAILURE(&m_Device, descriptorSetCopyDesc.baseDstRange < GetDesc().rangeNum, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.baseDstRange' is invalid"); - RETURN_ON_FAILURE(&m_Device, dstRangeValid, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.rangeNum' is invalid"); - RETURN_ON_FAILURE(&m_Device, srcOffsetValid, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.baseSrcDynamicConstantBuffer' is invalid"); - RETURN_ON_FAILURE(&m_Device, srcDynamicConstantBufferValid, ReturnVoid(), "CopyDescriptorSet: source range of dynamic constant buffers is invalid"); - RETURN_ON_FAILURE(&m_Device, dstOffsetValid, ReturnVoid(), "CopyDescriptorSet: 'descriptorSetCopyDesc.baseDstDynamicConstantBuffer' is invalid"); - RETURN_ON_FAILURE(&m_Device, dstDynamicConstantBufferValid, ReturnVoid(), "CopyDescriptorSet: destination range of dynamic constant buffers is invalid"); + RETURN_ON_FAILURE(&m_Device, srcRangeValid, ReturnVoid(), "'descriptorSetCopyDesc.rangeNum' is invalid"); + RETURN_ON_FAILURE(&m_Device, descriptorSetCopyDesc.baseDstRange < GetDesc().rangeNum, ReturnVoid(), "'descriptorSetCopyDesc.baseDstRange' is invalid"); + RETURN_ON_FAILURE(&m_Device, dstRangeValid, ReturnVoid(), "'descriptorSetCopyDesc.rangeNum' is invalid"); + RETURN_ON_FAILURE(&m_Device, srcOffsetValid, ReturnVoid(), "'descriptorSetCopyDesc.baseSrcDynamicConstantBuffer' is invalid"); + RETURN_ON_FAILURE(&m_Device, srcDynamicConstantBufferValid, ReturnVoid(), "source range of dynamic constant buffers is invalid"); + RETURN_ON_FAILURE(&m_Device, dstOffsetValid, ReturnVoid(), "'descriptorSetCopyDesc.baseDstDynamicConstantBuffer' is invalid"); + RETURN_ON_FAILURE(&m_Device, dstDynamicConstantBufferValid, ReturnVoid(), "destination range of dynamic constant buffers is invalid"); auto descriptorSetCopyDescImpl = descriptorSetCopyDesc; descriptorSetCopyDescImpl.srcDescriptorSet = NRI_GET_IMPL(DescriptorSet, descriptorSetCopyDesc.srcDescriptorSet); diff --git a/Source/Validation/DescriptorVal.cpp b/Source/Validation/DescriptorVal.cpp index 44f810a6..1bc91d3a 100644 --- a/Source/Validation/DescriptorVal.cpp +++ b/Source/Validation/DescriptorVal.cpp @@ -75,8 +75,11 @@ DescriptorVal::DescriptorVal(DeviceVal& device, Descriptor* descriptor, const Te case Texture2DViewType::DEPTH_STENCIL_ATTACHMENT: m_ResourceViewType = ResourceViewType::DEPTH_STENCIL_ATTACHMENT; break; + case Texture2DViewType::SHADING_RATE_ATTACHMENT: + m_ResourceViewType = ResourceViewType::SHADING_RATE_ATTACHMENT; + break; default: - CHECK(false, "unexpected TextureView"); + CHECK(false, "unexpected 'viewType'"); break; } } diff --git a/Source/Validation/DescriptorVal.h b/Source/Validation/DescriptorVal.h index 04de5a4d..7818eb33 100644 --- a/Source/Validation/DescriptorVal.h +++ b/Source/Validation/DescriptorVal.h @@ -18,7 +18,8 @@ enum class ResourceViewType { DEPTH_STENCIL_ATTACHMENT, SHADER_RESOURCE, SHADER_RESOURCE_STORAGE, - CONSTANT_BUFFER_VIEW + CONSTANT_BUFFER_VIEW, + SHADING_RATE_ATTACHMENT }; struct DescriptorVal : public DeviceObjectVal { diff --git a/Source/Validation/DeviceVal.cpp b/Source/Validation/DeviceVal.cpp index 68d547fa..da32797d 100644 --- a/Source/Validation/DeviceVal.cpp +++ b/Source/Validation/DeviceVal.cpp @@ -92,11 +92,11 @@ void DeviceVal::RegisterMemoryType(MemoryType memoryType, MemoryLocation memoryL } Result DeviceVal::CreateSwapChain(const SwapChainDesc& swapChainDesc, SwapChain*& swapChain) { - RETURN_ON_FAILURE(this, swapChainDesc.commandQueue != nullptr, Result::INVALID_ARGUMENT, "CreateSwapChain: 'swapChainDesc.commandQueue' is NULL"); - RETURN_ON_FAILURE(this, swapChainDesc.width != 0, Result::INVALID_ARGUMENT, "CreateSwapChain: 'swapChainDesc.width' is 0"); - RETURN_ON_FAILURE(this, swapChainDesc.height != 0, Result::INVALID_ARGUMENT, "CreateSwapChain: 'swapChainDesc.height' is 0"); - RETURN_ON_FAILURE(this, swapChainDesc.textureNum > 0, Result::INVALID_ARGUMENT, "CreateSwapChain: 'swapChainDesc.textureNum' is invalid"); - RETURN_ON_FAILURE(this, swapChainDesc.format < SwapChainFormat::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSwapChain: 'swapChainDesc.format' is invalid"); + RETURN_ON_FAILURE(this, swapChainDesc.commandQueue != nullptr, Result::INVALID_ARGUMENT, "'swapChainDesc.commandQueue' is NULL"); + RETURN_ON_FAILURE(this, swapChainDesc.width != 0, Result::INVALID_ARGUMENT, "'swapChainDesc.width' is 0"); + RETURN_ON_FAILURE(this, swapChainDesc.height != 0, Result::INVALID_ARGUMENT, "'swapChainDesc.height' is 0"); + RETURN_ON_FAILURE(this, swapChainDesc.textureNum > 0, Result::INVALID_ARGUMENT, "'swapChainDesc.textureNum' is invalid"); + RETURN_ON_FAILURE(this, swapChainDesc.format < SwapChainFormat::MAX_NUM, Result::INVALID_ARGUMENT, "'swapChainDesc.format' is invalid"); auto swapChainDescImpl = swapChainDesc; swapChainDescImpl.commandQueue = NRI_GET_IMPL(CommandQueue, swapChainDesc.commandQueue); @@ -125,7 +125,7 @@ const DeviceDesc& DeviceVal::GetDesc() const { } Result DeviceVal::GetCommandQueue(CommandQueueType commandQueueType, CommandQueue*& commandQueue) { - RETURN_ON_FAILURE(this, commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "GetCommandQueue: 'commandQueueType' is invalid"); + RETURN_ON_FAILURE(this, commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "'commandQueueType' is invalid"); CommandQueue* commandQueueImpl; Result result = m_CoreAPI.GetCommandQueue(m_Device, commandQueueType, commandQueueImpl); @@ -164,7 +164,7 @@ Result DeviceVal::CreateDescriptorPool(const DescriptorPoolDesc& descriptorPoolD } Result DeviceVal::CreateBuffer(const BufferDesc& bufferDesc, Buffer*& buffer) { - RETURN_ON_FAILURE(this, bufferDesc.size != 0, Result::INVALID_ARGUMENT, "CreateBuffer: 'bufferDesc.size' is 0"); + RETURN_ON_FAILURE(this, bufferDesc.size != 0, Result::INVALID_ARGUMENT, "'bufferDesc.size' is 0"); Buffer* bufferImpl = nullptr; Result result = m_CoreAPI.CreateBuffer(m_Device, bufferDesc, bufferImpl); @@ -175,8 +175,8 @@ Result DeviceVal::CreateBuffer(const BufferDesc& bufferDesc, Buffer*& buffer) { return result; } -Result DeviceVal::CreateBuffer(const AllocateBufferDesc& bufferDesc, Buffer*& buffer) { - RETURN_ON_FAILURE(this, bufferDesc.desc.size != 0, Result::INVALID_ARGUMENT, "AllocateBuffer: 'bufferDesc.size' is 0"); +Result DeviceVal::AllocateBuffer(const AllocateBufferDesc& bufferDesc, Buffer*& buffer) { + RETURN_ON_FAILURE(this, bufferDesc.desc.size != 0, Result::INVALID_ARGUMENT, "'bufferDesc.size' is 0"); Buffer* bufferImpl = nullptr; Result result = m_ResourceAllocatorAPI.AllocateBuffer(m_Device, bufferDesc, bufferImpl); @@ -209,14 +209,14 @@ static inline Mip_t GetMaxMipNum(uint16_t w, uint16_t h, uint16_t d) { Result DeviceVal::CreateTexture(const TextureDesc& textureDesc, Texture*& texture) { Mip_t maxMipNum = GetMaxMipNum(textureDesc.width, textureDesc.height, textureDesc.depth); - RETURN_ON_FAILURE(this, textureDesc.format > Format::UNKNOWN && textureDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.format' is invalid"); - RETURN_ON_FAILURE(this, textureDesc.width != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.width' is 0"); - RETURN_ON_FAILURE(this, textureDesc.height != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.height' is 0"); - RETURN_ON_FAILURE(this, textureDesc.depth != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.depth' is 0"); - RETURN_ON_FAILURE(this, textureDesc.mipNum != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.mipNum' is 0"); - RETURN_ON_FAILURE(this, textureDesc.mipNum <= maxMipNum, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.mipNum = %u' can't be > %u", textureDesc.mipNum, maxMipNum); - RETURN_ON_FAILURE(this, textureDesc.layerNum != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.layerNum' is 0"); - RETURN_ON_FAILURE(this, textureDesc.sampleNum != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.sampleNum' is 0"); + RETURN_ON_FAILURE(this, textureDesc.format > Format::UNKNOWN && textureDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, "'textureDesc.format' is invalid"); + RETURN_ON_FAILURE(this, textureDesc.width != 0, Result::INVALID_ARGUMENT, "'textureDesc.width' is 0"); + RETURN_ON_FAILURE(this, textureDesc.height != 0, Result::INVALID_ARGUMENT, "'textureDesc.height' is 0"); + RETURN_ON_FAILURE(this, textureDesc.depth != 0, Result::INVALID_ARGUMENT, "'textureDesc.depth' is 0"); + RETURN_ON_FAILURE(this, textureDesc.mipNum != 0, Result::INVALID_ARGUMENT, "'textureDesc.mipNum' is 0"); + RETURN_ON_FAILURE(this, textureDesc.mipNum <= maxMipNum, Result::INVALID_ARGUMENT, "'textureDesc.mipNum = %u' can't be > %u", textureDesc.mipNum, maxMipNum); + RETURN_ON_FAILURE(this, textureDesc.layerNum != 0, Result::INVALID_ARGUMENT, "'textureDesc.layerNum' is 0"); + RETURN_ON_FAILURE(this, textureDesc.sampleNum != 0, Result::INVALID_ARGUMENT, "'textureDesc.sampleNum' is 0"); Texture* textureImpl = nullptr; Result result = m_CoreAPI.CreateTexture(m_Device, textureDesc, textureImpl); @@ -227,17 +227,17 @@ Result DeviceVal::CreateTexture(const TextureDesc& textureDesc, Texture*& textur return result; } -Result DeviceVal::CreateTexture(const AllocateTextureDesc& textureDesc, Texture*& texture) { +Result DeviceVal::AllocateTexture(const AllocateTextureDesc& textureDesc, Texture*& texture) { Mip_t maxMipNum = GetMaxMipNum(textureDesc.desc.width, textureDesc.desc.height, textureDesc.desc.depth); - RETURN_ON_FAILURE(this, textureDesc.desc.format > Format::UNKNOWN && textureDesc.desc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.format' is invalid"); - RETURN_ON_FAILURE(this, textureDesc.desc.width != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.width' is 0"); - RETURN_ON_FAILURE(this, textureDesc.desc.height != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.height' is 0"); - RETURN_ON_FAILURE(this, textureDesc.desc.depth != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.depth' is 0"); - RETURN_ON_FAILURE(this, textureDesc.desc.mipNum != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.mipNum' is 0"); - RETURN_ON_FAILURE(this, textureDesc.desc.mipNum <= maxMipNum, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.mipNum = %u' can't be > %u", textureDesc.desc.mipNum, maxMipNum); - RETURN_ON_FAILURE(this, textureDesc.desc.layerNum != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.layerNum' is 0"); - RETURN_ON_FAILURE(this, textureDesc.desc.sampleNum != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.sampleNum' is 0"); + RETURN_ON_FAILURE(this, textureDesc.desc.format > Format::UNKNOWN && textureDesc.desc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, "'textureDesc.format' is invalid"); + RETURN_ON_FAILURE(this, textureDesc.desc.width != 0, Result::INVALID_ARGUMENT, "'textureDesc.width' is 0"); + RETURN_ON_FAILURE(this, textureDesc.desc.height != 0, Result::INVALID_ARGUMENT, "'textureDesc.height' is 0"); + RETURN_ON_FAILURE(this, textureDesc.desc.depth != 0, Result::INVALID_ARGUMENT, "'textureDesc.depth' is 0"); + RETURN_ON_FAILURE(this, textureDesc.desc.mipNum != 0, Result::INVALID_ARGUMENT, "'textureDesc.mipNum' is 0"); + RETURN_ON_FAILURE(this, textureDesc.desc.mipNum <= maxMipNum, Result::INVALID_ARGUMENT, "'textureDesc.mipNum = %u' can't be > %u", textureDesc.desc.mipNum, maxMipNum); + RETURN_ON_FAILURE(this, textureDesc.desc.layerNum != 0, Result::INVALID_ARGUMENT, "'textureDesc.layerNum' is 0"); + RETURN_ON_FAILURE(this, textureDesc.desc.sampleNum != 0, Result::INVALID_ARGUMENT, "'textureDesc.sampleNum' is 0"); Texture* textureImpl = nullptr; Result result = m_ResourceAllocatorAPI.AllocateTexture(m_Device, textureDesc, textureImpl); @@ -249,17 +249,17 @@ Result DeviceVal::CreateTexture(const AllocateTextureDesc& textureDesc, Texture* } Result DeviceVal::CreateDescriptor(const BufferViewDesc& bufferViewDesc, Descriptor*& bufferView) { - RETURN_ON_FAILURE(this, bufferViewDesc.buffer != nullptr, Result::INVALID_ARGUMENT, "CreateBufferView: 'bufferViewDesc.buffer' is NULL"); - RETURN_ON_FAILURE(this, bufferViewDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, "CreateBufferView: 'bufferViewDesc.format' is invalid"); - RETURN_ON_FAILURE(this, bufferViewDesc.viewType < BufferViewType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateBufferView: 'bufferViewDesc.viewType' is invalid"); + RETURN_ON_FAILURE(this, bufferViewDesc.buffer != nullptr, Result::INVALID_ARGUMENT, "'bufferViewDesc.buffer' is NULL"); + RETURN_ON_FAILURE(this, bufferViewDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, "'bufferViewDesc.format' is invalid"); + RETURN_ON_FAILURE(this, bufferViewDesc.viewType < BufferViewType::MAX_NUM, Result::INVALID_ARGUMENT, "'bufferViewDesc.viewType' is invalid"); const BufferDesc& bufferDesc = ((BufferVal*)bufferViewDesc.buffer)->GetDesc(); RETURN_ON_FAILURE(this, bufferViewDesc.offset < bufferDesc.size, Result::INVALID_ARGUMENT, - "CreateBufferView: 'bufferViewDesc.offset' is invalid. (bufferViewDesc.offset=%llu, bufferDesc.size=%llu)", bufferViewDesc.offset, bufferDesc.size); + "'bufferViewDesc.offset' is invalid. (bufferViewDesc.offset=%llu, bufferDesc.size=%llu)", bufferViewDesc.offset, bufferDesc.size); RETURN_ON_FAILURE(this, bufferViewDesc.offset + bufferViewDesc.size <= bufferDesc.size, Result::INVALID_ARGUMENT, - "CreateBufferView: 'bufferViewDesc.size' is invalid. (bufferViewDesc.offset=%llu, bufferViewDesc.size=%llu, bufferDesc.size=%llu)", bufferViewDesc.offset, + "'bufferViewDesc.size' is invalid. (bufferViewDesc.offset=%llu, bufferViewDesc.size=%llu, bufferDesc.size=%llu)", bufferViewDesc.offset, bufferViewDesc.size, bufferDesc.size); auto bufferViewDescImpl = bufferViewDesc; @@ -275,27 +275,27 @@ Result DeviceVal::CreateDescriptor(const BufferViewDesc& bufferViewDesc, Descrip } Result DeviceVal::CreateDescriptor(const Texture1DViewDesc& textureViewDesc, Descriptor*& textureView) { - RETURN_ON_FAILURE(this, textureViewDesc.texture != nullptr, Result::INVALID_ARGUMENT, "CreateTexture1DView: 'textureViewDesc.texture' is NULL"); - RETURN_ON_FAILURE(this, textureViewDesc.viewType < Texture1DViewType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateTexture1DView: 'textureViewDesc.viewType' is invalid"); + RETURN_ON_FAILURE(this, textureViewDesc.texture != nullptr, Result::INVALID_ARGUMENT, "'textureViewDesc.texture' is NULL"); + RETURN_ON_FAILURE(this, textureViewDesc.viewType < Texture1DViewType::MAX_NUM, Result::INVALID_ARGUMENT, "'textureViewDesc.viewType' is invalid"); RETURN_ON_FAILURE(this, textureViewDesc.format > Format::UNKNOWN && textureViewDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, - "CreateTexture1DView: 'textureViewDesc.format' is invalid"); + "'textureViewDesc.format' is invalid"); const TextureDesc& textureDesc = ((TextureVal*)textureViewDesc.texture)->GetDesc(); RETURN_ON_FAILURE(this, textureViewDesc.mipOffset < textureDesc.mipNum, Result::INVALID_ARGUMENT, - "CreateTexture1DView: 'textureViewDesc.mipOffset' is invalid (textureViewDesc.mipOffset=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, textureDesc.mipNum); + "'textureViewDesc.mipOffset' is invalid (textureViewDesc.mipOffset=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, textureDesc.mipNum); RETURN_ON_FAILURE(this, textureViewDesc.mipOffset + textureViewDesc.mipNum <= textureDesc.mipNum, Result::INVALID_ARGUMENT, - "CreateTexture1DView: 'textureViewDesc.mipNum' is invalid (textureViewDesc.mipOffset=%hu, textureViewDesc.mipNum=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, + "'textureViewDesc.mipNum' is invalid (textureViewDesc.mipOffset=%hu, textureViewDesc.mipNum=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, textureViewDesc.mipNum, textureDesc.mipNum); RETURN_ON_FAILURE(this, textureViewDesc.layerOffset < textureDesc.layerNum, Result::INVALID_ARGUMENT, - "CreateTexture1DView: 'textureViewDesc.layerOffset' is invalid (textureViewDesc.layerOffset=%hu, textureDesc.layerNum=%hu)", textureViewDesc.layerOffset, + "'textureViewDesc.layerOffset' is invalid (textureViewDesc.layerOffset=%hu, textureDesc.layerNum=%hu)", textureViewDesc.layerOffset, textureDesc.layerNum); RETURN_ON_FAILURE(this, textureViewDesc.layerOffset + textureViewDesc.layerNum <= textureDesc.layerNum, Result::INVALID_ARGUMENT, - "CreateTexture1DView: 'textureViewDesc.layerNum' is invalid (textureViewDesc.layerOffset=%hu, textureViewDesc.layerNum=%hu, textureDesc.layerNum=%hu)", + "'textureViewDesc.layerNum' is invalid (textureViewDesc.layerOffset=%hu, textureViewDesc.layerNum=%hu, textureDesc.layerNum=%hu)", textureViewDesc.layerOffset, textureViewDesc.layerNum, textureDesc.layerNum); auto textureViewDescImpl = textureViewDesc; @@ -311,31 +311,31 @@ Result DeviceVal::CreateDescriptor(const Texture1DViewDesc& textureViewDesc, Des } Result DeviceVal::CreateDescriptor(const Texture2DViewDesc& textureViewDesc, Descriptor*& textureView) { - RETURN_ON_FAILURE(this, textureViewDesc.texture != nullptr, Result::INVALID_ARGUMENT, "CreateTexture2DView: 'textureViewDesc.texture' is NULL"); - RETURN_ON_FAILURE(this, textureViewDesc.viewType < Texture2DViewType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateTexture2DView: 'textureViewDesc.viewType' is invalid"); + RETURN_ON_FAILURE(this, textureViewDesc.texture != nullptr, Result::INVALID_ARGUMENT, "'textureViewDesc.texture' is NULL"); + RETURN_ON_FAILURE(this, textureViewDesc.viewType < Texture2DViewType::MAX_NUM, Result::INVALID_ARGUMENT, "'textureViewDesc.viewType' is invalid"); RETURN_ON_FAILURE(this, textureViewDesc.format > Format::UNKNOWN && textureViewDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, - "CreateTexture2DView: 'textureViewDesc.format' is invalid"); + "'textureViewDesc.format' is invalid"); const TextureDesc& textureDesc = ((TextureVal*)textureViewDesc.texture)->GetDesc(); RETURN_ON_FAILURE(this, textureViewDesc.mipOffset < textureDesc.mipNum, Result::INVALID_ARGUMENT, - "CreateTexture2DView: 'textureViewDesc.mipOffset' is invalid. " + "'textureViewDesc.mipOffset' is invalid. " "(textureViewDesc.mipOffset=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, textureDesc.mipNum); RETURN_ON_FAILURE(this, textureViewDesc.mipOffset + textureViewDesc.mipNum <= textureDesc.mipNum, Result::INVALID_ARGUMENT, - "CreateTexture2DView: 'textureViewDesc.mipNum' is invalid. " + "'textureViewDesc.mipNum' is invalid. " "(textureViewDesc.mipOffset=%hu, textureViewDesc.mipNum=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, textureViewDesc.mipNum, textureDesc.mipNum); RETURN_ON_FAILURE(this, textureViewDesc.layerOffset < textureDesc.layerNum, Result::INVALID_ARGUMENT, - "CreateTexture2DView: 'textureViewDesc.layerOffset' is invalid. " + "'textureViewDesc.layerOffset' is invalid. " "(textureViewDesc.layerOffset=%hu, textureDesc.layerNum=%hu)", textureViewDesc.layerOffset, textureDesc.layerNum); RETURN_ON_FAILURE(this, textureViewDesc.layerOffset + textureViewDesc.layerNum <= textureDesc.layerNum, Result::INVALID_ARGUMENT, - "CreateTexture2DView: 'textureViewDesc.layerNum' is invalid. " + "'textureViewDesc.layerNum' is invalid. " "(textureViewDesc.layerOffset=%hu, textureViewDesc.layerNum=%hu, textureDesc.layerNum=%hu)", textureViewDesc.layerOffset, textureViewDesc.layerNum, textureDesc.layerNum); @@ -352,31 +352,31 @@ Result DeviceVal::CreateDescriptor(const Texture2DViewDesc& textureViewDesc, Des } Result DeviceVal::CreateDescriptor(const Texture3DViewDesc& textureViewDesc, Descriptor*& textureView) { - RETURN_ON_FAILURE(this, textureViewDesc.texture != nullptr, Result::INVALID_ARGUMENT, "CreateTexture3DView: 'textureViewDesc.texture' is NULL"); - RETURN_ON_FAILURE(this, textureViewDesc.viewType < Texture3DViewType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateTexture3DView: 'textureViewDesc.viewType' is invalid"); + RETURN_ON_FAILURE(this, textureViewDesc.texture != nullptr, Result::INVALID_ARGUMENT, "'textureViewDesc.texture' is NULL"); + RETURN_ON_FAILURE(this, textureViewDesc.viewType < Texture3DViewType::MAX_NUM, Result::INVALID_ARGUMENT, "'textureViewDesc.viewType' is invalid"); RETURN_ON_FAILURE(this, textureViewDesc.format > Format::UNKNOWN && textureViewDesc.format < Format::MAX_NUM, Result::INVALID_ARGUMENT, - "CreateTexture3DView: 'textureViewDesc.format' is invalid"); + "'textureViewDesc.format' is invalid"); const TextureDesc& textureDesc = ((TextureVal*)textureViewDesc.texture)->GetDesc(); RETURN_ON_FAILURE(this, textureViewDesc.mipOffset < textureDesc.mipNum, Result::INVALID_ARGUMENT, - "CreateTexture3DView: 'textureViewDesc.mipOffset' is invalid. " + "'textureViewDesc.mipOffset' is invalid. " "(textureViewDesc.mipOffset=%hu, textureViewDesc.mipOffset=%hu)", textureViewDesc.mipOffset, textureDesc.mipNum); RETURN_ON_FAILURE(this, textureViewDesc.mipOffset + textureViewDesc.mipNum <= textureDesc.mipNum, Result::INVALID_ARGUMENT, - "CreateTexture3DView: 'textureViewDesc.mipNum' is invalid. " + "'textureViewDesc.mipNum' is invalid. " "(textureViewDesc.mipOffset=%hu, textureViewDesc.mipNum=%hu, textureDesc.mipNum=%hu)", textureViewDesc.mipOffset, textureViewDesc.mipNum, textureDesc.mipNum); RETURN_ON_FAILURE(this, textureViewDesc.sliceOffset < textureDesc.depth, Result::INVALID_ARGUMENT, - "CreateTexture3DView: 'textureViewDesc.layerOffset' is invalid. " + "'textureViewDesc.layerOffset' is invalid. " "(textureViewDesc.sliceOffset=%hu, textureDesc.depth=%hu)", textureViewDesc.sliceOffset, textureDesc.depth); RETURN_ON_FAILURE(this, textureViewDesc.sliceOffset + textureViewDesc.sliceNum <= textureDesc.depth, Result::INVALID_ARGUMENT, - "CreateTexture3DView: 'textureViewDesc.layerNum' is invalid. " + "'textureViewDesc.layerNum' is invalid. " "(textureViewDesc.sliceOffset=%hu, textureViewDesc.sliceNum=%hu, textureDesc.depth=%hu)", textureViewDesc.sliceOffset, textureViewDesc.sliceNum, textureDesc.depth); @@ -393,15 +393,18 @@ Result DeviceVal::CreateDescriptor(const Texture3DViewDesc& textureViewDesc, Des } Result DeviceVal::CreateDescriptor(const SamplerDesc& samplerDesc, Descriptor*& sampler) { - RETURN_ON_FAILURE(this, samplerDesc.filters.mag < Filter::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.filters.mag' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.filters.min < Filter::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.filters.min' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.filters.mip < Filter::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.filters.mip' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.filters.ext < FilterExt::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.filters.ext' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.addressModes.u < AddressMode::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.addressModes.u' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.addressModes.v < AddressMode::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.addressModes.v' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.addressModes.w < AddressMode::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.addressModes.w' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.compareFunc < CompareFunc::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.compareFunc' is invalid"); - RETURN_ON_FAILURE(this, samplerDesc.borderColor < BorderColor::MAX_NUM, Result::INVALID_ARGUMENT, "CreateSampler: 'samplerDesc.borderColor' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.filters.mag < Filter::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.filters.mag' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.filters.min < Filter::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.filters.min' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.filters.mip < Filter::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.filters.mip' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.filters.ext < FilterExt::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.filters.ext' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.addressModes.u < AddressMode::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.addressModes.u' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.addressModes.v < AddressMode::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.addressModes.v' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.addressModes.w < AddressMode::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.addressModes.w' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.compareFunc < CompareFunc::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.compareFunc' is invalid"); + RETURN_ON_FAILURE(this, samplerDesc.borderColor < BorderColor::MAX_NUM, Result::INVALID_ARGUMENT, "'samplerDesc.borderColor' is invalid"); + + if (!GetDesc().isTextureFilterMinMaxSupported) + RETURN_ON_FAILURE(this, samplerDesc.filters.ext == FilterExt::NONE, Result::INVALID_ARGUMENT, "'isTextureFilterMinMaxSupported' is unsupported"); Descriptor* samplerImpl = nullptr; Result result = m_CoreAPI.CreateSampler(m_Device, samplerDesc, samplerImpl); @@ -418,10 +421,10 @@ Result DeviceVal::CreatePipelineLayout(const PipelineLayoutDesc& pipelineLayoutD const bool isRayTracing = pipelineLayoutDesc.shaderStages & StageBits::RAY_TRACING_SHADERS; const uint32_t supportedTypes = (uint32_t)isGraphics + (uint32_t)isCompute + (uint32_t)isRayTracing; - RETURN_ON_FAILURE(this, pipelineLayoutDesc.shaderStages != StageBits::NONE, Result::INVALID_ARGUMENT, "CreatePipelineLayout: 'pipelineLayoutDesc.shaderStages' can't be NONE"); - RETURN_ON_FAILURE(this, supportedTypes > 0, Result::INVALID_ARGUMENT, "CreatePipelineLayout: 'pipelineLayoutDesc.shaderStages' doesn't include any shader stages"); + RETURN_ON_FAILURE(this, pipelineLayoutDesc.shaderStages != StageBits::NONE, Result::INVALID_ARGUMENT, "'pipelineLayoutDesc.shaderStages' can't be NONE"); + RETURN_ON_FAILURE(this, supportedTypes > 0, Result::INVALID_ARGUMENT, "'pipelineLayoutDesc.shaderStages' doesn't include any shader stages"); RETURN_ON_FAILURE(this, supportedTypes == 1, Result::INVALID_ARGUMENT, - "CreatePipelineLayout: 'pipelineLayoutDesc.shaderStages' is invalid, it can't be compatible with more than one type of pipeline"); + "'pipelineLayoutDesc.shaderStages' is invalid, it can't be compatible with more than one type of pipeline"); for (uint32_t i = 0; i < pipelineLayoutDesc.descriptorSetNum; i++) { const DescriptorSetDesc& descriptorSetDesc = pipelineLayoutDesc.descriptorSets[i]; @@ -430,18 +433,18 @@ Result DeviceVal::CreatePipelineLayout(const PipelineLayoutDesc& pipelineLayoutD const DescriptorRangeDesc& range = descriptorSetDesc.ranges[j]; RETURN_ON_FAILURE(this, !range.isDescriptorNumVariable || range.isArray, Result::INVALID_ARGUMENT, - "CreatePipelineLayout: 'pipelineLayoutDesc.descriptorSets[%u].ranges[%u]' is invalid, " + "'pipelineLayoutDesc.descriptorSets[%u].ranges[%u]' is invalid, " "'isArray' can't be false if 'isDescriptorNumVariable' is true", i, j); - RETURN_ON_FAILURE(this, range.descriptorNum > 0, Result::INVALID_ARGUMENT, "CreatePipelineLayout: 'pipelineLayoutDesc.descriptorSets[%u].ranges[%u].descriptorNum' is 0", i, j); - RETURN_ON_FAILURE(this, range.descriptorType < DescriptorType::MAX_NUM, Result::INVALID_ARGUMENT, "CreatePipelineLayout: 'pipelineLayoutDesc.descriptorSets[%u].ranges[%u].descriptorType' is invalid", i, j); + RETURN_ON_FAILURE(this, range.descriptorNum > 0, Result::INVALID_ARGUMENT, "'pipelineLayoutDesc.descriptorSets[%u].ranges[%u].descriptorNum' is 0", i, j); + RETURN_ON_FAILURE(this, range.descriptorType < DescriptorType::MAX_NUM, Result::INVALID_ARGUMENT, "'pipelineLayoutDesc.descriptorSets[%u].ranges[%u].descriptorType' is invalid", i, j); if (range.shaderStages != StageBits::ALL) { const uint32_t filteredVisibilityMask = range.shaderStages & pipelineLayoutDesc.shaderStages; RETURN_ON_FAILURE(this, (uint32_t)range.shaderStages == filteredVisibilityMask, Result::INVALID_ARGUMENT, - "CreatePipelineLayout: 'pipelineLayoutDesc.descriptorSets[%u].ranges[%u].shaderStages' is not " + "'pipelineLayoutDesc.descriptorSets[%u].ranges[%u].shaderStages' is not " "compatible with 'pipelineLayoutDesc.shaderStages'", i, j); } @@ -458,9 +461,9 @@ Result DeviceVal::CreatePipelineLayout(const PipelineLayoutDesc& pipelineLayoutD } Result DeviceVal::CreatePipeline(const GraphicsPipelineDesc& graphicsPipelineDesc, Pipeline*& pipeline) { - RETURN_ON_FAILURE(this, graphicsPipelineDesc.pipelineLayout != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.pipelineLayout' is NULL"); - RETURN_ON_FAILURE(this, graphicsPipelineDesc.shaders != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.shaders' is NULL"); - RETURN_ON_FAILURE(this, graphicsPipelineDesc.shaderNum > 0, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.shaderNum' is 0"); + RETURN_ON_FAILURE(this, graphicsPipelineDesc.pipelineLayout != nullptr, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.pipelineLayout' is NULL"); + RETURN_ON_FAILURE(this, graphicsPipelineDesc.shaders != nullptr, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.shaders' is NULL"); + RETURN_ON_FAILURE(this, graphicsPipelineDesc.shaderNum > 0, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.shaderNum' is 0"); const PipelineLayoutVal& pipelineLayout = *(PipelineLayoutVal*)graphicsPipelineDesc.pipelineLayout; const StageBits shaderStages = pipelineLayout.GetPipelineLayoutDesc().shaderStages; @@ -471,17 +474,17 @@ Result DeviceVal::CreatePipeline(const GraphicsPipelineDesc& graphicsPipelineDes if (shaderDesc->stage == StageBits::VERTEX_SHADER || shaderDesc->stage == StageBits::MESH_CONTROL_SHADER) hasEntryPoint = true; - RETURN_ON_FAILURE(this, shaderDesc->stage & shaderStages, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.shaders[%u].stage' is not enabled in the pipeline layout", i); - RETURN_ON_FAILURE(this, shaderDesc->bytecode != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.shaders[%u].bytecode' is invalid", i); - RETURN_ON_FAILURE(this, shaderDesc->size != 0, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.shaders[%u].size' is 0", i); + RETURN_ON_FAILURE(this, shaderDesc->stage & shaderStages, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.shaders[%u].stage' is not enabled in the pipeline layout", i); + RETURN_ON_FAILURE(this, shaderDesc->bytecode != nullptr, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.shaders[%u].bytecode' is invalid", i); + RETURN_ON_FAILURE(this, shaderDesc->size != 0, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.shaders[%u].size' is 0", i); RETURN_ON_FAILURE(this, IsShaderStageValid(shaderDesc->stage, uniqueShaderStages, StageBits::GRAPHICS_SHADERS), Result::INVALID_ARGUMENT, - "CreatePipeline: 'graphicsPipelineDesc.shaders[%u].stage' must include only 1 graphics shader stage, unique for the entire pipeline", i); + "'graphicsPipelineDesc.shaders[%u].stage' must include only 1 graphics shader stage, unique for the entire pipeline", i); } - RETURN_ON_FAILURE(this, hasEntryPoint, Result::INVALID_ARGUMENT, "CreatePipeline: a VERTEX or MESH_CONTROL shader is not provided"); + RETURN_ON_FAILURE(this, hasEntryPoint, Result::INVALID_ARGUMENT, "a VERTEX or MESH_CONTROL shader is not provided"); for (uint32_t i = 0; i < graphicsPipelineDesc.outputMerger.colorNum; i++) { const ColorAttachmentDesc* color = graphicsPipelineDesc.outputMerger.color + i; - RETURN_ON_FAILURE(this, color->format > Format::UNKNOWN && color->format < Format::BC1_RGBA_UNORM, Result::INVALID_ARGUMENT, "CreatePipeline: 'graphicsPipelineDesc.outputMerger->color[%u].format = %u' is invalid", i, color->format); + RETURN_ON_FAILURE(this, color->format > Format::UNKNOWN && color->format < Format::BC1_RGBA_UNORM, Result::INVALID_ARGUMENT, "'graphicsPipelineDesc.outputMerger->color[%u].format = %u' is invalid", i, color->format); } if (graphicsPipelineDesc.vertexInput) { @@ -490,7 +493,7 @@ Result DeviceVal::CreatePipeline(const GraphicsPipelineDesc& graphicsPipelineDes uint32_t size = GetFormatProps(attribute->format).stride; uint32_t stride = graphicsPipelineDesc.vertexInput->streams[attribute->streamIndex].stride; RETURN_ON_FAILURE(this, attribute->offset + size <= stride, Result::INVALID_ARGUMENT, - "CreatePipeline: 'graphicsPipelineDesc.inputAssembly->attributes[%u]' is out of bounds of 'graphicsPipelineDesc.inputAssembly->streams[%u]' (stride = %u)", i, attribute->streamIndex, stride); + "'graphicsPipelineDesc.inputAssembly->attributes[%u]' is out of bounds of 'graphicsPipelineDesc.inputAssembly->streams[%u]' (stride = %u)", i, attribute->streamIndex, stride); } } @@ -507,10 +510,10 @@ Result DeviceVal::CreatePipeline(const GraphicsPipelineDesc& graphicsPipelineDes } Result DeviceVal::CreatePipeline(const ComputePipelineDesc& computePipelineDesc, Pipeline*& pipeline) { - RETURN_ON_FAILURE(this, computePipelineDesc.pipelineLayout != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'computePipelineDesc.pipelineLayout' is NULL"); - RETURN_ON_FAILURE(this, computePipelineDesc.shader.size != 0, Result::INVALID_ARGUMENT, "CreatePipeline: 'computePipelineDesc.shader.size' is 0"); - RETURN_ON_FAILURE(this, computePipelineDesc.shader.bytecode != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'computePipelineDesc.shader.bytecode' is NULL"); - RETURN_ON_FAILURE(this, computePipelineDesc.shader.stage == StageBits::COMPUTE_SHADER, Result::INVALID_ARGUMENT, "CreatePipeline: 'computePipelineDesc.shader.stage' must be 'StageBits::COMPUTE_SHADER'"); + RETURN_ON_FAILURE(this, computePipelineDesc.pipelineLayout != nullptr, Result::INVALID_ARGUMENT, "'computePipelineDesc.pipelineLayout' is NULL"); + RETURN_ON_FAILURE(this, computePipelineDesc.shader.size != 0, Result::INVALID_ARGUMENT, "'computePipelineDesc.shader.size' is 0"); + RETURN_ON_FAILURE(this, computePipelineDesc.shader.bytecode != nullptr, Result::INVALID_ARGUMENT, "'computePipelineDesc.shader.bytecode' is NULL"); + RETURN_ON_FAILURE(this, computePipelineDesc.shader.stage == StageBits::COMPUTE_SHADER, Result::INVALID_ARGUMENT, "'computePipelineDesc.shader.stage' must be 'StageBits::COMPUTE_SHADER'"); auto computePipelineDescImpl = computePipelineDesc; computePipelineDescImpl.pipelineLayout = NRI_GET_IMPL(PipelineLayout, computePipelineDesc.pipelineLayout); @@ -525,8 +528,8 @@ Result DeviceVal::CreatePipeline(const ComputePipelineDesc& computePipelineDesc, } Result DeviceVal::CreateQueryPool(const QueryPoolDesc& queryPoolDesc, QueryPool*& queryPool) { - RETURN_ON_FAILURE(this, queryPoolDesc.queryType < QueryType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateQueryPool: 'queryPoolDesc.queryType' is invalid"); - RETURN_ON_FAILURE(this, queryPoolDesc.capacity > 0, Result::INVALID_ARGUMENT, "CreateQueryPool: 'queryPoolDesc.capacity' is 0"); + RETURN_ON_FAILURE(this, queryPoolDesc.queryType < QueryType::MAX_NUM, Result::INVALID_ARGUMENT, "'queryPoolDesc.queryType' is invalid"); + RETURN_ON_FAILURE(this, queryPoolDesc.capacity > 0, Result::INVALID_ARGUMENT, "'queryPoolDesc.capacity' is 0"); QueryPool* queryPoolImpl = nullptr; Result result = m_CoreAPI.CreateQueryPool(m_Device, queryPoolDesc, queryPoolImpl); @@ -598,8 +601,8 @@ void DeviceVal::DestroyFence(Fence& fence) { } Result DeviceVal::AllocateMemory(const AllocateMemoryDesc& allocateMemoryDesc, Memory*& memory) { - RETURN_ON_FAILURE(this, allocateMemoryDesc.size > 0, Result::INVALID_ARGUMENT, "AllocateMemory: 'allocateMemoryDesc.size' is 0"); - RETURN_ON_FAILURE(this, allocateMemoryDesc.priority >= -1.0f && allocateMemoryDesc.priority <= 1.0f, Result::INVALID_ARGUMENT, "AllocateMemory: 'allocateMemoryDesc.priority' outside of [-1; 1] range"); + RETURN_ON_FAILURE(this, allocateMemoryDesc.size > 0, Result::INVALID_ARGUMENT, "'allocateMemoryDesc.size' is 0"); + RETURN_ON_FAILURE(this, allocateMemoryDesc.priority >= -1.0f && allocateMemoryDesc.priority <= 1.0f, Result::INVALID_ARGUMENT, "'allocateMemoryDesc.priority' outside of [-1; 1] range"); std::unordered_map::iterator it; std::unordered_map::iterator end; @@ -609,7 +612,7 @@ Result DeviceVal::AllocateMemory(const AllocateMemoryDesc& allocateMemoryDesc, M end = m_MemoryTypeMap.end(); } - RETURN_ON_FAILURE(this, it != end, Result::FAILURE, "AllocateMemory: 'memoryType' is invalid"); + RETURN_ON_FAILURE(this, it != end, Result::FAILURE, "'memoryType' is invalid"); Memory* memoryImpl; Result result = m_CoreAPI.AllocateMemory(m_Device, allocateMemoryDesc, memoryImpl); @@ -621,7 +624,7 @@ Result DeviceVal::AllocateMemory(const AllocateMemoryDesc& allocateMemoryDesc, M } Result DeviceVal::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum) { - RETURN_ON_FAILURE(this, memoryBindingDescs != nullptr, Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs' is NULL"); + RETURN_ON_FAILURE(this, memoryBindingDescs != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs' is NULL"); BufferMemoryBindingDesc* memoryBindingDescsImpl = StackAlloc(BufferMemoryBindingDesc, memoryBindingDescNum); @@ -629,13 +632,13 @@ Result DeviceVal::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingD BufferMemoryBindingDesc& destDesc = memoryBindingDescsImpl[i]; const BufferMemoryBindingDesc& srcDesc = memoryBindingDescs[i]; - RETURN_ON_FAILURE(this, srcDesc.buffer != nullptr, Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].buffer' is NULL", i); - RETURN_ON_FAILURE(this, srcDesc.memory != nullptr, Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].memory' is NULL", i); + RETURN_ON_FAILURE(this, srcDesc.buffer != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].buffer' is NULL", i); + RETURN_ON_FAILURE(this, srcDesc.memory != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].memory' is NULL", i); MemoryVal& memory = (MemoryVal&)*srcDesc.memory; BufferVal& buffer = (BufferVal&)*srcDesc.buffer; - RETURN_ON_FAILURE(this, !buffer.IsBoundToMemory(), Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].buffer' is already bound to memory", i); + RETURN_ON_FAILURE(this, !buffer.IsBoundToMemory(), Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].buffer' is already bound to memory", i); destDesc = srcDesc; destDesc.memory = memory.GetImpl(); @@ -648,14 +651,14 @@ Result DeviceVal::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingD MemoryDesc memoryDesc = {}; GetCoreInterface().GetBufferMemoryDesc(GetImpl(), buffer.GetDesc(), memory.GetMemoryLocation(), memoryDesc); - RETURN_ON_FAILURE(this, !memoryDesc.mustBeDedicated || srcDesc.offset == 0, Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].offset' must be zero for dedicated allocation", i); - RETURN_ON_FAILURE(this, memoryDesc.alignment != 0, Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].alignment' is 0", i); - RETURN_ON_FAILURE(this, srcDesc.offset % memoryDesc.alignment == 0, Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].offset' is misaligned", i); + RETURN_ON_FAILURE(this, !memoryDesc.mustBeDedicated || srcDesc.offset == 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' must be zero for dedicated allocation", i); + RETURN_ON_FAILURE(this, memoryDesc.alignment != 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].alignment' is 0", i); + RETURN_ON_FAILURE(this, srcDesc.offset % memoryDesc.alignment == 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' is misaligned", i); const uint64_t rangeMax = srcDesc.offset + memoryDesc.size; const bool memorySizeIsUnknown = memory.GetSize() == 0; - RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].offset' is invalid", i); + RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' is invalid", i); } Result result = m_CoreAPI.BindBufferMemory(m_Device, memoryBindingDescsImpl, memoryBindingDescNum); @@ -671,7 +674,7 @@ Result DeviceVal::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingD } Result DeviceVal::BindTextureMemory(const TextureMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum) { - RETURN_ON_FAILURE(this, memoryBindingDescs != nullptr, Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs' is a NULL"); + RETURN_ON_FAILURE(this, memoryBindingDescs != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs' is a NULL"); TextureMemoryBindingDesc* memoryBindingDescsImpl = StackAlloc(TextureMemoryBindingDesc, memoryBindingDescNum); @@ -679,13 +682,13 @@ Result DeviceVal::BindTextureMemory(const TextureMemoryBindingDesc* memoryBindin TextureMemoryBindingDesc& destDesc = memoryBindingDescsImpl[i]; const TextureMemoryBindingDesc& srcDesc = memoryBindingDescs[i]; - RETURN_ON_FAILURE(this, srcDesc.texture != nullptr, Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].texture' is NULL", i); - RETURN_ON_FAILURE(this, srcDesc.memory != nullptr, Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].memory' is NULL", i); + RETURN_ON_FAILURE(this, srcDesc.texture != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].texture' is NULL", i); + RETURN_ON_FAILURE(this, srcDesc.memory != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].memory' is NULL", i); MemoryVal& memory = (MemoryVal&)*srcDesc.memory; TextureVal& texture = (TextureVal&)*srcDesc.texture; - RETURN_ON_FAILURE(this, !texture.IsBoundToMemory(), Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].texture' is already bound to memory", i); + RETURN_ON_FAILURE(this, !texture.IsBoundToMemory(), Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].texture' is already bound to memory", i); destDesc = srcDesc; destDesc.memory = memory.GetImpl(); @@ -698,14 +701,14 @@ Result DeviceVal::BindTextureMemory(const TextureMemoryBindingDesc* memoryBindin MemoryDesc memoryDesc = {}; GetCoreInterface().GetTextureMemoryDesc(GetImpl(), texture.GetDesc(), memory.GetMemoryLocation(), memoryDesc); - RETURN_ON_FAILURE(this, !memoryDesc.mustBeDedicated || srcDesc.offset == 0, Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].offset' must be zero for dedicated allocation", i); - RETURN_ON_FAILURE(this, memoryDesc.alignment != 0, Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].alignment' is 0", i); - RETURN_ON_FAILURE(this, srcDesc.offset % memoryDesc.alignment == 0, Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].offset' is misaligned", i); + RETURN_ON_FAILURE(this, !memoryDesc.mustBeDedicated || srcDesc.offset == 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' must be zero for dedicated allocation", i); + RETURN_ON_FAILURE(this, memoryDesc.alignment != 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].alignment' is 0", i); + RETURN_ON_FAILURE(this, srcDesc.offset % memoryDesc.alignment == 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' is misaligned", i); const uint64_t rangeMax = srcDesc.offset + memoryDesc.size; const bool memorySizeIsUnknown = memory.GetSize() == 0; - RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].offset' is invalid", i); + RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' is invalid", i); } Result result = m_CoreAPI.BindTextureMemory(m_Device, memoryBindingDescsImpl, memoryBindingDescNum); @@ -740,8 +743,8 @@ FormatSupportBits DeviceVal::GetFormatSupport(Format format) const { #if NRI_USE_VULKAN Result DeviceVal::CreateCommandQueue(const CommandQueueVKDesc& commandQueueVKDesc, CommandQueue*& commandQueue) { - RETURN_ON_FAILURE(this, commandQueueVKDesc.vkQueue != 0, Result::INVALID_ARGUMENT, "CreateCommandQueue: 'commandQueueVKDesc.vkQueue' is NULL"); - RETURN_ON_FAILURE(this, commandQueueVKDesc.commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateCommandQueue: 'commandQueueVKDesc.commandQueueType' is invalid"); + RETURN_ON_FAILURE(this, commandQueueVKDesc.vkQueue != 0, Result::INVALID_ARGUMENT, "'commandQueueVKDesc.vkQueue' is NULL"); + RETURN_ON_FAILURE(this, commandQueueVKDesc.commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "'commandQueueVKDesc.commandQueueType' is invalid"); CommandQueue* commandQueueImpl = nullptr; Result result = m_WrapperVKAPI.CreateCommandQueueVK(m_Device, commandQueueVKDesc, commandQueueImpl); @@ -753,8 +756,8 @@ Result DeviceVal::CreateCommandQueue(const CommandQueueVKDesc& commandQueueVKDes } Result DeviceVal::CreateCommandAllocator(const CommandAllocatorVKDesc& commandAllocatorVKDesc, CommandAllocator*& commandAllocator) { - RETURN_ON_FAILURE(this, commandAllocatorVKDesc.vkCommandPool != 0, Result::INVALID_ARGUMENT, "CreateCommandAllocator: 'commandAllocatorVKDesc.vkCommandPool' is NULL"); - RETURN_ON_FAILURE(this, commandAllocatorVKDesc.commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateCommandAllocator: 'commandAllocatorVKDesc.commandQueueType' is invalid"); + RETURN_ON_FAILURE(this, commandAllocatorVKDesc.vkCommandPool != 0, Result::INVALID_ARGUMENT, "'commandAllocatorVKDesc.vkCommandPool' is NULL"); + RETURN_ON_FAILURE(this, commandAllocatorVKDesc.commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "'commandAllocatorVKDesc.commandQueueType' is invalid"); CommandAllocator* commandAllocatorImpl = nullptr; Result result = m_WrapperVKAPI.CreateCommandAllocatorVK(m_Device, commandAllocatorVKDesc, commandAllocatorImpl); @@ -766,8 +769,8 @@ Result DeviceVal::CreateCommandAllocator(const CommandAllocatorVKDesc& commandAl } Result DeviceVal::CreateCommandBuffer(const CommandBufferVKDesc& commandBufferVKDesc, CommandBuffer*& commandBuffer) { - RETURN_ON_FAILURE(this, commandBufferVKDesc.vkCommandBuffer != 0, Result::INVALID_ARGUMENT, "CreateCommandBuffer: 'commandBufferVKDesc.vkCommandBuffer' is NULL"); - RETURN_ON_FAILURE(this, commandBufferVKDesc.commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "CreateCommandBuffer: 'commandBufferVKDesc.commandQueueType' is invalid"); + RETURN_ON_FAILURE(this, commandBufferVKDesc.vkCommandBuffer != 0, Result::INVALID_ARGUMENT, "'commandBufferVKDesc.vkCommandBuffer' is NULL"); + RETURN_ON_FAILURE(this, commandBufferVKDesc.commandQueueType < CommandQueueType::MAX_NUM, Result::INVALID_ARGUMENT, "'commandBufferVKDesc.commandQueueType' is invalid"); CommandBuffer* commandBufferImpl = nullptr; Result result = m_WrapperVKAPI.CreateCommandBufferVK(m_Device, commandBufferVKDesc, commandBufferImpl); @@ -779,8 +782,8 @@ Result DeviceVal::CreateCommandBuffer(const CommandBufferVKDesc& commandBufferVK } Result DeviceVal::CreateDescriptorPool(const DescriptorPoolVKDesc& descriptorPoolVKDesc, DescriptorPool*& descriptorPool) { - RETURN_ON_FAILURE(this, descriptorPoolVKDesc.vkDescriptorPool != 0, Result::INVALID_ARGUMENT, "CreateDescriptorPool: 'vkDescriptorPool' is NULL"); - RETURN_ON_FAILURE(this, descriptorPoolVKDesc.descriptorSetMaxNum != 0, Result::INVALID_ARGUMENT, "CreateDescriptorPool: 'descriptorSetMaxNum' is 0"); + RETURN_ON_FAILURE(this, descriptorPoolVKDesc.vkDescriptorPool != 0, Result::INVALID_ARGUMENT, "'vkDescriptorPool' is NULL"); + RETURN_ON_FAILURE(this, descriptorPoolVKDesc.descriptorSetMaxNum != 0, Result::INVALID_ARGUMENT, "'descriptorSetMaxNum' is 0"); DescriptorPool* descriptorPoolImpl = nullptr; Result result = m_WrapperVKAPI.CreateDescriptorPoolVK(m_Device, descriptorPoolVKDesc, descriptorPoolImpl); @@ -792,8 +795,8 @@ Result DeviceVal::CreateDescriptorPool(const DescriptorPoolVKDesc& descriptorPoo } Result DeviceVal::CreateBuffer(const BufferVKDesc& bufferDesc, Buffer*& buffer) { - RETURN_ON_FAILURE(this, bufferDesc.vkBuffer != 0, Result::INVALID_ARGUMENT, "CreateBuffer: 'bufferDesc.vkBuffer' is NULL"); - RETURN_ON_FAILURE(this, bufferDesc.size > 0, Result::INVALID_ARGUMENT, "CreateBuffer: 'bufferDesc.bufferSize' is 0"); + RETURN_ON_FAILURE(this, bufferDesc.vkBuffer != 0, Result::INVALID_ARGUMENT, "'bufferDesc.vkBuffer' is NULL"); + RETURN_ON_FAILURE(this, bufferDesc.size > 0, Result::INVALID_ARGUMENT, "'bufferDesc.bufferSize' is 0"); Buffer* bufferImpl = nullptr; Result result = m_WrapperVKAPI.CreateBufferVK(m_Device, bufferDesc, bufferImpl); @@ -805,11 +808,11 @@ Result DeviceVal::CreateBuffer(const BufferVKDesc& bufferDesc, Buffer*& buffer) } Result DeviceVal::CreateTexture(const TextureVKDesc& textureVKDesc, Texture*& texture) { - RETURN_ON_FAILURE(this, textureVKDesc.vkImage != 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureVKDesc.vkImage' is NULL"); - RETURN_ON_FAILURE(this, nriConvertVKFormatToNRI(textureVKDesc.vkFormat) != Format::UNKNOWN, Result::INVALID_ARGUMENT, "CreateTexture: 'textureVKDesc.sampleNum' is 0"); - RETURN_ON_FAILURE(this, textureVKDesc.sampleNum > 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureVKDesc.sampleNum' is 0"); - RETURN_ON_FAILURE(this, textureVKDesc.layerNum > 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureVKDesc.layerNum' is 0"); - RETURN_ON_FAILURE(this, textureVKDesc.mipNum > 0, Result::INVALID_ARGUMENT, "CreateTexture: 'textureVKDesc.mipNum' is 0"); + RETURN_ON_FAILURE(this, textureVKDesc.vkImage != 0, Result::INVALID_ARGUMENT, "'textureVKDesc.vkImage' is NULL"); + RETURN_ON_FAILURE(this, nriConvertVKFormatToNRI(textureVKDesc.vkFormat) != Format::UNKNOWN, Result::INVALID_ARGUMENT, "'textureVKDesc.sampleNum' is 0"); + RETURN_ON_FAILURE(this, textureVKDesc.sampleNum > 0, Result::INVALID_ARGUMENT, "'textureVKDesc.sampleNum' is 0"); + RETURN_ON_FAILURE(this, textureVKDesc.layerNum > 0, Result::INVALID_ARGUMENT, "'textureVKDesc.layerNum' is 0"); + RETURN_ON_FAILURE(this, textureVKDesc.mipNum > 0, Result::INVALID_ARGUMENT, "'textureVKDesc.mipNum' is 0"); Texture* textureImpl = nullptr; Result result = m_WrapperVKAPI.CreateTextureVK(m_Device, textureVKDesc, textureImpl); @@ -821,8 +824,8 @@ Result DeviceVal::CreateTexture(const TextureVKDesc& textureVKDesc, Texture*& te } Result DeviceVal::CreateMemory(const MemoryVKDesc& memoryVKDesc, Memory*& memory) { - RETURN_ON_FAILURE(this, memoryVKDesc.vkDeviceMemory != 0, Result::INVALID_ARGUMENT, "CreateMemory: 'memoryVKDesc.vkDeviceMemory' is NULL"); - RETURN_ON_FAILURE(this, memoryVKDesc.size > 0, Result::INVALID_ARGUMENT, "CreateMemory: 'memoryVKDesc.size' is 0"); + RETURN_ON_FAILURE(this, memoryVKDesc.vkDeviceMemory != 0, Result::INVALID_ARGUMENT, "'memoryVKDesc.vkDeviceMemory' is NULL"); + RETURN_ON_FAILURE(this, memoryVKDesc.size > 0, Result::INVALID_ARGUMENT, "'memoryVKDesc.size' is 0"); Memory* memoryImpl = nullptr; Result result = m_WrapperVKAPI.CreateMemoryVK(m_Device, memoryVKDesc, memoryImpl); @@ -834,7 +837,7 @@ Result DeviceVal::CreateMemory(const MemoryVKDesc& memoryVKDesc, Memory*& memory } Result DeviceVal::CreateGraphicsPipeline(VKNonDispatchableHandle vkPipeline, Pipeline*& pipeline) { - RETURN_ON_FAILURE(this, vkPipeline != 0, Result::INVALID_ARGUMENT, "CreateGraphicsPipeline: 'vkPipeline' is NULL"); + RETURN_ON_FAILURE(this, vkPipeline != 0, Result::INVALID_ARGUMENT, "'vkPipeline' is NULL"); Pipeline* pipelineImpl = nullptr; Result result = m_WrapperVKAPI.CreateGraphicsPipelineVK(m_Device, vkPipeline, pipelineImpl); @@ -846,7 +849,7 @@ Result DeviceVal::CreateGraphicsPipeline(VKNonDispatchableHandle vkPipeline, Pip } Result DeviceVal::CreateComputePipeline(VKNonDispatchableHandle vkPipeline, Pipeline*& pipeline) { - RETURN_ON_FAILURE(this, vkPipeline != 0, Result::INVALID_ARGUMENT, "CreateComputePipeline: 'vkPipeline' is NULL"); + RETURN_ON_FAILURE(this, vkPipeline != 0, Result::INVALID_ARGUMENT, "'vkPipeline' is NULL"); Pipeline* pipelineImpl = nullptr; Result result = m_WrapperVKAPI.CreateComputePipelineVK(m_Device, vkPipeline, pipelineImpl); @@ -858,7 +861,7 @@ Result DeviceVal::CreateComputePipeline(VKNonDispatchableHandle vkPipeline, Pipe } Result DeviceVal::CreateQueryPool(const QueryPoolVKDesc& queryPoolVKDesc, QueryPool*& queryPool) { - RETURN_ON_FAILURE(this, queryPoolVKDesc.vkQueryPool != 0, Result::INVALID_ARGUMENT, "CreateQueryPool: 'queryPoolVKDesc.vkQueryPool' is NULL"); + RETURN_ON_FAILURE(this, queryPoolVKDesc.vkQueryPool != 0, Result::INVALID_ARGUMENT, "'queryPoolVKDesc.vkQueryPool' is NULL"); QueryPool* queryPoolImpl = nullptr; Result result = m_WrapperVKAPI.CreateQueryPoolVK(m_Device, queryPoolVKDesc, queryPoolImpl); @@ -872,7 +875,7 @@ Result DeviceVal::CreateQueryPool(const QueryPoolVKDesc& queryPoolVKDesc, QueryP } Result DeviceVal::CreateAccelerationStructure(const AccelerationStructureVKDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure) { - RETURN_ON_FAILURE(this, accelerationStructureDesc.vkAccelerationStructure != 0, Result::INVALID_ARGUMENT, "CreateAccelerationStructure: 'accelerationStructureDesc.vkAccelerationStructure' is NULL"); + RETURN_ON_FAILURE(this, accelerationStructureDesc.vkAccelerationStructure != 0, Result::INVALID_ARGUMENT, "'accelerationStructureDesc.vkAccelerationStructure' is NULL"); AccelerationStructure* accelerationStructureImpl = nullptr; Result result = m_WrapperVKAPI.CreateAccelerationStructureVK(m_Device, accelerationStructureDesc, accelerationStructureImpl); @@ -890,7 +893,7 @@ Result DeviceVal::CreateAccelerationStructure(const AccelerationStructureVKDesc& #if NRI_USE_D3D11 Result DeviceVal::CreateCommandBuffer(const CommandBufferD3D11Desc& commandBufferDesc, CommandBuffer*& commandBuffer) { - RETURN_ON_FAILURE(this, commandBufferDesc.d3d11DeviceContext != nullptr, Result::INVALID_ARGUMENT, "CreateCommandBuffer: 'commandBufferDesc.d3d11DeviceContext' is NULL"); + RETURN_ON_FAILURE(this, commandBufferDesc.d3d11DeviceContext != nullptr, Result::INVALID_ARGUMENT, "'commandBufferDesc.d3d11DeviceContext' is NULL"); CommandBuffer* commandBufferImpl = nullptr; Result result = m_WrapperD3D11API.CreateCommandBufferD3D11(m_Device, commandBufferDesc, commandBufferImpl); @@ -902,7 +905,7 @@ Result DeviceVal::CreateCommandBuffer(const CommandBufferD3D11Desc& commandBuffe } Result DeviceVal::CreateBuffer(const BufferD3D11Desc& bufferDesc, Buffer*& buffer) { - RETURN_ON_FAILURE(this, bufferDesc.d3d11Resource != nullptr, Result::INVALID_ARGUMENT, "CreateBuffer: 'bufferDesc.d3d11Resource' is NULL"); + RETURN_ON_FAILURE(this, bufferDesc.d3d11Resource != nullptr, Result::INVALID_ARGUMENT, "'bufferDesc.d3d11Resource' is NULL"); Buffer* bufferImpl = nullptr; Result result = m_WrapperD3D11API.CreateBufferD3D11(m_Device, bufferDesc, bufferImpl); @@ -914,7 +917,7 @@ Result DeviceVal::CreateBuffer(const BufferD3D11Desc& bufferDesc, Buffer*& buffe } Result DeviceVal::CreateTexture(const TextureD3D11Desc& textureDesc, Texture*& texture) { - RETURN_ON_FAILURE(this, textureDesc.d3d11Resource != nullptr, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.d3d11Resource' is NULL"); + RETURN_ON_FAILURE(this, textureDesc.d3d11Resource != nullptr, Result::INVALID_ARGUMENT, "'textureDesc.d3d11Resource' is NULL"); Texture* textureImpl = nullptr; Result result = m_WrapperD3D11API.CreateTextureD3D11(m_Device, textureDesc, textureImpl); @@ -930,8 +933,8 @@ Result DeviceVal::CreateTexture(const TextureD3D11Desc& textureDesc, Texture*& t #if NRI_USE_D3D12 Result DeviceVal::CreateCommandBuffer(const CommandBufferD3D12Desc& commandBufferDesc, CommandBuffer*& commandBuffer) { - RETURN_ON_FAILURE(this, commandBufferDesc.d3d12CommandAllocator != nullptr, Result::INVALID_ARGUMENT, "CreateCommandBuffer: 'commandBufferDesc.d3d12CommandAllocator' is NULL"); - RETURN_ON_FAILURE(this, commandBufferDesc.d3d12CommandList != nullptr, Result::INVALID_ARGUMENT, "CreateCommandBuffer: 'commandBufferDesc.d3d12CommandList' is NULL"); + RETURN_ON_FAILURE(this, commandBufferDesc.d3d12CommandAllocator != nullptr, Result::INVALID_ARGUMENT, "'commandBufferDesc.d3d12CommandAllocator' is NULL"); + RETURN_ON_FAILURE(this, commandBufferDesc.d3d12CommandList != nullptr, Result::INVALID_ARGUMENT, "'commandBufferDesc.d3d12CommandList' is NULL"); CommandBuffer* commandBufferImpl = nullptr; Result result = m_WrapperD3D12API.CreateCommandBufferD3D12(m_Device, commandBufferDesc, commandBufferImpl); @@ -944,7 +947,7 @@ Result DeviceVal::CreateCommandBuffer(const CommandBufferD3D12Desc& commandBuffe Result DeviceVal::CreateDescriptorPool(const DescriptorPoolD3D12Desc& descriptorPoolD3D12Desc, DescriptorPool*& descriptorPool) { RETURN_ON_FAILURE(this, descriptorPoolD3D12Desc.d3d12ResourceDescriptorHeap || descriptorPoolD3D12Desc.d3d12SamplerDescriptorHeap, - Result::INVALID_ARGUMENT, "CreateDescriptorPool: 'descriptorPoolD3D12Desc.d3d12ResourceDescriptorHeap' and 'descriptorPoolD3D12Desc.d3d12ResourceDescriptorHeap' are both NULL"); + Result::INVALID_ARGUMENT, "'descriptorPoolD3D12Desc.d3d12ResourceDescriptorHeap' and 'descriptorPoolD3D12Desc.d3d12ResourceDescriptorHeap' are both NULL"); DescriptorPool* descriptorPoolImpl = nullptr; Result result = m_WrapperD3D12API.CreateDescriptorPoolD3D12(m_Device, descriptorPoolD3D12Desc, descriptorPoolImpl); @@ -956,7 +959,7 @@ Result DeviceVal::CreateDescriptorPool(const DescriptorPoolD3D12Desc& descriptor } Result DeviceVal::CreateBuffer(const BufferD3D12Desc& bufferDesc, Buffer*& buffer) { - RETURN_ON_FAILURE(this, bufferDesc.d3d12Resource != nullptr, Result::INVALID_ARGUMENT, "CreateBuffer: 'bufferDesc.d3d12Resource' is NULL"); + RETURN_ON_FAILURE(this, bufferDesc.d3d12Resource != nullptr, Result::INVALID_ARGUMENT, "'bufferDesc.d3d12Resource' is NULL"); Buffer* bufferImpl = nullptr; Result result = m_WrapperD3D12API.CreateBufferD3D12(m_Device, bufferDesc, bufferImpl); @@ -968,7 +971,7 @@ Result DeviceVal::CreateBuffer(const BufferD3D12Desc& bufferDesc, Buffer*& buffe } Result DeviceVal::CreateTexture(const TextureD3D12Desc& textureDesc, Texture*& texture) { - RETURN_ON_FAILURE(this, textureDesc.d3d12Resource != nullptr, Result::INVALID_ARGUMENT, "CreateTexture: 'textureDesc.d3d12Resource' is NULL"); + RETURN_ON_FAILURE(this, textureDesc.d3d12Resource != nullptr, Result::INVALID_ARGUMENT, "'textureDesc.d3d12Resource' is NULL"); Texture* textureImpl = nullptr; Result result = m_WrapperD3D12API.CreateTextureD3D12(m_Device, textureDesc, textureImpl); @@ -980,7 +983,7 @@ Result DeviceVal::CreateTexture(const TextureD3D12Desc& textureDesc, Texture*& t } Result DeviceVal::CreateMemory(const MemoryD3D12Desc& memoryDesc, Memory*& memory) { - RETURN_ON_FAILURE(this, memoryDesc.d3d12Heap != nullptr, Result::INVALID_ARGUMENT, "CreateMemory: 'memoryDesc.d3d12Heap' is NULL"); + RETURN_ON_FAILURE(this, memoryDesc.d3d12Heap != nullptr, Result::INVALID_ARGUMENT, "'memoryDesc.d3d12Heap' is NULL"); Memory* memoryImpl = nullptr; Result result = m_WrapperD3D12API.CreateMemoryD3D12(m_Device, memoryDesc, memoryImpl); @@ -994,7 +997,7 @@ Result DeviceVal::CreateMemory(const MemoryD3D12Desc& memoryDesc, Memory*& memor } Result DeviceVal::CreateAccelerationStructure(const AccelerationStructureD3D12Desc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure) { - RETURN_ON_FAILURE(this, accelerationStructureDesc.d3d12Resource != nullptr, Result::INVALID_ARGUMENT, "CreateAccelerationStructure: 'accelerationStructureDesc.d3d12Resource' is NULL"); + RETURN_ON_FAILURE(this, accelerationStructureDesc.d3d12Resource != nullptr, Result::INVALID_ARGUMENT, "'accelerationStructureDesc.d3d12Resource' is NULL"); AccelerationStructure* accelerationStructureImpl = nullptr; Result result = m_WrapperD3D12API.CreateAccelerationStructureD3D12(m_Device, accelerationStructureDesc, accelerationStructureImpl); @@ -1010,14 +1013,14 @@ Result DeviceVal::CreateAccelerationStructure(const AccelerationStructureD3D12De #endif uint32_t DeviceVal::CalculateAllocationNumber(const ResourceGroupDesc& resourceGroupDesc) const { - RETURN_ON_FAILURE(this, resourceGroupDesc.memoryLocation < MemoryLocation::MAX_NUM, 0, "CalculateAllocationNumber: 'resourceGroupDesc.memoryLocation' is invalid"); - RETURN_ON_FAILURE(this, resourceGroupDesc.bufferNum == 0 || resourceGroupDesc.buffers != nullptr, 0, "CalculateAllocationNumber: 'resourceGroupDesc.buffers' is NULL"); - RETURN_ON_FAILURE(this, resourceGroupDesc.textureNum == 0 || resourceGroupDesc.textures != nullptr, 0, "CalculateAllocationNumber: 'resourceGroupDesc.textures' is NULL"); + RETURN_ON_FAILURE(this, resourceGroupDesc.memoryLocation < MemoryLocation::MAX_NUM, 0, "'resourceGroupDesc.memoryLocation' is invalid"); + RETURN_ON_FAILURE(this, resourceGroupDesc.bufferNum == 0 || resourceGroupDesc.buffers != nullptr, 0, "'resourceGroupDesc.buffers' is NULL"); + RETURN_ON_FAILURE(this, resourceGroupDesc.textureNum == 0 || resourceGroupDesc.textures != nullptr, 0, "'resourceGroupDesc.textures' is NULL"); Buffer** buffersImpl = StackAlloc(Buffer*, resourceGroupDesc.bufferNum); for (uint32_t i = 0; i < resourceGroupDesc.bufferNum; i++) { - RETURN_ON_FAILURE(this, resourceGroupDesc.buffers[i] != nullptr, 0, "CalculateAllocationNumber: 'resourceGroupDesc.buffers[%u]' is NULL", i); + RETURN_ON_FAILURE(this, resourceGroupDesc.buffers[i] != nullptr, 0, "'resourceGroupDesc.buffers[%u]' is NULL", i); BufferVal& bufferVal = *(BufferVal*)resourceGroupDesc.buffers[i]; buffersImpl[i] = bufferVal.GetImpl(); @@ -1026,7 +1029,7 @@ uint32_t DeviceVal::CalculateAllocationNumber(const ResourceGroupDesc& resourceG Texture** texturesImpl = StackAlloc(Texture*, resourceGroupDesc.textureNum); for (uint32_t i = 0; i < resourceGroupDesc.textureNum; i++) { - RETURN_ON_FAILURE(this, resourceGroupDesc.textures[i] != nullptr, 0, "CalculateAllocationNumber: 'resourceGroupDesc.textures[%u]' is NULL", i); + RETURN_ON_FAILURE(this, resourceGroupDesc.textures[i] != nullptr, 0, "'resourceGroupDesc.textures[%u]' is NULL", i); TextureVal& textureVal = *(TextureVal*)resourceGroupDesc.textures[i]; texturesImpl[i] = textureVal.GetImpl(); @@ -1040,15 +1043,15 @@ uint32_t DeviceVal::CalculateAllocationNumber(const ResourceGroupDesc& resourceG } Result DeviceVal::AllocateAndBindMemory(const ResourceGroupDesc& resourceGroupDesc, Memory** allocations) { - RETURN_ON_FAILURE(this, allocations != nullptr, Result::INVALID_ARGUMENT, "AllocateAndBindMemory: 'allocations' is NULL"); - RETURN_ON_FAILURE(this, resourceGroupDesc.memoryLocation < MemoryLocation::MAX_NUM, Result::INVALID_ARGUMENT, "AllocateAndBindMemory: 'resourceGroupDesc.memoryLocation' is invalid"); - RETURN_ON_FAILURE(this, resourceGroupDesc.bufferNum == 0 || resourceGroupDesc.buffers != nullptr, Result::INVALID_ARGUMENT, "AllocateAndBindMemory: 'resourceGroupDesc.buffers' is NULL"); - RETURN_ON_FAILURE(this, resourceGroupDesc.textureNum == 0 || resourceGroupDesc.textures != nullptr, Result::INVALID_ARGUMENT, "AllocateAndBindMemory: 'resourceGroupDesc.textures' is NULL"); + RETURN_ON_FAILURE(this, allocations != nullptr, Result::INVALID_ARGUMENT, "'allocations' is NULL"); + RETURN_ON_FAILURE(this, resourceGroupDesc.memoryLocation < MemoryLocation::MAX_NUM, Result::INVALID_ARGUMENT, "'resourceGroupDesc.memoryLocation' is invalid"); + RETURN_ON_FAILURE(this, resourceGroupDesc.bufferNum == 0 || resourceGroupDesc.buffers != nullptr, Result::INVALID_ARGUMENT, "'resourceGroupDesc.buffers' is NULL"); + RETURN_ON_FAILURE(this, resourceGroupDesc.textureNum == 0 || resourceGroupDesc.textures != nullptr, Result::INVALID_ARGUMENT, "'resourceGroupDesc.textures' is NULL"); Buffer** buffersImpl = StackAlloc(Buffer*, resourceGroupDesc.bufferNum); for (uint32_t i = 0; i < resourceGroupDesc.bufferNum; i++) { - RETURN_ON_FAILURE(this, resourceGroupDesc.buffers[i] != nullptr, Result::INVALID_ARGUMENT, "AllocateAndBindMemory: 'resourceGroupDesc.buffers[%u]' is NULL", i); + RETURN_ON_FAILURE(this, resourceGroupDesc.buffers[i] != nullptr, Result::INVALID_ARGUMENT, "'resourceGroupDesc.buffers[%u]' is NULL", i); BufferVal& bufferVal = *(BufferVal*)resourceGroupDesc.buffers[i]; buffersImpl[i] = bufferVal.GetImpl(); @@ -1057,7 +1060,7 @@ Result DeviceVal::AllocateAndBindMemory(const ResourceGroupDesc& resourceGroupDe Texture** texturesImpl = StackAlloc(Texture*, resourceGroupDesc.textureNum); for (uint32_t i = 0; i < resourceGroupDesc.textureNum; i++) { - RETURN_ON_FAILURE(this, resourceGroupDesc.textures[i] != nullptr, Result::INVALID_ARGUMENT, "AllocateAndBindMemory: 'resourceGroupDesc.textures[%u]' is NULL", i); + RETURN_ON_FAILURE(this, resourceGroupDesc.textures[i] != nullptr, Result::INVALID_ARGUMENT, "'resourceGroupDesc.textures[%u]' is NULL", i); TextureVal& textureVal = *(TextureVal*)resourceGroupDesc.textures[i]; texturesImpl[i] = textureVal.GetImpl(); @@ -1094,21 +1097,21 @@ Result DeviceVal::QueryVideoMemoryInfo(MemoryLocation memoryLocation, VideoMemor } Result DeviceVal::CreatePipeline(const RayTracingPipelineDesc& pipelineDesc, Pipeline*& pipeline) { - RETURN_ON_FAILURE(this, pipelineDesc.pipelineLayout != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.pipelineLayout' is NULL"); - RETURN_ON_FAILURE(this, pipelineDesc.shaderLibrary != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.shaderLibrary' is NULL"); - RETURN_ON_FAILURE(this, pipelineDesc.shaderGroupDescs != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.shaderGroupDescs' is NULL"); - RETURN_ON_FAILURE(this, pipelineDesc.shaderGroupDescNum != 0, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.shaderGroupDescNum' is 0"); - RETURN_ON_FAILURE(this, pipelineDesc.recursionDepthMax != 0, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.recursionDepthMax' is 0"); + RETURN_ON_FAILURE(this, pipelineDesc.pipelineLayout != nullptr, Result::INVALID_ARGUMENT, "'pipelineDesc.pipelineLayout' is NULL"); + RETURN_ON_FAILURE(this, pipelineDesc.shaderLibrary != nullptr, Result::INVALID_ARGUMENT, "'pipelineDesc.shaderLibrary' is NULL"); + RETURN_ON_FAILURE(this, pipelineDesc.shaderGroupDescs != nullptr, Result::INVALID_ARGUMENT, "'pipelineDesc.shaderGroupDescs' is NULL"); + RETURN_ON_FAILURE(this, pipelineDesc.shaderGroupDescNum != 0, Result::INVALID_ARGUMENT, "'pipelineDesc.shaderGroupDescNum' is 0"); + RETURN_ON_FAILURE(this, pipelineDesc.recursionDepthMax != 0, Result::INVALID_ARGUMENT, "'pipelineDesc.recursionDepthMax' is 0"); uint32_t uniqueShaderStages = 0; for (uint32_t i = 0; i < pipelineDesc.shaderLibrary->shaderNum; i++) { const ShaderDesc& shaderDesc = pipelineDesc.shaderLibrary->shaders[i]; - RETURN_ON_FAILURE(this, shaderDesc.bytecode != nullptr, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.shaderLibrary->shaders[%u].bytecode' is invalid", i); + RETURN_ON_FAILURE(this, shaderDesc.bytecode != nullptr, Result::INVALID_ARGUMENT, "'pipelineDesc.shaderLibrary->shaders[%u].bytecode' is invalid", i); - RETURN_ON_FAILURE(this, shaderDesc.size != 0, Result::INVALID_ARGUMENT, "CreatePipeline: 'pipelineDesc.shaderLibrary->shaders[%u].size' is 0", i); + RETURN_ON_FAILURE(this, shaderDesc.size != 0, Result::INVALID_ARGUMENT, "'pipelineDesc.shaderLibrary->shaders[%u].size' is 0", i); RETURN_ON_FAILURE(this, IsShaderStageValid(shaderDesc.stage, uniqueShaderStages, StageBits::RAY_TRACING_SHADERS), Result::INVALID_ARGUMENT, - "CreatePipeline: 'pipelineDesc.shaderLibrary->shaders[%u].stage' must include only 1 ray tracing shader stage, unique for the entire pipeline", i); + "'pipelineDesc.shaderLibrary->shaders[%u].stage' must include only 1 ray tracing shader stage, unique for the entire pipeline", i); } auto pipelineDescImpl = pipelineDesc; @@ -1125,7 +1128,7 @@ Result DeviceVal::CreatePipeline(const RayTracingPipelineDesc& pipelineDesc, Pip Result DeviceVal::CreateAccelerationStructure(const AccelerationStructureDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure) { RETURN_ON_FAILURE(this, accelerationStructureDesc.instanceOrGeometryObjectNum != 0, Result::INVALID_ARGUMENT, - "CreateAccelerationStructure: 'accelerationStructureDesc.instanceOrGeometryObjectNum' is 0"); + "'accelerationStructureDesc.instanceOrGeometryObjectNum' is 0"); AccelerationStructureDesc accelerationStructureDescImpl = accelerationStructureDesc; @@ -1150,8 +1153,8 @@ Result DeviceVal::CreateAccelerationStructure(const AccelerationStructureDesc& a return result; } -Result DeviceVal::CreateAccelerationStructure(const AllocateAccelerationStructureDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure) { - RETURN_ON_FAILURE(this, accelerationStructureDesc.desc.instanceOrGeometryObjectNum != 0, Result::INVALID_ARGUMENT, "CreateAccelerationStructure: 'accelerationStructureDesc.instanceOrGeometryObjectNum' is 0"); +Result DeviceVal::AllocateAccelerationStructure(const AllocateAccelerationStructureDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure) { + RETURN_ON_FAILURE(this, accelerationStructureDesc.desc.instanceOrGeometryObjectNum != 0, Result::INVALID_ARGUMENT, "'accelerationStructureDesc.instanceOrGeometryObjectNum' is 0"); AllocateAccelerationStructureDesc accelerationStructureDescImpl = accelerationStructureDesc; @@ -1177,7 +1180,7 @@ Result DeviceVal::CreateAccelerationStructure(const AllocateAccelerationStructur } Result DeviceVal::BindAccelerationStructureMemory(const AccelerationStructureMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum) { - RETURN_ON_FAILURE(this, memoryBindingDescs != nullptr, Result::INVALID_ARGUMENT, "BindAccelerationStructureMemory: 'memoryBindingDescs' is NULL"); + RETURN_ON_FAILURE(this, memoryBindingDescs != nullptr, Result::INVALID_ARGUMENT, "'memoryBindingDescs' is NULL"); AccelerationStructureMemoryBindingDesc* memoryBindingDescsImpl = StackAlloc(AccelerationStructureMemoryBindingDesc, memoryBindingDescNum); for (uint32_t i = 0; i < memoryBindingDescNum; i++) { @@ -1188,15 +1191,15 @@ Result DeviceVal::BindAccelerationStructureMemory(const AccelerationStructureMem AccelerationStructureVal& accelerationStructure = (AccelerationStructureVal&)*srcDesc.accelerationStructure; const MemoryDesc& memoryDesc = accelerationStructure.GetMemoryDesc(); - RETURN_ON_FAILURE(this, !accelerationStructure.IsBoundToMemory(), Result::INVALID_ARGUMENT, "BindAccelerationStructureMemory: 'memoryBindingDescs[%u].accelerationStructure' is already bound to memory", i); - RETURN_ON_FAILURE(this, !memoryDesc.mustBeDedicated || srcDesc.offset == 0, Result::INVALID_ARGUMENT, "BindAccelerationStructureMemory: 'memoryBindingDescs[%u].offset' must be 0 for dedicated allocation", i); - RETURN_ON_FAILURE(this, memoryDesc.alignment != 0, Result::INVALID_ARGUMENT, "BindAccelerationStructureMemory: 'memoryBindingDescs[%u].alignment' is 0", i); - RETURN_ON_FAILURE(this, srcDesc.offset % memoryDesc.alignment == 0, Result::INVALID_ARGUMENT, "BindAccelerationStructureMemory: 'memoryBindingDescs[%u].offset' is misaligned", i); + RETURN_ON_FAILURE(this, !accelerationStructure.IsBoundToMemory(), Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].accelerationStructure' is already bound to memory", i); + RETURN_ON_FAILURE(this, !memoryDesc.mustBeDedicated || srcDesc.offset == 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' must be 0 for dedicated allocation", i); + RETURN_ON_FAILURE(this, memoryDesc.alignment != 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].alignment' is 0", i); + RETURN_ON_FAILURE(this, srcDesc.offset % memoryDesc.alignment == 0, Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' is misaligned", i); const uint64_t rangeMax = srcDesc.offset + memoryDesc.size; const bool memorySizeIsUnknown = memory.GetSize() == 0; - RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "BindAccelerationStructureMemory: 'memoryBindingDescs[%u].offset' is invalid", i); + RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "'memoryBindingDescs[%u].offset' is invalid", i); destDesc = srcDesc; destDesc.memory = memory.GetImpl(); diff --git a/Source/Validation/DeviceVal.h b/Source/Validation/DeviceVal.h index 88119434..57ef7d72 100644 --- a/Source/Validation/DeviceVal.h +++ b/Source/Validation/DeviceVal.h @@ -73,12 +73,12 @@ struct DeviceVal final : public DeviceBase { Result CreateMemory(const MemoryVKDesc& memoryVKDesc, Memory*& memory); Result CreateMemory(const MemoryD3D12Desc& memoryDesc, Memory*& memory); Result CreateBuffer(const BufferDesc& bufferDesc, Buffer*& buffer); - Result CreateBuffer(const AllocateBufferDesc& bufferDesc, Buffer*& buffer); + Result AllocateBuffer(const AllocateBufferDesc& bufferDesc, Buffer*& buffer); Result CreateBuffer(const BufferVKDesc& bufferDesc, Buffer*& buffer); Result CreateBuffer(const BufferD3D11Desc& bufferDesc, Buffer*& buffer); Result CreateBuffer(const BufferD3D12Desc& bufferDesc, Buffer*& buffer); Result CreateTexture(const TextureDesc& textureDesc, Texture*& texture); - Result CreateTexture(const AllocateTextureDesc& textureDesc, Texture*& texture); + Result AllocateTexture(const AllocateTextureDesc& textureDesc, Texture*& texture); Result CreateTexture(const TextureVKDesc& textureVKDesc, Texture*& texture); Result CreateTexture(const TextureD3D11Desc& textureDesc, Texture*& texture); Result CreateTexture(const TextureD3D12Desc& textureDesc, Texture*& texture); @@ -106,7 +106,7 @@ struct DeviceVal final : public DeviceBase { Result CreateCommandAllocator(const CommandQueue& commandQueue, CommandAllocator*& commandAllocator); Result CreateCommandAllocator(const CommandAllocatorVKDesc& commandAllocatorDesc, CommandAllocator*& commandAllocator); Result CreateAccelerationStructure(const AccelerationStructureDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure); - Result CreateAccelerationStructure(const AllocateAccelerationStructureDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure); + Result AllocateAccelerationStructure(const AllocateAccelerationStructureDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure); Result CreateAccelerationStructure(const AccelerationStructureVKDesc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure); Result CreateAccelerationStructure(const AccelerationStructureD3D12Desc& accelerationStructureDesc, AccelerationStructure*& accelerationStructure); diff --git a/Source/Validation/DeviceVal.hpp b/Source/Validation/DeviceVal.hpp index 16b6991b..c7793d57 100644 --- a/Source/Validation/DeviceVal.hpp +++ b/Source/Validation/DeviceVal.hpp @@ -343,15 +343,15 @@ Result DeviceVal::FillFunctionTable(RayTracingInterface& table) const { #pragma region[ ResourceAllocator ] static Result AllocateBuffer(Device& device, const AllocateBufferDesc& bufferDesc, Buffer*& buffer) { - return ((DeviceVal&)device).CreateBuffer(bufferDesc, buffer); + return ((DeviceVal&)device).AllocateBuffer(bufferDesc, buffer); } static Result AllocateTexture(Device& device, const AllocateTextureDesc& textureDesc, Texture*& texture) { - return ((DeviceVal&)device).CreateTexture(textureDesc, texture); + return ((DeviceVal&)device).AllocateTexture(textureDesc, texture); } static Result AllocateAccelerationStructure(Device& device, const AllocateAccelerationStructureDesc& acelerationStructureDesc, AccelerationStructure*& accelerationStructure) { - return ((DeviceVal&)device).CreateAccelerationStructure(acelerationStructureDesc, accelerationStructure); + return ((DeviceVal&)device).AllocateAccelerationStructure(acelerationStructureDesc, accelerationStructure); } Result DeviceVal::FillFunctionTable(ResourceAllocatorInterface& table) const { @@ -379,7 +379,7 @@ static Result CreateStreamer(Device& device, const StreamerDesc& streamerDesc, S DeviceVal& deviceVal = (DeviceVal&)device; bool isUpload = (streamerDesc.constantBufferMemoryLocation == MemoryLocation::HOST_UPLOAD || streamerDesc.constantBufferMemoryLocation == MemoryLocation::DEVICE_UPLOAD) && (streamerDesc.dynamicBufferMemoryLocation == MemoryLocation::HOST_UPLOAD || streamerDesc.dynamicBufferMemoryLocation == MemoryLocation::DEVICE_UPLOAD); - RETURN_ON_FAILURE(&deviceVal, isUpload, Result::INVALID_ARGUMENT, "CreateStreamer: memory location must be an UPLOAD heap"); + RETURN_ON_FAILURE(&deviceVal, isUpload, Result::INVALID_ARGUMENT, "memory location must be an UPLOAD heap"); Streamer* impl = nullptr; Result result = deviceVal.GetStreamerInterface().CreateStreamer(deviceVal.GetImpl(), streamerDesc, impl); diff --git a/Source/Validation/SharedVal.h b/Source/Validation/SharedVal.h index 4f8263ae..d96c469f 100644 --- a/Source/Validation/SharedVal.h +++ b/Source/Validation/SharedVal.h @@ -122,10 +122,10 @@ constexpr bool IsAccessMaskSupported(BufferUsageBits usageMask, AccessBits acces if (accessMask & AccessBits::COLOR_ATTACHMENT) return false; - if (accessMask & AccessBits::DEPTH_STENCIL_WRITE) + if (accessMask & AccessBits::DEPTH_STENCIL_ATTACHMENT_WRITE) return false; - if (accessMask & AccessBits::DEPTH_STENCIL_READ) + if (accessMask & AccessBits::DEPTH_STENCIL_ATTACHMENT_READ) return false; if (accessMask & AccessBits::ACCELERATION_STRUCTURE_READ) @@ -134,6 +134,9 @@ constexpr bool IsAccessMaskSupported(BufferUsageBits usageMask, AccessBits acces if (accessMask & AccessBits::ACCELERATION_STRUCTURE_WRITE) return false; + if (accessMask & AccessBits::SHADING_RATE_ATTACHMENT) + return false; + return (uint32_t)(requiredUsageMask & usageMask) == (uint32_t)requiredUsageMask; } @@ -161,12 +164,15 @@ constexpr bool IsAccessMaskSupported(TextureUsageBits usageMask, AccessBits acce if (accessMask & AccessBits::COLOR_ATTACHMENT) requiredUsageMask |= TextureUsageBits::COLOR_ATTACHMENT; - if (accessMask & AccessBits::DEPTH_STENCIL_WRITE) + if (accessMask & AccessBits::DEPTH_STENCIL_ATTACHMENT_WRITE) requiredUsageMask |= TextureUsageBits::DEPTH_STENCIL_ATTACHMENT; - if (accessMask & AccessBits::DEPTH_STENCIL_READ) + if (accessMask & AccessBits::DEPTH_STENCIL_ATTACHMENT_READ) requiredUsageMask |= TextureUsageBits::DEPTH_STENCIL_ATTACHMENT; + if (accessMask & AccessBits::SHADING_RATE_ATTACHMENT) + requiredUsageMask |= TextureUsageBits::SHADING_RATE_ATTACHMENT; + if (accessMask & AccessBits::ACCELERATION_STRUCTURE_READ) return false; @@ -179,13 +185,14 @@ constexpr bool IsAccessMaskSupported(TextureUsageBits usageMask, AccessBits acce constexpr std::array TEXTURE_USAGE_FOR_TEXTURE_LAYOUT_TABLE = { TextureUsageBits::NONE, // UNKNOWN TextureUsageBits::COLOR_ATTACHMENT, // COLOR_ATTACHMENT - TextureUsageBits::DEPTH_STENCIL_ATTACHMENT, // DEPTH_STENCIL + TextureUsageBits::DEPTH_STENCIL_ATTACHMENT, // DEPTH_STENCIL_ATTACHMENT TextureUsageBits::DEPTH_STENCIL_ATTACHMENT, // DEPTH_STENCIL_READONLY TextureUsageBits::SHADER_RESOURCE, // SHADER_RESOURCE TextureUsageBits::SHADER_RESOURCE_STORAGE, // SHADER_RESOURCE_STORAGE TextureUsageBits::NONE, // COPY_SOURCE TextureUsageBits::NONE, // COPY_DESTINATION TextureUsageBits::NONE, // PRESENT + TextureUsageBits::SHADING_RATE_ATTACHMENT, // SHADING_RATE_ATTACHMENT }; constexpr bool IsTextureLayoutSupported(TextureUsageBits usageMask, Layout textureLayout) {