mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 07:23:35 +00:00
working on d3d11 backend
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HLSL_SOURCE(...) #__VA_ARGS__
|
||||
|
||||
void DebugCallBack(PulseDebugMessageSeverity severity, const char* message)
|
||||
{
|
||||
@@ -18,12 +21,42 @@ void DebugCallBack(PulseDebugMessageSeverity severity, const char* message)
|
||||
|
||||
#define BUFFER_SIZE (256 * sizeof(uint32_t))
|
||||
|
||||
const char* hlsl_source = HLSL_SOURCE(
|
||||
RWStructuredBuffer<int> ssbo : register(u0);
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
void CSMain(uint3 grid : SV_DispatchThreadID)
|
||||
{
|
||||
ssbo[grid.x * grid.y] = (int)(grid.x * grid.y);
|
||||
}
|
||||
);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
PulseBackend backend = PulseLoadBackend(PULSE_BACKEND_D3D11, PULSE_SHADER_FORMAT_DXBC_BIT, PULSE_HIGH_DEBUG);
|
||||
PulseBackend backend = PulseLoadBackend(PULSE_BACKEND_D3D11, PULSE_SHADER_FORMAT_HLSL_BIT, PULSE_HIGH_DEBUG);
|
||||
PulseSetDebugCallback(backend, DebugCallBack);
|
||||
PulseDevice device = PulseCreateDevice(backend, NULL, 0);
|
||||
|
||||
PulseBufferCreateInfo buffer_create_info = { 0 };
|
||||
buffer_create_info.size = BUFFER_SIZE;
|
||||
buffer_create_info.usage = PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE | PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD;
|
||||
PulseBuffer buffer = PulseCreateBuffer(device, &buffer_create_info);
|
||||
|
||||
// GPU computations
|
||||
{
|
||||
PulseComputePipelineCreateInfo info = { 0 };
|
||||
info.code_size = strlen(hlsl_source);
|
||||
info.code = (const uint8_t*)hlsl_source;
|
||||
info.entrypoint = "CSMain";
|
||||
info.format = PULSE_SHADER_FORMAT_HLSL_BIT;
|
||||
info.num_readwrite_storage_buffers = 1;
|
||||
PulseComputePipeline pipeline = PulseCreateComputePipeline(device, &info);
|
||||
|
||||
PulseDestroyComputePipeline(device, pipeline);
|
||||
}
|
||||
|
||||
PulseDestroyBuffer(device, buffer);
|
||||
|
||||
PulseDestroyDevice(device);
|
||||
PulseUnloadBackend(backend);
|
||||
puts("Successfully executed Pulse example using D3D11 !");
|
||||
|
||||
@@ -77,6 +77,7 @@ typedef enum PulseShaderFormatsBits
|
||||
PULSE_SHADER_FORMAT_WGSL_BIT = PULSE_BIT(4), // Can be used by WebGPU backend
|
||||
PULSE_SHADER_FORMAT_GLSL_BIT = PULSE_BIT(5), // Can be used by OpenGL / OpenGL_ES backend
|
||||
PULSE_SHADER_FORMAT_DXBC_BIT = PULSE_BIT(6), // Can be used by D3D11 backend
|
||||
PULSE_SHADER_FORMAT_HLSL_BIT = PULSE_BIT(7), // Can be used by D3D11 backend
|
||||
// More to come
|
||||
} PulseShaderFormatsBits;
|
||||
typedef PulseFlags PulseShaderFormatsFlags;
|
||||
@@ -270,7 +271,7 @@ PULSE_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderF
|
||||
PULSE_API void PulseDestroyDevice(PulseDevice device);
|
||||
|
||||
PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
|
||||
PULSE_API bool PulseMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data);
|
||||
PULSE_API bool PulseMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data); // Data writing may only apply when unmapping
|
||||
PULSE_API void PulseUnmapBuffer(PulseBuffer buffer);
|
||||
PULSE_API bool PulseCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst);
|
||||
PULSE_API bool PulseCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst);
|
||||
|
||||
@@ -8,11 +8,14 @@
|
||||
#include "D3D11.h"
|
||||
#include "D3D11Device.h"
|
||||
|
||||
#pragma comment(lib,"d3d11.lib")
|
||||
#pragma comment(lib,"d3dcompiler.lib")
|
||||
|
||||
PulseBackendFlags Direct3D11CheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used)
|
||||
{
|
||||
if(candidates != PULSE_BACKEND_ANY && (candidates & PULSE_BACKEND_D3D11) == 0)
|
||||
return PULSE_BACKEND_INVALID;
|
||||
if((shader_formats_used & PULSE_SHADER_FORMAT_DXBC_BIT) == 0)
|
||||
if((shader_formats_used & PULSE_SHADER_FORMAT_DXBC_BIT) == 0 && (shader_formats_used & PULSE_SHADER_FORMAT_HLSL_BIT) == 0)
|
||||
return PULSE_BACKEND_INVALID;
|
||||
return PULSE_BACKEND_D3D11;
|
||||
}
|
||||
@@ -28,11 +31,58 @@ void Direct3D11UnloadBackend(PulseBackend backend)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef D3D11_ERROR_FILE_NOT_FOUND
|
||||
#define D3D11_ERROR_FILE_NOT_FOUND 0x887C0002
|
||||
#endif
|
||||
|
||||
#ifndef D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS
|
||||
#define D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS 0x887C0001
|
||||
#endif
|
||||
|
||||
#ifndef D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS
|
||||
#define D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS 0x887C0003
|
||||
#endif
|
||||
|
||||
#ifndef D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD
|
||||
#define D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD 0x887C0004
|
||||
#endif
|
||||
|
||||
#ifndef D3DERR_INVALIDCALL
|
||||
#define D3DERR_INVALIDCALL 0x887A0001
|
||||
#endif
|
||||
|
||||
#ifndef D3DERR_WASSTILLDRAWING
|
||||
#define D3DERR_WASSTILLDRAWING 0x887A000A
|
||||
#endif
|
||||
|
||||
const char* D3D11VerbaliseResult(HRESULT res)
|
||||
{
|
||||
switch(res)
|
||||
{
|
||||
case S_OK:
|
||||
case S_FALSE: return "success";
|
||||
|
||||
case D3D11_ERROR_FILE_NOT_FOUND: return "a file was not found";
|
||||
case D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS: return "too many instances of a particular state objects";
|
||||
case D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS: return "too many instances of a particular view objects";
|
||||
case D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD: return "deffered context mapped without initial discard";
|
||||
case D3DERR_INVALIDCALL: return "invalid call";
|
||||
case D3DERR_WASSTILLDRAWING: return "was still drawing";
|
||||
case E_FAIL: return "attempted to create a device with the debug layer enabled and the layer is not installed";
|
||||
case E_INVALIDARG: return "an invalid parameter was passed to the returning function";
|
||||
case E_OUTOFMEMORY: return "could not allocate sufficient memory to complete the call";
|
||||
case E_NOTIMPL: return "method call isn't implemented with the passed parameter combination";
|
||||
|
||||
default: return "Unknown D3D11 error";
|
||||
}
|
||||
return "Unknown D3D11 error"; // Just to avoid warnings
|
||||
}
|
||||
|
||||
PulseBackendHandler D3D11Driver = {
|
||||
.PFN_LoadBackend = Direct3D11LoadBackend,
|
||||
.PFN_UnloadBackend = Direct3D11UnloadBackend,
|
||||
.PFN_CreateDevice = Direct3D11CreateDevice,
|
||||
.backend = PULSE_BACKEND_D3D11,
|
||||
.supported_shader_formats = PULSE_SHADER_FORMAT_DXBC_BIT,
|
||||
.supported_shader_formats = PULSE_SHADER_FORMAT_DXBC_BIT | PULSE_SHADER_FORMAT_HLSL_BIT,
|
||||
.driver_data = PULSE_NULLPTR
|
||||
};
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#ifndef PULSE_D3D11_H_
|
||||
#define PULSE_D3D11_H_
|
||||
|
||||
#define D3D11_NO_HELPERS
|
||||
#define CINTERFACE
|
||||
#define COBJMACROS
|
||||
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
#include <initguid.h>
|
||||
#endif
|
||||
@@ -20,6 +24,21 @@
|
||||
|
||||
#define D3D11_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data)
|
||||
|
||||
#define CHECK_D3D11_RETVAL(backend, res, error, retval) \
|
||||
do { \
|
||||
if((res) != S_OK && (res) != S_FALSE) \
|
||||
{ \
|
||||
if(backend != PULSE_NULL_HANDLE && PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(backend)) \
|
||||
PulseLogErrorFmt(backend, "(D3D11) call to a D3D11 function failed due to %s", D3D11VerbaliseResult(res)); \
|
||||
PulseSetInternalError(error); \
|
||||
return retval; \
|
||||
} \
|
||||
} while(0) \
|
||||
|
||||
#define CHECK_D3D11(backend, res, error) CHECK_D3D11_RETVAL(backend, res, error, )
|
||||
|
||||
const char* D3D11VerbaliseResult(HRESULT res);
|
||||
|
||||
PulseBackendFlags Direct3D11CheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Returns corresponding PULSE_BACKEND enum in case of success and PULSE_BACKEND_INVALID otherwise
|
||||
|
||||
#endif // PULSE_D3D11_H_
|
||||
|
||||
@@ -2,18 +2,40 @@
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <Pulse.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../PulseInternal.h"
|
||||
#include "D3D11.h"
|
||||
#include "D3D11Device.h"
|
||||
#include "D3D11Buffer.h"
|
||||
#include "D3D11CommandList.h"
|
||||
|
||||
PulseBuffer Direct3D11CreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos)
|
||||
{
|
||||
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(device, Direct3D11Device*);
|
||||
|
||||
PulseBuffer buffer = (PulseBuffer)calloc(1, sizeof(PulseBufferHandler));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(buffer, PULSE_NULL_HANDLE);
|
||||
|
||||
Direct3D11Buffer* d3d11_buffer = (Direct3D11Buffer*)calloc(1, sizeof(Direct3D11Buffer));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(d3d11_buffer, PULSE_NULL_HANDLE);
|
||||
|
||||
buffer->device = device;
|
||||
buffer->driver_data = d3d11_buffer;
|
||||
buffer->size = create_infos->size;
|
||||
buffer->usage = create_infos->usage;
|
||||
|
||||
D3D11_BUFFER_DESC description = { 0 };
|
||||
description.ByteWidth = create_infos->size;
|
||||
description.Usage = D3D11_USAGE_DEFAULT;
|
||||
if(create_infos->usage & (PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE))
|
||||
{
|
||||
description.BindFlags |= D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
|
||||
description.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
|
||||
}
|
||||
|
||||
CHECK_D3D11_RETVAL(device->backend, ID3D11Device_CreateBuffer(d3d11_device->device, &description, PULSE_NULLPTR, &d3d11_buffer->buffer), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULL_HANDLE);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -38,4 +60,8 @@ bool Direct3D11CopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion*
|
||||
|
||||
void Direct3D11DestroyBuffer(PulseDevice device, PulseBuffer buffer)
|
||||
{
|
||||
Direct3D11Buffer* d3d11_buffer = D3D11_RETRIEVE_DRIVER_DATA_AS(buffer, Direct3D11Buffer*);
|
||||
ID3D11Buffer_Release(d3d11_buffer->buffer);
|
||||
free(d3d11_buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
typedef struct Direct3D11Buffer
|
||||
{
|
||||
int dummy;
|
||||
ID3D11Buffer* buffer;
|
||||
} Direct3D11Buffer;
|
||||
|
||||
PulseBuffer Direct3D11CreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
|
||||
|
||||
@@ -8,10 +8,71 @@
|
||||
#include "D3D11Device.h"
|
||||
#include "D3D11ComputePipeline.h"
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
#include <string.h>
|
||||
|
||||
static HRESULT CompileComputeShader(PulseDevice device, const unsigned char* src, uint32_t src_size, const char* entry_point, ID3DBlob** blob)
|
||||
{
|
||||
if(!src || !entry_point || !device || !blob)
|
||||
return E_INVALIDARG;
|
||||
|
||||
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(device, Direct3D11Device*);
|
||||
*blob = PULSE_NULLPTR;
|
||||
|
||||
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||
flags |= D3DCOMPILE_DEBUG;
|
||||
|
||||
// We generally prefer to use the higher CS shader profile when possible as CS 5.0 is better performance on 11-class hardware
|
||||
LPCSTR profile = (ID3D11Device_GetFeatureLevel(d3d11_device->device) >= D3D_FEATURE_LEVEL_11_0) ? "cs_5_0" : "cs_4_0";
|
||||
|
||||
ID3DBlob* shader_blob = PULSE_NULLPTR;
|
||||
ID3DBlob* error_blob = PULSE_NULLPTR;
|
||||
HRESULT hr = D3DCompile(src, src_size, PULSE_NULLPTR, PULSE_NULLPTR, PULSE_NULLPTR, entry_point, profile, flags, 0, &shader_blob, &error_blob);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(error_blob)
|
||||
{
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
PulseLogInfoFmt(device->backend, "(D3D11) failed to compile HLSL shader. %s", ID3D10Blob_GetBufferPointer(error_blob));
|
||||
ID3D10Blob_Release(error_blob);
|
||||
}
|
||||
if(shader_blob)
|
||||
ID3D10Blob_Release(shader_blob);
|
||||
return hr;
|
||||
}
|
||||
|
||||
*blob = shader_blob;
|
||||
return hr;
|
||||
}
|
||||
|
||||
PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info)
|
||||
{
|
||||
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(device, Direct3D11Device*);
|
||||
|
||||
PulseComputePipelineHandler* pipeline = (PulseComputePipelineHandler*)calloc(1, sizeof(PulseComputePipelineHandler));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(pipeline, PULSE_NULL_HANDLE);
|
||||
|
||||
Direct3D11ComputePipeline* d3d11_pipeline = (Direct3D11ComputePipeline*)calloc(1, sizeof(Direct3D11ComputePipeline));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(d3d11_pipeline, PULSE_NULL_HANDLE);
|
||||
|
||||
pipeline->driver_data = d3d11_pipeline;
|
||||
|
||||
ID3D10Blob* blob = PULSE_NULLPTR;
|
||||
if(info->format & PULSE_SHADER_FORMAT_HLSL_BIT)
|
||||
CHECK_D3D11_RETVAL(device->backend, CompileComputeShader(device, info->code, info->code_size, info->entrypoint, &blob), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULL_HANDLE);
|
||||
|
||||
if(blob == PULSE_NULLPTR)
|
||||
{
|
||||
D3DCreateBlob(info->code_size, &blob);
|
||||
memcpy(ID3D10Blob_GetBufferPointer(blob), (void*)info->code, info->code_size);
|
||||
}
|
||||
|
||||
CHECK_D3D11_RETVAL(device->backend, ID3D11Device_CreateComputeShader(d3d11_device->device, ID3D10Blob_GetBufferPointer(blob), ID3D10Blob_GetBufferSize(blob), PULSE_NULLPTR, &d3d11_pipeline->shader), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULL_HANDLE);;
|
||||
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||
PulseLogInfoFmt(device->backend, "(D3D11) created new compute pipeline %p", pipeline);
|
||||
return pipeline;
|
||||
@@ -19,4 +80,16 @@ PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const P
|
||||
|
||||
void Direct3D11DestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline)
|
||||
{
|
||||
if(pipeline == PULSE_NULL_HANDLE)
|
||||
{
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
PulseLogWarning(device->backend, "compute pipeline is NULL, this may be a bug in your application");
|
||||
return;
|
||||
}
|
||||
Direct3D11ComputePipeline* d3d11_pipeline = D3D11_RETRIEVE_DRIVER_DATA_AS(pipeline, Direct3D11ComputePipeline*);
|
||||
ID3D11ComputeShader_Release(d3d11_pipeline->shader);
|
||||
free(d3d11_pipeline);
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||
PulseLogInfoFmt(device->backend, "(D3D11) destroyed compute pipeline %p", pipeline);
|
||||
free(pipeline);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
typedef struct Direct3D11ComputePipeline
|
||||
{
|
||||
int dummy;
|
||||
ID3D11ComputeShader* shader;
|
||||
} Direct3D11ComputePipeline;
|
||||
|
||||
PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);
|
||||
|
||||
@@ -35,7 +35,7 @@ bool Direct3D11IsDedicatedAdapter(IDXGIAdapter1* adapter)
|
||||
static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
adapter->lpVtbl->GetDesc1(adapter, &desc);
|
||||
IDXGIAdapter1_GetDesc1(adapter, &desc);
|
||||
|
||||
D3D_FEATURE_LEVEL feature_levels[] = {
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
@@ -58,10 +58,19 @@ static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
||||
if(FAILED(hr))
|
||||
return 0;
|
||||
|
||||
hr = base_device->lpVtbl->QueryInterface(base_device, &IID_ID3D11Device1, (void**)&d3d_device1);
|
||||
hr = ID3D11Device_QueryInterface(base_device, &IID_ID3D11Device1, (void**)&d3d_device1);
|
||||
if(FAILED(hr) || out_feature_level < D3D_FEATURE_LEVEL_10_0)
|
||||
goto Cleanup;
|
||||
|
||||
// Verify compute shader support presence
|
||||
if(ID3D11Device_GetFeatureLevel(base_device) < D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts = { 0 };
|
||||
ID3D11Device_CheckFeatureSupport(base_device, D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts));
|
||||
if(!hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x)
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if(Direct3D11IsDedicatedAdapter(adapter))
|
||||
score += 50000;
|
||||
else if(!(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE))
|
||||
@@ -77,9 +86,9 @@ static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
||||
|
||||
Cleanup:
|
||||
if(base_device)
|
||||
base_device->lpVtbl->Release(base_device);
|
||||
ID3D11Device_Release(base_device);
|
||||
if(base_context)
|
||||
base_context->lpVtbl->Release(base_context);
|
||||
ID3D11DeviceContext_Release(base_context);
|
||||
return score;
|
||||
}
|
||||
|
||||
@@ -90,11 +99,11 @@ static bool Direct3D11IsAdapterForbidden(IDXGIAdapter1* adapter, PulseDevice* fo
|
||||
for(uint32_t i = 0; i < forbiden_devices_count; i++)
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc1;
|
||||
adapter->lpVtbl->GetDesc1(adapter, &desc1);
|
||||
IDXGIAdapter1_GetDesc1(adapter, &desc1);
|
||||
|
||||
DXGI_ADAPTER_DESC1 desc2;
|
||||
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(forbiden_devices[i], Direct3D11Device*);
|
||||
d3d11_device->adapter->lpVtbl->GetDesc1(d3d11_device->adapter, &desc2);
|
||||
IDXGIAdapter1_GetDesc1(d3d11_device->adapter, &desc2);
|
||||
|
||||
if(desc1.AdapterLuid.HighPart == desc2.AdapterLuid.HighPart && desc1.AdapterLuid.LowPart == desc2.AdapterLuid.LowPart)
|
||||
return true;
|
||||
@@ -118,9 +127,9 @@ static IDXGIAdapter1* Direct3D11SelectAdapter(IDXGIFactory1* factory, PulseDevic
|
||||
best_device_score = current_device_score;
|
||||
best_device_id = i;
|
||||
}
|
||||
adapter->lpVtbl->Release(adapter);
|
||||
IDXGIAdapter1_Release(adapter);
|
||||
}
|
||||
if(factory->lpVtbl->EnumAdapters1(factory, best_device_id, &adapter) == DXGI_ERROR_NOT_FOUND)
|
||||
if(IDXGIFactory1_EnumAdapters1(factory, best_device_id, &adapter) == DXGI_ERROR_NOT_FOUND)
|
||||
return PULSE_NULLPTR;
|
||||
return adapter;
|
||||
}
|
||||
@@ -141,7 +150,7 @@ PulseDevice Direct3D11CreateDevice(PulseBackend backend, PulseDevice* forbiden_d
|
||||
CreateDXGIFactory1(&IID_IDXGIFactory, (void**)&device->factory);
|
||||
|
||||
device->adapter = Direct3D11SelectAdapter(device->factory, forbiden_devices, forbiden_devices_count);
|
||||
device->adapter->lpVtbl->GetDesc1(device->adapter, &device->description);
|
||||
IDXGIAdapter1_GetDesc1(device->adapter, &device->description);
|
||||
|
||||
D3D_FEATURE_LEVEL feature_levels[] = {
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
@@ -150,7 +159,11 @@ PulseDevice Direct3D11CreateDevice(PulseBackend backend, PulseDevice* forbiden_d
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
};
|
||||
|
||||
D3D11CreateDevice((IDXGIAdapter*)device->adapter, D3D_DRIVER_TYPE_UNKNOWN, PULSE_NULLPTR, 0, feature_levels, PULSE_SIZEOF_ARRAY(feature_levels), D3D11_SDK_VERSION, &device->device, PULSE_NULLPTR, &device->context);
|
||||
UINT flags = 0;
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend))
|
||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
|
||||
D3D11CreateDevice((IDXGIAdapter*)device->adapter, D3D_DRIVER_TYPE_UNKNOWN, PULSE_NULLPTR, flags, feature_levels, PULSE_SIZEOF_ARRAY(feature_levels), D3D11_SDK_VERSION, &device->device, PULSE_NULLPTR, &device->context);
|
||||
PULSE_LOAD_DRIVER_DEVICE(Direct3D11);
|
||||
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend))
|
||||
@@ -163,10 +176,10 @@ void Direct3D11DestroyDevice(PulseDevice device)
|
||||
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(device, Direct3D11Device*);
|
||||
if(d3d11_device == PULSE_NULLPTR || d3d11_device->device == PULSE_NULLPTR)
|
||||
return;
|
||||
d3d11_device->device->lpVtbl->Release(d3d11_device->device);
|
||||
d3d11_device->context->lpVtbl->Release(d3d11_device->context);
|
||||
d3d11_device->adapter->lpVtbl->Release(d3d11_device->adapter);
|
||||
d3d11_device->factory->lpVtbl->Release(d3d11_device->factory);
|
||||
ID3D11Device_Release(d3d11_device->device);
|
||||
ID3D11DeviceContext_Release(d3d11_device->context);
|
||||
IDXGIAdapter1_Release(d3d11_device->adapter);
|
||||
IDXGIFactory1_Release(d3d11_device->factory);
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||
PulseLogInfoFmt(device->backend, "(D3D11) destroyed device created from %ls", d3d11_device->description.Description);
|
||||
free(d3d11_device);
|
||||
|
||||
@@ -24,16 +24,6 @@ PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const Pulse
|
||||
|
||||
pipeline->driver_data = opengl_pipeline;
|
||||
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
{
|
||||
if(info->code == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->entrypoint == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->format == PULSE_SHADER_FORMAT_WGSL_BIT && (device->backend->supported_shader_formats & PULSE_SHADER_FORMAT_WGSL_BIT) == 0)
|
||||
PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo");
|
||||
}
|
||||
|
||||
uint8_t* code = (uint8_t*)calloc(info->code_size + 1, 1);
|
||||
memcpy(code, info->code, info->code_size);
|
||||
|
||||
|
||||
@@ -119,16 +119,6 @@ PulseComputePipeline SoftCreateComputePipeline(PulseDevice device, const PulseCo
|
||||
SoftComputePipeline* soft_pipeline = (SoftComputePipeline*)calloc(1, sizeof(SoftComputePipeline));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(soft_pipeline, PULSE_NULL_HANDLE);
|
||||
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
{
|
||||
if(info->code == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->entrypoint == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->format == PULSE_SHADER_FORMAT_SPIRV_BIT && (device->backend->supported_shader_formats & PULSE_SHADER_FORMAT_SPIRV_BIT) == 0)
|
||||
PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo");
|
||||
}
|
||||
|
||||
soft_pipeline->program = spvm_program_create(soft_device->spv_context, (spvm_source)info->code, info->code_size / sizeof(spvm_word));
|
||||
soft_pipeline->entry_point = calloc(1, strlen(info->entrypoint));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(soft_pipeline->entry_point, PULSE_NULL_HANDLE);
|
||||
|
||||
@@ -19,16 +19,6 @@ PulseComputePipeline VulkanCreateComputePipeline(PulseDevice device, const Pulse
|
||||
|
||||
pipeline->driver_data = vulkan_pipeline;
|
||||
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
{
|
||||
if(info->code == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->entrypoint == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->format == PULSE_SHADER_FORMAT_SPIRV_BIT && (device->backend->supported_shader_formats & PULSE_SHADER_FORMAT_SPIRV_BIT) == 0)
|
||||
PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo");
|
||||
}
|
||||
|
||||
VkShaderModuleCreateInfo shader_module_create_info = { 0 };
|
||||
shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
shader_module_create_info.codeSize = info->code_size;
|
||||
|
||||
@@ -335,16 +335,6 @@ PulseComputePipeline WebGPUCreateComputePipeline(PulseDevice device, const Pulse
|
||||
|
||||
pipeline->driver_data = webgpu_pipeline;
|
||||
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
{
|
||||
if(info->code == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->entrypoint == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->format == PULSE_SHADER_FORMAT_WGSL_BIT && (device->backend->supported_shader_formats & PULSE_SHADER_FORMAT_WGSL_BIT) == 0)
|
||||
PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo");
|
||||
}
|
||||
|
||||
WGPUShaderSourceWGSL source = { 0 };
|
||||
source.chain.next = PULSE_NULLPTR;
|
||||
source.chain.sType = WGPUSType_ShaderSourceWGSL;
|
||||
|
||||
@@ -11,6 +11,15 @@ PULSE_API PulseComputePipeline PulseCreateComputePipeline(PulseDevice device, co
|
||||
if(info == PULSE_NULLPTR && PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
PulseLogError(device->backend, "null infos pointer");
|
||||
PULSE_CHECK_PTR_RETVAL(info, PULSE_NULL_HANDLE);
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
{
|
||||
if(info->code == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo");
|
||||
if(info->entrypoint == PULSE_NULLPTR)
|
||||
PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo");
|
||||
if((info->format & device->backend->supported_shader_formats) == 0)
|
||||
PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo");
|
||||
}
|
||||
PulseComputePipeline pipeline = device->PFN_CreateComputePipeline(device, info);
|
||||
if(pipeline == PULSE_NULL_HANDLE)
|
||||
return PULSE_NULL_HANDLE;
|
||||
|
||||
@@ -15,6 +15,27 @@ void TestDeviceSetup()
|
||||
CleanupPulse(backend);
|
||||
}
|
||||
|
||||
void TestMultipleDevices()
|
||||
{
|
||||
PulseBackend backend;
|
||||
SetupPulse(&backend);
|
||||
|
||||
#define DEVICES_COUNT 10
|
||||
|
||||
PulseDevice devices[DEVICES_COUNT];
|
||||
for(int i = 0; i < DEVICES_COUNT; i++)
|
||||
{
|
||||
devices[i] = PulseCreateDevice(backend, NULL, 0);
|
||||
TEST_ASSERT_NOT_EQUAL_MESSAGE(devices[i], PULSE_NULL_HANDLE, PulseVerbaliseErrorType(PulseGetLastErrorType()));
|
||||
}
|
||||
|
||||
for(int i = 0; i < DEVICES_COUNT; i++)
|
||||
PulseDestroyDevice(devices[i]);
|
||||
|
||||
#undef DEVICES_COUNT
|
||||
CleanupPulse(backend);
|
||||
}
|
||||
|
||||
void TestForbiddenDeviceSetup()
|
||||
{
|
||||
PulseBackend backend;
|
||||
@@ -78,6 +99,7 @@ void TestDevice()
|
||||
RUN_TEST(TestDeviceSetup);
|
||||
RUN_TEST(TestForbiddenDeviceSetup);
|
||||
RUN_TEST(TestInvalidBackendDeviceSetup);
|
||||
RUN_TEST(TestMultipleDevices);
|
||||
RUN_TEST(TestBackendInUse);
|
||||
RUN_TEST(TestShaderFormatSupport);
|
||||
}
|
||||
|
||||
@@ -35,12 +35,7 @@ local backends = {
|
||||
option = "d3d11",
|
||||
default = is_plat("windows", "msys", "mingw"),
|
||||
custom = function()
|
||||
if is_plat("linux") then
|
||||
add_sysincludedirs("/usr/include/dxvk/")
|
||||
add_syslinks("dxvk_d3d11", "dxvk_dxgi")
|
||||
else
|
||||
add_syslinks("d3d11", "dxgi", "windowscodecs")
|
||||
end
|
||||
add_syslinks("d3d11", "d3dcompiler_47", "dxgi", "windowscodecs")
|
||||
end
|
||||
},
|
||||
Software = {
|
||||
|
||||
Reference in New Issue
Block a user