Path: blob/21.2-virgl/src/microsoft/clc/compute_test.h
4560 views
/*1* Copyright © Microsoft Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <stdio.h>24#include <stdint.h>25#include <stdexcept>2627#include <directx/d3d12.h>28#include <dxgi1_4.h>29#include <gtest/gtest.h>30#include <wrl.h>3132#include "clc_compiler.h"3334using std::runtime_error;35using Microsoft::WRL::ComPtr;3637inline D3D12_CPU_DESCRIPTOR_HANDLE38offset_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle, UINT offset)39{40handle.ptr += offset;41return handle;42}4344inline size_t45align(size_t value, unsigned alignment)46{47assert(alignment > 0);48return ((value + (alignment - 1)) / alignment) * alignment;49}5051class ComputeTest : public ::testing::Test {52protected:53struct Shader {54std::shared_ptr<struct clc_object> obj;55std::shared_ptr<struct clc_dxil_object> dxil;56};5758static void59enable_d3d12_debug_layer();6061static IDXGIFactory4 *62get_dxgi_factory();6364static IDXGIAdapter1 *65choose_adapter(IDXGIFactory4 *factory);6667static ID3D12Device *68create_device(IDXGIAdapter1 *adapter);6970struct Resources {71void add(ComPtr<ID3D12Resource> res,72D3D12_DESCRIPTOR_RANGE_TYPE type,73unsigned spaceid,74unsigned resid)75{76descs.push_back(res);7778if(!ranges.empty() &&79ranges.back().RangeType == type &&80ranges.back().RegisterSpace == spaceid &&81ranges.back().BaseShaderRegister + ranges.back().NumDescriptors == resid) {82ranges.back().NumDescriptors++;83return;84}8586D3D12_DESCRIPTOR_RANGE1 range;8788range.RangeType = type;89range.NumDescriptors = 1;90range.BaseShaderRegister = resid;91range.RegisterSpace = spaceid;92range.OffsetInDescriptorsFromTableStart = descs.size() - 1;93range.Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS;94ranges.push_back(range);95}9697std::vector<D3D12_DESCRIPTOR_RANGE1> ranges;98std::vector<ComPtr<ID3D12Resource>> descs;99};100101ComPtr<ID3D12RootSignature>102create_root_signature(const Resources &resources);103104ComPtr<ID3D12PipelineState>105create_pipeline_state(ComPtr<ID3D12RootSignature> &root_sig,106const struct clc_dxil_object &dxil);107108ComPtr<ID3D12Resource>109create_buffer(int size, D3D12_HEAP_TYPE heap_type);110111ComPtr<ID3D12Resource>112create_upload_buffer_with_data(const void *data, size_t size);113114ComPtr<ID3D12Resource>115create_sized_buffer_with_data(size_t buffer_size, const void *data,116size_t data_size);117118ComPtr<ID3D12Resource>119create_buffer_with_data(const void *data, size_t size)120{121return create_sized_buffer_with_data(size, data, size);122}123124void125get_buffer_data(ComPtr<ID3D12Resource> res,126void *buf, size_t size);127128void129resource_barrier(ComPtr<ID3D12Resource> &res,130D3D12_RESOURCE_STATES state_before,131D3D12_RESOURCE_STATES state_after);132133void134execute_cmdlist();135136void137create_uav_buffer(ComPtr<ID3D12Resource> res,138size_t width, size_t byte_stride,139D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle);140141void create_cbv(ComPtr<ID3D12Resource> res, size_t size,142D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle);143144ComPtr<ID3D12Resource>145add_uav_resource(Resources &resources, unsigned spaceid, unsigned resid,146const void *data = NULL, size_t num_elems = 0,147size_t elem_size = 0);148149ComPtr<ID3D12Resource>150add_cbv_resource(Resources &resources, unsigned spaceid, unsigned resid,151const void *data, size_t size);152153void154SetUp() override;155156void157TearDown() override;158159Shader160compile(const std::vector<const char *> &sources,161const std::vector<const char *> &compile_args = {},162bool create_library = false);163164Shader165link(const std::vector<Shader> &sources,166bool create_library = false);167168void169configure(Shader &shader,170const struct clc_runtime_kernel_conf *conf);171172void173validate(Shader &shader);174175enum ShaderArgDirection {176SHADER_ARG_INPUT = 1,177SHADER_ARG_OUTPUT = 2,178SHADER_ARG_INOUT = SHADER_ARG_INPUT | SHADER_ARG_OUTPUT,179};180181class RawShaderArg {182public:183RawShaderArg(enum ShaderArgDirection dir) : dir(dir) { }184virtual size_t get_elem_size() const = 0;185virtual size_t get_num_elems() const = 0;186virtual const void *get_data() const = 0;187virtual void *get_data() = 0;188enum ShaderArgDirection get_direction() { return dir; }189private:190enum ShaderArgDirection dir;191};192193class NullShaderArg : public RawShaderArg {194public:195NullShaderArg() : RawShaderArg(SHADER_ARG_INPUT) { }196size_t get_elem_size() const override { return 0; }197size_t get_num_elems() const override { return 0; }198const void *get_data() const override { return NULL; }199void *get_data() override { return NULL; }200};201202template <typename T>203class ShaderArg : public std::vector<T>, public RawShaderArg204{205public:206ShaderArg(const T &v, enum ShaderArgDirection dir = SHADER_ARG_INOUT) :207std::vector<T>({ v }), RawShaderArg(dir) { }208ShaderArg(const std::vector<T> &v, enum ShaderArgDirection dir = SHADER_ARG_INOUT) :209std::vector<T>(v), RawShaderArg(dir) { }210ShaderArg(const std::initializer_list<T> v, enum ShaderArgDirection dir = SHADER_ARG_INOUT) :211std::vector<T>(v), RawShaderArg(dir) { }212213ShaderArg<T>& operator =(const T &v)214{215this->clear();216this->push_back(v);217return *this;218}219220operator T&() { return this->at(0); }221operator const T&() const { return this->at(0); }222223ShaderArg<T>& operator =(const std::vector<T> &v)224{225*this = v;226return *this;227}228229ShaderArg<T>& operator =(std::initializer_list<T> v)230{231*this = v;232return *this;233}234235size_t get_elem_size() const override { return sizeof(T); }236size_t get_num_elems() const override { return this->size(); }237const void *get_data() const override { return this->data(); }238void *get_data() override { return this->data(); }239};240241struct CompileArgs242{243unsigned x, y, z;244std::vector<const char *> compiler_command_line;245clc_work_properties_data work_props;246};247248private:249void gather_args(std::vector<RawShaderArg *> &args) { }250251template <typename T, typename... Rest>252void gather_args(std::vector<RawShaderArg *> &args, T &arg, Rest&... rest)253{254args.push_back(&arg);255gather_args(args, rest...);256}257258void run_shader_with_raw_args(Shader shader,259const CompileArgs &compile_args,260const std::vector<RawShaderArg *> &args);261262protected:263template <typename... Args>264void run_shader(Shader shader,265const CompileArgs &compile_args,266Args&... args)267{268std::vector<RawShaderArg *> raw_args;269gather_args(raw_args, args...);270run_shader_with_raw_args(shader, compile_args, raw_args);271}272273template <typename... Args>274void run_shader(const std::vector<const char *> &sources,275unsigned x, unsigned y, unsigned z,276Args&... args)277{278std::vector<RawShaderArg *> raw_args;279gather_args(raw_args, args...);280CompileArgs compile_args = { x, y, z };281run_shader_with_raw_args(compile(sources), compile_args, raw_args);282}283284template <typename... Args>285void run_shader(const std::vector<const char *> &sources,286const CompileArgs &compile_args,287Args&... args)288{289std::vector<RawShaderArg *> raw_args;290gather_args(raw_args, args...);291run_shader_with_raw_args(292compile(sources, compile_args.compiler_command_line),293compile_args, raw_args);294}295296template <typename... Args>297void run_shader(const char *source,298unsigned x, unsigned y, unsigned z,299Args&... args)300{301std::vector<RawShaderArg *> raw_args;302gather_args(raw_args, args...);303CompileArgs compile_args = { x, y, z };304run_shader_with_raw_args(compile({ source }), compile_args, raw_args);305}306307IDXGIFactory4 *factory;308IDXGIAdapter1 *adapter;309ID3D12Device *dev;310ID3D12Fence *cmdqueue_fence;311ID3D12CommandQueue *cmdqueue;312ID3D12CommandAllocator *cmdalloc;313ID3D12GraphicsCommandList *cmdlist;314ID3D12DescriptorHeap *uav_heap;315316struct clc_context *compiler_ctx;317318UINT uav_heap_incr;319int fence_value;320321HANDLE event;322static PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature;323};324325326