From 2952588a54c8fa746b30066914ccb4013e73b0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 26 Dec 2016 17:31:20 +0100 Subject: [PATCH] Add a selection of device caps to check for features. Unfinished. --- ext/native/thin3d/thin3d.h | 15 ++++++++++++++- ext/native/thin3d/thin3d_d3d9.cpp | 16 ++++++++++++---- ext/native/thin3d/thin3d_gl.cpp | 6 ++++++ ext/native/thin3d/thin3d_vulkan.cpp | 19 ++++++++++++++++--- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 8f5109cdb6f5..e381f087a311 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -436,11 +436,24 @@ struct PipelineDesc { RasterState *raster; }; +struct DeviceCaps { + DataFormat preferredDepthBufferFormat; + DataFormat preferredShadowMapFormatLow; + DataFormat preferredShadowMapFormatHigh; + bool anisoSupported; + bool depthRangeMinusOneToOne; // OpenGL style depth + bool geometryShaderSupported; + bool tesselationShaderSupported; + bool multiViewport; + bool dualSourceBlend; +}; + class DrawContext : public RefCountedObject { public: virtual ~DrawContext(); - virtual std::vector GetFeatureList() { return std::vector(); } + virtual const DeviceCaps &GetDeviceCaps() const = 0; + virtual std::vector GetFeatureList() const { return std::vector(); } // Partial pipeline state, used to create pipelines. (in practice, in d3d11 they'll use the native state objects directly). virtual DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) = 0; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index d3842db8b27c..3f23cfc5b6e5 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -470,6 +470,10 @@ class D3D9Context : public DrawContext { D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); ~D3D9Context(); + const DeviceCaps &GetDeviceCaps() const override { + return caps_; + } + DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; @@ -520,20 +524,24 @@ class D3D9Context : public DrawContext { LPDIRECT3DDEVICE9EX deviceEx_; int adapterId_; D3DADAPTER_IDENTIFIER9 identifier_; - D3DCAPS9 caps_; + D3DCAPS9 d3dCaps_; char shadeLangVersion_[64]; D3D9Pipeline *curPipeline_; + DeviceCaps caps_; }; D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) - : d3d_(d3d), d3dEx_(d3dEx), adapterId_(adapterId), device_(device), deviceEx_(deviceEx) { + : d3d_(d3d), d3dEx_(d3dEx), adapterId_(adapterId), device_(device), deviceEx_(deviceEx), caps_{} { CreatePresets(); d3d->GetAdapterIdentifier(adapterId, 0, &identifier_); - if (!FAILED(device->GetDeviceCaps(&caps_))) { - sprintf(shadeLangVersion_, "PS: %04x VS: %04x", caps_.PixelShaderVersion & 0xFFFF, caps_.VertexShaderVersion & 0xFFFF); + if (!FAILED(device->GetDeviceCaps(&d3dCaps_))) { + sprintf(shadeLangVersion_, "PS: %04x VS: %04x", d3dCaps_.PixelShaderVersion & 0xFFFF, d3dCaps_.VertexShaderVersion & 0xFFFF); } else { strcpy(shadeLangVersion_, "N/A"); } + caps_.multiViewport = false; + caps_.anisoSupported = true; + caps_.depthRangeMinusOneToOne = false; } D3D9Context::~D3D9Context() { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 82781ff751b9..a018c8323dea 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -419,6 +419,10 @@ class OpenGLContext : public DrawContext { OpenGLContext(); virtual ~OpenGLContext(); + const DeviceCaps &GetDeviceCaps() const override { + return caps_; + } + DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; @@ -508,10 +512,12 @@ class OpenGLContext : public DrawContext { std::vector samplerStates_; OpenGLPipeline *curPipeline_; + DeviceCaps caps_; }; OpenGLContext::OpenGLContext() { CreatePresets(); + // TODO: Detect caps } OpenGLContext::~OpenGLContext() { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index f2d6cbb6e553..ff1a6773d426 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -360,6 +360,10 @@ class VKContext : public DrawContext { VKContext(VulkanContext *vulkan); virtual ~VKContext(); + const DeviceCaps &GetDeviceCaps() const override { + return caps_; + } + DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override; Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; @@ -411,7 +415,7 @@ class VKContext : public DrawContext { VkDescriptorSet GetOrCreateDescriptorSet(VkBuffer buffer); - std::vector GetFeatureList() override; + std::vector GetFeatureList() const override; private: void ApplyDynamicState(); @@ -455,6 +459,8 @@ class VKContext : public DrawContext { int frameNum_; VulkanPushBuffer *push_; + + DeviceCaps caps_; }; int GetBpp(VkFormat format) { @@ -613,7 +619,13 @@ class VKTexture : public Texture { }; VKContext::VKContext(VulkanContext *vulkan) - : viewportDirty_(false), scissorDirty_(false), vulkan_(vulkan), frameNum_(0) { + : viewportDirty_(false), scissorDirty_(false), vulkan_(vulkan), frameNum_(0), caps_{} { + caps_.anisoSupported = vulkan->GetFeaturesAvailable().samplerAnisotropy != 0; + caps_.geometryShaderSupported = vulkan->GetFeaturesAvailable().geometryShader != 0; + caps_.tesselationShaderSupported = vulkan->GetFeaturesAvailable().tessellationShader != 0; + caps_.multiViewport = vulkan->GetFeaturesAvailable().multiViewport != 0; + caps_.dualSourceBlend = vulkan->GetFeaturesAvailable().dualSrcBlend != 0; + device_ = vulkan->GetDevice(); queue_ = vulkan->GetGraphicsQueue(); @@ -1139,9 +1151,10 @@ void AddFeature(std::vector &features, const char *name, VkBool32 a features.push_back(buf); } -std::vector VKContext::GetFeatureList() { +std::vector VKContext::GetFeatureList() const { const VkPhysicalDeviceFeatures &available = vulkan_->GetFeaturesAvailable(); const VkPhysicalDeviceFeatures &enabled = vulkan_->GetFeaturesEnabled(); + std::vector features; AddFeature(features, "dualSrcBlend", available.dualSrcBlend, enabled.dualSrcBlend); AddFeature(features, "logicOp", available.logicOp, enabled.logicOp);