diff options
Diffstat (limited to 'src/d3d11/gpu.h')
-rw-r--r-- | src/d3d11/gpu.h | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/d3d11/gpu.h b/src/d3d11/gpu.h new file mode 100644 index 0000000..cbc706a --- /dev/null +++ b/src/d3d11/gpu.h @@ -0,0 +1,212 @@ +/* + * This file is part of libplacebo. + * + * libplacebo is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libplacebo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <stdalign.h> +#include <d3d11_4.h> +#include <dxgi1_6.h> +#include <d3dcompiler.h> +#include <spirv_cross_c.h> + +#include "../gpu.h" +#include "../glsl/spirv.h" + +#include "common.h" +#include "utils.h" + +pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx); + +// --- pl_gpu internal structs and helpers + +// Size of one constant in a constant buffer +#define CBUF_ELEM (sizeof(float[4])) + +struct d3d_stream_buf { + UINT bind_flags; + ID3D11Buffer *buf; + size_t size; + size_t used; + unsigned int align; +}; + +struct pl_gpu_d3d11 { + struct pl_gpu_fns impl; + struct d3d11_ctx *ctx; + ID3D11Device *dev; + ID3D11Device1 *dev1; + ID3D11Device5 *dev5; + ID3D11DeviceContext *imm; + ID3D11DeviceContext1 *imm1; + ID3D11DeviceContext4 *imm4; + + // The Direct3D 11 minor version number + int minor; + + pl_spirv spirv; + + pD3DCompile D3DCompile; + struct dll_version d3d_compiler_ver; + + // Device capabilities + D3D_FEATURE_LEVEL fl; + bool has_timestamp_queries; + bool has_monitored_fences; + + int max_srvs; + int max_uavs; + + // Streaming vertex and index buffers + struct d3d_stream_buf vbuf; + struct d3d_stream_buf ibuf; + + // Shared rasterizer state + ID3D11RasterizerState *rstate; + + // Shared depth-stencil state + ID3D11DepthStencilState *dsstate; + + // Array of ID3D11SamplerStates for every combination of sample/address modes + ID3D11SamplerState *samplers[PL_TEX_SAMPLE_MODE_COUNT][PL_TEX_ADDRESS_MODE_COUNT]; + + // Resources for finish() + ID3D11Fence *finish_fence; + uint64_t finish_value; + HANDLE finish_event; + ID3D11Query *finish_query; + pl_buf finish_buf_src; + pl_buf finish_buf_dst; +}; + +void pl_d3d11_setup_formats(struct pl_gpu_t *gpu); + +void pl_d3d11_timer_start(pl_gpu gpu, pl_timer timer); +void pl_d3d11_timer_end(pl_gpu gpu, pl_timer timer); + +struct pl_buf_d3d11 { + ID3D11Buffer *buf; + ID3D11Buffer *staging; + ID3D11ShaderResourceView *raw_srv; + ID3D11UnorderedAccessView *raw_uav; + ID3D11ShaderResourceView *texel_srv; + ID3D11UnorderedAccessView *texel_uav; + + char *data; + bool dirty; +}; + +void pl_d3d11_buf_destroy(pl_gpu gpu, pl_buf buf); +pl_buf pl_d3d11_buf_create(pl_gpu gpu, const struct pl_buf_params *params); +void pl_d3d11_buf_write(pl_gpu gpu, pl_buf buf, size_t offset, const void *data, + size_t size); +bool pl_d3d11_buf_read(pl_gpu gpu, pl_buf buf, size_t offset, void *dest, + size_t size); +void pl_d3d11_buf_copy(pl_gpu gpu, pl_buf dst, size_t dst_offset, pl_buf src, + size_t src_offset, size_t size); + +// Ensure a buffer is up-to-date with its system memory mirror before it is used +void pl_d3d11_buf_resolve(pl_gpu gpu, pl_buf buf); + +struct pl_tex_d3d11 { + // res mirrors one of tex1d, tex2d or tex3d for convenience. It does not + // hold an additional reference to the texture object. + ID3D11Resource *res; + + ID3D11Texture1D *tex1d; + ID3D11Texture2D *tex2d; + ID3D11Texture3D *tex3d; + int array_slice; + + // Mirrors one of staging1d, staging2d, or staging3d, and doesn't hold a ref + ID3D11Resource *staging; + + // Staging textures for pl_tex_download + ID3D11Texture1D *staging1d; + ID3D11Texture2D *staging2d; + ID3D11Texture3D *staging3d; + + ID3D11ShaderResourceView *srv; + ID3D11RenderTargetView *rtv; + ID3D11UnorderedAccessView *uav; + + // for tex_upload/download fallback code + pl_fmt texel_fmt; +}; + +void pl_d3d11_tex_destroy(pl_gpu gpu, pl_tex tex); +pl_tex pl_d3d11_tex_create(pl_gpu gpu, const struct pl_tex_params *params); +void pl_d3d11_tex_invalidate(pl_gpu gpu, pl_tex tex); +void pl_d3d11_tex_clear_ex(pl_gpu gpu, pl_tex tex, + const union pl_clear_color color); +void pl_d3d11_tex_blit(pl_gpu gpu, const struct pl_tex_blit_params *params); +bool pl_d3d11_tex_upload(pl_gpu gpu, const struct pl_tex_transfer_params *params); +bool pl_d3d11_tex_download(pl_gpu gpu, const struct pl_tex_transfer_params *params); + +// Constant buffer layout used for gl_NumWorkGroups emulation +struct d3d_num_workgroups_buf { + alignas(CBUF_ELEM) uint32_t num_wgs[3]; +}; + +enum { + HLSL_BINDING_NOT_USED = -1, // Slot should always be bound as NULL + HLSL_BINDING_NUM_WORKGROUPS = -2, // Slot used for gl_NumWorkGroups emulation +}; + +// Represents a specific shader stage in a pl_pass (VS, PS, CS) +struct d3d_pass_stage { + // Lists for each resource type, to simplify binding in pl_pass_run. Indexes + // match the index of the arrays passed to the ID3D11DeviceContext methods. + // Entries are the index of pass->params.descriptors which should be bound + // in that position, or a HLSL_BINDING_* special value. + PL_ARRAY(int) cbvs; + PL_ARRAY(int) srvs; + PL_ARRAY(int) samplers; +}; + +struct pl_pass_d3d11 { + ID3D11PixelShader *ps; + ID3D11VertexShader *vs; + ID3D11ComputeShader *cs; + ID3D11InputLayout *layout; + ID3D11BlendState *bstate; + + // gl_NumWorkGroups emulation + struct d3d_num_workgroups_buf last_num_wgs; + ID3D11Buffer *num_workgroups_buf; + bool num_workgroups_used; + + // Maximum binding number + int max_binding; + + struct d3d_pass_stage main; // PS and CS + struct d3d_pass_stage vertex; + + // List of resources, as in `struct pass_stage`, except UAVs are shared + // between all shader stages + PL_ARRAY(int) uavs; + + // Pre-allocated resource arrays to use in pl_pass_run + ID3D11Buffer **cbv_arr; + ID3D11ShaderResourceView **srv_arr; + ID3D11SamplerState **sampler_arr; + ID3D11UnorderedAccessView **uav_arr; +}; + +void pl_d3d11_pass_destroy(pl_gpu gpu, pl_pass pass); +const struct pl_pass_t *pl_d3d11_pass_create(pl_gpu gpu, + const struct pl_pass_params *params); +void pl_d3d11_pass_run(pl_gpu gpu, const struct pl_pass_run_params *params); |