mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 15:33:34 +00:00
working on d3d11 backend
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define HLSL_SOURCE(...) #__VA_ARGS__
|
||||||
|
|
||||||
void DebugCallBack(PulseDebugMessageSeverity severity, const char* message)
|
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))
|
#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)
|
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);
|
PulseSetDebugCallback(backend, DebugCallBack);
|
||||||
PulseDevice device = PulseCreateDevice(backend, NULL, 0);
|
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);
|
PulseDestroyDevice(device);
|
||||||
PulseUnloadBackend(backend);
|
PulseUnloadBackend(backend);
|
||||||
puts("Successfully executed Pulse example using D3D11 !");
|
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_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_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_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
|
// More to come
|
||||||
} PulseShaderFormatsBits;
|
} PulseShaderFormatsBits;
|
||||||
typedef PulseFlags PulseShaderFormatsFlags;
|
typedef PulseFlags PulseShaderFormatsFlags;
|
||||||
@@ -270,7 +271,7 @@ PULSE_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderF
|
|||||||
PULSE_API void PulseDestroyDevice(PulseDevice device);
|
PULSE_API void PulseDestroyDevice(PulseDevice device);
|
||||||
|
|
||||||
PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
|
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 void PulseUnmapBuffer(PulseBuffer buffer);
|
||||||
PULSE_API bool PulseCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst);
|
PULSE_API bool PulseCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst);
|
||||||
PULSE_API bool PulseCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst);
|
PULSE_API bool PulseCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst);
|
||||||
|
|||||||
@@ -8,11 +8,14 @@
|
|||||||
#include "D3D11.h"
|
#include "D3D11.h"
|
||||||
#include "D3D11Device.h"
|
#include "D3D11Device.h"
|
||||||
|
|
||||||
|
#pragma comment(lib,"d3d11.lib")
|
||||||
|
#pragma comment(lib,"d3dcompiler.lib")
|
||||||
|
|
||||||
PulseBackendFlags Direct3D11CheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used)
|
PulseBackendFlags Direct3D11CheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used)
|
||||||
{
|
{
|
||||||
if(candidates != PULSE_BACKEND_ANY && (candidates & PULSE_BACKEND_D3D11) == 0)
|
if(candidates != PULSE_BACKEND_ANY && (candidates & PULSE_BACKEND_D3D11) == 0)
|
||||||
return PULSE_BACKEND_INVALID;
|
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_INVALID;
|
||||||
return PULSE_BACKEND_D3D11;
|
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 = {
|
PulseBackendHandler D3D11Driver = {
|
||||||
.PFN_LoadBackend = Direct3D11LoadBackend,
|
.PFN_LoadBackend = Direct3D11LoadBackend,
|
||||||
.PFN_UnloadBackend = Direct3D11UnloadBackend,
|
.PFN_UnloadBackend = Direct3D11UnloadBackend,
|
||||||
.PFN_CreateDevice = Direct3D11CreateDevice,
|
.PFN_CreateDevice = Direct3D11CreateDevice,
|
||||||
.backend = PULSE_BACKEND_D3D11,
|
.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
|
.driver_data = PULSE_NULLPTR
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
#ifndef PULSE_D3D11_H_
|
#ifndef PULSE_D3D11_H_
|
||||||
#define PULSE_D3D11_H_
|
#define PULSE_D3D11_H_
|
||||||
|
|
||||||
|
#define D3D11_NO_HELPERS
|
||||||
|
#define CINTERFACE
|
||||||
|
#define COBJMACROS
|
||||||
|
|
||||||
#ifdef PULSE_PLAT_WINDOWS
|
#ifdef PULSE_PLAT_WINDOWS
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -20,6 +24,21 @@
|
|||||||
|
|
||||||
#define D3D11_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data)
|
#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
|
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_
|
#endif // PULSE_D3D11_H_
|
||||||
|
|||||||
@@ -2,18 +2,40 @@
|
|||||||
// This file is part of "Pulse"
|
// This file is part of "Pulse"
|
||||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <Pulse.h>
|
#include <Pulse.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "../../PulseInternal.h"
|
#include "../../PulseInternal.h"
|
||||||
#include "D3D11.h"
|
#include "D3D11.h"
|
||||||
|
#include "D3D11Device.h"
|
||||||
#include "D3D11Buffer.h"
|
#include "D3D11Buffer.h"
|
||||||
#include "D3D11CommandList.h"
|
#include "D3D11CommandList.h"
|
||||||
|
|
||||||
PulseBuffer Direct3D11CreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos)
|
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));
|
PulseBuffer buffer = (PulseBuffer)calloc(1, sizeof(PulseBufferHandler));
|
||||||
PULSE_CHECK_ALLOCATION_RETVAL(buffer, PULSE_NULL_HANDLE);
|
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;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,4 +60,8 @@ bool Direct3D11CopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion*
|
|||||||
|
|
||||||
void Direct3D11DestroyBuffer(PulseDevice device, PulseBuffer buffer)
|
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
|
typedef struct Direct3D11Buffer
|
||||||
{
|
{
|
||||||
int dummy;
|
ID3D11Buffer* buffer;
|
||||||
} Direct3D11Buffer;
|
} Direct3D11Buffer;
|
||||||
|
|
||||||
PulseBuffer Direct3D11CreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
|
PulseBuffer Direct3D11CreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
|
||||||
|
|||||||
@@ -8,10 +8,71 @@
|
|||||||
#include "D3D11Device.h"
|
#include "D3D11Device.h"
|
||||||
#include "D3D11ComputePipeline.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)
|
PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info)
|
||||||
{
|
{
|
||||||
|
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(device, Direct3D11Device*);
|
||||||
|
|
||||||
PulseComputePipelineHandler* pipeline = (PulseComputePipelineHandler*)calloc(1, sizeof(PulseComputePipelineHandler));
|
PulseComputePipelineHandler* pipeline = (PulseComputePipelineHandler*)calloc(1, sizeof(PulseComputePipelineHandler));
|
||||||
PULSE_CHECK_ALLOCATION_RETVAL(pipeline, PULSE_NULL_HANDLE);
|
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))
|
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||||
PulseLogInfoFmt(device->backend, "(D3D11) created new compute pipeline %p", pipeline);
|
PulseLogInfoFmt(device->backend, "(D3D11) created new compute pipeline %p", pipeline);
|
||||||
return pipeline;
|
return pipeline;
|
||||||
@@ -19,4 +80,16 @@ PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const P
|
|||||||
|
|
||||||
void Direct3D11DestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline)
|
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
|
typedef struct Direct3D11ComputePipeline
|
||||||
{
|
{
|
||||||
int dummy;
|
ID3D11ComputeShader* shader;
|
||||||
} Direct3D11ComputePipeline;
|
} Direct3D11ComputePipeline;
|
||||||
|
|
||||||
PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);
|
PulseComputePipeline Direct3D11CreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ bool Direct3D11IsDedicatedAdapter(IDXGIAdapter1* adapter)
|
|||||||
static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
||||||
{
|
{
|
||||||
DXGI_ADAPTER_DESC1 desc;
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
adapter->lpVtbl->GetDesc1(adapter, &desc);
|
IDXGIAdapter1_GetDesc1(adapter, &desc);
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL feature_levels[] = {
|
D3D_FEATURE_LEVEL feature_levels[] = {
|
||||||
D3D_FEATURE_LEVEL_11_1,
|
D3D_FEATURE_LEVEL_11_1,
|
||||||
@@ -58,10 +58,19 @@ static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
|||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
return 0;
|
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)
|
if(FAILED(hr) || out_feature_level < D3D_FEATURE_LEVEL_10_0)
|
||||||
goto Cleanup;
|
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))
|
if(Direct3D11IsDedicatedAdapter(adapter))
|
||||||
score += 50000;
|
score += 50000;
|
||||||
else if(!(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE))
|
else if(!(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE))
|
||||||
@@ -77,9 +86,9 @@ static uint64_t Direct3D11ScoreAdapter(IDXGIAdapter1* adapter)
|
|||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
if(base_device)
|
if(base_device)
|
||||||
base_device->lpVtbl->Release(base_device);
|
ID3D11Device_Release(base_device);
|
||||||
if(base_context)
|
if(base_context)
|
||||||
base_context->lpVtbl->Release(base_context);
|
ID3D11DeviceContext_Release(base_context);
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,11 +99,11 @@ static bool Direct3D11IsAdapterForbidden(IDXGIAdapter1* adapter, PulseDevice* fo
|
|||||||
for(uint32_t i = 0; i < forbiden_devices_count; i++)
|
for(uint32_t i = 0; i < forbiden_devices_count; i++)
|
||||||
{
|
{
|
||||||
DXGI_ADAPTER_DESC1 desc1;
|
DXGI_ADAPTER_DESC1 desc1;
|
||||||
adapter->lpVtbl->GetDesc1(adapter, &desc1);
|
IDXGIAdapter1_GetDesc1(adapter, &desc1);
|
||||||
|
|
||||||
DXGI_ADAPTER_DESC1 desc2;
|
DXGI_ADAPTER_DESC1 desc2;
|
||||||
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(forbiden_devices[i], Direct3D11Device*);
|
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)
|
if(desc1.AdapterLuid.HighPart == desc2.AdapterLuid.HighPart && desc1.AdapterLuid.LowPart == desc2.AdapterLuid.LowPart)
|
||||||
return true;
|
return true;
|
||||||
@@ -118,9 +127,9 @@ static IDXGIAdapter1* Direct3D11SelectAdapter(IDXGIFactory1* factory, PulseDevic
|
|||||||
best_device_score = current_device_score;
|
best_device_score = current_device_score;
|
||||||
best_device_id = i;
|
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 PULSE_NULLPTR;
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
@@ -141,7 +150,7 @@ PulseDevice Direct3D11CreateDevice(PulseBackend backend, PulseDevice* forbiden_d
|
|||||||
CreateDXGIFactory1(&IID_IDXGIFactory, (void**)&device->factory);
|
CreateDXGIFactory1(&IID_IDXGIFactory, (void**)&device->factory);
|
||||||
|
|
||||||
device->adapter = Direct3D11SelectAdapter(device->factory, forbiden_devices, forbiden_devices_count);
|
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 feature_levels[] = {
|
||||||
D3D_FEATURE_LEVEL_11_1,
|
D3D_FEATURE_LEVEL_11_1,
|
||||||
@@ -150,7 +159,11 @@ PulseDevice Direct3D11CreateDevice(PulseBackend backend, PulseDevice* forbiden_d
|
|||||||
D3D_FEATURE_LEVEL_10_0
|
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);
|
PULSE_LOAD_DRIVER_DEVICE(Direct3D11);
|
||||||
|
|
||||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend))
|
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*);
|
Direct3D11Device* d3d11_device = D3D11_RETRIEVE_DRIVER_DATA_AS(device, Direct3D11Device*);
|
||||||
if(d3d11_device == PULSE_NULLPTR || d3d11_device->device == PULSE_NULLPTR)
|
if(d3d11_device == PULSE_NULLPTR || d3d11_device->device == PULSE_NULLPTR)
|
||||||
return;
|
return;
|
||||||
d3d11_device->device->lpVtbl->Release(d3d11_device->device);
|
ID3D11Device_Release(d3d11_device->device);
|
||||||
d3d11_device->context->lpVtbl->Release(d3d11_device->context);
|
ID3D11DeviceContext_Release(d3d11_device->context);
|
||||||
d3d11_device->adapter->lpVtbl->Release(d3d11_device->adapter);
|
IDXGIAdapter1_Release(d3d11_device->adapter);
|
||||||
d3d11_device->factory->lpVtbl->Release(d3d11_device->factory);
|
IDXGIFactory1_Release(d3d11_device->factory);
|
||||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||||
PulseLogInfoFmt(device->backend, "(D3D11) destroyed device created from %ls", d3d11_device->description.Description);
|
PulseLogInfoFmt(device->backend, "(D3D11) destroyed device created from %ls", d3d11_device->description.Description);
|
||||||
free(d3d11_device);
|
free(d3d11_device);
|
||||||
|
|||||||
@@ -24,16 +24,6 @@ PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const Pulse
|
|||||||
|
|
||||||
pipeline->driver_data = opengl_pipeline;
|
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);
|
uint8_t* code = (uint8_t*)calloc(info->code_size + 1, 1);
|
||||||
memcpy(code, info->code, info->code_size);
|
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));
|
SoftComputePipeline* soft_pipeline = (SoftComputePipeline*)calloc(1, sizeof(SoftComputePipeline));
|
||||||
PULSE_CHECK_ALLOCATION_RETVAL(soft_pipeline, PULSE_NULL_HANDLE);
|
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->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));
|
soft_pipeline->entry_point = calloc(1, strlen(info->entrypoint));
|
||||||
PULSE_CHECK_ALLOCATION_RETVAL(soft_pipeline->entry_point, PULSE_NULL_HANDLE);
|
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;
|
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 };
|
VkShaderModuleCreateInfo shader_module_create_info = { 0 };
|
||||||
shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
shader_module_create_info.codeSize = info->code_size;
|
shader_module_create_info.codeSize = info->code_size;
|
||||||
|
|||||||
@@ -335,16 +335,6 @@ PulseComputePipeline WebGPUCreateComputePipeline(PulseDevice device, const Pulse
|
|||||||
|
|
||||||
pipeline->driver_data = webgpu_pipeline;
|
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 };
|
WGPUShaderSourceWGSL source = { 0 };
|
||||||
source.chain.next = PULSE_NULLPTR;
|
source.chain.next = PULSE_NULLPTR;
|
||||||
source.chain.sType = WGPUSType_ShaderSourceWGSL;
|
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))
|
if(info == PULSE_NULLPTR && PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||||
PulseLogError(device->backend, "null infos pointer");
|
PulseLogError(device->backend, "null infos pointer");
|
||||||
PULSE_CHECK_PTR_RETVAL(info, PULSE_NULL_HANDLE);
|
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);
|
PulseComputePipeline pipeline = device->PFN_CreateComputePipeline(device, info);
|
||||||
if(pipeline == PULSE_NULL_HANDLE)
|
if(pipeline == PULSE_NULL_HANDLE)
|
||||||
return PULSE_NULL_HANDLE;
|
return PULSE_NULL_HANDLE;
|
||||||
|
|||||||
@@ -15,6 +15,27 @@ void TestDeviceSetup()
|
|||||||
CleanupPulse(backend);
|
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()
|
void TestForbiddenDeviceSetup()
|
||||||
{
|
{
|
||||||
PulseBackend backend;
|
PulseBackend backend;
|
||||||
@@ -78,6 +99,7 @@ void TestDevice()
|
|||||||
RUN_TEST(TestDeviceSetup);
|
RUN_TEST(TestDeviceSetup);
|
||||||
RUN_TEST(TestForbiddenDeviceSetup);
|
RUN_TEST(TestForbiddenDeviceSetup);
|
||||||
RUN_TEST(TestInvalidBackendDeviceSetup);
|
RUN_TEST(TestInvalidBackendDeviceSetup);
|
||||||
|
RUN_TEST(TestMultipleDevices);
|
||||||
RUN_TEST(TestBackendInUse);
|
RUN_TEST(TestBackendInUse);
|
||||||
RUN_TEST(TestShaderFormatSupport);
|
RUN_TEST(TestShaderFormatSupport);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,12 +35,7 @@ local backends = {
|
|||||||
option = "d3d11",
|
option = "d3d11",
|
||||||
default = is_plat("windows", "msys", "mingw"),
|
default = is_plat("windows", "msys", "mingw"),
|
||||||
custom = function()
|
custom = function()
|
||||||
if is_plat("linux") then
|
add_syslinks("d3d11", "d3dcompiler_47", "dxgi", "windowscodecs")
|
||||||
add_sysincludedirs("/usr/include/dxvk/")
|
|
||||||
add_syslinks("dxvk_d3d11", "dxvk_dxgi")
|
|
||||||
else
|
|
||||||
add_syslinks("d3d11", "dxgi", "windowscodecs")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
Software = {
|
Software = {
|
||||||
|
|||||||
Reference in New Issue
Block a user