mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-15 03:41:34 +00:00
We now always use Tint. Bug: dawn:571 Change-Id: Ic65669a9e00493292ed60cde00af6fa3f6e55ec2 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65665 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com>
180 lines
7.0 KiB
C++
180 lines
7.0 KiB
C++
// Copyright 2020 The Dawn Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "common/Math.h"
|
|
#include "tests/DawnTest.h"
|
|
|
|
#include "utils/WGPUHelpers.h"
|
|
|
|
class ShaderFloat16Tests : public DawnTest {
|
|
protected:
|
|
std::vector<const char*> GetRequiredFeatures() override {
|
|
mIsShaderFloat16Supported = SupportsFeatures({"shader-float16"});
|
|
if (!mIsShaderFloat16Supported) {
|
|
return {};
|
|
}
|
|
|
|
return {"shader-float16"};
|
|
}
|
|
|
|
bool IsShaderFloat16Supported() const {
|
|
return mIsShaderFloat16Supported;
|
|
}
|
|
|
|
bool mIsShaderFloat16Supported = false;
|
|
};
|
|
|
|
// Test basic 16bit float arithmetic and 16bit storage features.
|
|
// TODO(crbug.com/tint/404): Implement float16 in Tint.
|
|
TEST_P(ShaderFloat16Tests, DISABLED_Basic16BitFloatFeaturesTest) {
|
|
DAWN_TEST_UNSUPPORTED_IF(!IsShaderFloat16Supported());
|
|
DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsIntel()); // Flaky crashes. crbug.com/dawn/586
|
|
|
|
uint16_t uniformData[] = {Float32ToFloat16(1.23), Float32ToFloat16(0.0)}; // 0.0 is a padding.
|
|
wgpu::Buffer uniformBuffer = utils::CreateBufferFromData(
|
|
device, &uniformData, sizeof(uniformData), wgpu::BufferUsage::Uniform);
|
|
|
|
uint16_t bufferInData[] = {Float32ToFloat16(2.34), Float32ToFloat16(0.0)}; // 0.0 is a padding.
|
|
wgpu::Buffer bufferIn = utils::CreateBufferFromData(device, &bufferInData, sizeof(bufferInData),
|
|
wgpu::BufferUsage::Storage);
|
|
|
|
wgpu::BufferDescriptor bufferDesc;
|
|
bufferDesc.size = 2 * sizeof(uint16_t);
|
|
bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
|
|
wgpu::Buffer bufferOut = device.CreateBuffer(&bufferDesc);
|
|
|
|
// SPIR-V ASM produced by glslang for the following fragment shader:
|
|
//
|
|
// #version 450
|
|
// #extension GL_AMD_gpu_shader_half_float : require
|
|
//
|
|
// struct S {
|
|
// float16_t f;
|
|
// float16_t padding;
|
|
// };
|
|
// layout(std140, set = 0, binding = 0) uniform uniformBuf { S c; };
|
|
// layout(std140, set = 0, binding = 1) readonly buffer bufA { S a; };
|
|
// layout(std140, set = 0, binding = 2) buffer bufB { S b; };
|
|
//
|
|
// void main() {
|
|
// b.f = a.f + c.f;
|
|
// }
|
|
|
|
wgpu::ShaderModule module = utils::CreateShaderModuleFromASM(device, R"(
|
|
; SPIR-V
|
|
; Version: 1.0
|
|
; Generator: Khronos Glslang Reference Front End; 10
|
|
; Bound: 26
|
|
; Schema: 0
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpCapability UniformAndStorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 1 1
|
|
OpSource GLSL 450
|
|
OpSourceExtension "GL_AMD_gpu_shader_half_float"
|
|
OpName %main "main"
|
|
OpName %S "S"
|
|
OpMemberName %S 0 "f"
|
|
OpMemberName %S 1 "padding"
|
|
OpName %bufB "bufB"
|
|
OpMemberName %bufB 0 "b"
|
|
OpName %_ ""
|
|
OpName %bufA "bufA"
|
|
OpMemberName %bufA 0 "a"
|
|
OpName %__0 ""
|
|
OpName %uniformBuf "uniformBuf"
|
|
OpMemberName %uniformBuf 0 "c"
|
|
OpName %__1 ""
|
|
OpMemberDecorate %S 0 Offset 0
|
|
OpMemberDecorate %S 1 Offset 2
|
|
OpMemberDecorate %bufB 0 Offset 0
|
|
OpDecorate %bufB BufferBlock
|
|
OpDecorate %_ DescriptorSet 0
|
|
OpDecorate %_ Binding 2
|
|
OpMemberDecorate %bufA 0 NonWritable
|
|
OpMemberDecorate %bufA 0 Offset 0
|
|
OpDecorate %bufA BufferBlock
|
|
OpDecorate %__0 DescriptorSet 0
|
|
OpDecorate %__0 Binding 1
|
|
OpMemberDecorate %uniformBuf 0 Offset 0
|
|
OpDecorate %uniformBuf Block
|
|
OpDecorate %__1 DescriptorSet 0
|
|
OpDecorate %__1 Binding 0
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%half = OpTypeFloat 16
|
|
%S = OpTypeStruct %half %half
|
|
%bufB = OpTypeStruct %S
|
|
%_ptr_Uniform_bufB = OpTypePointer Uniform %bufB
|
|
%_ = OpVariable %_ptr_Uniform_bufB Uniform
|
|
%int = OpTypeInt 32 1
|
|
%int_0 = OpConstant %int 0
|
|
%bufA = OpTypeStruct %S
|
|
%_ptr_Uniform_bufA = OpTypePointer Uniform %bufA
|
|
%__0 = OpVariable %_ptr_Uniform_bufA Uniform
|
|
%_ptr_Uniform_half = OpTypePointer Uniform %half
|
|
%uniformBuf = OpTypeStruct %S
|
|
%_ptr_Uniform_uniformBuf = OpTypePointer Uniform %uniformBuf
|
|
%__1 = OpVariable %_ptr_Uniform_uniformBuf Uniform
|
|
%main = OpFunction %void None %3
|
|
%5 = OpLabel
|
|
%17 = OpAccessChain %_ptr_Uniform_half %__0 %int_0 %int_0
|
|
%18 = OpLoad %half %17
|
|
%22 = OpAccessChain %_ptr_Uniform_half %__1 %int_0 %int_0
|
|
%23 = OpLoad %half %22
|
|
%24 = OpFAdd %half %18 %23
|
|
%25 = OpAccessChain %_ptr_Uniform_half %_ %int_0 %int_0
|
|
OpStore %25 %24
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)");
|
|
|
|
wgpu::ComputePipelineDescriptor csDesc;
|
|
csDesc.compute.module = module;
|
|
csDesc.compute.entryPoint = "main";
|
|
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);
|
|
|
|
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
|
{
|
|
{0, uniformBuffer, 0, sizeof(uniformData)},
|
|
{1, bufferIn, 0, sizeof(bufferInData)},
|
|
{2, bufferOut},
|
|
});
|
|
|
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
|
pass.SetPipeline(pipeline);
|
|
pass.SetBindGroup(0, bindGroup);
|
|
pass.Dispatch(1);
|
|
pass.EndPass();
|
|
wgpu::CommandBuffer commands = encoder.Finish();
|
|
queue.Submit(1, &commands);
|
|
|
|
uint16_t expected[] = {Float32ToFloat16(3.57), Float32ToFloat16(0.0)}; // 0.0 is a padding.
|
|
|
|
EXPECT_BUFFER_U16_RANGE_EQ(expected, bufferOut, 0, 2);
|
|
}
|
|
|
|
DAWN_INSTANTIATE_TEST(ShaderFloat16Tests,
|
|
D3D12Backend(),
|
|
MetalBackend(),
|
|
OpenGLBackend(),
|
|
OpenGLESBackend(),
|
|
VulkanBackend());
|